Tom Kelliher, CS 320
Apr. 5, 2013
Read 5.1-3.
3-D projections, Movement in 3-D, Problems with 3-D movement.
Project day; light.
Consider building a room.
Two approaches:
Again, two approaches:
Rotate, then translate:
mv = Translate(...) * RotateX(...); ...
Translate, then rotate:
mv = Translate(...) * RotateX(...); ...What's the difference???
Consider the transformations necessary for constructing:
when what you have to start with is the one block.
Steps:
reset to world frame;
translate 4 left
draw;
translate 8 right;
draw;
reset to world frame;
translate 11 left, 5 down;
// Repeat the following 4 times.
draw;
translate 10 up;
draw;
translate 6 right and 6 up;
rotate -90; // Why -90???
draw;
move 10 up;
draw; // Don't forget that we also rotated the
// local coordinate system!
See room() for the real code.
A couple vertex lists:
Point Wall[] =
{ Point(-1.0, -5.0, 0.0), Point( 1.0, -5.0, 0.0),
Point( 1.0, 5.0, 0.0), Point(-1.0, 5.0, 0.0),
Point(-1.0, -5.0, 8.0), Point( 1.0, -5.0, 8.0),
Point( 1.0, 5.0, 8.0), Point(-1.0, 5.0, 8.0)
};
Point Floor[] =
{ Point(-12.0, -12.0, 0.0), Point( 12.0, -12.0, 0.0),
Point( 12.0, 12.0, 0.0), Point(-12.0, 12.0, 0.0)
};
Is there a general way for drawing?
colorCube():
// colorCube draws a cube.
// vertices: the vertex list specifying the cube.
//
// Assumptions regarding the vertex list:
// Index Vertex
// 0 Lower left vertex of bottom face.
// 1 Lower right vertex of bottom face.
// 2 Upper right vertex of bottom face.
// 3 Upper left vertex of bottom face.
// 4--7 Similar for top face.
// (Assumes we are looking at the origin from the +z axis with the +y axis
// being "up."
//
// generate 12 triangles: 36 vertices.
void colorcube(const Point vertices[])
{
quad( vertices, 1, 0, 3, 2 );
quad( vertices, 2, 3, 7, 6 );
quad( vertices, 3, 0, 4, 7 );
quad( vertices, 6, 5, 1, 2 );
quad( vertices, 4, 5, 6, 7 );
quad( vertices, 5, 4, 0, 1 );
}
quad():
// quad generates two triangles for each face.
void quad(const Point vertices[], int a, int b, int c, int d )
{
points[Index] = vertices[a]; Index++;
points[Index] = vertices[b]; Index++;
points[Index] = vertices[c]; Index++;
points[Index] = vertices[a]; Index++;
points[Index] = vertices[c]; Index++;
points[Index] = vertices[d]; Index++;
}
init() showing creation of drawn objects:
Index = 0; colorcube(Wall); // Dumps vertices into points. oWall.vao = createVAO(); // Uses vertices from points. oWall.numVertices = 36; oWall.geometry = GL_TRIANGLES; Index = 0; quad(Floor, 0, 1, 2, 3); oFloor.vao = createVAO(); oFloor.numVertices = 6; oFloor.geometry = GL_TRIANGLES; Index = 0; quad(Viewer, 0, 1, 2, 3); oViewer.vao = createVAO(); oViewer.numVertices = 6; oViewer.geometry = GL_TRIANGLES;
What about this case?
Sketch of display():
clear color and depth buffers;
// Prepare for the map view.
set an orthographic projection;
set viewport;
draw room;
draw viewer;
flush all polygons; // Ensure that none are "hanging" around.
// Prepare for the first-person view
set a perspective projection;
set viewport;
position the camera; // Remember: viewer transformation, then
// model transformations.
draw room;
draw ceiling;
swap color buffers;
display():
void display(void)
{
mat4 p; /* Projection matrix */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Set-up to draw the map.
p = Ortho(-13.0, 13.0, -13.0, 13.0, -10.0, 1.0);
glUniformMatrix4fv(projection, 1, GL_TRUE, p);
glViewport(0, 0, 100, 100);
// Draw viewer.
mv = Translate(viewerPosition[0], viewerPosition[1], 10.0);
glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);
glBindVertexArray(oViewer.vao);
glUniform3fv(vColor, 1, black);
glDrawArrays(oViewer.geometry, 0, oViewer.numVertices);
// Draw the room.
mv = Translate(0.0, 0.0, 0.0);
glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);
room();
glFlush();
// Set-up the do the first-person view.
p = Perspective(90.0, 1.0, 0.1, 100.0);
glUniformMatrix4fv(projection, 1, GL_TRUE, p);
glViewport(100, 100, windowWidth - 100, windowHeight - 100);
// Position the camera.
mv = LookAt(vec4(viewerPosition[0], viewerPosition[1],
viewerPosition[2], 1.0),
vec4(viewerPosition[0] + cos(viewerTheta),
viewerPosition[1] + sin(viewerTheta),
viewerPosition[2], 1.0),
vec4(0.0, 0.0, 1.0, 1.0));
glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);
room();
// Draw ceiling.
mv = mv * Translate(0.0, 0.0, 8.0);
glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);
glBindVertexArray(oFloor.vao);
glUniform3fv(vColor, 1, magenta);
glDrawArrays(oFloor.geometry, 0, oFloor.numVertices);
glutSwapBuffers();
}
room():
/*********************************************************************
* room() --- draw the room. Because of the separate needs of the map
* and first-person views, it draws neither the ceiling nor the
* viewer.
*********************************************************************/
void room()
{
mat4 lmv; // Local copy of the global modelview matrix.
// Draw floor.
glBindVertexArray(oFloor.vao);
glUniform3fv(vColor, 1, white);
glDrawArrays(oFloor.geometry, 0, oFloor.numVertices);
// Draw middle walls.
lmv = mv * Translate(-4.0, 0.0, 0.0);
glUniformMatrix4fv(model_view, 1, GL_TRUE, lmv);
glBindVertexArray(oWall.vao);
glUniform3fv(vColor, 1, red);
glDrawArrays(oWall.geometry, 0, oWall.numVertices);
lmv = lmv * Translate(8.0, 0.0, 0.0);
glUniformMatrix4fv(model_view, 1, GL_TRUE, lmv);
glDrawArrays(oWall.geometry, 0, oWall.numVertices);
// Draw walls defining room boundaries.
lmv = mv * Translate(-11.0, -5.0, 0.0);
glUniformMatrix4fv(model_view, 1, GL_TRUE, lmv);
for (int i = 0; i < 4; i++)
{
glUniform3fv(vColor, 1, (i == 1) ? green : blue);
glDrawArrays(oWall.geometry, 0, oWall.numVertices);
lmv = lmv * Translate(0.0, 10.0, 0.0);
glUniformMatrix4fv(model_view, 1, GL_TRUE, lmv);
glUniform3fv(vColor, 1, (i == 1) ? green : blue);
glDrawArrays(oWall.geometry, 0, oWall.numVertices);
lmv = lmv * Translate(6.0, 6.0, 0.0) * RotateZ(-90.0);
glUniformMatrix4fv(model_view, 1, GL_TRUE, lmv);
}
}
A and S keys for rotation.