In this lab, we are going to create a spherical surface procedurally in C++ and apply a texture to it in GLSL.
Please download the code for the lab and go over the code.
In our past labs, we loaded the mesh from an .obj file, but in this lab, we will be creating our mesh procedurally by defining the vertex position, normal, texture coordinates, and triangle indices.
When you run the program initially, you’ll see a textured square. The camera can be controlled using the mouse. Study the function init()
to understand how the vertex data are being specified. We are filling the position, normal, and texture coordinate buffers with data for the four vertices of the square. To create the two triangles that make up this square, we’re passing in z
key to toggle the drawing mode to wireframe to see the two triangles.
Note that the vertices are specified counterclockwise looking down the z-axis. This ordering implies that the “front side” of the triangle is facing the camera. If you press c
, then OpenGL’s “cull face” mode will be turned on, making the “back side” of the triangles invisible. With culling turned on, rotate the square 180 degrees to verify that it becomes invisible.
Remove the code for specifying the vertex data for the square and replace it with your own code that creates the triangulated grid shown below. Do not hard code anything. You should use a double for-loop; the outer for-loop should iterate over the rows, and the inner for-loop should iterate over the columns. (It may be helpful to do this in two stages:
Now we’re going to turn this grid into a sphere using spherical coordinates. In a spherical coordinate system, a point in 3D is defined using the radius (
Spherical coordinates [Wikipedia]
For this lab, we will assume that the radius is constant:
Note that the expression above isn’t exactly the same as the one in the Wikipedia article. This is because we are using the convention that Y is up.
How do we go about creating the vertex data for a sphere? In Task
for i = 1 ...
for j = 1 ...
x = ...
y = ...
z = 0
end
end
Similarly, we can create a grid in the parametric space
for i = 1 ...
for j = 1 ...
theta = ...
phi = ...
x = sin(theta) * sin(phi)
y = cos(theta)
z = sin(theta) * cos(phi)
end
end
For a unit sphere at the origin, the normal is the same as the position. For texture coordinates, we can keep the same code from Task
Finally, we’re going to animate the sphere. We’re going to make it bounce up and down while changing the scale to “squash and stretch” the sphere.
To do so, apply translation and scale to the modelview matrix. We want the Y translation to be a sinusoid with some amplitude, period, and phase. We also want the X and Z scale to be another sinusoid.
The graph above shows the translation in blue and the scale in red. Since we want the sphere to bounce up, the blue curve has a minimum of
where
Do not forget to send and use the inverse transpose of the modelview matrix in the vertex shader to transform the normal from model space to camera space. You need to multiply the incoming normal by the inverse transpose matrix and normalize the result.