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.