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
- 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)
-
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:
-
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 theattribute
storage qualifier; I recommend naming itaColor
(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 avec4
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 avec4
; you can either directly assign from avec4
, or you can create a newvec4
using a constructor that takes in thevec3
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).
- This variable could be a
-
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 thevertexPositionhandle
as a template. -
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 newgl.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!
-
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 thevertexPositionBuffer
. - 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).
-
You do this by setting the a pointer with
-
You'll need to modify the vertex shader (
-
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 theglDrawElements()
method to draw the indexed vertices. Don't forget to rebind thegl.ELEMENT_ARRAY_BUFFER
!
- You'll need to change your
-
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 drawgl.TRIANGLES
, you specify to draw agl.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 :)