Пример #1
0
  // 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;
    }
  }
Пример #2
0
 // TODO: update javadoc when the rendering process becomes the FrameBuffersManager
 public void obtainStaticFBOs() {
   buffers.downSampledScene[4] = renderingProcess.getFBO("scene16");
   buffers.downSampledScene[3] = renderingProcess.getFBO("scene8");
   buffers.downSampledScene[2] = renderingProcess.getFBO("scene4");
   buffers.downSampledScene[1] = renderingProcess.getFBO("scene2");
   buffers.downSampledScene[0] = renderingProcess.getFBO("scene1");
 }
Пример #3
0
  // TODO: verify if this can be achieved entirely in the GPU, during tone mapping perhaps?
  public void downsampleSceneAndUpdateExposure() {
    if (renderingConfig.isEyeAdaptation()) {
      PerformanceMonitor.startActivity("Updating exposure");

      downsampleSceneInto1x1pixelsBuffer();

      renderingProcess
          .getCurrentReadbackPBO()
          .copyFromFBO(
              buffers.downSampledScene[0].fboId, 1, 1, GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE);

      renderingProcess.swapReadbackPBOs();

      ByteBuffer pixels = renderingProcess.getCurrentReadbackPBO().readBackPixels();

      if (pixels.limit() < 3) {
        logger.error("Failed to auto-update the exposure value.");
        return;
      }

      // TODO: make this line more readable by breaking it in smaller pieces
      currentSceneLuminance =
          0.2126f * (pixels.get(2) & 0xFF) / 255.f
              + 0.7152f * (pixels.get(1) & 0xFF) / 255.f
              + 0.0722f * (pixels.get(0) & 0xFF) / 255.f;

      float targetExposure = hdrMaxExposure;

      if (currentSceneLuminance > 0) {
        targetExposure = hdrTargetLuminance / currentSceneLuminance;
      }

      float maxExposure = hdrMaxExposure;

      if (CoreRegistry.get(BackdropProvider.class).getDaylight()
          == 0.0) { // TODO: fetch the backdropProvider earlier and only once
        maxExposure = hdrMaxExposureNight;
      }

      if (targetExposure > maxExposure) {
        targetExposure = maxExposure;
      } else if (targetExposure < hdrMinExposure) {
        targetExposure = hdrMinExposure;
      }

      currentExposure = TeraMath.lerp(currentExposure, targetExposure, hdrExposureAdjustmentSpeed);

    } else {
      if (CoreRegistry.get(BackdropProvider.class).getDaylight() == 0.0) {
        currentExposure = hdrMaxExposureNight;
      } else {
        currentExposure = hdrExposureDefault;
      }
    }
    PerformanceMonitor.endActivity();
  }
Пример #4
0
  /**
   * Part of the deferred lighting technique, this method applies lighting through screen-space
   * calculations to the previously flat-lit world rendering stored in the primary FBO. // TODO:
   * rename sceneOpaque* FBOs to primaryA/B
   *
   * <p>See http://en.wikipedia.org/wiki/Deferred_shading as a starting point.
   */
  public void applyLightBufferPass() {

    int texId = 0;

    GL13.glActiveTexture(GL13.GL_TEXTURE0 + texId);
    buffers.sceneOpaque.bindTexture();
    materials.lightBufferPass.setInt("texSceneOpaque", texId++);

    GL13.glActiveTexture(GL13.GL_TEXTURE0 + texId);
    buffers.sceneOpaque.bindDepthTexture();
    materials.lightBufferPass.setInt("texSceneOpaqueDepth", texId++);

    GL13.glActiveTexture(GL13.GL_TEXTURE0 + texId);
    buffers.sceneOpaque.bindNormalsTexture();
    materials.lightBufferPass.setInt("texSceneOpaqueNormals", texId++);

    GL13.glActiveTexture(GL13.GL_TEXTURE0 + texId);
    buffers.sceneOpaque.bindLightBufferTexture();
    materials.lightBufferPass.setInt("texSceneOpaqueLightBuffer", texId, true);

    buffers.sceneOpaquePingPong.bind();
    graphicState.setRenderBufferMask(buffers.sceneOpaquePingPong, true, true, true);

    setViewportTo(buffers.sceneOpaquePingPong.dimensions());
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // TODO: verify this is necessary

    renderFullscreenQuad();

    graphicState.bindDisplay(); // TODO: verify this is necessary
    setViewportToWholeDisplay(); // TODO: verify this is necessary

    renderingProcess.swapSceneOpaqueFBOs();
    buffers.sceneOpaque.attachDepthBufferTo(buffers.sceneReflectiveRefractive);
  }
