一、目标结果
二、分析过程
分析流程简图如下
三、全部代码如下:
下面从main.cpp 的流水线讲解整个实现过程
3.1 准备工作
3.1.1 设置当前工作目录
gltSetWorkingDirectory(argv[0]); |
其中argv
源自int main(int argc,char *argv[]){}
函数的参数
3.1.2 初始化GLUT的库
glutInit(&argc, argv); |
3.1.3 初始化双缓冲区
初始化双缓冲窗口,其中标志GLUT_DOUBLE、GLUT_RGBA、GLUT_DEPTH、GLUT_STENCIL分别指双缓冲窗口、RGBA颜色模式、深度测试、模板缓冲区
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL); |
3.1.4 配置GLUT 窗口
glutInitWindowSize(300, 300); // 初始化窗口 |
3.2 GLUT 内部循环
3.2.1 注册重塑函数
glutReshapeFunc(changeSize); |
ChangeSize函数,主要作用是窗口大小改变是,接收新的宽度和高度,实现如下:
void changeSize(int w,int h) |
3.2.2 注册显示函数(渲染)
glutDisplayFunc(RenderScene); |
有以下步骤
清理一个或一组特定的缓冲区
- GL_COLOR_BUFFER_BIT :指示当前激活的用来进行颜色写入缓冲区
- GL_DEPTH_BUFFER_BIT :指示深度缓存区
- GL_STENCIL_BUFFER_BIT:指示模板缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
设置一组浮点数来表示红色
GLfloat vRed[] = {1.0,0.0,0.0,1.0f};
传递到存储着色器
shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed);
提交着色器
triangleBatch.Draw();
交换缓冲区:这里主要是讲后台缓冲区进行渲染,结束后把图像结果交给前台
glutSwapBuffers();
3.2.3 注册特殊函数(键位移动)
glutSpecialFunc(SpecialKeys); |
其实这里的键位比较简单,主要步骤如下:
设置按键每次移动的步长
GLfloat stepSize = 0.25f;
配置移动起始X, Y坐标,
GLfloat blockX = vVerts[0];
GLfloat blockY = vVerts[10];移动后X,Y坐标,这里主要判断key
if (key == GLUT_KEY_UP) {
blockY += stepSize;
}
if (key == GLUT_KEY_DOWN) {
blockY -= stepSize;
}
if (key == GLUT_KEY_LEFT) {
blockX -= stepSize;
}
if (key == GLUT_KEY_RIGHT) {
blockX += stepSize;
}边界碰撞的配置(碰撞后返回)
碰到最左边
if (blockX < -1.0f) {
blockX = -1.0f;
}碰到最右边
//1.0 - blockSize * 2 = 总边长 - 正方形的边长 = 最左边点的位置
if (blockX > (1.0 - blockSize * 2)) {
blockX = 1.0f - blockSize * 2;
}碰到最下边
//-1.0 - blockSize * 2 = Y(负轴边界) - 正方形边长 = 最下面点的位置
if (blockY < -1.0f + blockSize * 2 ) {
blockY = -1.0f + blockSize * 2;
}碰到最顶边
if (blockY > 1.0f) {
blockY = 1.0f;
}
重新计算所有顶点
vVerts[0] = blockX;
vVerts[1] = blockY - blockSize*2;
printf("(%f,%f)\n",vVerts[0],vVerts[1]);
vVerts[3] = blockX + blockSize*2;
vVerts[4] = blockY - blockSize*2;
printf("(%f,%f)\n",vVerts[3],vVerts[4]);
vVerts[6] = blockX + blockSize*2;
vVerts[7] = blockY;
printf("(%f,%f)\n",vVerts[6],vVerts[7]);
vVerts[9] = blockX;
vVerts[10] = blockY;
printf("(%f,%f)\n",vVerts[9],vVerts[10]);添加顶点到缓冲区
triangleBatch.CopyVertexData3f(vVerts);
通知重新渲染
glutPostRedisplay();
3.3 GLUEW 库安全
初始化一个GLEW库,确保OpenGL API对程序完全可用
GLenum status = glewInit(); |
3.4 配置渲染环境
setupRC(); |
3.4.1 设置清屏颜色
其实也是设置当前窗口的背景色
glClearColor(0.98f, 0.80f, 0.7f, 1); |
3.4.2 初始化固定着色器
shaderManager.InitializeStockShaders(); |
3.4.3 顶点连接类型配置和提交缓冲区
triangleBatch.Begin(GL_TRIANGLE_FAN, 4); |
3.5 添加到任务的 loop
glutMainLoop(); |
3.6 总流程main 的步骤
gltSetWorkingDirectory(argv[0]); |
四、小结
这篇文章,简单的介绍了,在特定色彩下,绘制一个正方形,并且通过按键移动它,可以见到,OpenGL 语句还是相当的见解。