@Override
  protected void onRender(final long ellapsedTime, final double deltaTime) {
    mUserScene = getCurrentScene();

    setRenderTarget(mLeftRenderTarget);
    getCurrentScene().switchCamera(mCameraLeft);
    GLES20.glViewport(0, 0, mViewportWidthHalf, mDefaultViewportHeight);
    mCameraLeft.setProjectionMatrix(mViewportWidthHalf, mDefaultViewportHeight);
    mCameraLeft.setOrientation(mCameraOrientation);

    render(ellapsedTime, deltaTime);

    setRenderTarget(mRightRenderTarget);

    getCurrentScene().switchCamera(mCameraRight);
    mCameraRight.setProjectionMatrix(mViewportWidthHalf, mDefaultViewportHeight);
    mCameraRight.setOrientation(mCameraOrientation);

    render(ellapsedTime, deltaTime);

    switchSceneDirect(mSideBySideScene);
    GLES20.glViewport(0, 0, mDefaultViewportWidth, mDefaultViewportHeight);

    setRenderTarget(null);

    render(ellapsedTime, deltaTime);

    switchSceneDirect(mUserScene);
  }
  @Override
  public void initScene() {
    mCameraLeft = new Camera();
    mCameraLeft.setNearPlane(.01f);
    mCameraLeft.setFieldOfView(getCurrentCamera().getFieldOfView());
    mCameraLeft.setNearPlane(getCurrentCamera().getNearPlane());
    mCameraLeft.setFarPlane(getCurrentCamera().getFarPlane());

    mCameraRight = new Camera();
    mCameraRight.setNearPlane(.01f);
    mCameraRight.setFieldOfView(getCurrentCamera().getFieldOfView());
    mCameraRight.setNearPlane(getCurrentCamera().getNearPlane());
    mCameraRight.setFarPlane(getCurrentCamera().getFarPlane());

    setPupilDistance(mPupilDistance);

    mLeftQuadMaterial = new Material();
    mLeftQuadMaterial.setColorInfluence(0);
    mRightQuadMaterial = new Material();
    mRightQuadMaterial.setColorInfluence(0);

    mSideBySideScene = new RajawaliScene(this);

    mLeftQuad = new ScreenQuad();
    mLeftQuad.setScaleX(.5);
    mLeftQuad.setX(-.25);
    mLeftQuad.setMaterial(mLeftQuadMaterial);
    mSideBySideScene.addChild(mLeftQuad);

    mRightQuad = new ScreenQuad();
    mRightQuad.setScaleX(.5);
    mRightQuad.setX(.25);
    mRightQuad.setMaterial(mRightQuadMaterial);
    mSideBySideScene.addChild(mRightQuad);

    addScene(mSideBySideScene);

    mViewportWidthHalf = (int) (mDefaultViewportWidth * .5f);

    mLeftRenderTarget = new RenderTarget("sbsLeftRT", mViewportWidthHalf, mDefaultViewportHeight);
    mLeftRenderTarget.setFullscreen(false);
    mRightRenderTarget = new RenderTarget("sbsRightRT", mViewportWidthHalf, mDefaultViewportHeight);
    mRightRenderTarget.setFullscreen(false);

    mCameraLeft.setProjectionMatrix(mViewportWidthHalf, mDefaultViewportHeight);
    mCameraRight.setProjectionMatrix(mViewportWidthHalf, mDefaultViewportHeight);

    addRenderTarget(mLeftRenderTarget);
    addRenderTarget(mRightRenderTarget);

    try {
      mLeftQuadMaterial.addTexture(mLeftRenderTarget.getTexture());
      mRightQuadMaterial.addTexture(mRightRenderTarget.getTexture());
    } catch (TextureException e) {
      e.printStackTrace();
    }
  }
