计算机视觉【003-OpenGL创建可移动的正方形】


一、目标结果

二、分析过程

分析流程简图如下

渲染流程简图

三、全部代码如下:

下面从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_DOUBLEGLUT_RGBAGLUT_DEPTHGLUT_STENCIL分别指双缓冲窗口、RGBA颜色模式、深度测试、模板缓冲区

glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);

3.1.4 配置GLUT 窗口

glutInitWindowSize(300, 300); // 初始化窗口
glutCreateWindow("Triangle"); // 配置创建窗口名

3.2 GLUT 内部循环

3.2.1 注册重塑函数

glutReshapeFunc(changeSize);

ChangeSize函数,主要作用是窗口大小改变是,接收新的宽度和高度,实现如下:

void changeSize(int w,int h)
{
    /*
      x,y 参数代表窗口中视图的左下角坐标,而宽度、高度是像素为表示,通常x,y 都是为0
     */
    glViewport(0, 0, w, 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);

其实这里的键位比较简单,主要步骤如下:

  1. 设置按键每次移动的步长

     GLfloat stepSize = 0.25f;
  2. 配置移动起始X, Y坐标,

        GLfloat blockX = vVerts[0];
        GLfloat blockY = vVerts[10];
  3. 移动后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;
        }
  4. 边界碰撞的配置(碰撞后返回)

    • 碰到最左边

      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;
        }
  1. 重新计算所有顶点

        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]);
  2. 添加顶点到缓冲区

    triangleBatch.CopyVertexData3f(vVerts);
  3. 通知重新渲染

    glutPostRedisplay();

3.3 GLUEW 库安全

初始化一个GLEW库,确保OpenGL API对程序完全可用

    GLenum status = glewInit();
    if (GLEW_OK != status) {

        printf("GLEW Error:%s\n",glewGetErrorString(status));
        return 1;

    }

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);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();

3.5 添加到任务的 loop

glutMainLoop();

3.6 总流程main 的步骤

    gltSetWorkingDirectory(argv[0]);
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
    glutInitWindowSize(300, 300);
    glutCreateWindow("Triangle");

    //注册重塑函数
    glutReshapeFunc(changeSize);
    //注册显示函数
    glutDisplayFunc(RenderScene);
    //注册特殊函数
   glutSpecialFunc(SpecialKeys);

    GLenum status = glewInit();
    if (GLEW_OK != status) {

        printf("GLEW Error:%s\n",glewGetErrorString(status));
        return 1;

    }
    setupRC();
    glutMainLoop();

小结

这篇文章,简单的介绍了,在特定色彩下,绘制一个正方形,并且通过按键移动它,可以见到,OpenGL 语句还是相当的见解。


文章作者: 李佳
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 李佳 !
评论
  目录