美文网首页
《OpenGL编程指南》第九版——2.绘制两个三角形

《OpenGL编程指南》第九版——2.绘制两个三角形

作者: 祝你万事顺利 | 来源:发表于2019-06-18 08:07 被阅读0次

    我将跟随OpenGL编程指南对每个例子进行详解,每个例子将贴出实验结果和实验代码,仅供参考,代码部分可能我会进行一些修改与官方代码不同。

    实现效果:


    TwoTriangles.PNG

    1.Main函数

    1.glfwInit初始化GLFW库
    2.glfwCreateWindow设置程序所使用的窗口类型以及期望的窗口尺寸。还创建了一个与窗口关联的OpenGL设备环境。在使用环境之前,我们需要设置它为当前环境。在一个程序中我们可以设置多个设备环境,但是用户指令只会传递到当前设备环境中。
    3.gl3wInit调用GL3W库,简化获取函数地址的过程
    4.接下来调用Init函数初始化所有OpenGl相关数据,以便之后的渲染工作
    5.无限循环指令,一直处理窗口和操作系统的用户输入,在循环中判断是否需要关闭窗口(glfwWindowShouldClose),重绘内容,并展现给用户(glfwSwapBuffers),然后查看操作系统返回的任何信息(glfwPollEvents)

    //----------------------------------------------------------------------------
    //
    // main
    //
    
    #ifdef _WIN32
    int CALLBACK WinMain(
      _In_ HINSTANCE hInstance,
      _In_ HINSTANCE hPrevInstance,
      _In_ LPSTR     lpCmdLine,
      _In_ int       nCmdShow
    )
    #else
    int
    main( int argc, char** argv )
    #endif
    {
        glfwInit();
    
        GLFWwindow* window = glfwCreateWindow(800, 600, "Triangles", NULL, NULL);
    
        glfwMakeContextCurrent(window);
        gl3wInit();
    
        init();
    
        while (!glfwWindowShouldClose(window))
        {
            display();
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        glfwDestroyWindow(window);
    
        glfwTerminate();
    }
    

    2.Init

    1.glCreateVertexArrays分配顶点数组对象
    2.得到对象后将其绑定(bind)到OpenGL环境以便使用,glBindVertexArray函数创建并且绑定一个顶点数组对象,如果array变量非零,并且是glCreateVertexArrays所返回的,那么会激活这个顶点数组对象。总的来说,在两种情况下需要绑定对象:创建对象并初始化它所需的数据;以及每次我们准备使用此对象的时候。
    在较大的程序里,通过调用3.glDeleteVertexArrays释放顶点数组对象。
    4.为了保证完整性,调用gllsVertexArray检查某个名称是否已经被保留位一个定点数组对象了。

    顶点数组对象保存一系列顶点的数据,这些数据保存到缓存对象中,并且由当前绑定的顶点数组对象管理。
    1.glCreateBuffers创建顶点缓存对象,在例子中创建NumVBOs个对象到数组buffers当中。
    2.调用glBindBuffer规定他们到OpenGL环境。
    3.所有缓存对象都可以使用glDeleteBuffers直接释放。
    4.glNamedBufferStorge分配顶点数据所需的存储空间,将数据从应用程序拷贝到内存中。
    glNamedBufferStorge函数详细定义:作用于名为buffer的缓存区域,由于我们的数据是顶点属性数据,因此设置这个缓存目标为GL_ARRAY_BUFFER。制定内存分配的大小size,data指定客户端内存的指针,以便初始化对象,如果是NULL,那么将保留size大小的未初始化数据。,最后指定数据在OpenGL中的使用方式。

    //----------------------------------------------------------------------------
    //
    // init
    //
    
    void
    init( void )
    {
        glGenVertexArrays( NumVAOs, VAOs );
        glBindVertexArray( VAOs[Triangles] );
    
        GLfloat  vertices[NumVertices][2] = {
            { -0.90f, -0.90f }, {  0.85f, -0.90f }, { -0.90f,  0.85f },  // Triangle 1
            {  0.90f, -0.85f }, {  0.90f,  0.90f }, { -0.85f,  0.90f }   // Triangle 2
        };
    
        glCreateBuffers( NumBuffers, Buffers );
        glBindBuffer( GL_ARRAY_BUFFER, Buffers[ArrayBuffer] );
        glBufferStorage( GL_ARRAY_BUFFER, sizeof(vertices), vertices, 0);
    
        ShaderInfo  shaders[] =
        {
            { GL_VERTEX_SHADER, "media/shaders/triangles/triangles.vert" },
            { GL_FRAGMENT_SHADER, "media/shaders/triangles/triangles.frag" },
            { GL_NONE, NULL }
        };
    
        GLuint program = LoadShaders( shaders );
        glUseProgram( program );
    
        glVertexAttribPointer( vPosition, 2, GL_FLOAT,
                               GL_FALSE, 0, BUFFER_OFFSET(0) );
        glEnableVertexAttribArray( vPosition );
    }
    

    3.初始化顶点与片元着色器

    通过LoadShaders函数指定两个着色器,使用GLSL语言编写着色器程序。

    #version 400 core表示我们使用OpenGL4.5版本对应的GLSL语言
    vPosition是输入变量被声明为in指定了数据进入着色器的流向,最后字段layout(location = 0),布局限定符为变量提供元数据。
    main函数实现输入顶点位置复制到顶点着色器的指定输出位置gl_Position中,

    #version 400 core
    
    layout( location = 0 ) in vec4 vPosition;
    
    void
    main()
    {
        gl_Position = vPosition;
    }
    

    片元着色器
    声明变量fColor使用限定符out,这里着色器将fColor对应的数值输出,也就是片元对应的颜色值。

    #version 450 core
    
    out vec4 fColor;
    
    void main()
    {
        fColor = vec4(0.5, 0.4, 0.8, 1.0);
    }
    
    

    init中最后两个函数指定了顶点着色器变量与缓存对象中数据的关系。
    glEnableVertexAttribArray启用顶点属性数组,

    3.Display

    1.首先清除帧缓存的数据再进行渲染。
    2.选择准备绘制的定点数据,然后请求进行绘制。调用glBindVertexArray选择作为顶点数据使用的顶点数组。
    3.glDrawArrays实现顶点数据向OpenGL管线的传输。

    //----------------------------------------------------------------------------
    //
    // display
    //
    
    void
    display( void )
    {
        static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
    
        glClearBufferfv(GL_COLOR, 0, black);
    
        glBindVertexArray( VAOs[Triangles] );
        glDrawArrays( GL_TRIANGLES, 0, NumVertices );
    }
    

    相关文章

      网友评论

          本文标题:《OpenGL编程指南》第九版——2.绘制两个三角形

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