Пример #3
0
  public Scene(Renderer renderer) {
    mRenderer = renderer;
    mAlpha = 0;
    mAnimations = Collections.synchronizedList(new CopyOnWriteArrayList<Animation>());
    mPreCallbacks = Collections.synchronizedList(new CopyOnWriteArrayList<ASceneFrameCallback>());
    mPreDrawCallbacks =
        Collections.synchronizedList(new CopyOnWriteArrayList<ASceneFrameCallback>());
    mPostCallbacks = Collections.synchronizedList(new CopyOnWriteArrayList<ASceneFrameCallback>());
    mChildren = Collections.synchronizedList(new CopyOnWriteArrayList<Object3D>());
    mPlugins = Collections.synchronizedList(new CopyOnWriteArrayList<IRendererPlugin>());
    mCameras = Collections.synchronizedList(new CopyOnWriteArrayList<Camera>());
    mLights = Collections.synchronizedList(new CopyOnWriteArrayList<ALight>());
    mFrameTaskQueue = new LinkedList<>();

    mCamera = new Camera();
    mCamera.setZ(mEyeZ);
    mCameras.add(mCamera);

    mAntiAliasingConfig = ISurface.ANTI_ALIASING_CONFIG.NONE; // Default to none
  }
Пример #4
0
    private Matrix4 createLightViewProjectionMatrix(DirectionalLight light) {
      //
      // -- Get the frustum corners in world space
      //
      mCamera.getFrustumCorners(mFrustumCorners, true);
      //
      // -- Get the frustum centroid
      //
      mFrustumCentroid.setAll(0, 0, 0);
      for (int i = 0; i < 8; i++) mFrustumCentroid.add(mFrustumCorners[i]);
      mFrustumCentroid.divide(8.0);

      //
      // --
      //

      BoundingBox lightBox = new BoundingBox(mFrustumCorners);
      double distance = mFrustumCentroid.distanceTo(lightBox.getMin());
      Vector3 lightDirection = light.getDirectionVector().clone();
      lightDirection.normalize();
      Vector3 lightPosition =
          Vector3.subtractAndCreate(
              mFrustumCentroid, Vector3.multiplyAndCreate(lightDirection, distance));

      //
      // --
      //

      mLightViewMatrix.setToLookAt(lightPosition, mFrustumCentroid, Vector3.Y);

      for (int i = 0; i < 8; i++) mFrustumCorners[i].multiply(mLightViewMatrix);

      BoundingBox b = new BoundingBox(mFrustumCorners);
      mLightProjectionMatrix.setToOrthographic(
          b.getMin().x, b.getMax().x, b.getMin().y, b.getMax().y, -b.getMax().z, -b.getMin().z);

      mLightModelViewProjectionMatrix.setAll(mLightProjectionMatrix);
      mLightModelViewProjectionMatrix.multiply(mLightViewMatrix);
      return mLightModelViewProjectionMatrix;
    }
Пример #5
0
 /**
  * Updates the projection matrix of the current camera for new view port dimensions.
  *
  * @param width int the new viewport width in pixels.
  * @param height in the new viewport height in pixes.
  */
 public void updateProjectionMatrix(int width, int height) {
   mCamera.setProjectionMatrix(width, height);
 }
