Skip to content

Commit 33b6c0e

Browse files
committed
fix state diagram for attribute values
1 parent 42d4b59 commit 33b6c0e

File tree

5 files changed

+128
-28
lines changed

5 files changed

+128
-28
lines changed

webgl/lessons/resources/webgl-state-diagram.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
/\_/\
6868
((@v@)) WebGL Owl
6969
():::() sees no WebGL
70-
VV-VV
70+
VV-VV
7171
</pre>
7272
</div>
7373
<div id="hint"></div>
@@ -160,7 +160,7 @@
160160

161161
<template id="vertex-attributes-template">
162162
<table>
163-
<thead><th>enabled</th><th>value</th><th>size</th><th>type</th><th>normalize</th><th>stride</th><th>offset</th><th>divisor</th><th>buffer</th></thead>
163+
<thead><th>enabled</th><th>size</th><th>type</th><th>int</th><th>normalize</th><th>stride</th><th>offset</th><th>divisor</th><th>buffer</th></thead>
164164
<tbody>
165165
</tbody>
166166
</table>
@@ -256,7 +256,7 @@
256256
# WebGL State diagram
257257

258258
This is an attempt to give a visual representation
259-
of most of WebGL's internal state.
259+
of most of WebGL's internal state.
260260

261261
WebGL is really just an API to run shaders. The only
262262
functions that actually write pixels are `gl.clear`,

webgl/lessons/resources/webgl-state-diagram/global-ui.js

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,123 @@ function createTextureUnits(parent, maxUnits = 8) {
170170
};
171171
}
172172

