The previous program used a matrix to translate and rotate a torus. This program will do the same transformations, but the matrix will no longer be the only matrix. It will be the topmost matrix in a stack of matrices. Somewhat anticlimactically, the matrices below it in the stack will not be used.
The
modelView
in
threedimensions.cpp
is a stack of matrices,
initially consisting of one identity matrix.
The identity matrix keeps the torus
in its default position at the origin,
and in its default attitude lying in the XY plane.
The
PushMatrix
member function of the
modelView
creates a copy of the topmost matrix in the stack,
and pushes this copy onto the stack.
The stack now consists of two identity matrices.
Conversely,
PopMatrix
removes and destroys the topmost matrix.
The stack now consists of one identity matrix again.
The
assert
s
check for overflow and underflow after each push and pop,
even though the stack has room for 64 matrices.
The
Translate
and
Rotate
member functions change the topmost matrix on the stack.
Originally an identity matrix,
this matrix now translates the torus away from the observer and rotates it.
The
GetMatrix
member function returns the topmost matrix.
The
projectMatrix
is another stack of matrices,
initially consisting of one identity matrix.
The
LoadMatrix
in
reshape
replaces this identity matrix with
a matrix that causes closer objects to appear bigger
and farther objects to appear smaller.
threedimensions.cpp
main.m
GLAppDelegate
GLViewController
EAGLView
Same as the
previous program,
but with a different
threedimensions.cpp
file.
GLGeometryTransform
is an object that can hold (the addresses of) the two stacks of matrices.
We’ll put it in now,
even though we don’t need it yet.
Define a
GLGeometryTransform
along with the other global objects
at the top of the
threedimensions.cpp
file,
and include
<GLGeometryTransform.h>
.
GLGeometryTransform geometryTransform;At the end of the
reshape
function,
store the addresses of the two stacks into the
geometryTransform
.
geometryTransform.SetMatrixStacks(modelView, projection);Change the call to
UseStackShader
in the
display
function to the following.
shaderManager.UseStockShader( GLT_SHADER_POINT_LIGHT_DIFF, geometryTransform.GetModelViewMatrix(), geometryTransform.GetProjectionMatrix(), lightPosition, red );
GLTriangleBatch sphere; //at the top of threedimensions.cpp
gltMakeSphere(sphere, .25, 40, 40); //in SetupRC
void display(GLfloat theta) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); static const M3DVector4f lightPosition = {0.0f, 10.0f, 5.0f, 1.0f}; static const GLfloat red[] = {1.0f, 0.0f, 0.0f, 1.0f}; modelView.PushMatrix(); modelView.Translate(0.0f, 0.0f, -7.0f); modelView.Rotate(theta, 0.0f, 1.0f, 0.0f); shaderManager.UseStockShader( GLT_SHADER_POINT_LIGHT_DIFF, geometryTransform.GetModelViewMatrix(), geometryTransform.GetProjectionMatrix(), lightPosition, red ); torus.Draw(); modelView.PushMatrix(); modelView.Translate(0.0f, 0.0f, 1.0f); shaderManager.UseStockShader( GLT_SHADER_POINT_LIGHT_DIFF, geometryTransform.GetModelViewMatrix(), geometryTransform.GetProjectionMatrix(), lightPosition, red ); sphere.Draw(); modelView.PopMatrix(); modelView.PopMatrix(); }
0.01f
to
1000.0f
.
GLTriangleBatch sphere; //at the top of threedimensions.cpp
gltMakeSphere(sphere, 1.0f, 40, 40); //in SetupRC
void useStockShader() { static const M3DVector4f lightPosition = {0.0f, 10.0f, 5.0f, 1.0f}; static const GLfloat snow[] = {1.0f, 0.980392f, 0.980392f, 1.0f}; shaderManager.UseStockShader( GLT_SHADER_POINT_LIGHT_DIFF, geometryTransform.GetModelViewMatrix(), geometryTransform.GetProjectionMatrix(), lightPosition, snow ); sphere.Draw(); } void display(GLfloat theta) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //ground modelView.PushMatrix(); modelView.Translate(0.0f, -1000.1f, 0.0f); modelView.Scale(1000.0f, 1000.0f, 1000.0f); useStockShader(); modelView.PopMatrix(); //snow man modelView.PushMatrix(); //This translation will apply to the abdomen, thorax, and head. modelView.Translate(0.0f, 0.0f, -7.0f); //abdomen modelView.PushMatrix(); modelView.Scale(0.5f, 0.5f, 0.5f); useStockShader(); modelView.PopMatrix(); //This translation will apply to the thorax and head. modelView.Translate(0.0f, 0.6f, 0.0f); //thorax modelView.PushMatrix(); modelView.Scale(0.4f, 0.4f, 0.4f); useStockShader(); modelView.PopMatrix(); //head modelView.PushMatrix(); modelView.Translate(0.0f, 0.5f, 0.0f); modelView.Scale(0.25f, 0.25f, 0.25f); useStockShader(); modelView.PopMatrix(); modelView.PopMatrix(); }Give him a carrot nose and coal-lump eyes.