OpenGL之利用矩阵的平移、旋转、综合变换等实现矩阵的移动
程序员文章站
2024-03-20 14:46:28
...
核心业务
- 矩形的绘制
// 加载矩形
squareBatch.Begin(GL_TRIANGLE_FAN, 4);
squareBatch.CopyVertexData3f(vVerts);
squareBatch.End();
- 碰撞检测
// 碰撞检测
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;
// 每次操作方向键之后, 重新调用RenderScene进行新的场景渲染
glutPostRedisplay();
- 矩阵的变换(平移、旋转、综合变换)
// 矩阵变化
M3DMatrix44f mFinalTransform, mTranslationMatrix, mRotationMatrix;
// 平移 xPos,yPos
m3dTranslationMatrix44(mTranslationMatrix, xPos, yPos, 0.0f);
// 每次重绘时,旋转5度
static float yRot = 0.0f;
yRot += 5.0f;
m3dRotationMatrix44(mRotationMatrix, m3dDegToRad(yRot), 0.0f, 0.0f, 1.0f);
// 将旋转和移动的结果合并到 mFinalTransform 中
m3dMatrixMultiply44(mFinalTransform, mTranslationMatrix, mRotationMatrix);
示例代码
#include <stdio.h>
// GLTool.h头⽂文件包含了大部分GLTool中类似C语言的独立函数
#include "GLTools.h"
// 矩阵的⼯具类.可以利于GLMatrixStack 加载单元矩阵/矩阵/矩阵相乘/压栈/出栈/缩放/平移/旋转
#include "GLMatrixStack.h"
// 矩阵工具类,表示位置.通过设置vOrigin,vForward,vUps等
#include "GLFrame.h"
// 矩阵⼯具类,⽤来快速设置正/透视投影矩阵.完成坐标从3D->2D的映射过程
#include "GLFrustum.h"
// 三⻆形批次类,帮助类,利用它可以传输顶点/光照/纹理/颜⾊数据到存储着⾊器中
#include "GLBatch.h"
// 变换管道类,⽤来快速在代码中传输视图矩阵/投影矩阵/视图投影变换矩阵等
#include "GLGeometryTransform.h"
// 在Mac 系统下,`#include<glut/glut.h>`在Windows 和 Linux上,我们使用freeglut的静态库版本并且需要添加一个宏
#include <math.h> // 数学库
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
GLShaderManager shaderManager;
GLBatch squareBatch;
GLfloat blockSize = 0.1f;
GLfloat vVerts[] = {
-blockSize, -blockSize, 0.0f,
blockSize, -blockSize, 0.0f,
blockSize, blockSize, 0.0f,
-blockSize, blockSize, 0.0f};
GLfloat xPos = 0.0f;
GLfloat yPos = 0.0f;
void SetupRC() {
// 背景颜色
glClearColor(0.5f, 0.5f, 0.0f, 1.0f );
shaderManager.InitializeStockShaders();
// 加载矩形
squareBatch.Begin(GL_TRIANGLE_FAN, 4);
squareBatch.CopyVertexData3f(vVerts);
squareBatch.End();
}
// 移动(移动只是计算了X,Y移动的距离,以及碰撞检测)
void SpecialKeys(int key, int x, int y) {
GLfloat stepSize = 0.025f;
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;
// 每次操作方向键之后, 重新调用RenderScene进行新的场景渲染
glutPostRedisplay();
}
void RenderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
GLfloat vRed[] = {0.5f, 0.0f, 0.5f, 1.0f};
// 矩阵变化
M3DMatrix44f mFinalTransform, mTranslationMatrix, mRotationMatrix;
// 平移 xPos,yPos
m3dTranslationMatrix44(mTranslationMatrix, xPos, yPos, 0.0f);
// 每次重绘时,旋转5度
static float yRot = 0.0f;
yRot += 5.0f;
m3dRotationMatrix44(mRotationMatrix, m3dDegToRad(yRot), 0.0f, 0.0f, 1.0f);
// 将旋转和移动的结果合并到 mFinalTransform 中
m3dMatrixMultiply44(mFinalTransform, mTranslationMatrix, mRotationMatrix);
// 将矩阵结果提交到固定着色器(平面着色器)中。
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[]) {
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(600, 600);
glutCreateWindow("Move Block with Arrow Keys");
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
return 1;
}
// 设置视口大小
glutReshapeFunc(ChangeSize);
// 渲染场景
glutDisplayFunc(RenderScene);
// 键盘方向键操作
glutSpecialFunc(SpecialKeys);
SetupRC();
glutMainLoop();
return 0;
}
效果展示
本例是键盘的上下左右方向键来控制矩形的旋转平移:
下一篇: 33、Cookie的简单使用