From ed2160a935e247acd25408af98fc63e1b63fbe1e Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sat, 25 Jul 2026 22:08:36 -0500 Subject: [PATCH] png: always expand 3-byte-per-pixel textures as 4-byte-per-pixel --- gltf.wgsl | 2 +- index2.js | 18 ++---------------- src/png.cpp | 39 +++++++++++++++++++++++---------------- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/gltf.wgsl b/gltf.wgsl index 48ca072..1246b3b 100644 --- a/gltf.wgsl +++ b/gltf.wgsl @@ -95,5 +95,5 @@ fn fragmentMain(input: FragmentInput) -> @location(0) vec4f let intensity = lighting(input.positionWorld, normalize(input.normal)); let color = textureSample(colorTexture, linearSampler, input.texture); - return vec4(color.xyz * intensity, 1.0); + return vec4(color.xyz, 1.0); } diff --git a/index2.js b/index2.js index c6e6363..d98818d 100644 --- a/index2.js +++ b/index2.js @@ -278,15 +278,6 @@ function memoryString(memory, offset) return new TextDecoder().decode(new Uint8Array(s)); } -function pngComponents(colorType) -{ - if (colorType == 2) - return 3; - if (colorType == 6) - return 4; - throw new Error("non-implemented png color type"); -} - async function loadTextures(device, memory, module, gltf) { const tempTable = module.instance.exports.mem_alloc(256 * 4); @@ -326,11 +317,6 @@ async function loadTextures(device, memory, module, gltf) const width = tempHeaderU32[0]; const height = tempHeaderU32[1]; - const bitDepth = tempHeaderU32[2]; - const colorType = tempHeaderU32[3]; - const components = pngComponents(colorType); - console.log(components); - const texture = device.createTexture({ size: [width, height], format: 'rgba8unorm', @@ -339,7 +325,7 @@ async function loadTextures(device, memory, module, gltf) device.queue.writeTexture({ texture: texture }, tempOutputU8, - { bytesPerRow: width * components }, + { bytesPerRow: width * 4 }, { width: width, height: height }); textures.push(texture); @@ -368,7 +354,7 @@ async function loadGltf(device, canvasFormat, memory, module) code: await code, }); - const renderer = new GltfRenderer(device, canvasFormat, shaderModule, gltf, textures[2]); + const renderer = new GltfRenderer(device, canvasFormat, shaderModule, gltf, textures[0]); console.log(renderer.nodeBuffer); device.queue.writeBuffer(renderer.nodeBuffer, 0, memory.buffer, nodesHandle, (4 * 4 * 4) * gltf.json.nodes.length); diff --git a/src/png.cpp b/src/png.cpp index 4966873..7d863df 100644 --- a/src/png.cpp +++ b/src/png.cpp @@ -104,9 +104,11 @@ static int buffer_get(uint8_t const * buf, int stride, int x, int y) static int reconstruct(int function, uint8_t const * ibuf, int istride, uint8_t const * obuf, int ostride, - int x, int y, int cpp) + int ix, int y, + int ox, + int ocpp) { - int f = ibuf[y * istride + x + 1]; + int f = ibuf[y * istride + ix + 1]; switch (function) { case 0: // none { @@ -114,25 +116,25 @@ static int reconstruct(int function, } case 1: // sub { - int a = buffer_get(obuf, ostride, x - cpp, y); + int a = buffer_get(obuf, ostride, ox - ocpp, y); return (f + a) & 0xff; } case 2: // up { - int b = buffer_get(obuf, ostride, x, y - 1); + int b = buffer_get(obuf, ostride, ox, y - 1); return (f + b) & 0xff; } case 3: // average { - int a = buffer_get(obuf, ostride, x - cpp, y); - int b = buffer_get(obuf, ostride, x, y - 1); + int a = buffer_get(obuf, ostride, ox - ocpp, y); + int b = buffer_get(obuf, ostride, ox, y - 1); return (f + ((a + b) / 2)) & 0xff; } case 4: // paeth { - int a = buffer_get(obuf, ostride, x - cpp, y); - int b = buffer_get(obuf, ostride, x, y - 1); - int c = buffer_get(obuf, ostride, x - cpp, y - 1); + int a = buffer_get(obuf, ostride, ox - ocpp, y); + int b = buffer_get(obuf, ostride, ox, y - 1); + int c = buffer_get(obuf, ostride, ox - ocpp, y - 1); return (f + paeth(a, b, c)) & 0xff; } default: @@ -230,22 +232,27 @@ static int decode_iend(uint32_t length, return -(22 | (header->bit_depth << 8)); } - int cpp = components_per_pixel(header); - if (cpp < 0) { + int icpp = components_per_pixel(header); + if (icpp < 0) { state->error = "unsupported color type"; return -(3 | (header->color_type << 8)); } - int obpp = cpp * 1; + int ocpp = 4; + int obpp = ocpp * 1; int ostride = header->width * obpp; - int ibpp = cpp * 1; + int ibpp = icpp * 1; int istride = header->width * ibpp + 1; for (int y = 0; y < header->height; y++) { int function = state->ibuf[y * istride]; - for (int x = 0; x < header->width * cpp; x++) { - int value = reconstruct(function, state->ibuf, istride, obuf, ostride, x, y, cpp); - obuf[y * ostride + x] = value; + for (int x = 0; x < header->width; x++) { + for (int c = 0; c < icpp; c++) { + int ix = x * icpp + c; + int ox = x * ocpp + c; + int value = reconstruct(function, state->ibuf, istride, obuf, ostride, ix, y, ox, ocpp); + obuf[y * ostride + ox] = value; + } } }