twgl.js/test/tests/texture-tests.js
Gregg Tavares 8f53aa82a9 Fix issues with compressed texture support
* Get rid of the compression option

  We know if a texture is compressed based on its internalFormat

* Remove level stuff

  I think there was a mis-understanding how how twgl works. If you
  want to set anything other than level 0 you need to directly
  call `setTextureFormArray` directly (or `setTextureFromElement`)

* Fix tests

  The tests needed to check that the extension exists

Note: we need to decide if and how to handle cubemaps.
The code in their currently will fail. Will fix in next PR
2025-07-11 20:21:23 -07:00

146 lines
4.3 KiB
JavaScript

import {
// assertArrayEqual,
// assertTruthy,
// assertFalsy,
assertEqual,
} from '../assert.js';
import {describe} from '../mocha-support.js';
import {
assertNoWebGLError,
createContext,
createContext2,
itWebGL,
itWebGL2,
checkColor,
setCanvasAndViewportSizeTo1x1
} from '../webgl.js';
function assertPixelFromTexture(gl, texture, expected) {
twgl.createFramebufferInfo(gl, [ { attachment: texture } ], 1, 2);
const actual = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, actual);
assertEqual(actual, expected);
}
function createRedGreenURL() {
const ctx = document.createElement('canvas').getContext('2d');
ctx.canvas.width = 1;
ctx.canvas.height = 2;
ctx.fillStyle = '#F00';
ctx.fillRect(0, 0, 1, 1);
ctx.fillStyle = '#0F0';
ctx.fillRect(0, 1, 1, 1);
return ctx.canvas.toDataURL();
}
function create1PixelTextureRenderingProgram(gl) {
const vs = `#version 300 es
void main() {
gl_Position = vec4(0, 0, 0, 1);
gl_PointSize = 1.0;
}
`;
const fs = `#version 300 es
precision highp float;
uniform sampler2D u_texture;
out vec4 fragColor;
void main() {
fragColor = texture(u_texture, vec2(0.5));
}
`;
return twgl.createProgram(gl, [vs, fs]);
}
describe('texture tests', () => {
itWebGL(`test y flips correctly`, async() => {
const {gl} = createContext();
const red = [255, 0, 0, 255];
const green = [0, 255, 0, 255];
const src = [...red, ...green];
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
const t1gr = twgl.createTexture(gl, { src, width: 1 });
const t2rg = twgl.createTexture(gl, { src, width: 1, flipY: false });
const t3gr = twgl.createTexture(gl, { src, width: 1 });
assertPixelFromTexture(gl, t1gr, green);
assertPixelFromTexture(gl, t2rg, red);
assertPixelFromTexture(gl, t3gr, green);
// Test that the state is saved when async.
const p = twgl.createTextureAsync(gl, { src: createRedGreenURL() });
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
const { texture: t4gr } = await p;
assertPixelFromTexture(gl, t4gr, green);
assertNoWebGLError(gl);
});
itWebGL(`test pre-multiplies alpha correctly`, () => {
const {gl} = createContext();
const src = [255, 0, 0, 128];
const premultiplied = [128, 0, 0, 128];
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
const t1gr = twgl.createTexture(gl, { src });
const t2rg = twgl.createTexture(gl, { src, premultiplyAlpha: false });
const t3gr = twgl.createTexture(gl, { src });
assertPixelFromTexture(gl, t1gr, premultiplied);
assertPixelFromTexture(gl, t2rg, src);
assertPixelFromTexture(gl, t3gr, premultiplied);
assertNoWebGLError(gl);
});
itWebGL2(`test compressed texture format EXT_texture_compression_bptc`, ['EXT_texture_compression_bptc'], async() => {
const {gl} = createContext2();
twgl.addExtensionsToContext(gl);
setCanvasAndViewportSizeTo1x1(gl);
const green = [2, 255, 2, 255];
const internalFormat = gl.COMPRESSED_RGBA_BPTC_UNORM;
const green_4x4 = new Uint8Array([32, 128, 193, 255, 15, 24, 252, 255, 175, 170, 170, 170, 0, 0, 0, 0]);
const width = 4;
const height = 4;
// eslint-disable-next-line no-unused-vars
const texture = twgl.createTexture(gl, { src: green_4x4, width, height, internalFormat });
assertNoWebGLError(gl);
const prg = create1PixelTextureRenderingProgram(gl);
gl.useProgram(prg);
gl.drawArrays(gl.POINTS, 0, 1);
checkColor(gl, green);
});
itWebGL2(`test compressed texture format WEBGL_compressed_texture_s3tc`, ['WEBGL_compressed_texture_s3tc'], async() => {
const {gl} = createContext2();
twgl.addExtensionsToContext(gl);
setCanvasAndViewportSizeTo1x1(gl);
const red = [255, 0, 0, 255];
const internalFormat = gl.COMPRESSED_RGB_S3TC_DXT1_EXT;
const red_4x4 = new Uint16Array([
0b11111_000000_00000,
0b11111_000000_00000,
0, 0,
]);
const width = 4;
const height = 4;
// eslint-disable-next-line no-unused-vars
const texture = twgl.createTexture(gl, { src: red_4x4, width, height, internalFormat });
assertNoWebGLError(gl);
const prg = create1PixelTextureRenderingProgram(gl);
gl.useProgram(prg);
gl.drawArrays(gl.POINTS, 0, 1);
checkColor(gl, red);
assertNoWebGLError(gl);
});
});