首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OpenGL -重新绑定glBindVertexArray不会在屏幕上画任何东西

OpenGL -重新绑定glBindVertexArray不会在屏幕上画任何东西
EN

Stack Overflow用户
提问于 2015-03-14 15:50:28
回答 1查看 769关注 0票数 0

我刚开始学习opengl,在将代码的各个部分分离成类的过程中,我遇到了一些问题。

这是一个很简单的问题。在下面的代码中,如果Mesh构造函数底部的glBindVertexArray(0)被注释掉,它会将图像绘制到屏幕上,但如果我将其放入其中,则不会绘制图像。

glBindVertexArray(vao)函数中的glDrawElements调用之前有一个Mesh.draw()命令,所以它看起来应该可以工作,但它不能。

主要代码:

代码语言:javascript
运行
复制
int main(int argc, char*argv[]) {

    if (SDL_Init(SDL_INIT_VIDEO) < 0)
        std::cout << "SDL did not intizlize.  SDL Error: " << SDL_GetError() << std::endl;

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    SDL_Window* window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
    SDL_GLContext context = SDL_GL_CreateContext(window);


    glewExperimental = GL_TRUE;
    GLenum glewTest = glewInit();
    if (glewTest != GLEW_OK)
        std::cout << glewGetErrorString(glewTest) << std::endl;
    std::cout << glGetError() << std::endl;

    Mesh mesh;
    Shaders shaders("basicShader");
    Texture texture("kitten.png");

    //Loop stuff
    bool quit = false;
    SDL_Event e;
    double frameCounter = 0;
    double time = SDL_GetTicks();

    while (!quit) {
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT) {
                quit = true;
            }
            if (e.type == SDL_KEYDOWN) {
                if (e.key.keysym.sym == SDLK_ESCAPE)
                    quit = true;
            }
        }

        ++frameCounter;
        if (SDL_GetTicks() - time >= 500) {
            std::cout << "FPS: " << frameCounter / ((SDL_GetTicks() - time) / 1000) << std::endl;
            frameCounter = 0;
            time = SDL_GetTicks();
        }

        // Clear the screen to black
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        mesh.draw();
        //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        // Swap buffers
        SDL_GL_SwapWindow(window);
    }

    mesh.~Mesh();
    SDL_GL_DeleteContext(context);
    SDL_Quit();
    return 0;
}

网格类代码:

代码语言:javascript
运行
复制
Mesh::Mesh() {
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);
    GLfloat vertices[] = {
        -0.5f, 0.5f, 0.0, 0.0,
        0.5f, 0.5f, 1.0, 0.0,
        0.5f, -0.5f, 1.0, 1.0,
        -0.5f, -0.5f, 0.0, 1.0
    };
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &ebo);
    GLuint elements[] = {
        0, 1, 2,
        2, 3, 0
    };
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

    //glBindVertexArray(0);
}

void Mesh::draw() {
    glBindVertexArray(vao);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    //glBindVertexArray(0);
}

Mesh::~Mesh() {
    glDeleteVertexArrays(1, &vao);
}

我还没有在这里发布着色器设置代码,它调用glVertexArrayPointer()glEnableVertexAttribArray()来设置顶点属性。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-14 16:40:08

问题在于您在设置着色器时所做的glVertexAttribPointer()glEnableVertexAttribArray()调用。这两个调用都修改当前VAO的状态。

如果你打电话:

代码语言:javascript
运行
复制
glBindVertexArray(0);

在设置网格结束时,0现在是您当前的VAO (这是兼容性配置文件中的合法VAO,而不是核心配置文件中的合法VAO)。因此,在此之后对glVertexAttribPointer()glEnableVertexAttribArray()的调用将修改VAO 0中的状态。

当您在draw()方法开始时调用绑定VAO时:

代码语言:javascript
运行
复制
glBindVertexArray(vao);

你把所有的状态都用在你的网眼里。这反过来意味着您在VAO 0中设置的状态不被使用。由于在mesh VAO被绑定时从未进行glVertexAttribPointer()glEnableVertexAttribArray()调用,所以现在根本没有设置顶点属性。

您真的很幸运,当您没有在构造函数的末尾解绑定VAO时,它就起作用了。由于mesh VAO在您设置着色器时仍然是绑定的,所以glVertexAttribPointer()glEnableVertexAttribArray()调用修改了您的mesh VAO状态,从而产生了所需的结果。但是,如果你曾经使用过一个以上的网格/着色器,这很可能会很不幸地失败。

在设置网格时,确实需要设置顶点状态,而特定网格的VAO是绑定的。以下调用都修改了VAO状态,并且必须在绑定正确的VAO时进行:

  • glEnableVertexAttribArray(...)
  • glDisableVertexAttribArray(...)
  • glVertexAttribPointer(...)
  • glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)

在设置着色器程序时修改顶点设置状态在概念上也是有问题的。顶点设置状态不是着色器程序状态的一部分。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29050877

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档