Aquacolor

Aquacolor



LearningOpenGL【3】

Gumdrop · 2025-08-26 · 29浏览 · 未分类


(由于又莫名同时使用了“绑定”和“注册”的说法,所以认为同义)

  1. VBO+LVA部分工作流

    (有时也记作BO+LVA)

    VBO工作流

    float vertices[] = {
    -0.5f, -0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    0.0f,  0.5f, 0.0f
    };
    //NDC,用[-1,1]映射到窗口长宽。这里的D是Device即设备,“窗口是一个设备”的表述还算有点印象。
    //窗口句柄好像也就是设备上下文。。。
    //NDC将在Viewport Trans中转为SSC,这步发生在Rasterization。
    
    unsigned int VBO;
    glGenBuffers(1, &VBO);//GLsizei、GLuint*类型
    glBindBuffer(GL_ARRAY_BUFFER, VBO);//GLenum、GLuint类型
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//GLsizeiptr类型
    //glGetActiveAttrib
    //glfwSetCharCallback
    //glBindBuffer(GL_ARRAY_BUFFER, 0),“back to default”。
    //OpenGL中的对象具有的函数通常有glGen、glBind、gl...Data、glSet(可选)。
    //常用的参数类型中,GLuint*是为了传出值到函数作用域外(典型C风格),并且也说明了可以是数组。
    //GLenum起到各种hints的作用,都是以GL_开头的宏。
    //GLsizei是要创建的Object的个数,个数大于1时传出到GLuint*是一个数组名。
    //GLsizeiptr是“ptr的GLsizei”。这里的ptr是以常指针方式传入的外界数组,所以该参数要求的是传入数组的大小。
    //ptr通常是const void*或者const GLvoid*。
    //从这里可以知道用来与OpenGL直接交互的数据类型全都必须是C风格的!
    //GL_STATIC_DRAW是三种缓冲区标记之一,用于写一次读多次的缓冲区。
    

    记忆:生成、绑定/解绑、配置数据

    Link Vertex Attributes工作流

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    //VBO虽然通常认为是连续的一片内存空间,但是:
    //1. 它首先分为不同的顶点数据集,如位置、颜色……
    //2. 每个数据集又由固定大小的数据组成,如位置数据集中,每个点的位置都是一个浮点向量。
    //因此通过第一个参数GLuint index确定是哪个数据集
    //第二个参数GLint size是确定每个数据是几维向量,第三个是为确定分量类型
    //第五个GLsizei stride和第六个GLvoid* offset共同确定数据集的组成方式:从offset开始每隔stride个数据取一个
    //第四个数据用于确定是否标准化,[-1,1]或[0,1]。
    //glVertexAttribPointer()提供给shader解释VBO数据的方法,这是必须的,与EBO无关,因此一定要有且最好和VBO写一起。
    //glEnableVertexAttribArray(GLuint index)和glDisableVertexAttribArray(GLuint index)分别控制第index个VAA的启用与否。
    

    记忆:切片注册、启用/禁用

    最后使用glDrawArrays(GLenum mode,GLint,GLsizei)绘制。

    第一个参数是要绘制的图元,通过后两个参数begin+size切片。

    (Link时的切片是begin+interval切片)

  2. EBO部分工作流

    //前文注册VBO到OpenGL。
    
    unsigned int indices[] = {
        0,1,2,
        1,2,3
    };
    unsigned int EBO;
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    //除了EBO会被注册到GL_ELEMENT_ARRAY_BUFFER这个不同的属性之外,其他步骤一样。
    

    最后使用glDrawElements(GLenum mode,GLsizei,GLenum type,const GLvoid*)绘制。

    主要区别是在前文绑定EBO时,通过第二和第四个参数实现begin+size切片。

    或者未绑定EBO时通过第三和第四个参数在调用该函数时传入EBO,此时只能实现size切片。

  3. VAO部分工作流

    (VAO+BO+EBO【可选】+LVA)

    unsigned int VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    //绑定VAO后,VBO、EBO将会绑定在OpenGL的VAO上
    
    float vertices[] = {
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f,  0.5f, 0.0f
    };
    unsigned int VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    unsigned int indices[] = {
        0,1,2,
        1,2,3
    };
    unsigned int EBO;
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    //在VAO中有VBO、EBO、VAA
    //实际上是记录了glBindBuffer、glBufferData、glVertexAttribPointer、glEnableVertexAttribArray的运行。
    
    glBindVertexArray(0);
    //解绑后,VAO就不会被意外修改了。
    

    记忆:生成、绑定/解绑、配置数据

    配置通过记录后文完成。

    1. EBO绑定在VAO上的,所以不能在配置数据时解绑EBO;而VBO通过VAP()转化成VAA绑定在VAO上,在配置数据末期可以解绑VBO。

    2. 如果render loop中绘制函数发现OpenGL中没有VAO,core版本规则是不进行任何绘制。



©

comment 评论区

添加新评论

face表情



  • ©2026 bilibili.com

textsms
内容不能为空
昵称不能为空
email
邮件地址格式错误
web
beach_access
验证码不能为空
keyboard发表评论


star_outline 咱快来抢个沙发吧!




©2026 Aquacolor

Theme Romanticism2.2 by Akashi
Powered by Typecho