上一篇完成了三角形的绘制,今天来添加一个变换控制,通过键盘的↑↓←→控制图形的移动
画正方形
基于原来的工程,把三角形改为正方形,GL_TRIANGLES
修改为GL_TRIANGLE_FAN
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| GLfloat blockSize = 0.2f;
GLfloat vVerts[] = { -blockSize,-blockSize,0.0f, blockSize,-blockSize,0.0f, blockSize,blockSize,0.0f, -blockSize,blockSize,0.0f };
...
void setupRC() { ...
triangleBatch.Begin(GL_TRIANGLE_FAN, 4); triangleBatch.CopyVertexData3f(vVerts); triangleBatch.End(); }
|
平移变换
修改坐标
平移变换可以直接修改正方形的4个顶点,然后重新刷新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| GLfloat xStepSize = 0.025f;
GLfloat yStepSize = 0.025f;
GLfloat vVerts[] = { -blockSize + xStepSize, -blockSize + yStepSize, 0.0f, blockSize + xStepSize, -blockSize + yStepSize, 0.0f, blockSize + xStepSize, blockSize + yStepSize, 0.0f, -blockSize + xStepSize, blockSize + yStepSize, 0.0f };
triangleBatch.CopyVertexData3f(vVerts);
glutPostRedisplay();
|
矩阵变换
上面直接通过修改坐标的方式过于麻烦,对于复杂的图形做变换会非常麻烦,而推荐使用矩阵变换
,基于平面着色器
,可以作用于任何的图形,不需要手动计算坐标,不仅可以做平移,还能做旋转缩放等
renderScene
操作流程
- 清理特定缓存区
- 根据平移距离生成
平移矩阵
- 如果有多个矩阵变换,通过
叉乘
得到最终矩阵
- 将
矩阵结果
交给存储着色器(平面着色器
)中绘制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| GLfloat xPos = 0.1f;
GLfloat yPos = 0.1f;
GLfloat rotate = 5.0f;
void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
M3DMatrix44f mTransfromMatrix, mRotationMartix;
m3dTranslationMatrix44(mTransfromMatrix, xPos, yPos, 0.0f);
m3dRotationMatrix44(mRotationMartix, m3dDegToRad(rotate), 0.0f, 0.0f, 1.0f);
M3DMatrix44f mFinalTransform; m3dMatrixMultiply44(mFinalTransform, mTransfromMatrix, mRotationMartix);
GLfloat vRed[] = {1.0f,0.0f,0.0f,0.0f};
shaderManager.UseStockShader(GLT_SHADER_FLAT, mFinalTransform, vRed);
triangleBatch.Draw();
glutSwapBuffers(); }
|
键盘控制
GLUT提供了键盘监听事件
1 2
| glutSpecialFunc(onSpecialKeys);
|
实现上下左右键的监听
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| void SpecialKeys(int key, int x, int y){ 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(); }
|
完整代码见这里