CS 315 Lab - Hexagon

Overview

You task for this lab is to use WebGL to render a multi-colored hexagon:

This will give you a chance to practice working with OpenGL code, and to learn how to work with Vertex Attribute Arrays---lists of attributes (properties) of vertices.

Necessary Files

You should download, unzip and start from a copy of the starter code. This is a slightly cleaned-up copy of the demo code from lecture. It will give you examples of all the various OpenGL methods we need to get things runing.

Lab Details

  1. First, make sure you've downloaded the starter code and are able to run it. You should see the familiar blue triangle. (Note that I adjusted the dimensions of the canvas, so it may look slightly smooshed. You might think about why the same coordinates make the triangle look different)
  2. Next, rather than giving a uniform variable for the triangle's color, you'll want to specify the color of each individual vertex as an attribute. OpenGL will then automatically interpolate between the colors of the vertices to produce nice gradiant shading:

    There are a few steps to accomplish this:

    1. You'll need to modify the vertex shader (shader/vertex.vert) so that it has a new attribute variable to represent the color of each vertex. This variable should be given the attribute storage qualifier; I recommend naming it aColor (the attribute representing color).
      • This variable could be a vec3 if you want to pass in 3 values for the color (R,G,B), or a vec4 if you want to pass in 4 values (R,G,B,A)
      • You should also make sure that the output variable vColor gets it's color from your new (input) attribute! vColor is a vec4; you can either directly assign from a vec4, or you can create a new vec4 using a constructor that takes in the vec3 as a parameter. For example: vec4(aColor, 1.0)
      • You can continue to use the uColorChoice variable if you want to be able to specify a particular color (e.g., for the guides).
    2. Now that you've specified a new variable in the shader, you'll need to make sure we have access to it in the JavaScript! Use the gl.getAttribLocation() method to store a new handle to that variable's memory location. (We're using getAttribLocation instead of getUniformLocation because the variable is an attribute, not a uniform!). You can use the code that creates the vertexPositionhandle as a template.
    3. Next you will need to specify some colors for the vertices! This is going to be a new buffered array of data.
      • Start by making a new JavaScript array of the colors. This will be similar to your array that holds the vertex coordinates/position, but it will need 3 or 4 components (RGB or RGBA) for each vertex. MAKE EACH VERTEX A DIFFERENT COLOR (but what color doesn't matter).
      • You will need a new vertex buffer object to hold this data in a format OpenGL can read. Convert your color array to a Float32Array and store it in a new gl.ARRAY_BUFFER.
      • Again, you can use the buffer creation for the position array as a template. But be very careful about changing variable names when copy-pasting code!
    4. Finally, in your drawing method, you will need to point OpenGL at your newly created buffer so it knows where to find the colors.
      • You do this by setting the a pointer with gl.vertexAttribPointer() method. You might be interested in the documentation for this method so that you know what the parameters are. But basically, you're going to (again) do the same thing as with the vertexPositionBuffer.
      • IMPORTANT: remember to specify the number of components (the second parameter) that each attribute has. So if the color of each vertex has 4 components, that should be a 4.
      • You will need to be sure and bind your color buffer before you set this pointer, so OpenGL knows what data it should be pointing to!
      • Also remember to enable the vertex attribute array (otherwise OpenGL won't know to go looking for it).
    If you run your code, you should now see a multi-colored triangle! If not, first check the console for errors (there may be a typo/bug), and/or check for help!
  3. Now that you have the multi-colored triangle drawing, you should tweak the model so it shows a hexagon instead!
    • Note that you won't need to make any further changes to the shader or the drawing--you can simply update the model!
    • I recommend a "find and replace" change and make your "triangle" object into a "hexagon" object, as a place to start :)
    • Specify further vertex positions so that your polygon is a hexagon made up of 6 triangles. You can guestimate these by hand, but you could also calculate them directly using polar coordinates polar coordinates:
      x = radius * Math.cos(angle)
      y = radius * Math.sin(angle)
      If you specify angles at 0 degrees, 60 degrees, 120 degrees, etc. (and convert to radians), you can easily produce the 6 outer coordinates!
    • You will of course also need to specify colors for all of your vertices.
    • Since each vertex is shared between at least 2 triangles (and the ceter between all 6 triangles), it would make sense to use an index array to represent this model! Using the code for the quad as a template, add an index array and Uint16Array buffer containing the indices of your vertices.
      • You'll need to change your drawing method so that you use the glDrawElements() method to draw the indexed vertices. Don't forget to rebind the gl.ELEMENT_ARRAY_BUFFER!
    • You could even easily specify this shape using a triangle fan. To do this, you'll need to give your indices following the triangle fan format (so rather than having every 3 indices represent a triangle, you have a sequence of indices that will represent the fan). Then in your glDrawElements() method, instead of specifying to draw gl.TRIANGLES, you specify to draw a gl.TRIANGLE_FAN.

And that's the end of the lab! If you have more time, you're welcome to play around with drawing more complex polygons or using different colors :)