mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-14 12:29:30 -07:00
Using webgl-debug to emit the low-level WebGL API calls from the regl project
This commit is contained in:
261
js/main.js
261
js/main.js
@@ -23,6 +23,7 @@ const loadJS = (src) =>
|
|||||||
|
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
await loadJS("lib/regl.js");
|
await loadJS("lib/regl.js");
|
||||||
|
await loadJS("lib/webgl-debug.js");
|
||||||
|
|
||||||
const resize = () => {
|
const resize = () => {
|
||||||
const devicePixelRatio = window.devicePixelRatio ?? 1;
|
const devicePixelRatio = window.devicePixelRatio ?? 1;
|
||||||
@@ -49,7 +50,249 @@ const init = async () => {
|
|||||||
// These extensions are also needed, but Safari misreports that they are missing
|
// These extensions are also needed, but Safari misreports that they are missing
|
||||||
const optionalExtensions = ["EXT_color_buffer_half_float", "WEBGL_color_buffer_float", "OES_standard_derivatives"];
|
const optionalExtensions = ["EXT_color_buffer_half_float", "WEBGL_color_buffer_float", "OES_standard_derivatives"];
|
||||||
|
|
||||||
const regl = createREGL({ canvas, pixelRatio: 1, extensions, optionalExtensions });
|
const { makeDebugContext } = WebGLDebugUtils;
|
||||||
|
|
||||||
|
const glConsts = {
|
||||||
|
DEPTH_TEST: 0x0B71,
|
||||||
|
BLEND: 0x0BE2,
|
||||||
|
UNPACK_ALIGNMENT: 0x0CF5,
|
||||||
|
TEXTURE_2D: 0x0DE1,
|
||||||
|
RGBA: 0x1908,
|
||||||
|
LUMINANCE: 0x1909,
|
||||||
|
NEAREST: 0x2600,
|
||||||
|
LINEAR: 0x2601,
|
||||||
|
TEXTURE_MAG_FILTER: 0x2800,
|
||||||
|
TEXTURE_MIN_FILTER: 0x2801,
|
||||||
|
TEXTURE_WRAP_S: 0x2802,
|
||||||
|
TEXTURE_WRAP_T: 0x2803,
|
||||||
|
CLAMP_TO_EDGE: 0x812F,
|
||||||
|
DEPTH_STENCIL_ATTACHMENT: 0x821A,
|
||||||
|
TEXTURE0: 0x84C0,
|
||||||
|
DEPTH_STENCIL: 0x84F9,
|
||||||
|
RGBA16F_EXT: 0x881A,
|
||||||
|
STATIC_DRAW: 0x88E4,
|
||||||
|
ACTIVE_UNIFORMS: 0x8B86,
|
||||||
|
ACTIVE_ATTRIBUTES: 0x8B89,
|
||||||
|
COLOR_ATTACHMENT0: 0x8CE0,
|
||||||
|
DEPTH_ATTACHMENT: 0x8D00,
|
||||||
|
STENCIL_ATTACHMENT: 0x8D20,
|
||||||
|
FRAMEBUFFER: 0x8D40,
|
||||||
|
RENDERBUFFER: 0x8D41,
|
||||||
|
HALF_FLOAT_OES: 0x8D61,
|
||||||
|
UNPACK_FLIP_Y_WEBGL: 0x9240,
|
||||||
|
UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241,
|
||||||
|
UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243,
|
||||||
|
BROWSER_DEFAULT_WEBGL: 0x9244,
|
||||||
|
|
||||||
|
ARRAY_BUFFER: 34962,
|
||||||
|
FRAGMENT_SHADER: 35632,
|
||||||
|
FRAGMENT_SHADER: 35632,
|
||||||
|
VERTEX_SHADER: 35633,
|
||||||
|
COMPILE_STATUS: 35713,
|
||||||
|
LINK_STATUS: 35714,
|
||||||
|
TRIANGLES: 4,
|
||||||
|
UNSIGNED_BYTE: 5121,
|
||||||
|
FLOAT: 5126,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let i = 1; i < 32; i++) {
|
||||||
|
glConsts[`TEXTURE${i}`] = 0x84C0 + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
const betterNames = {
|
||||||
|
[11]: "defaultFragShader",
|
||||||
|
[12]: "defaultVertShader",
|
||||||
|
[13]: "defaultProgram",
|
||||||
|
[17]: "fullscreen_geometry",
|
||||||
|
[18]: "rain_compute_doublebuffer_1_texture", [19]: "rain_compute_doublebuffer_1_framebuffer",
|
||||||
|
[20]: "rain_compute_doublebuffer_2_texture", [21]: "rain_compute_doublebuffer_2_framebuffer",
|
||||||
|
[22]: "rain_compute_shader",
|
||||||
|
[23]: "placeholder_texture",
|
||||||
|
[24]: "rain_output_texture", [25]: "rain_output_framebuffer", [26]: "rain_output_renderbuffer",
|
||||||
|
[27]: "rain_frag_shader",
|
||||||
|
[28]: "rain_vert_shader",
|
||||||
|
[29]: "rain_program",
|
||||||
|
[47]: "rain_geometry",
|
||||||
|
|
||||||
|
[48]: "bloom_high_pass_pyr_0_texture", [49]: "bloom_high_pass_pyr_0_framebuffer", [50]: "bloom_high_pass_pyr_0_renderbuffer",
|
||||||
|
[51]: "bloom_high_pass_pyr_1_texture", [52]: "bloom_high_pass_pyr_1_framebuffer", [53]: "bloom_high_pass_pyr_1_renderbuffer",
|
||||||
|
[54]: "bloom_high_pass_pyr_2_texture", [55]: "bloom_high_pass_pyr_2_framebuffer", [56]: "bloom_high_pass_pyr_2_renderbuffer",
|
||||||
|
[57]: "bloom_high_pass_pyr_3_texture", [58]: "bloom_high_pass_pyr_3_framebuffer", [59]: "bloom_high_pass_pyr_3_renderbuffer",
|
||||||
|
[60]: "bloom_high_pass_pyr_4_texture", [61]: "bloom_high_pass_pyr_4_framebuffer", [62]: "bloom_high_pass_pyr_4_renderbuffer",
|
||||||
|
|
||||||
|
[63]: "bloom_h_blur_pyr_0_texture", [64]: "bloom_h_blur_pyr_0_framebuffer", [65]: "bloom_h_blur_pyr_0_renderbuffer",
|
||||||
|
[66]: "bloom_h_blur_pyr_1_texture", [67]: "bloom_h_blur_pyr_1_framebuffer", [68]: "bloom_h_blur_pyr_1_renderbuffer",
|
||||||
|
[69]: "bloom_h_blur_pyr_2_texture", [70]: "bloom_h_blur_pyr_2_framebuffer", [71]: "bloom_h_blur_pyr_2_renderbuffer",
|
||||||
|
[72]: "bloom_h_blur_pyr_3_texture", [73]: "bloom_h_blur_pyr_3_framebuffer", [74]: "bloom_h_blur_pyr_3_renderbuffer",
|
||||||
|
[75]: "bloom_h_blur_pyr_4_texture", [76]: "bloom_h_blur_pyr_4_framebuffer", [77]: "bloom_h_blur_pyr_4_renderbuffer",
|
||||||
|
|
||||||
|
[78]: "bloom_v_blur_pyr_0_texture", [79]: "bloom_v_blur_pyr_0_framebuffer", [80]: "bloom_v_blur_pyr_0_renderbuffer",
|
||||||
|
[81]: "bloom_v_blur_pyr_1_texture", [82]: "bloom_v_blur_pyr_1_framebuffer", [83]: "bloom_v_blur_pyr_1_renderbuffer",
|
||||||
|
[84]: "bloom_v_blur_pyr_2_texture", [85]: "bloom_v_blur_pyr_2_framebuffer", [86]: "bloom_v_blur_pyr_2_renderbuffer",
|
||||||
|
[87]: "bloom_v_blur_pyr_3_texture", [88]: "bloom_v_blur_pyr_3_framebuffer", [89]: "bloom_v_blur_pyr_3_renderbuffer",
|
||||||
|
[90]: "bloom_v_blur_pyr_4_texture", [91]: "bloom_v_blur_pyr_4_framebuffer", [92]: "bloom_v_blur_pyr_4_renderbuffer",
|
||||||
|
|
||||||
|
[93]: "bloom_output_texture", [94]: "bloom_output_framebuffer", [95]: "bloom_output_renderbuffer",
|
||||||
|
[96]: "bloom_high_pass_shader",
|
||||||
|
[97]: "bloom_blur_shader",
|
||||||
|
[98]: "bloom_combine_shader",
|
||||||
|
[99]: "palette_output_texture", [100]: "palette_output_framebuffer", [101]: "palette_output_renderbuffer",
|
||||||
|
[102]: "palette_texture",
|
||||||
|
[103]: "palette_shader",
|
||||||
|
[104]: "msdf_texture",
|
||||||
|
[105]: "rain_compute_program",
|
||||||
|
[125]: "bloom_high_pass_program",
|
||||||
|
[131]: "bloom_blur_program",
|
||||||
|
[141]: "bloom_combine_program",
|
||||||
|
[155]: "palette_program",
|
||||||
|
};
|
||||||
|
|
||||||
|
const returnedValueNames = [];
|
||||||
|
|
||||||
|
const glConstsByID = {};
|
||||||
|
Object.entries(glConsts).forEach(([key, value]) => {
|
||||||
|
if (glConstsByID[value] == null) {
|
||||||
|
glConstsByID[value] = [];
|
||||||
|
}
|
||||||
|
glConstsByID[value].push(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
const returnedValues = [];
|
||||||
|
const returnedValueUsages = [];
|
||||||
|
const commands = [];
|
||||||
|
|
||||||
|
const log = [];
|
||||||
|
|
||||||
|
const printCommands = (label) => {
|
||||||
|
const printedCommands = [];
|
||||||
|
for (const {name, args, retIndex} of commands) {
|
||||||
|
const printedArgs = [];
|
||||||
|
for (const [type, value] of args) {
|
||||||
|
if (value == null) {
|
||||||
|
printedArgs.push(`null`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Array.isArray(value) || ArrayBuffer.isView(value)) {
|
||||||
|
printedArgs.push(`[${value.join(", ")}]`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (type) {
|
||||||
|
case "string":
|
||||||
|
printedArgs.push(`\`${value}\``);
|
||||||
|
break;
|
||||||
|
case "GLenum":
|
||||||
|
printedArgs.push(`gl.${value}`);
|
||||||
|
break;
|
||||||
|
case "object":
|
||||||
|
printedArgs.push(`${value}`);
|
||||||
|
break;
|
||||||
|
case "returnedValue":
|
||||||
|
printedArgs.push(`state.${returnedValueNames[value]}`);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printedArgs.push(`${value}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (retIndex != -1 && returnedValueUsages[retIndex] > 0) {
|
||||||
|
printedCommands.push(`state.${returnedValueNames[retIndex]} = gl.${name}(${printedArgs.join(", ")});`);
|
||||||
|
} else {
|
||||||
|
printedCommands.push(`gl.${name}(${printedArgs.join(", ")});`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.push(`// ${label}`);
|
||||||
|
log.push(printedCommands.join("\n"));
|
||||||
|
commands.length = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const rawGL = canvas.getContext("webgl");
|
||||||
|
|
||||||
|
const gl = new Proxy(makeDebugContext(
|
||||||
|
rawGL,
|
||||||
|
null,
|
||||||
|
(...a) => {
|
||||||
|
const name = a[0];
|
||||||
|
const args = Array.from(a[1]);
|
||||||
|
const ret = a[2];
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
let value = args[i];
|
||||||
|
let type = typeof value;
|
||||||
|
if (type === "number" && glConstsByID[value] != null) {
|
||||||
|
type = "GLenum";
|
||||||
|
value = glConstsByID[value][0];
|
||||||
|
}
|
||||||
|
if (returnedValues.includes(value)) {
|
||||||
|
type = "returnedValue";
|
||||||
|
value = returnedValues.indexOf(value);
|
||||||
|
returnedValueUsages[value]++;
|
||||||
|
}
|
||||||
|
args[i] = [type, value];
|
||||||
|
}
|
||||||
|
|
||||||
|
let retIndex = -1;
|
||||||
|
if (typeof ret === "object" && !returnedValues.includes(ret)) {
|
||||||
|
returnedValues.push(ret);
|
||||||
|
returnedValueUsages.push(0);
|
||||||
|
retIndex = returnedValues.length - 1;
|
||||||
|
let glType = (ret[Symbol.toStringTag] ?? "object").replaceAll("WebGL", "").toLowerCase();
|
||||||
|
let retName = glType + "_" + retIndex;
|
||||||
|
switch (name) {
|
||||||
|
case "getExtension":
|
||||||
|
retName = glType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (glType) {
|
||||||
|
case "texture":
|
||||||
|
break;
|
||||||
|
case "framebuffer":
|
||||||
|
break;
|
||||||
|
case "renderbuffer":
|
||||||
|
break;
|
||||||
|
case "program":
|
||||||
|
break;
|
||||||
|
case "shader":
|
||||||
|
if (args[0][1].toLowerCase().includes("fragment")) {
|
||||||
|
retName = "fragment_shader" + "_" + retIndex;
|
||||||
|
} else {
|
||||||
|
retName = "vertex_shader" + "_" + retIndex;;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "activeinfo":
|
||||||
|
retName = returnedValueNames[args[0][1]] + "_a_" + ret.name;
|
||||||
|
break;
|
||||||
|
case "uniformlocation":
|
||||||
|
retName = returnedValueNames[args[0][1]] + "_u_" + args[1][1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (returnedValueNames.includes(retName)) {
|
||||||
|
retName = retName + "_" + retIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (betterNames[retIndex] != null) {
|
||||||
|
retName = betterNames[retIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
returnedValueNames[retIndex] = retName;
|
||||||
|
}
|
||||||
|
|
||||||
|
commands.push({ name, args, retIndex });
|
||||||
|
}
|
||||||
|
), {
|
||||||
|
/*
|
||||||
|
get(target, prop, receiver) {
|
||||||
|
const ret = Reflect.get(...arguments);
|
||||||
|
if (typeof ret !== "function") {
|
||||||
|
console.log("GET", prop, ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
});
|
||||||
|
|
||||||
|
const regl = createREGL({ gl, pixelRatio: 1, extensions, optionalExtensions });
|
||||||
|
|
||||||
|
printCommands("INIT");
|
||||||
|
returnedValueUsages.fill(0);
|
||||||
|
|
||||||
// All this takes place in a full screen quad.
|
// All this takes place in a full screen quad.
|
||||||
const fullScreenQuad = makeFullScreenQuad(regl);
|
const fullScreenQuad = makeFullScreenQuad(regl);
|
||||||
@@ -58,6 +301,8 @@ const init = async () => {
|
|||||||
const drawToScreen = regl({ uniforms: screenUniforms });
|
const drawToScreen = regl({ uniforms: screenUniforms });
|
||||||
await Promise.all(pipeline.map((step) => step.ready));
|
await Promise.all(pipeline.map((step) => step.ready));
|
||||||
|
|
||||||
|
printCommands("LOAD");
|
||||||
|
|
||||||
const render = ({ viewportWidth, viewportHeight }) => {
|
const render = ({ viewportWidth, viewportHeight }) => {
|
||||||
const now = regl.now() * 1000;
|
const now = regl.now() * 1000;
|
||||||
|
|
||||||
@@ -67,6 +312,7 @@ const init = async () => {
|
|||||||
for (const step of pipeline) {
|
for (const step of pipeline) {
|
||||||
step.setSize(viewportWidth, viewportHeight);
|
step.setSize(viewportWidth, viewportHeight);
|
||||||
}
|
}
|
||||||
|
printCommands("RESIZE");
|
||||||
}
|
}
|
||||||
fullScreenQuad(() => {
|
fullScreenQuad(() => {
|
||||||
for (const step of pipeline) {
|
for (const step of pipeline) {
|
||||||
@@ -74,11 +320,20 @@ const init = async () => {
|
|||||||
}
|
}
|
||||||
drawToScreen();
|
drawToScreen();
|
||||||
});
|
});
|
||||||
|
printCommands("DRAW");
|
||||||
};
|
};
|
||||||
|
|
||||||
render({ viewportWidth: 1, viewportHeight: 1 });
|
render({ viewportWidth: 640, viewportHeight: 480 });
|
||||||
|
|
||||||
const tick = regl.frame(render);
|
await new Promise(resolve => {
|
||||||
|
setTimeout(() => resolve(), 1000)
|
||||||
|
});
|
||||||
|
|
||||||
|
render({ viewportWidth: 640, viewportHeight: 480 });
|
||||||
|
|
||||||
|
console.log(log.join("\n"));
|
||||||
|
|
||||||
|
// const tick = regl.frame(render);
|
||||||
};
|
};
|
||||||
|
|
||||||
document.body.onload = () => {
|
document.body.onload = () => {
|
||||||
|
|||||||
@@ -115,14 +115,6 @@ export default ({ regl }) => {
|
|||||||
framebuffer: computeDoubleBuffer.front,
|
framebuffer: computeDoubleBuffer.front,
|
||||||
});
|
});
|
||||||
|
|
||||||
const quadPositions = Array(1)
|
|
||||||
.fill()
|
|
||||||
.map((_, y) =>
|
|
||||||
Array(1)
|
|
||||||
.fill()
|
|
||||||
.map((_, x) => Array(numVerticesPerQuad).fill([x, y]))
|
|
||||||
);
|
|
||||||
|
|
||||||
// We render the code into an FBO using MSDFs: https://github.com/Chlumsky/msdfgen
|
// We render the code into an FBO using MSDFs: https://github.com/Chlumsky/msdfgen
|
||||||
const glyphMSDF = loadImage(regl, "assets/matrixcode_msdf.png");
|
const glyphMSDF = loadImage(regl, "assets/matrixcode_msdf.png");
|
||||||
const output = makePassFBO(regl);
|
const output = makePassFBO(regl);
|
||||||
@@ -137,13 +129,13 @@ export default ({ regl }) => {
|
|||||||
vert: `
|
vert: `
|
||||||
precision lowp float;
|
precision lowp float;
|
||||||
|
|
||||||
attribute vec2 aPosition, aCorner;
|
attribute vec2 aPosition;
|
||||||
uniform vec2 screenSize;
|
uniform vec2 screenSize;
|
||||||
varying vec2 vUV;
|
varying vec2 vUV;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vUV = aPosition + aCorner;
|
vUV = aPosition;
|
||||||
gl_Position = vec4((aPosition + aCorner - 0.5) * 2.0 * screenSize, 0.0, 1.0);
|
gl_Position = vec4((aPosition - 0.5) * 2.0 * screenSize, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
frag: `
|
frag: `
|
||||||
@@ -232,8 +224,7 @@ export default ({ regl }) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
attributes: {
|
attributes: {
|
||||||
aPosition: quadPositions,
|
aPosition: quadVertices,
|
||||||
aCorner: quadVertices,
|
|
||||||
},
|
},
|
||||||
count: numVerticesPerQuad,
|
count: numVerticesPerQuad,
|
||||||
|
|
||||||
|
|||||||
1195
lib/webgl-debug.js
Normal file
1195
lib/webgl-debug.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user