OpenGL红皮书-如果枚举默认为整数,从0开始,glBindVertexArray如何绑定到保留值0

OpenGL Red Book - If enums default to ints starting at 0, how does glBindVertexArray bind to the reserved value of 0?

本文关键字:何绑定 glBindVertexArray 保留 绑定 开始 如果 枚举 整数 默认 OpenGL      更新时间:2023-10-16

我对OpenGL编程指南的第一个例子有点困惑。

作者用这个例子:

///////////////////////////////////////////////////////////////////////
//
// triangles.cpp
//
///////////////////////////////////////////////////////////////////////
// g++ -g -o tri triangles.cpp LoadShader.cpp -lglut -lGLEW -lGLU -lGL -lX11 -lm
#include <iostream>
using namespace std;
#include "vgl.h"
#include "LoadShader.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.90, -0.90 },  // Triangle 1
        {  0.85, -0.90 },
        { -0.90,  0.85 },
        {  0.90, -0.85 },  // Triangle 2
        {  0.90,  0.90 },
        { -0.85,  0.90 }
    };
    glGenBuffers(NumBuffers, Buffers);
    glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
                 vertices, GL_STATIC_DRAW);
    ShaderInfo  shaders[] = {
        { GL_VERTEX_SHADER, "triangles.vert" },
        { GL_FRAGMENT_SHADER, "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)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(VAOs[Triangles]);
    glDrawArrays(GL_TRIANGLES, 0, NumVertices);
    glFlush();
}
//---------------------------------------------------------------------
//
// main
//
int
main(int argc, char** argv)
{

     glutInit(&argc, argv);
     glutInitDisplayMode(GLUT_RGBA);
     glutInitWindowSize(512, 512);
     glutInitContextVersion(4, 3);
     glutInitContextProfile(GLUT_CORE_PROFILE);
     glutCreateWindow(argv[0]);
     glewExperimental = GL_TRUE;
     if (glewInit()) {
         cerr << "Unable to initialize GLEW ... exiting" << endl;
         exit(EXIT_FAILURE);
     }
     init();
     glutDisplayFunc(display);
     glutMainLoop();
}

这是我的实现:

#include <GLglew.h>
#include <GLFWglfw3.h>
#include <iostream>
#include <GLShaderLoader.hpp> 
using namespace std;
// Reserved VAO ID indicies
enum VAO_IDs {TRIS, NUM_VAO};
// Reserved VBO ID indicies
enum VBO_IDs {BUFFER, NUM_BUFFER};
// Reserved names (for VAOs and VBOs)
GLuint VAOs[NUM_VAO];
GLuint buffers[NUM_BUFFER];
// Hard-coded vertex count
const GLuint numVerts = 6;
// Initialize VAOs and VBOs, populate VBOs, and provide OGL server memory access
void glInit() {
    glGenVertexArrays(NUM_VAO, VAOs);
    glBindVertexArray(VAOs[TRIS]);
    GLfloat verts[numVerts][2] {
        { 0.0, 0.5 },
        { 0.5, -0.5 },
        { -0.5, -0.5},
        {-0.9, 0.9},
        {-0.9, 0.7},
        {-0.7, 0.7}
    };
    glGenBuffers(NUM_BUFFER, buffers);
    glBindBuffer(GL_ARRAY_BUFFER, buffers[BUFFER]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
    GLuint prog = loadShaders("pass.vert", "pass.frag");
    glUseProgram(prog);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);
}
// Main entry point
void main(int argc, char** argv) {
    glewExperimental = GL_TRUE;
    GLFWwindow* window;
    if (!glfwInit()) {
    }
    window = glfwCreateWindow(640, 480, "Hello Fam", NULL, NULL);
    if (!window) {
        glfwTerminate();
    }
    glfwMakeContextCurrent(window);
    GLenum err = glewInit();
    if (GLEW_OK != err) {
        fprintf(stderr, "Error: %sn", glewGetErrorString(err));
    }
    glInit();
    //*************
    //  MAIN LOOP
    //*************
    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glBindVertexArray(VAOs[TRIS]);
        glDrawArrays(GL_TRIANGLES, 0, numVerts);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwTerminate();
}

现在,问题是,我的实现编译和运行得很好,但我很困惑。在书中,它说glBindVertexArray()不取0,因为0是为默认状态保留的。然而,枚举永远不会初始化,并且默认为它们的索引。这意味着当我调用glBindVertexArray(VAOs[TRIS])时,OpenGL绑定到一个为0的VAO名称。

我的问题是:是OpenGL 真的绑定到一个名字是0,还是我错过了什么/理解错误?

提前感谢!

前一行glGenVertexArrays(NUM_VAO, VAOs);GLuint s填充VAOs数组。其中之一就是你要传递给glBindVertexArray(VAOs[TRIS]);

的内容

如果你想看到你传入的是什么,设置一个调试器断点并检查VAOs

VAOs[TRIS]表示取VAOs数组的第一个元素(如TRIS == 0)。