• OpenGL编程指南(第九版) Tiangles 学习笔记


    //////////////////////////////////////////////////////////////////////////////
    //
    //  Triangles.cpp
    //
    //////////////////////////////////////////////////////////////////////////////
    
    #include "vgl.h"
    #include "LoadShaders.h"
    
    enum VAO_IDs { Triangles, NumVAOs };
    enum Buffer_IDs { ArrayBuffer, NumBuffers };
    enum Attrib_IDs { vPosition = 0 };
    
    GLuint  VAOs[NumVAOs];
    GLuint  Buffers[NumBuffers];
    
    const GLuint  NumVertices = 6;
    
    //----------------------------------------------------------------------------
    //
    // 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 );
    }
    
    //----------------------------------------------------------------------------
    //
    // display
    //
    
    void
    display( void )
    {
        static const float black[] = { 1.0f, 0.0f, 0.0f, 0.0f };
    
        glClearBufferfv(GL_COLOR, 0, black);
    
        glBindVertexArray( VAOs[Triangles] );
        glDrawArrays( GL_TRIANGLES, 0, NumVertices );
    }
    
    //----------------------------------------------------------------------------
    //
    // 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();
    }

    一、环境问题

      首先就是环境的问题,样例中使用的 glCreateBuffers() 函数要求显卡驱动支持OpenGL 4.5才可以使用,如果版本不达标会出现空指针错误。

      解决方法:升级你的显卡驱动, 如果驱动已经是最新,则检查是否为双显卡,将独显(一般都是n卡)设为首选。

    二、全局变量

      程序在开头位置(头文件下边)声明了一些对于初学者不明觉厉的枚举值和整型数组。

      其中那些以 IDs 结尾枚举值都是起到了索引的功能,因为 OpenGL 是使用一些整数作为对象(比如缓冲区,顶点数组等)的标记,这些整数通常没有规律可言,因此将同类型的对象的标记存放在一个整型数组中能够便于我们进行管理。

      值得注意的是,每个索引的最后一个元素(以Num为前缀,数组名为后缀的那个元素)只起到表示对象数量的作用,没有其他实际意义。

    三、顶点数组与顶点着色器

      顶点数组也是个相当令人困惑的地方。

      有人会说有了顶点着色器表示顶点的信息要顶点数组有什么用,但是仔细去看,顶点着色器只是起到一个中间处理的作用,最终进入绘制函数的仍然是顶点数组。

      因此顶点数据的流向其实是这样的:在一般数组中创建(只包含位置信息) -> 进入顶点着色器进行加工(本例程中虽然只起到了传递数据的作用) -> 传入顶点数组中准备进行绘制。

      此外顶点数组的创建过程也很有意思:glCreateVertexArrays() 只负责进行空间的分配 -> glBindVertexArray() 将数组选中准备进行操作 -> glVertexAttribPointer() 负责对它进行赋值。

    四、缓冲区

      在我理解中缓冲区大概就是一个全局可用的数据块。

      值得注意的是在顶点数据的流动中缓冲区起到了不可替代的作用。或者可以说凡是跨函数的数据操作,都用到了缓冲区:要么是向被调用函数中传入缓冲区的编号(之前提到的标志),要么是通过 glBindBuffer 将要用到的缓冲区设为激活状态。

      在本程序中使用了后者:顶点数据先从数组中被存放在缓冲区中 -> 顶点着色器再通过访问 / 修改缓冲区进行顶点着色 ->  最后 glVertexAttribPointer() 从缓冲区中将定点数据赋值给顶点数组。

      缓冲区的创建与顶点数组相同,Create 函数是成批地创建缓存的,它接受的是一个数组和它的大小,结果是把创建的缓冲区的编号写入给出的数组中。

     

  • 相关阅读:
    「应用管理与交付」为什么会成为云原生新的价值聚焦点?
    Quick BI:降低使用门槛,大东鞋业8000家门店的数据导航
    如何用Netty写一个高性能的分布式服务框架?
    印度批准苹果和三星1430亿美元的智能手机制造计划
    东京证券交易所暂停了全天交易,与黑客有关吗?
    这些杀毒软件现漏洞,可能使计算机更易受黑客攻击
    又躺赚1亿?东方联盟创始人郭盛华,会的仅仅是技术吗?
    谷歌的VR虚拟现实为何失败了?VR的未来何去何从?
    爆料电脑天才郭盛华的稀有童年照,原来小时候就很帅
    好莱坞野心导演:郭盛华的传奇故事将拍黑客电影?他会参演吗?
  • 原文地址:https://www.cnblogs.com/moonfair/p/10768621.html
Copyright © 2020-2023  润新知