美文网首页
八、OpenGL入门案例 -- 绘制三角形

八、OpenGL入门案例 -- 绘制三角形

作者: 东篱采桑人 | 来源:发表于2020-07-12 12:35 被阅读0次

    学习了前面相关知识后,今天我们试着用OpenGL来绘制一个三角形。

    一、 绘制思路

    OpenGL绘制三角形

    二、 代码实现

    1. 准备工作
    • 引入"GLTools.h"<GLUT/GLUT.h>这两个文件;
    • 声明一个GLBatch和一个GLShaderManager对象。
    • 声明两个窗口事件的回调函数。因为C语言是由上到下执行的,在main函数里如果需要调用函数,必须提前声明。
    #include "GLTools.h"
    #include <GLUT/GLUT.h>
    
    GLBatch triangleBatch;
    GLShaderManager shaderManger;
    
    //窗口重塑回调函数
    void ChangeSize(int w, int h){}
    //内容显示回调函数
    void RenderScene(void){}
    
    2. 设置当前工作目录

    glSetWorkingDrectoryGLTools里的函数,用来设置当前工作目录,针对于macOS X。因为在Windows中工作目录默认就是与程序可执行程序相同的目录。但是在macOS X中,程序会将当前工作文件夹改为应用程序捆绑包中的/Resource文件夹。

    PS:暂时还不知道这个设置工作目录有什么作用,因为在macOS X上注释掉这一行代码,也是可以正常渲染。只能留待后续解惑,读者中如果有知道的话,请留言告知。

    gltSetWorkingDirectory(argv[0]);
    
    3. 设置窗口

    这里使用glut库实现窗口相关设置。在设置窗口显示模式时,其中GLUT_DOUBLEGLUT_RGBAGLUT_DEPTHGLUT_STENCIL分别指双缓冲窗口、RGBA颜色模式、深度测试、模板缓冲区*

    • GLUT_DOUBLE:双缓存窗口,是指绘图命令实际上是离屏缓存区执行的,然后迅速转换成窗口视图。这种方式可以避免渲染动画时帧与帧之间的闪烁情况。
    • GLUT_DEPTH:标志将一个深度缓存区分配为显示的一部分,因此我们能够执行深度测试;
    • GLUT_STENCIL:确保我们也会有一个可用的模板缓存区。
    初始化glut库
    glutInit(&argc, argv);
    //设置窗口显示模式(开启双缓冲机制、RGBA颜色模式、深度测试、模板缓冲区)
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
    //设置窗口大小
    glutInitWindowSize(800, 600);
    //创建窗口,设置窗口标题
    glutCreateWindow("Triangle");
    //注册窗口事件回调函数
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);
    
    4. 初始化glew库
    • 初始化glew库:glew库能够识别当前平台支持的OpenGL API,确保OpenGL API对程序完全可用。
    • 判断初始化结果:在试图做任何渲染之前,要检查确定驱动程序的初始化过程中没有任何问题。
    GLenum err = glewInit();
    if(err != GLEW_OK){
        
        fprintf(stderr, "glew error:%s\n", glewGetErrorString(err));
        return 1;
    }
    
    5. 设置渲染相关信息

    这里进行重置背景色、批次处理图形顶点数据以及设置着色器操作。
    因为只是渲染一个三角形,所以选择单元着色器来渲染。

    //重置背景色
    glClearColor(0.f, 0.f, 1.f, 1.f);
    
    //设置图形顶点数据,数组vVert包含3个顶点的xyz笛卡尔坐标对。
    GLfloat vVerts[] = {
    
        -0.5f, 0.0f, 0.0f,
        0.5f, 0.0f, 0.0f,
        0.0f, 0.5f, 0.0f
    };
    
    //利用三角形批次对象将数据拷贝到显存
    triangleBatch.Begin(GL_TRIANGLES, 3);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();
    
    //初始化着色管理器
    shaderManager.InitializeStockShaders();
    //设置单元着色器,颜色为红色
    GLfloat vRed[] = {1.0f, 0.0f, 0.0f, 1.0f};
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
    
    6. 实现窗口事件回调函数

    6.1 重塑事件回调函数
    重塑事件是在窗口第一次显示或窗口大小发生改变时触发。
    在回调函数里设置视口大小和窗口大小一致,投影方式默认为正投影。

    void ChangeSize(int w, int h){
        
        //0,0代表窗口中视口的左下角坐标,w,h代表像素
        glViewport(0, 0, w, h);
    }
    

    6.2 内容显示事件回调函数
    内容显示事件在重塑事件发生后或主动重绘内容时触发,因此在回调函数里执行图形渲染,处理如下:

    • 清空缓存区:缓冲区是一块存有图像信息的存储空间,在每次渲染前都需要清空缓存区。
    • 开始渲染:通过三角形批次类发起渲染。
    • 交换前后台缓冲区:在前面设置openGL窗口的时候,指定了一个双缓冲区的渲染环境,使得图形在后台缓冲区渲染,所以在渲染完后需要手动交互缓冲区,交由前台显示。
    void RenderScene(void){
    
        /*
         清除一个或一组特定的缓冲区,当不确定需要清除哪个时,就全部清除掉:
         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);
        //开始渲染
        triangleBatch.Draw();
        //渲染完后交换前后台缓冲区,实现双缓冲机制
        glutSwapBuffers();
    }
    
    7. 开启窗口运行循环

    GLUT内部会运行一个本地消息循环,需要手动开启后,才能处理窗口消息事件。

    glutMainLoop();
    

    三、程序运行效果

    拓展阅读

    OpenGL在MAC上的配置

    相关文章

      网友评论

          本文标题:八、OpenGL入门案例 -- 绘制三角形

          本文链接:https://www.haomeiwen.com/subject/buxycktx.html