// TODO: have a flag to invert the eyes (Cross Eye 3D), as mentioned in // TODO: http://forum.terasology.org/threads/happy-coding.1018/#post-11264 private void renderFinalStereoImage(WorldRenderer.WorldRenderingStage renderingStage) { if (renderingProcess.isNotTakingScreenshot()) { buffers.sceneFinal.bind(); } else { buffers.ocUndistorted.bind(); } switch (renderingStage) { case LEFT_EYE: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderFullscreenQuad(0, 0, fullScale.width() / 2, fullScale.height()); break; case RIGHT_EYE: // no glClear() here: the rendering for the second eye is being added besides the first // eye's rendering renderFullscreenQuad( fullScale.width() / 2 + 1, 0, fullScale.width() / 2, fullScale.height()); if (renderingProcess.isNotTakingScreenshot()) { graphicState.bindDisplay(); applyOculusDistortion(buffers.sceneFinal); } else { buffers.sceneFinal.bind(); applyOculusDistortion(buffers.ocUndistorted); renderingProcess.saveScreenshot(); // when saving a screenshot we do NOT send the image to screen, // to avoid the brief flicker of the screenshot for one frame } break; } }
private void renderFinalMonoImage() { if (renderingProcess.isNotTakingScreenshot()) { graphicState.bindDisplay(); renderFullscreenQuad(0, 0, Display.getWidth(), Display.getHeight()); } else { buffers.sceneFinal.bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderFullscreenQuad(0, 0, fullScale.width(), fullScale.height()); renderingProcess.saveScreenshot(); // when saving a screenshot we do not send the image to screen, // to avoid the brief one-frame flicker of the screenshot // This is needed to avoid the UI (which is not currently saved within the // screenshot) being rendered for one frame with buffers.sceneFinal size. setViewportToWholeDisplay(); } }
private void updateOcShaderParametersForVP( int vpX, int vpY, int vpWidth, int vpHeight, WorldRenderer.WorldRenderingStage renderingStage) { float w = (float) vpWidth / fullScale.width(); float h = (float) vpHeight / fullScale.height(); float x = (float) vpX / fullScale.width(); float y = (float) vpY / fullScale.height(); float as = (float) vpWidth / vpHeight; materials.ocDistortion.setFloat4( "ocHmdWarpParam", OculusVrHelper.getDistortionParams()[0], OculusVrHelper.getDistortionParams()[1], OculusVrHelper.getDistortionParams()[2], OculusVrHelper.getDistortionParams()[3], true); float ocLensCenter = (renderingStage == WorldRenderer.WorldRenderingStage.RIGHT_EYE) ? -1.0f * OculusVrHelper.getLensViewportShift() : OculusVrHelper.getLensViewportShift(); materials.ocDistortion.setFloat2( "ocLensCenter", x + (w + ocLensCenter * 0.5f) * 0.5f, y + h * 0.5f, true); materials.ocDistortion.setFloat2("ocScreenCenter", x + w * 0.5f, y + h * 0.5f, true); float scaleFactor = 1.0f / OculusVrHelper.getScaleFactor(); materials.ocDistortion.setFloat2( "ocScale", (w / 2) * scaleFactor, (h / 2) * scaleFactor * as, true); materials.ocDistortion.setFloat2("ocScaleIn", (2 / w), (2 / h) / as, true); }
private void setViewportTo(FBO.Dimensions dimensions) { glViewport(0, 0, dimensions.width(), dimensions.height()); }
private void setViewportToWholeDisplay() { glViewport(0, 0, fullScale.width(), fullScale.height()); }
private void applyOculusDistortion(FBO inputBuffer) { materials.ocDistortion.enable(); int texId = 0; GL13.glActiveTexture(GL13.GL_TEXTURE0 + texId); inputBuffer.bindTexture(); materials.ocDistortion.setInt("texInputBuffer", texId, true); if (renderingProcess.isNotTakingScreenshot()) { updateOcShaderParametersForVP( 0, 0, fullScale.width() / 2, fullScale.height(), WorldRenderer.WorldRenderingStage.LEFT_EYE); renderFullscreenQuad(0, 0, Display.getWidth(), Display.getHeight()); updateOcShaderParametersForVP( fullScale.width() / 2 + 1, 0, fullScale.width() / 2, fullScale.height(), WorldRenderer.WorldRenderingStage.RIGHT_EYE); renderFullscreenQuad(0, 0, Display.getWidth(), Display.getHeight()); } else { // what follows -should- work also when there is no screenshot being taken, but somehow it // doesn't, hence the block above updateOcShaderParametersForVP( 0, 0, fullScale.width() / 2, fullScale.height(), WorldRenderer.WorldRenderingStage.LEFT_EYE); renderFullscreenQuad(0, 0, fullScale.width(), fullScale.height()); updateOcShaderParametersForVP( fullScale.width() / 2 + 1, 0, fullScale.width() / 2, fullScale.height(), WorldRenderer.WorldRenderingStage.RIGHT_EYE); renderFullscreenQuad(0, 0, fullScale.width(), fullScale.height()); } }