Пример #5
0
  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();
    }
  }
Пример #6
0
  /**
   * Adds outlines and ambient occlusion to the rendering obtained so far stored in the primary FBO.
   * Stores the resulting output back into the primary buffer.
   */
  public void generatePrePostComposite() {
    materials.prePostComposite.enable();

    // TODO: verify if there should be bound textures here.
    buffers.sceneOpaquePingPong.bind();

    setViewportTo(buffers.sceneOpaquePingPong.dimensions());
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // TODO: verify this is necessary

    renderFullscreenQuad();

    graphicState.bindDisplay(); // TODO: verify this is necessary
    setViewportToWholeDisplay(); // TODO: verify this is necessary

    renderingProcess.swapSceneOpaqueFBOs();
    buffers.sceneOpaque.attachDepthBufferTo(buffers.sceneReflectiveRefractive);
  }
Пример #7
0
  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());
    }
  }
Пример #8
0
 /**
  * In a number of occasions the rendering loop swaps two important FBOs. This method is used to
  * trigger the PostProcessor instance into refreshing the internal references to these FBOs.
  */
 public void refreshSceneOpaqueFBOs() {
   buffers.sceneOpaque = renderingProcess.getFBO("sceneOpaque");
   buffers.sceneOpaquePingPong = renderingProcess.getFBO("sceneOpaquePingPong");
 }
Пример #9
0
  // TODO: update javadoc when the rendering process becomes the FrameBuffersManager
  public void refreshDynamicFBOs() {
    // initial renderings
    buffers.sceneOpaque = renderingProcess.getFBO("sceneOpaque");
    buffers.sceneOpaquePingPong = renderingProcess.getFBO("sceneOpaquePingPong");

    buffers.sceneSkyBand0 = renderingProcess.getFBO("sceneSkyBand0");
    buffers.sceneSkyBand1 = renderingProcess.getFBO("sceneSkyBand1");

    buffers.sceneReflectiveRefractive = renderingProcess.getFBO("sceneReflectiveRefractive");
    // sceneReflected, in case one wonders, is not used by the post-processor.

    // pre-post composite
    buffers.outline = renderingProcess.getFBO("outline");
    buffers.ssao = renderingProcess.getFBO("ssao");
    buffers.ssaoBlurred = renderingProcess.getFBO("ssaoBlurred");

    // initial post-processing
    buffers.lightShafts = renderingProcess.getFBO("lightShafts");
    buffers.initialPost = renderingProcess.getFBO("initialPost");
    buffers.currentReadbackPBO = renderingProcess.getCurrentReadbackPBO();
    buffers.sceneToneMapped = renderingProcess.getFBO("sceneToneMapped");

    buffers.sceneHighPass = renderingProcess.getFBO("sceneHighPass");
    buffers.sceneBloom0 = renderingProcess.getFBO("sceneBloom0");
    buffers.sceneBloom1 = renderingProcess.getFBO("sceneBloom1");
    buffers.sceneBloom2 = renderingProcess.getFBO("sceneBloom2");

    buffers.sceneBlur0 = renderingProcess.getFBO("sceneBlur0");
    buffers.sceneBlur1 = renderingProcess.getFBO("sceneBlur1");

    // final post-processing
    buffers.ocUndistorted = renderingProcess.getFBO("ocUndistorted");
    buffers.sceneFinal = renderingProcess.getFBO("sceneFinal");

    fullScale = buffers.sceneOpaque.dimensions();
  }