173+
function createAttribValues(parent, maxAttribs = 8) {
174+
const expander = createExpander(parent, 'Attribute Values', {}, `
175+
Each attribute has a value that is used if it is NOT
176+
enabled via --gl.enableVertexAttribArray--.
177+
178+
For example you have a shader with position and color attributes
179+
180+
---glsl
181+
attribute vec4 position;
182+
attribute vec4 color;
183+
---
184+
185+
To draw a shape where every vertex gets a different color you'd setup
186+
the color attribute with a buffer
187+
188+
---js
189+
gl.bindBuffer(gl.ARRAY_BUFFER, bufferWithColorData);
190+
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
191+
gl.enableVertexAttribArray(colorLoc); // use the data from the buffer
192+
---
193+
194+
To draw a shape where every vertex gets the same color you can
195+
disable the attribute and set its value
196+
197+
---js
198+
gl.disableVertexAttribArray(colorLoc);
199+
gl.vertexAttrib4fv(colorLoc, colorForAllVertices);
200+
---
201+
202+
> Note: Only 8 attribute values are shown here for space reasons but
203+
the actual number of attribute available you can look up with
204+
--gl.getParameter(gl.MAX_VERTEX_ATTRIBS)--
205+
which will be a minimum of ${globals.isWebGL2 ? 16 : 8}.
206+
207+
> Note: It's arguably
208+
confusing that this value is not part of a vertex array
209+
since the flag to use it or not is in the vertex array.
210+
211+
`);
212+
213+
const tbody = createTable(expander, ['value']);
214+
tbody.parentElement.classList.add('attrib-values');
215+
const arrows = [];
216+
217+
for (let i = 0; i < maxAttribs; ++i) {
218+
arrows.push({});
219+
const tr = addElem('tr', tbody);
220+
addElem('td', tr, {
221+
className: 'used-when-disabled',
222+
textContent: '0, 0, 0, 1',
223+
dataset: {
224+
help: helpToMarkdown(`
225+
value for this attribute when disabled (the default)
226+
227+
---js
228+
const loc = gl.getAttribLocation(program, 'someAttrib'); // ${i};
229+
gl.disableVertexAttribArray(loc); // disable if it's not already disabled
230+
gl.vertexAttrib4fv(loc, [1, 2, 3, 4]); // set the value
231+
---
232+
233+
note that the enabled/disabled state is part of
234+
the current vertex array but the values when disabled
235+
are global state.
236+
`),
237+
},
238+
});
239+
}
240+
241+
const updateAttribValue = loc => {
242+
const row = tbody.rows[loc];
243+
const cell = row.cells[0];
244+
const enabled = gl.getVertexAttrib(loc, gl.VERTEX_ATTRIB_ARRAY_ENABLED);
245+
row.classList.toggle('attrib-enable', enabled);
246+
247+
const value = gl.getVertexAttrib(loc, gl.CURRENT_VERTEX_ATTRIB).join(', ');
248+
if (updateElemAndFlashExpanderIfClosed(cell, value)) {
249+
/*
250+
Note: This code is copied and pasted from the texture unit code above
251+
so it would have to be adapted but, None of the examples use these
252+
values, even for a moment, I haven't bothered to make the arrows work.
253+
254+
To work, arrows from the current program to an attribute need to change
255+
so if enabled they connect as they do now but if disable they connect
256+
to these values.
257+
258+
const oldArrow = arrows[unit][targetBinding];
259+
if (oldArrow) {
260+
arrowManager.remove(oldArrow);
261+
arrows[unit][targetBinding] = null;
262+
}
263+
if (texture) {
264+
const targetInfo = getWebGLObjectInfo(texture);
265+
if (!targetInfo.deleted) {
266+
arrows[unit][targetBinding] = arrowManager.add(
267+
cell,
268+
targetInfo.ui.elem.querySelector('.name'),
269+
getColorForWebGLObject(texture, targetInfo.ui.elem, unit / maxUnits),
270+
{offset: { start: {x: 0, y: colNdx * 2 - 4}}});
271+
}
272+
}
273+
*/
274+
}
275+
};
276+
277+
const updateAttribValues = () => {
278+
for (let i = 0; i < maxAttribs; ++i) {
279+
updateAttribValue(i);
280+
}
281+
};
282+
283+
return {
284+
elem: expander,
285+
updateAttribValue,
286+
updateAttribValues,
287+
};
288+
}
289+
173290
function createUniformBufferBindings(parent, maxUnits = 8) {
174291
const expander = createExpander(parent, 'Uniform Buffer Bindings', {}, `
175292
In each program you tell each uniform block which index to find
@@ -336,6 +453,7 @@ export function createGlobalUI(globalStateElem) {
336453
commonState: createStateUI(globalState.commonState, globalStateElem, 'common state', globalStateQuery),
337454
textureUnits: createTextureUnits(globalStateElem, 8),
338455
clearState: createStateUI(globalState.clearState, globalStateElem, 'clear state', globalStateQuery),
456+
attribValueState: createAttribValues(globalStateElem, 8),
339457
...globals.isWebGL2 && {
340458
transformFeedbackState: createStateUI(globalState.transformFeedbackState, globalStateElem, 'transform feedback', globalStateQuery),
341459
uniformBufferBindingsState: createUniformBufferBindings(globalStateElem, Math.min(8, gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS))),

webgl/lessons/resources/webgl-state-diagram/state-diagram.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ body {
157157
background: inherit;
158158
}
159159

160+
.attrib-values .attrib-enable .used-when-disabled,
160161
.vertex-array .attrib-enable .used-when-disabled,
161162
.vertex-array .used-when-enabled { /* but not enabled */
162163
background: #444;

webgl/lessons/resources/webgl-state-diagram/state-diagram.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,11 +456,13 @@ export default function main({webglVersion, examples}) {
456456
origFn.call(this, ...args);
457457
const {ui} = getCurrentVAOInfo();
458458
ui.updateAttributes();
459+
globals.globalUI.attribValueState.updateAttribValue(args[0]);
459460
});
460461
wrapFn('disableVertexAttribArray', function(origFn, ...args) {
461462
origFn.call(this, ...args);
462463
const {ui} = getCurrentVAOInfo();
463464
ui.updateAttributes();
465+
globals.globalUI.attribValueState.updateAttribValue(args[0]);
464466
});
465467
wrapFn('vertexAttribPointer', function(origFn, ...args) {
466468
origFn.call(this, ...args);
@@ -488,6 +490,7 @@ export default function main({webglVersion, examples}) {
488490
const {ui} = getCurrentVAOInfo();
489491
moveToFront(ui.elem);
490492
updateProgramAttributesAndUniforms(gl.getParameter(gl.CURRENT_PROGRAM));
493+
globals.globalUI.attribValueState.updateAttribValues();
491494
});
492495
wrapFn('useProgram', function(origFn, vao) {
493496
const oldProg = gl.getParameter(gl.CURRENT_PROGRAM);

webgl/lessons/resources/webgl-state-diagram/vertex-array-ui.js

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export function createVertexArrayDisplay(parent, name /*, webglObject */) {
6363
dataset: {
6464
help: helpToMarkdown(`
6565
* --true-- this attribute uses data from a buffer.
66-
* --false-- it uses --value--.
66+
* --false-- it uses the corresponding global state attribute value.
6767
6868
---js
6969
const index = gl.getAttribLocation(program, 'someAttrib'); // ${i}
@@ -74,20 +74,6 @@ export function createVertexArrayDisplay(parent, name /*, webglObject */) {
7474
${vaoNote}`),
7575
},
7676
});
77-
addElem('td', tr, {
78-
className: 'used-when-disabled',
79-
dataset: {
80-
help: helpToMarkdown(`
81-
The value used if this attribute is disabled.
82-
83-
---js
84-
const index = gl.getAttribLocation(program, 'someAttrib'); // ${i}
85-
gl.vertexAttrib4fv(index, [1, 2, 3, 4]);
86-
---
87-
88-
${vaoNote}`),
89-
},
90-
});
9177
addElem('td', tr, {
9278
className: 'used-when-enabled',
9379
dataset: {
@@ -248,7 +234,6 @@ export function createVertexArrayDisplay(parent, name /*, webglObject */) {
248234
const formatters = globals.isWebGL2
249235
? [
250236
formatBoolean, // enable
251-
formatUniformValue, // value
252237
formatUniformValue, // size
253238
formatEnum, // type
254239
formatBoolean, // integer
@@ -260,7 +245,6 @@ export function createVertexArrayDisplay(parent, name /*, webglObject */) {
260245
]
261246
: [
262247
formatBoolean, // enable
263-
formatUniformValue, // value
264248
formatUniformValue, // size
265249
formatEnum, // type
266250
formatBoolean, // normalize
@@ -277,7 +261,6 @@ export function createVertexArrayDisplay(parent, name /*, webglObject */) {
277261
const data = globals.isWebGL2
278262
? [
279263
gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_ENABLED),
280-
gl.getVertexAttrib(i, gl.CURRENT_VERTEX_ATTRIB),
281264
gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_SIZE),
282265
gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_TYPE),
283266
gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_INTEGER),
@@ -289,7 +272,6 @@ export function createVertexArrayDisplay(parent, name /*, webglObject */) {
289272
]
290273
: [
291274
gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_ENABLED),
292-
gl.getVertexAttrib(i, gl.CURRENT_VERTEX_ATTRIB),
293275
gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_SIZE),
294276
gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_TYPE),
295277
gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED),
@@ -298,12 +280,8 @@ export function createVertexArrayDisplay(parent, name /*, webglObject */) {
298280
gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_DIVISOR),
299281
gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING),
300282
];
301-
if (data[0]) {
302-
row.classList.add('attrib-enable');
303-
} else {
304-
row.classList.remove('attrib-enable');
305-
}
306-
const bufferNdx = globals.isWebGL2 ? 9 : 8; // FIXME
283+
row.classList.toggle('attrib-enable', data[0]);
284+
const bufferNdx = globals.isWebGL2 ? 8 : 7; // FIXME
307285
data.forEach((value, cellNdx) => {
308286
const cell = row.cells[cellNdx];
309287
const newValue = formatters[cellNdx](value);

0 commit comments

Comments
 (0)