提交 b32c8de3 编写于 作者: M Marius Kintel

Green refactoring of WebGLRenderTarget resource handling, preparing for depth texture support

上级 1e5e00d2
/**
* @author szimek / https://github.com/szimek/
* @author alteredq / http://alteredqualia.com/
* @author Marius Kintel / https://github.com/kintel
*/
/*
In options, we can specify:
* Texture parameters for an auto-generated target texture
* depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
*/
THREE.WebGLRenderTarget = function ( width, height, options ) {
this.uuid = THREE.Math.generateUUID();
......@@ -17,8 +23,6 @@ THREE.WebGLRenderTarget = function ( width, height, options ) {
this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
this.shareDepthFrom = options.shareDepthFrom !== undefined ? options.shareDepthFrom : null;
};
THREE.WebGLRenderTarget.prototype = {
......@@ -54,8 +58,6 @@ THREE.WebGLRenderTarget.prototype = {
this.depthBuffer = source.depthBuffer;
this.stencilBuffer = source.stencilBuffer;
this.shareDepthFrom = source.shareDepthFrom;
return this;
},
......
......@@ -2714,10 +2714,10 @@ THREE.WebGLRenderer = function ( parameters ) {
texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
var image = texture.image,
isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
glFormat = paramThreeToGL( texture.format ),
glType = paramThreeToGL( texture.type );
var image = texture.image;
var isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );
var glFormat = paramThreeToGL( texture.format );
var glType = paramThreeToGL( texture.type );
setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );
......@@ -2907,10 +2907,10 @@ THREE.WebGLRenderer = function ( parameters ) {
}
var image = cubeImage[ 0 ],
isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
glFormat = paramThreeToGL( texture.format ),
glType = paramThreeToGL( texture.type );
var image = cubeImage[ 0 ];
var isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );
var glFormat = paramThreeToGL( texture.format );
var glType = paramThreeToGL( texture.type );
setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );
......@@ -2990,148 +2990,126 @@ THREE.WebGLRenderer = function ( parameters ) {
// Render targets
function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
// Setup storage for target texture and bind it to correct framebuffer
function setupFrameBufferTexture ( framebuffer, renderTarget, attachment, textureTarget ) {
var glFormat = paramThreeToGL( renderTarget.texture.format );
var glType = paramThreeToGL( renderTarget.texture.type );
state.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
}
function setupRenderBuffer ( renderbuffer, renderTarget ) {
// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
function setupRenderBufferStorage ( renderbuffer, renderTarget ) {
_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
/* For some reason this is not working. Defaulting to RGBA4.
} else if ( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
*/
} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
} else {
// FIXME: We don't support !depth !stencil
_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
}
_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
}
this.setRenderTarget = function ( renderTarget ) {
// Setup GL resources for a non-texture depth buffer
function setupDepthRenderbuffer(renderTarget) {
var renderTargetProperties = properties.get( renderTarget );
var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
var renderTargetProperties = properties.get( renderTarget );
var textureProperties = properties.get( renderTarget.texture );
if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
textureProperties.__webglTexture = _gl.createTexture();
_infoMemory.textures ++;
// Setup texture, create render and frame buffers
var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height ),
glFormat = paramThreeToGL( renderTarget.texture.format ),
glType = paramThreeToGL( renderTarget.texture.type );
if ( isCube ) {
renderTargetProperties.__webglFramebuffer = [];
renderTargetProperties.__webglRenderbuffer = [];
state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
for ( var i = 0; i < 6; i ++ ) {
renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
renderTargetProperties.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
setupFrameBuffer( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
setupRenderBuffer( renderTargetProperties.__webglRenderbuffer[ i ], renderTarget );
}
if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
} else {
renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
if ( renderTarget.shareDepthFrom ) {
renderTargetProperties.__webglRenderbuffer = renderTarget.shareDepthFrom.__webglRenderbuffer;
} else {
renderTargetProperties.__webglRenderbuffer = _gl.createRenderbuffer();
}
state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
setupFrameBuffer( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
if ( renderTarget.shareDepthFrom ) {
if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTargetProperties.__webglRenderbuffer );
} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTargetProperties.__webglRenderbuffer );
}
} else {
setupRenderBuffer( renderTargetProperties.__webglRenderbuffer, renderTarget );
}
if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
if ( isCube ) {
renderTargetProperties.__webglDepthbuffer = [];
for ( var i = 0; i < 6; i ++ ) {
_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ]);
renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
}
}
else {
_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
}
_gl.bindFramebuffer(_gl.FRAMEBUFFER, null );
};
// Release everything
// Set up GL resources for the render target
function setupRenderTarget(renderTarget) {
var renderTargetProperties = properties.get( renderTarget );
var textureProperties = properties.get( renderTarget.texture );
if ( isCube ) {
renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
textureProperties.__webglTexture = _gl.createTexture();
_infoMemory.textures ++;
state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
var glFormat = paramThreeToGL( renderTarget.texture.format );
var glType = paramThreeToGL( renderTarget.texture.type );
} else {
//
// Setup framebuffer
//
state.bindTexture( _gl.TEXTURE_2D, null );
if ( isCube ) {
renderTargetProperties.__webglFramebuffer = [];
for ( var i = 0; i < 6; i ++ ) {
renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
}
} else {
renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
}
//
// Setup color buffer
//
if ( isCube ) {
state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
for ( var i = 0; i < 6; i ++ ) {
setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
}
if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
} else {
state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );
if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
state.bindTexture( _gl.TEXTURE_2D, null );
}
//
// Setup depth and stencil buffers
//
if ( renderTarget.depthBuffer ) {
setupDepthRenderbuffer(renderTarget);
}
_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
}
this.setRenderTarget = function ( renderTarget ) {
if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
setupRenderTarget(renderTarget);
}
var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
var framebuffer, width, height, vx, vy;
if ( renderTarget ) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册