setupRenderTarget method

void setupRenderTarget(
  1. RenderTarget renderTarget
)

Implementation

void setupRenderTarget(RenderTarget renderTarget) {
		final texture = renderTarget.texture;

		final renderTargetProperties = properties.get( renderTarget );
		final textureProperties = properties.get( texture );

		renderTarget.addEventListener( 'dispose', onRenderTargetDispose );

		final textures = renderTarget.textures;

		final isCube = renderTarget is WebGLCubeRenderTarget;
		final isMultipleRenderTargets = ( textures.length > 1 );

		if ( ! isMultipleRenderTargets ) {
			if ( textureProperties['__webglTexture'] == null ) {
				textureProperties['__webglTexture'] = _gl.createTexture();
			}

			textureProperties['__version'] = texture.version;
			info.memory['textures'] = info.memory['textures']! + 1;
		}

		// Setup framebuffer

		if ( isCube ) {
			renderTargetProperties['__webglFramebuffer'] = [];
			for ( int i = 0; i < 6; i ++ ) {
				if (texture.mipmaps.isNotEmpty ) {
					renderTargetProperties['__webglFramebuffer'][ i ] = [];
					for ( int level = 0; level < texture.mipmaps.length; level ++ ) {
						renderTargetProperties['__webglFramebuffer'][ i ][ level ] = _gl.createFramebuffer();
					}
				} else {
					(renderTargetProperties['__webglFramebuffer'] as List).listSetter(i, _gl.createFramebuffer());
				}
			}
		} else {
			if ( texture.mipmaps.isNotEmpty ) {
				renderTargetProperties['__webglFramebuffer'] = [];
				for ( int level = 0; level < texture.mipmaps.length; level ++ ) {
					renderTargetProperties['__webglFramebuffer'][ level ] = _gl.createFramebuffer();
				}
			} else {
				renderTargetProperties['__webglFramebuffer'] = _gl.createFramebuffer();
			}

			if ( isMultipleRenderTargets ) {
				for ( int i = 0, il = textures.length; i < il; i ++ ) {
					final attachmentProperties = properties.get( textures[ i ] );
					if ( attachmentProperties['__webglTexture'] == null ) {
						attachmentProperties['__webglTexture'] = _gl.createTexture();
						info.memory['textures'] = info.memory['textures']! +1;;
					}
				}
			}

			if ( ( renderTarget.samples > 0 ) && useMultisampledRTT( renderTarget ) == false ) {
				renderTargetProperties['__webglMultisampledFramebuffer'] = _gl.createFramebuffer();
				renderTargetProperties['__webglColorRenderbuffer'] = [];

				state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglMultisampledFramebuffer'] );

				for ( int i = 0; i < textures.length; i ++ ) {
					final texture = textures[ i ];
					(renderTargetProperties['__webglColorRenderbuffer'] as List).listSetter(i, _gl.createRenderbuffer());

					_gl.bindRenderbuffer( WebGL.RENDERBUFFER, renderTargetProperties['__webglColorRenderbuffer'][ i ] );

					final glFormat = utils.convert( texture.format, texture.colorSpace );
					final glType = utils.convert( texture.type );
					final glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace, renderTarget.isXRRenderTarget == true );
					final samples = getRenderTargetSamples( renderTarget );

					_gl.renderbufferStorageMultisample( WebGL.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );
					_gl.framebufferRenderbuffer( WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0 + i, WebGL.RENDERBUFFER, renderTargetProperties['__webglColorRenderbuffer'][ i ] );
				}

				_gl.bindRenderbuffer( WebGL.RENDERBUFFER, null );

				if ( renderTarget.depthBuffer ) {
					renderTargetProperties['__webglDepthRenderbuffer'] = _gl.createRenderbuffer();
					setupRenderBufferStorage( renderTargetProperties['__webglDepthRenderbuffer'], renderTarget, true );
				}

				state.bindFramebuffer( WebGL.FRAMEBUFFER, null );
			}
		}

		// Setup color buffer

		if ( isCube ) {
			state.bindTexture( WebGL.TEXTURE_CUBE_MAP, textureProperties['__webglTexture'] );
			setTextureParameters( WebGL.TEXTURE_CUBE_MAP, texture );

			for ( int i = 0; i < 6; i ++ ) {
				if (texture.mipmaps.isNotEmpty ) {
					for ( int level = 0; level < texture.mipmaps.length; level ++ ) {
						setupFrameBufferTexture( renderTargetProperties['__webglFramebuffer'][ i ][ level ], renderTarget, texture, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, level );
					}
				} else {
					setupFrameBufferTexture( renderTargetProperties['__webglFramebuffer'][ i ], renderTarget, texture, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0 );
				}
			}

			if ( textureNeedsGenerateMipmaps( texture ) ) {
				generateMipmap( WebGL.TEXTURE_CUBE_MAP );
			}

			state.unbindTexture();

		} else if ( isMultipleRenderTargets ) {
			for ( int i = 0, il = textures.length; i < il; i ++ ) {
				final attachment = textures[ i ];
				final attachmentProperties = properties.get( attachment );

				state.bindTexture( WebGL.TEXTURE_2D, attachmentProperties['__webglTexture'] );
				setTextureParameters( WebGL.TEXTURE_2D, attachment );
				setupFrameBufferTexture( renderTargetProperties['__webglFramebuffer'], renderTarget, attachment, WebGL.COLOR_ATTACHMENT0 + i, WebGL.TEXTURE_2D, 0 );

				if ( textureNeedsGenerateMipmaps( attachment ) ) {
					generateMipmap( WebGL.TEXTURE_2D );
				}
			}

			state.unbindTexture();
		} else {
			int glTextureType = WebGL.TEXTURE_2D;

			if ( renderTarget is WebGL3DRenderTarget || renderTarget is WebGLArrayRenderTarget ) {
				glTextureType = renderTarget is WebGL3DRenderTarget ? WebGL.TEXTURE_3D : WebGL.TEXTURE_2D_ARRAY;
			}

			state.bindTexture( glTextureType, textureProperties['__webglTexture'] );
			setTextureParameters( glTextureType, texture );

			if (texture.mipmaps.isNotEmpty ) {
				for ( int level = 0; level < texture.mipmaps.length; level ++ ) {
					setupFrameBufferTexture( renderTargetProperties['__webglFramebuffer'][ level ], renderTarget, texture, WebGL.COLOR_ATTACHMENT0, glTextureType, level );
				}
			} else {
				setupFrameBufferTexture( renderTargetProperties['__webglFramebuffer'], renderTarget, texture, WebGL.COLOR_ATTACHMENT0, glTextureType, 0 );
			}

			if ( textureNeedsGenerateMipmaps( texture ) ) {
				generateMipmap( glTextureType );
			}
			state.unbindTexture();
		}


		if ( renderTarget.depthBuffer ) {
			setupDepthRenderbuffer( renderTarget );
		}
}