More Scenarios for Data in WebGL

  1. 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.
  2. 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.
    • 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); 
  3. 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)
  4. 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
    • 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.
  5. 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.