png: always expand 3-byte-per-pixel textures as 4-byte-per-pixel

This commit is contained in:
Zack Buhman 2026-07-25 22:08:36 -05:00
parent 96636d1cb1
commit ed2160a935
3 changed files with 26 additions and 33 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}
}
}