opengl超級寶典(第五版)閱讀筆記 8 模型檢視投影矩陣
阿新 • • 發佈:2019-01-01
從這裡開始就進入了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;
}