Skip to content

Commit 05b611b

Browse files
authored
feat: gl.getActiveUniform (#8)
1 parent d5f1e6b commit 05b611b

File tree

15 files changed

+983
-269
lines changed

15 files changed

+983
-269
lines changed

apps/docs/src/components/example/Example.astro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@
8585
sourceButton.href = `https://github.com/software-mansion-labs/byegl/blob/main/apps/docs/src/examples/${exampleKey}/index.ts`;
8686
sourceButton.classList.remove("hidden");
8787

88-
runExample(example).catch(() => {
88+
runExample(example).catch((err) => {
89+
console.error(err);
8990
webgpuUnsupported.classList.remove("hidden");
9091
});
9192
}
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import type { ExampleContext } from '../../types.ts';
2+
3+
export default function ({ canvas, trace }: ExampleContext) {
4+
const gl = canvas.getContext('webgl')!;
5+
6+
if (!gl) {
7+
throw new Error('WebGL not supported');
8+
}
9+
10+
const vertexShaderSource = `
11+
attribute vec2 a_position;
12+
attribute vec3 a_color;
13+
14+
varying vec3 v_color;
15+
varying vec2 v_uv;
16+
17+
void main() {
18+
gl_Position = vec4(a_position, 0.0, 1.0);
19+
v_color = a_color;
20+
v_uv = a_position.xy;
21+
}
22+
`;
23+
24+
const fragmentShaderSource = `
25+
precision mediump float;
26+
27+
varying vec3 v_color;
28+
varying vec2 v_uv;
29+
30+
struct Light {
31+
vec2 position;
32+
vec3 color;
33+
};
34+
35+
uniform Light u_light[4];
36+
37+
void main() {
38+
vec3 lightColor = vec3(0.0);
39+
for (int i = 0; i < 4; i++) {
40+
float dist = length(u_light[i].position - v_uv);
41+
float acc = pow(max(0.0, 1.0 - dist), 2.0);
42+
lightColor += acc * u_light[i].color;
43+
}
44+
gl_FragColor = vec4(lightColor * 0.8 + vec3(0.2), 1.0);
45+
}
46+
`;
47+
48+
const vertexShader = gl.createShader(gl.VERTEX_SHADER) as WebGLShader;
49+
gl.shaderSource(vertexShader, vertexShaderSource);
50+
gl.compileShader(vertexShader);
51+
52+
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
53+
console.error(
54+
'Error compiling vertex shader:',
55+
gl.getShaderInfoLog(vertexShader),
56+
);
57+
}
58+
59+
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER) as WebGLShader;
60+
gl.shaderSource(fragmentShader, fragmentShaderSource);
61+
gl.compileShader(fragmentShader);
62+
63+
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
64+
console.error(
65+
'Error compiling fragment shader:',
66+
gl.getShaderInfoLog(fragmentShader),
67+
);
68+
}
69+
70+
const program = gl.createProgram();
71+
gl.attachShader(program, vertexShader);
72+
gl.attachShader(program, fragmentShader);
73+
gl.linkProgram(program);
74+
75+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
76+
console.error('Error linking program:', gl.getProgramInfoLog(program));
77+
}
78+
79+
console.log('Uniforms:');
80+
for (
81+
let i = 0;
82+
i < gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
83+
i++
84+
) {
85+
console.log(gl.getActiveUniform(program, i));
86+
}
87+
88+
console.log('Attributes:');
89+
for (
90+
let i = 0;
91+
i < gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
92+
i++
93+
) {
94+
console.log(gl.getActiveAttrib(program, i));
95+
}
96+
97+
const positionLocation = gl.getAttribLocation(program, 'a_position');
98+
const colorLocation = gl.getAttribLocation(program, 'a_color');
99+
100+
const positionBuffer = gl.createBuffer();
101+
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
102+
gl.bufferData(
103+
gl.ARRAY_BUFFER,
104+
new Float32Array([
105+
// bottom-left
106+
-1, -1,
107+
// bottom-right
108+
1, -1,
109+
// top-left
110+
-1, 1,
111+
// top-right
112+
1, 1,
113+
]),
114+
gl.STATIC_DRAW,
115+
);
116+
117+
gl.enableVertexAttribArray(positionLocation);
118+
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
119+
120+
const colorBuffer = gl.createBuffer();
121+
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
122+
gl.bufferData(
123+
gl.ARRAY_BUFFER,
124+
new Uint8Array([
125+
// bottom-left
126+
255, 0, 0,
127+
// bottom-right
128+
255, 0, 255,
129+
// top-left
130+
0, 255, 0,
131+
// top-right
132+
0, 255, 255,
133+
]),
134+
gl.STATIC_DRAW,
135+
);
136+
137+
gl.enableVertexAttribArray(colorLocation);
138+
gl.vertexAttribPointer(colorLocation, 3, gl.UNSIGNED_BYTE, true, 0, 0);
139+
140+
const indexBuffer = gl.createBuffer();
141+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
142+
gl.bufferData(
143+
gl.ELEMENT_ARRAY_BUFFER,
144+
new Uint16Array([
145+
// first triangle
146+
0, 1, 2,
147+
// second triangle
148+
2, 1, 3,
149+
]),
150+
gl.STATIC_DRAW,
151+
);
152+
153+
function animate(timestamp: number) {
154+
handle = requestAnimationFrame(animate);
155+
156+
gl.useProgram(program);
157+
158+
const colors = [
159+
[1, 0.2, 0.2],
160+
[0.2, 1, 0.2],
161+
[0.2, 0.2, 1],
162+
[1, 1, 1],
163+
];
164+
for (let i = 0; i < 4; ++i) {
165+
gl.uniform2f(
166+
gl.getUniformLocation(program, `u_light[${i}].position`),
167+
Math.sin(timestamp * (0.002 + Math.sin(i) * 0.001) + i),
168+
Math.cos(timestamp * (0.001 + Math.sin(i) * 0.002) + i),
169+
);
170+
gl.uniform3fv(
171+
gl.getUniformLocation(program, `u_light[${i}].color`),
172+
colors[i],
173+
);
174+
}
175+
176+
gl.clearColor(0, 0, 0, 1);
177+
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
178+
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
179+
}
180+
181+
let handle = requestAnimationFrame(animate);
182+
183+
return () => {
184+
cancelAnimationFrame(handle);
185+
};
186+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "Compat: Multi-light"
3+
}

0 commit comments

Comments
 (0)