Пример #6
0
  public void render(
      long ellapsedTime, double deltaTime, RenderTarget renderTarget, Material sceneMaterial) {
    // Scene color-picking requests are relative to the prior frame's render
    // state, so handle any pending request before applying this frame's updates...
    if (mPickerInfo != null) {
      doColorPicking(mPickerInfo);
      // One-shot, once per frame at most
      mPickerInfo = null;
    }

    performFrameTasks(); // Handle the task queue

    synchronized (mFrameTaskQueue) {
      if (mLightsDirty) {
        updateMaterialsWithLights();
        mLightsDirty = false;
      }
    }

    synchronized (mNextSkyboxLock) {
      // Check if we need to switch the skybox, and if so, do it.
      if (mNextSkybox != null) {
        mSkybox = mNextSkybox;
        mNextSkybox = null;
      }
    }
    synchronized (mNextCameraLock) {
      // Check if we need to switch the camera, and if so, do it.
      if (mNextCamera != null) {
        mCamera = mNextCamera;
        mCamera.setProjectionMatrix(mRenderer.getViewportWidth(), mRenderer.getViewportHeight());
        mNextCamera = null;
      }
    }

    int clearMask = mAlwaysClearColorBuffer ? GLES20.GL_COLOR_BUFFER_BIT : 0;

    if (renderTarget != null) {
      renderTarget.bind();
      GLES20.glClearColor(mRed, mGreen, mBlue, mAlpha);
    } else {
      //			GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
      GLES20.glClearColor(mRed, mGreen, mBlue, mAlpha);
    }

    if (mEnableDepthBuffer) {
      clearMask |= GLES20.GL_DEPTH_BUFFER_BIT;
      GLES20.glEnable(GLES20.GL_DEPTH_TEST);
      GLES20.glDepthFunc(GLES20.GL_LESS);
      GLES20.glDepthMask(true);
      GLES20.glClearDepthf(1.0f);
    }
    if (mAntiAliasingConfig.equals(ISurface.ANTI_ALIASING_CONFIG.COVERAGE)) {
      clearMask |= GL_COVERAGE_BUFFER_BIT_NV;
    }

    GLES20.glClear(clearMask);

    // Execute onPreFrame callbacks
    // We explicitly break out the steps here to help the compiler optimize
    final int preCount = mPreCallbacks.size();
    if (preCount > 0) {
      synchronized (mPreCallbacks) {
        for (int i = 0; i < preCount; ++i) {
          mPreCallbacks.get(i).onPreFrame(ellapsedTime, deltaTime);
        }
      }
    }

    // Update all registered animations
    synchronized (mAnimations) {
      for (int i = 0, j = mAnimations.size(); i < j; ++i) {
        Animation anim = mAnimations.get(i);
        if (anim.isPlaying()) anim.update(deltaTime);
      }
    }

    // We are beginning the render process so we need to update the camera matrix before fetching
    // its values
    mCamera.onRecalculateModelMatrix(null);

    // Get the view and projection matrices in advance
    mVMatrix = mCamera.getViewMatrix();
    mPMatrix = mCamera.getProjectionMatrix();
    // Pre-multiply View and Projection matrices once for speed
    mVPMatrix.setAll(mPMatrix).multiply(mVMatrix);
    mInvVPMatrix.setAll(mVPMatrix).inverse();
    mCamera.updateFrustum(mInvVPMatrix); // Update frustum plane

    // Update the model matrices of all the lights
    synchronized (mLights) {
      final int numLights = mLights.size();
      for (int i = 0; i < numLights; ++i) {
        mLights.get(i).onRecalculateModelMatrix(null);
      }
    }

    // Execute onPreDraw callbacks
    // We explicitly break out the steps here to help the compiler optimize
    final int preDrawCount = mPreDrawCallbacks.size();
    if (preDrawCount > 0) {
      synchronized (mPreDrawCallbacks) {
        for (int i = 0; i < preDrawCount; ++i) {
          mPreDrawCallbacks.get(i).onPreDraw(ellapsedTime, deltaTime);
        }
      }
    }

    if (mSkybox != null) {
      GLES20.glDisable(GLES20.GL_DEPTH_TEST);
      GLES20.glDepthMask(false);

      mSkybox.setPosition(mCamera.getX(), mCamera.getY(), mCamera.getZ());
      // Model matrix updates are deferred to the render method due to parent matrix needs
      // Render the skybox
      mSkybox.render(mCamera, mVPMatrix, mPMatrix, mVMatrix, null);

      if (mEnableDepthBuffer) {
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
        GLES20.glDepthMask(true);
      }
    }

    if (sceneMaterial != null) {
      sceneMaterial.useProgram();
      sceneMaterial.bindTextures();
    }

    synchronized (mChildren) {
      for (int i = 0, j = mChildren.size(); i < j; ++i) {
        // Model matrix updates are deferred to the render method due to parent matrix needs
        mChildren.get(i).render(mCamera, mVPMatrix, mPMatrix, mVMatrix, sceneMaterial);
      }
    }

    if (mDisplaySceneGraph) {
      mSceneGraph.displayGraph(mCamera, mVPMatrix, mPMatrix, mVMatrix);
    }

    if (sceneMaterial != null) {
      sceneMaterial.unbindTextures();
    }

    synchronized (mPlugins) {
      for (int i = 0, j = mPlugins.size(); i < j; i++) mPlugins.get(i).render();
    }

    if (renderTarget != null) {
      renderTarget.unbind();
    }

    // Execute onPostFrame callbacks
    // We explicitly break out the steps here to help the compiler optimize
    final int postCount = mPostCallbacks.size();
    if (postCount > 0) {
      synchronized (mPostCallbacks) {
        for (int i = 0; i < postCount; ++i) {
          mPostCallbacks.get(i).onPostFrame(ellapsedTime, deltaTime);
        }
      }
    }
  }
 public void setPupilDistance(double pupilDistance) {
   mPupilDistance = pupilDistance;
   if (mCameraLeft != null) mCameraLeft.setX(pupilDistance * -.5);
   if (mCameraLeft != null) mCameraRight.setX(pupilDistance * .5);
 }