Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/jsm/renderers/common/Renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1086,12 +1086,12 @@ class Renderer {

}

copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {

this._textures.updateTexture( srcTexture );
this._textures.updateTexture( dstTexture );

this.backend.copyTextureToTexture( position, srcTexture, dstTexture, level );
this.backend.copyTextureToTexture( srcTexture, dstTexture, srcRegion, dstPosition, level );

}

Expand Down
62 changes: 56 additions & 6 deletions examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -524,41 +524,91 @@ class WebGLTextureUtils {

}

copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {

const { gl, backend } = this;
const { state } = this.backend;

const width = srcTexture.image.width;
const height = srcTexture.image.height;
const { textureGPU: dstTextureGPU, glTextureType, glType, glFormat } = backend.get( dstTexture );


let width, height, minX, minY;
let dstX, dstY;
if ( srcRegion !== null ) {

width = srcRegion.max.x - srcRegion.min.x;
height = srcRegion.max.y - srcRegion.min.y;
minX = srcRegion.min.x;
minY = srcRegion.min.y;

} else {

width = srcTexture.image.width;
height = srcTexture.image.height;
minX = 0;
minY = 0;

}

if ( dstPosition !== null ) {

dstX = dstPosition.x;
dstY = dstPosition.y;

} else {

dstX = 0;
dstY = 0;

}

state.bindTexture( glTextureType, dstTextureGPU );

// As another texture upload may have changed pixelStorei
// parameters, make sure they are correct for the dstTexture
gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );

const currentUnpackRowLen = gl.getParameter( gl.UNPACK_ROW_LENGTH );
const currentUnpackImageHeight = gl.getParameter( gl.UNPACK_IMAGE_HEIGHT );
const currentUnpackSkipPixels = gl.getParameter( gl.UNPACK_SKIP_PIXELS );
const currentUnpackSkipRows = gl.getParameter( gl.UNPACK_SKIP_ROWS );
const currentUnpackSkipImages = gl.getParameter( gl.UNPACK_SKIP_IMAGES );

const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ level ] : srcTexture.image;

gl.pixelStorei( gl.UNPACK_ROW_LENGTH, image.width );
gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, image.height );
gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, minX );
gl.pixelStorei( gl.UNPACK_SKIP_ROWS, minY );


if ( srcTexture.isDataTexture ) {

gl.texSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data );
gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image.data );

} else {

if ( srcTexture.isCompressedTexture ) {

gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data );
gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, image.width, image.height, glFormat, image.data );

} else {

gl.texSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image );
gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, glFormat, glType, image );

}

}

gl.pixelStorei( gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
gl.pixelStorei( gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );

// Generate mipmaps only when copying level 0
if ( level === 0 && dstTexture.generateMipmaps ) gl.generateMipmap( gl.TEXTURE_2D );

Expand Down
14 changes: 12 additions & 2 deletions examples/jsm/renderers/webgpu/WebGPUBackend.js
Original file line number Diff line number Diff line change
Expand Up @@ -1235,8 +1235,18 @@ class WebGPUBackend extends Backend {

}

copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {

let dstX = 0;
let dstY = 0;

if ( dstPosition !== null ) {

dstX = dstPosition.x;
dstY = dstPosition.y;

}

const encoder = this.device.createCommandEncoder( { label: 'copyTextureToTexture_' + srcTexture.id + '_' + dstTexture.id } );

const sourceGPU = this.get( srcTexture ).texture;
Expand All @@ -1251,7 +1261,7 @@ class WebGPUBackend extends Backend {
{
texture: destinationGPU,
mipLevel: level,
origin: { x: position.x, y: position.y, z: position.z }
origin: { x: dstX, y: dstY, z: 0 }
},
[
srcTexture.image.width,
Expand Down