从这里开始就进入了opengl最关键的部分了。
1.构造平移矩阵
m3dTranslationMatrix44(mTranslate, 0.0f, 0.0f, -2.5f);
第一个参数是4x4的矩阵,后面是位移向量
2.构造旋转矩阵
m3dRotationMatrix44(mRotate, m3dDegToRad(yRot), 1.0f, 1.0f, 1.0f);//构造旋转矩阵
第一个参数的4x4的矩阵,第二个是旋转的弧度,后面是旋转的轴
3.矩阵乘法
m3dMatrixMultiply44(mModelview, mTranslate, mRotate);
这样就可以把两个变化保存到一个矩阵里面
4.获取投影矩阵
viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 1000.0f);//设置透视投影
viewFrustum.GetProjectionMatrix();//会返回投影矩阵
5.应用变换的矩阵结果,mModelViewProjection为变换结果
shaderManager.UseStockShader(GLT_SHADER_FLAT, mModelViewProjection, vBlack);
完整代码如下:
#include <GLTools.h> // OpenGL toolkit
#include <GLMatrixStack.h>
#include <GLFrame.h>
#include <GLFrustum.h>
#include <GLGeometryTransform.h>
#include <GLBatch.h>
#include <StopWatch.h>
#include <math.h>
#define FREEGLUT_STATIC //在windows和linux上,使用freeglut静态版本,需要添加这一行,否则会出现错误
#include <glut.h>
#pragma comment(lib,"gltools.lib")//要加上这一行链接一下gltools库
// Global view frustum class
GLFrustum viewFrustum;
// The shader manager
GLShaderManager shaderManager;
// The torus
GLTriangleBatch torusBatch;
// Set up the viewport and the projection matrix
void ChangeSize(int w, int h)
{
// Prevent a divide by zero
if (h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 1000.0f);//设置透视投影
}
// Called to draw scene
void RenderScene(void)
{
// Set up time based animation
static CStopWatch rotTimer;
float yRot = rotTimer.GetElapsedSeconds() * 60.0f;//每秒转动60度
// Clear the window and the depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Matrix Variables
M3DMatrix44f mTranslate, mRotate, mModelview, mModelViewProjection;
m3dTranslationMatrix44(mTranslate, 0.0f, 0.0f, -2.5f);//构造移动的矩阵
m3dRotationMatrix44(mRotate, m3dDegToRad(yRot), 1.0f, 1.0f, 1.0f);//构造旋转矩阵
m3dMatrixMultiply44(mModelview, mTranslate, mRotate);//将上述的两个矩阵的变换结果存储在mModelview中
// Add the modelview matrix to the projection matrix,
// the final matrix is the ModelViewProjection matrix.
m3dMatrixMultiply44(mModelViewProjection, viewFrustum.GetProjectionMatrix(), mModelview);//将mModelview和投影矩阵相乘保存在mModelViewProjection中
// Pass this completed matrix to the shader, and render the torus
GLfloat vBlack[] = { 0.0f, 0.0f, 0.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_FLAT, mModelViewProjection, vBlack);
torusBatch.Draw();
// Swap buffers, and immediately refresh
glutSwapBuffers();
glutPostRedisplay();//实时刷新才能看得到动画
}
// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
// Black background
glClearColor(0.8f, 0.8f, 0.8f, 1.0f);//灰色背景
glEnable(GL_DEPTH_TEST);//开启深度测试
shaderManager.InitializeStockShaders();
// This makes a torus
gltMakeTorus(torusBatch, 0.4f, 0.15f, 30, 30);//创建花环
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//使用线性模式进行填充
}
///////////////////////////////////////////////////////////////////////////////
// Main entry point for GLUT based programs
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("ModelViewProjection Example");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
return 0;
}