主要使用了:
矩阵构造(平移、旋转、综合变换)
模型视图矩阵
三角形批次类(创建花托)
投影矩阵(透视投影)
示例程序绘制了一个在屏幕中间旋转的线框花托。
// ModelviewProjection.cpp// OpenGL SuperBible// Demonstrates OpenGL the ModelviewProjection matrix// Program by Richard S. Wright Jr.#include// OpenGL toolkit#include #include #include #include #include #include #include #ifdef __APPLE__#include #else#define FREEGLUT_STATIC#include #endif// Global view frustum class//使用GLFrustum类来设置透视投影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 //防止h变为0 if(h == 0) h = 1; // Set Viewport to window dimensions //设置视口窗口尺寸 glViewport(0, 0, w, h); //SetPerspective函数的参数是一个从顶点方向看去的视场角度(用角度值表示) //宽度和高度的比值和从近剪切面到原件切面的距离 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; // Clear the window and the depth buffer //清除窗口和深度缓冲区 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Matrix Variables //矩阵变量 M3DMatrix44f mTranslate, mRotate, mModelview, mModelViewProjection; // Create a translation matrix to move the torus back and into sight //创建一个平移矩阵来移动这个圆环面 m3dTranslationMatrix44(mTranslate, 0.0f, 0.0f, -2.5f); // Create a rotation matrix based on the current value of yRot //创建一个基于yrot值的旋转矩阵 m3dRotationMatrix44(mRotate, m3dDegToRad(yRot), 0.0f, 1.0f, 0.0f); // Add the rotation to the translation, store the result in mModelView //加上旋转的位移,结果存储在mmodelview m3dMatrixMultiply44(mModelview, mTranslate, mRotate); // Add the modelview matrix to the projection matrix, // the final matrix is the ModelViewProjection matrix. //添加模型视图矩阵的投影矩阵, 最后的矩阵是modelviewprojection矩阵。 m3dMatrixMultiply44(mModelViewProjection, viewFrustum.GetProjectionMatrix(),mModelview); // 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 programsint main(int argc, char* argv[]) { gltSetWorkingDirectory(argv[0]);//设置当前工作目录 glutInit(&argc, argv);//传输命令行参数并初始化GLUT库 //使用双缓冲窗口和使用RGBA颜色模式 //GLUT_DEPTH位标志将一个深度缓冲区分配为显示的一部分,因此我们可以执行深度测试 // GLUT_STENCIL确保我们也会有一个可用的模板缓冲区 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowSize(800, 600);//窗口大小 glutCreateWindow("ModelViewProjection Example");//窗口标题 glutReshapeFunc(ChangeSize);//改变窗口大小的回调函数 glutDisplayFunc(RenderScene);//OpenGL渲染代码 //初始化glew库 GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); return 1; } SetupRC();//RC代表渲染环境(Rendering Context) glutMainLoop();//主消息循环 return 0; }
运行结果: