From 72ddd053fe2290262b8360a6024fa1d583e26f32 Mon Sep 17 00:00:00 2001 From: xiaoiver Date: Wed, 13 Dec 2023 12:50:46 +0800 Subject: [PATCH] Fix 102 (#106) * fix: use internal format in webgl2 #102 * chore: commit changeset --- .changeset/stupid-scissors-pretend.md | 5 +++++ examples/demos/set-image-data.ts | 24 +++++++++++++++++----- src/webgl/Device.ts | 29 +++++++++++++++++++++++++++ src/webgl/Texture.ts | 8 ++++++-- 4 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 .changeset/stupid-scissors-pretend.md diff --git a/.changeset/stupid-scissors-pretend.md b/.changeset/stupid-scissors-pretend.md new file mode 100644 index 0000000..2c6beb7 --- /dev/null +++ b/.changeset/stupid-scissors-pretend.md @@ -0,0 +1,5 @@ +--- +'@antv/g-device-api': patch +--- + +Use internal format in webgl2 when calling texImage2D. diff --git a/examples/demos/set-image-data.ts b/examples/demos/set-image-data.ts index 08270ab..6ab3686 100644 --- a/examples/demos/set-image-data.ts +++ b/examples/demos/set-image-data.ts @@ -13,21 +13,35 @@ export async function render( swapChain.configureSwapChain($canvas.width, $canvas.height); const device = swapChain.getDevice(); - const dataTexture = device.createTexture({ - format: Format.U8_LUMINANCE, + // const luminance = device.createTexture({ + // format: Format.U8_LUMINANCE, + // width: 1, + // height: 1, + // usage: TextureUsage.SAMPLED, + // pixelStore: { + // unpackFlipY: false, + // packAlignment: 1, + // }, + // mipLevelCount: 0, + // }); + // luminance.setImageData([new Uint8Array([10])]); + + const floatRGB = device.createTexture({ + format: Format.F32_RGB, width: 1, height: 1, usage: TextureUsage.SAMPLED, pixelStore: { unpackFlipY: false, - packAlignment: 1, + packAlignment: 4, }, mipLevelCount: 0, }); - dataTexture.setImageData([new Uint8Array([10])]); + floatRGB.setImageData([new Float32Array([10, 20, 30])]); return () => { - dataTexture.destroy(); + // luminance.destroy(); + floatRGB.destroy(); device.destroy(); // For debug. diff --git a/src/webgl/Device.ts b/src/webgl/Device.ts index 2dd1c36..e415762 100644 --- a/src/webgl/Device.ts +++ b/src/webgl/Device.ts @@ -688,6 +688,35 @@ export class Device_GL implements SwapChain, Device { } } + /** + * Only works in WebGL2 + * @see https://webgl2fundamentals.org/webgl/lessons/webgl-data-textures.html + */ + translateInternalTextureFormat(fmt: Format): GLenum { + switch (fmt) { + case Format.F32_R: + return GL.R32F; + case Format.F32_RG: + return GL.RG32F; + case Format.F32_RGB: + return GL.RGB32F; + case Format.F32_RGBA: + return GL.RGBA32F; + case Format.F16_R: + return GL.R16F; + case Format.F16_RG: + return GL.RG16F; + case Format.F16_RGB: + return GL.RGB16F; + case Format.F16_RGBA: + return GL.RGBA16F; + default: + break; + } + + return this.translateTextureFormat(fmt); + } + translateTextureFormat(fmt: Format): GLenum { if ( isTextureFormatCompressed(fmt) || diff --git a/src/webgl/Texture.ts b/src/webgl/Texture.ts index c83ebe5..eb5dfff 100644 --- a/src/webgl/Texture.ts +++ b/src/webgl/Texture.ts @@ -253,6 +253,10 @@ export class Texture_GL extends ResourceBase_GL implements Texture { gl.bindTexture(this.gl_target, this.gl_texture); const gl_format = this.device.translateTextureFormat(this.format); + // In WebGL 1, this must be the same as internalformat + const gl_internal_format = isWebGL2(gl) + ? this.device.translateInternalTextureFormat(this.format) + : gl_format; const gl_type = this.device.translateTextureType(this.format); this.preprocessImage(); @@ -289,7 +293,7 @@ export class Texture_GL extends ResourceBase_GL implements Texture { gl.texImage3D( gl_target, lod, - gl_format, + gl_internal_format, width, height, this.depthOrArrayLayers, @@ -303,7 +307,7 @@ export class Texture_GL extends ResourceBase_GL implements Texture { gl.texImage2D( gl_target, lod, - gl_format, + gl_internal_format, width, height, 0, // border must be 0