OpenGL代码学习(12)--矩阵变化
注意:需要在配置好OpenGL的编程环境中运行下列代码,环境配置文章可参考:
OpenGL在Mac项目上的配置
下面的代码,直接放置在main.cpp文件中即可:
#include "GLTools.h" #include "GLShaderManager.h" #include "math3d.h" #include <GLUT/GLUT.h> GLBatch squareBatch; GLShaderManager shaderManager; GLfloat blockSize = 0.1f; GLfloat xPos = 0.0f; GLfloat yPos = 0.0f; // 矩形4个顶点位置坐标 GLfloat vVerts[] = { -blockSize, -blockSize, 0.0f, blockSize, -blockSize, 0.0f, blockSize, blockSize, 0.0f, -blockSize, blockSize, 0.0f }; // 初始化环境 void SetupRC() { // 设置窗口背景为蓝色 glClearColor(0.0f, 0.0f, 1.0f, 1.0f); // 着色器管理器初始化 shaderManager.InitializeStockShaders(); // 移动矩形批次初始化顶点数据 squareBatch.Begin(GL_TRIANGLE_FAN, 4); squareBatch.CopyVertexData3f(vVerts); squareBatch.End(); } // 特殊按键点击响应回调 void SpecialKeys(int key, int x, int y) { // 步进值,每次按键移动的距离 GLfloat stepSize = 0.025f; // 4个方向位置偏移 if (key == GLUT_KEY_UP) { yPos += stepSize; } if (key == GLUT_KEY_DOWN) { yPos -= stepSize; } if (key == GLUT_KEY_LEFT) { xPos -= stepSize; } if (key == GLUT_KEY_RIGHT) { xPos += stepSize; } // 边界判断和限制 if (xPos < (-1.0f + blockSize)) { xPos = (-1.0f + blockSize); } if (xPos > (1.0f - blockSize)) { xPos = (1.0f - blockSize); } if (yPos < (-1.0f + blockSize)) { yPos = (-1.0f + blockSize); } if (yPos > (1.0f - blockSize)) { yPos = (1.0f - blockSize); } // 触发渲染 glutPostRedisplay(); } // 窗口渲染回调 void RenderScene(void) { // 清楚缓存区 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // 创建3个4x4矩阵,分别是最终合成矩阵、平移矩阵、旋转矩阵 M3DMatrix44f mFinalTransform, mTranslationMatrix, mRotationMatrix; // 平移(xPos, yPos, 0)的矩阵表示 m3dTranslationMatrix44(mTranslationMatrix, xPos, yPos, 0.0f); // 绕z轴旋转的矩阵,每次旋转角度加5度,m3dDegToRad = 角度 -> 弧度 static float zRot = 0.0f; zRot += 5.0f; m3dRotationMatrix44(mRotationMatrix, m3dDegToRad(zRot), 0.0f, 0.0f, 1.0f); // 矩阵相乘,参数顺序很重要,先平移,后旋转 m3dMatrixMultiply44(mFinalTransform, mTranslationMatrix, mRotationMatrix); // 着色器上色,移动矩形为红色 GLfloat vRed[] = {1.0f, 0.0f, 0.0f, 1.0f}; shaderManager.UseStockShader(GLT_SHADER_FLAT, mFinalTransform, vRed); squareBatch.Draw(); // 因为是双缓冲区模式,后台缓冲区替换到前台缓冲区进行显示 glutSwapBuffers(); } // 窗口变化回调 void ChangeSize(int w, int h) { // 设置视口 glViewport(0, 0, w, h); } // 程序入口 int main(int argc, char *argv[]) { // 设置 Mac OS 工作l目录路径 gltSetWorkingDirectory(argv[0]); // GLUT初始化 glutInit(&argc, argv); // 设置渲染模式 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); // 初始化窗口大小 glutInitWindowSize(800, 720); // 创建窗口并命名 glutCreateWindow("Move Block with Arrow keys"); // 判断驱动程序是否初始化完成 GLenum err = glewInit(); if (err != GLEW_OK) { fprintf(stderr, "Error:%s\n", glewGetErrorString(err)); return 1; } // 窗口变化回调函数设置 glutReshapeFunc(ChangeSize); // 窗口渲染回调函数设置 glutDisplayFunc(RenderScene); // 特殊按钮响应回调函数设置 glutSpecialFunc(SpecialKeys); // 初始化环境 SetupRC(); // 主消息循环 glutMainLoop(); return 0; }
运行后的效果如下: