opengl超级宝典(第五版)阅读笔记 8 模型视图投影矩阵

从这里开始就进入了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;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43813453/article/details/85537826