关键函数讲解
平移
//创建单元矩阵
M3DMatrix44f m3;
m3dLoadIdentity44(m3);
/*
m3dTranslationMatrix44(M3DMatrix44f m, float x, float y, float z)
参数1:结果矩阵,平移之后的结果矩阵
参数2:沿着X轴移动多少,正数\负数
参数3:沿着Y轴移动多少,正数\负数
参数4:沿着Z轴移动多少,正数\负数
*/
m3dTranslationMatrix44(m3, 0.0f, 10.0f, 0.0f);
旋转
/*
m3dRotationMatrix44(M3DMatrix44f m, float angle, float x, float y, float z);
参数1:结果矩阵,旋转之后的结果矩阵
参数2:旋转多少弧度
参数3:是否围绕X轴旋转,是(1),不是(0)
参数4:是否围绕Y轴旋转,是(1),不是(0)
参数5:是否围绕Z轴旋转,是(1),不是(0)
*/
m3dRotationMatrix44(m3, m3dDegToRad(45.0f), 1.0f, 0.0f, 0.0f);
缩放
/*
void m3dScaleMatrix44(M3DMatrix44f m, float xScale, float yScale, float zScale)
参数1:结果矩阵
参数2:围绕X轴放大\缩小;放大x>1,缩小:0.5f
参数3:围绕Y轴放大\缩小;放大x>1,缩小:0.5f
参数4:围绕Z轴放大\缩小;放大x>1,缩小:0.5f
*/
m3dScaleMatrix44(m3, 1.0f, 10.0f, 1.0f);
案例1 : 利用矩阵的平移、旋转、综合变化等, 实现矩阵的移动.
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.0f, 0.0f, 1.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[] = { 1.0f, 0.0f, 0.0f, 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;
}
效果图:
注: 本例是键盘的上下左右方向键来控制矩形的旋转平移, 具体代码参见上面

案例2 : 利用模型视图矩阵和投影矩阵让一个球体旋转
绘制球体
gltMakeSphere(torusBatch, 0.4f, 10, 20);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
设置模型视图矩阵 和 投影矩阵
//建立一个基于时间变化的动画
static CStopWatch rotTimer;
//当前时间 * 60s
float yRot = rotTimer.GetElapsedSeconds() * 60.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//矩阵变量
M3DMatrix44f mTranlate,mRotate,mModelView,mModelViewProjection;
//将圆球像Z轴负方向移动2.5个单位长度
m3dTranslationMatrix44(mTranlate, 0.0f , 0.0f,-2.5f);
//旋转
m3dRotationMatrix44(mRotate, m3dDegToRad(yRot), 0.0f, 1.0f, 0.0f);
//将平移和旋转的矩阵进行叉乘,产生一个新的矩阵mModelView
m3dMatrixMultiply44(mModelView, mTranlate, mRotate);
//模型视图矩阵 和 投影矩阵
//将投影矩阵 与 模型视图矩阵进行叉乘 ,将变化最终结果通过矩阵叉乘的方式应用到mModelViewProjection中来
m3dMatrixMultiply44(mModelViewProjection, viewFrustum.GetProjectionMatrix(), mModelView);
GLfloat vBlack[] = {0.0f,0.0f,0.0f,1.0f};
//平面着色器来渲染图像
shaderManager.UseStockShader(GLT_SHADER_FLAT,mModelViewProjection,vBlack);
//开始绘图
torusBatch.Draw();
glutSwapBuffers();
glutPostRedisplay();
效果图

网友评论