setRenderTarget method

void setRenderTarget(
  1. RenderTarget? renderTarget, [
  2. int activeCubeFace = 0,
  3. int activeMipmapLevel = 0
])

Implementation

void setRenderTarget(RenderTarget? renderTarget, [int activeCubeFace = 0, int activeMipmapLevel = 0]) {
  _currentRenderTarget = renderTarget;
  _currentActiveCubeFace = activeCubeFace;
  _currentActiveMipmapLevel = activeMipmapLevel;

  bool useDefaultFramebuffer = true;
  Framebuffer? framebuffer;
  bool isCube = false;
  bool isRenderTarget3D = false;

  if (renderTarget != null) {
    final renderTargetProperties = properties.get(renderTarget);

    if (renderTargetProperties["__useDefaultFramebuffer"] != null) {
      // We need to make sure to rebind the framebuffer.
      state.bindFramebuffer(WebGL.FRAMEBUFFER, null);
      useDefaultFramebuffer = false;
    }
    else if (renderTargetProperties["__webglFramebuffer"] == null) {
      textures.setupRenderTarget(renderTarget);
    }
    else if (renderTargetProperties["__hasExternalTextures"] == true) {
      // Color and depth texture must be rebound in order for the swapchain to update.
      textures.rebindTextures(renderTarget, properties.get(renderTarget.texture)["__webglTexture"],properties.get(renderTarget.depthTexture)["__webglTexture"]);
    }else if ( renderTarget.depthBuffer ) {
      // check if the depth texture is already bound to the frame buffer and that it's been initialized
      final depthTexture = renderTarget.depthTexture;
      if ( renderTargetProperties['__boundDepthTexture'] != depthTexture ) {

        // check if the depth texture is compatible
        if (
          depthTexture != null &&
          properties.has( depthTexture ) &&
          ( renderTarget.width != depthTexture.image.width || renderTarget.height != depthTexture.image.height )
        ) {
          throw( 'WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size.' );
        }

        // Swap the depth buffer to the currently attached one
        textures.setupDepthRenderbuffer( renderTarget );
      }
    }

    final texture = renderTarget.texture;

    if (texture is Data3DTexture || texture is DataArrayTexture || texture is CompressedArrayTexture) {
      isRenderTarget3D = true;
    }

    final webglFramebuffer = properties.get(renderTarget)["__webglFramebuffer"];

    if (renderTarget is WebGLCubeRenderTarget) {
      if (webglFramebuffer[ activeCubeFace ] is List) {
        framebuffer = webglFramebuffer[ activeCubeFace ][ activeMipmapLevel ];
      }
      else {
        framebuffer = webglFramebuffer[ activeCubeFace ];
      }
      isCube = true;
    }
    else if ((renderTarget.samples > 0) && textures.useMultisampledRTT(renderTarget) == false) {
      framebuffer = properties.get(renderTarget)["__webglMultisampledFramebuffer"];
    }
    else {
      if (webglFramebuffer is List) {
        framebuffer = webglFramebuffer[ activeMipmapLevel ];
      } else {
        framebuffer = webglFramebuffer;
      }
    }

    _currentViewport.setFrom(renderTarget.viewport);
    _currentScissor.setFrom(renderTarget.scissor);
    _currentScissorTest = renderTarget.scissorTest;
  }
  else {
    _currentViewport.setFrom(_viewport).scale(_pixelRatio).floor();
    _currentScissor.setFrom(_scissor).scale(_pixelRatio).floor();
    _currentScissorTest = _scissorTest;
  }

  // Use a scratch frame buffer if rendering to a mip level to avoid depth buffers
  // being bound that are different sizes.
  if ( activeMipmapLevel != 0 ) {
    framebuffer = _scratchFrameBuffer;
  }

  final framebufferBound = state.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer);

  if (framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer) {
    state.drawBuffers(renderTarget, framebuffer);
  }

  state.viewport(_currentViewport);
  state.scissor(_currentScissor);
  state.setScissorTest(_currentScissorTest!);

  if (isCube) {
    final textureProperties = properties.get(renderTarget!.texture);
    _gl.framebufferTexture2D(WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + activeCubeFace, textureProperties["__webglTexture"], activeMipmapLevel);
  }
  else if (isRenderTarget3D) {
    final textureProperties = properties.get(renderTarget!.texture);
    final layer = activeCubeFace;
    _gl.framebufferTextureLayer( WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, textureProperties["__webglTexture"], activeMipmapLevel, layer);
  }
  else if ( renderTarget != null && activeMipmapLevel != 0 ) {
    // Only bind the frame buffer if we are using a scratch frame buffer to render to a mipmap.
    // If we rebind the texture when using a multi sample buffer then an error about inconsistent samples will be thrown.
    final textureProperties = properties.get( renderTarget.texture );
    _gl.framebufferTexture2D( WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_2D, textureProperties['__webglTexture'], activeMipmapLevel );
  }

  _currentMaterialId = -1; // reset current material to ensure correct uniform bindings
}