More Scenarios for Data in WebGL
- In the first demo, we just had vertex data.
- We used a single vbo.
- We used a single attribute in the shader.
- No offset and no stride
- We used drawArrays with no offset.
- In the second demo
- This has a new vertex shader and a new fragment shader
- A new attribute, color.
- Be aware that the shader compiler optimizes out attributes that are not used.
- So unless you actually use the attribute, it is not available.
- This takes the color attribute and passes it down the pipeline via a varying variable.
- These are used to communicate data from the vertex shader to the fragment shader.
- They need to be declared in both shaders.
- Declaring a varying variable then requires us to set precision.
-
precision highp float;is probably the best for us.
-
- Notice how the color is interpolated between points.
- This is just a lerp, done for us.
- This is applied to all varying variables.
- A new attribute, color.
- These shaders will remain constant for the rest of the demos.
- Notice in this demo we have packed the points and the colors into a single array.
- The set of points first.
- The set of colors next.
- In my mind this is not the natural way to do this.
- But we can.
- In the widget
- We now divide the length by 2, as each vertex has two data points (position and color)
- The data arrangement requires a second attribute pointer.
-
this.size = edges.length/2; this.vpos = gl.getAttribLocation(program, posName); this.cpos = gl.getAttribLocation(program, colorName); - There is no change to the VBO.
- But in draw
- We set up each attribute
- Note the stride stays the same
- The data is tightly packed.
- But the offset for the colors is the array size * 12
- This is given in terms of bytes.
- Each float is 4 bytes.
- So each position is 12 bytes
- And there are size positions.
- So the color starts at
12*this.size -
gl.vertexAttribPointer(this.vpos, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(this.vpos); gl.vertexAttribPointer(this.cpos, 3, gl.FLOAT, false, 0, this.size*12); gl.enableVertexAttribArray(this.cpos);
- Note the stride stays the same
- We set up each attribute
- This has a new vertex shader and a new fragment shader
- In the third demo
- The only change here is how the data is stored.
- The points and the colors are mixed.
- This is what would happen if we had a vertex class.
- This stored the point and the color.
- This means we need to change the attribute pointers in the widget
- Each data point is still 12 bytes in size.
- But there is a 12 byte gap between each point.
- So the stride is 24
- And the offset is either
- 0 (position data)
- 12 (color data)
- The only change here is how the data is stored.
- In the fourth demo
- This is a major departure.
- Data is stored as a vertex (position, color) as part of a vertex list.
- But the shapes are stored as a set of polygon lists.
- Each polygon in the object has a separate list.
- This list contains the index into vertex list for the points in the polygon.
- Note this hierarchy is sometimes amended to include an edge list
- This is a standard way to do things in graphics, supported by VBO configurations.
- I added a parameter to the Widget constructor
- The vertex list and the polygon lists
- The widget now declares two vbos
- The vertex list is still a ARRAY_BUFFER
- We now add a set of polygon lists in the form of a ELEMENT_ARRAY_BUFFER
- These need to be one of the following
- gl.UNSIGNED_BYTE
- gl.UNSIGNED_SHORT
- So after we flatten the array, we convert it to Uint16
- These need to be one of the following
- The attributes stay the same.
- But we need to bind both buffers.
- And we draw with gl.drawElements.
- This takes a drawing method
- The number of points to draw
- The type of points to draw
- An offset into the array to start
- In this case, note the size is a Uint16, so only 2 bytes per index point.
- Since we will draw each face separately we will use the offset.
- There is one further arrangement
- We could put the position data in one vbo
- We could put the color data in a second vbo
- And the index data in a third vbo.