【问题标题】:Binding a Non-Zero Texture Crashes Program With VBO's使用 VBO 绑定非零纹理崩溃程序
【发布时间】:2014-08-10 13:24:35
【问题描述】:

所以我想实现一个简单的 VBO,看看是否值得从我的场景中的静态对象的显示列表切换。到目前为止,我认为我不会很快这样做。所以这是我的问题:我可以很好地渲染顶点,但是只要我输入纹理坐标,它就会崩溃。所以我做了一些实验,因为我将纹理绑定到这个东西上。我从来没有听说过这是一个问题。从字面上看,使用显示列表的代码完全相同。这是我的代码:

//create a vertex buffer object for the particles to use
        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);

        //create the data, this is really sloppy
        float QuadVertextData[] = {0,0,0,1,0,0,1,1,0,0,1,0};
        float QuadTextureData[] = {0,1,1,1,1,0,0,0};

        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3, &QuadVertextData, GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, 0);

        //generate another buffer for the texcoords
        glGenBuffers(1, &VBOT);
        glBindBuffer(GL_ARRAY_BUFFER, VBOT);
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*2, &QuadTextureData, GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, 0);

和渲染:

        glUseProgram(shader);

        glBindTexture(GL_TEXTURE_2D, texture);

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glVertexPointer(3, GL_FLOAT, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, VBOT);
        glTexCoordPointer(2, GL_FLOAT, 0, 0);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glDrawArrays(GL_QUADS, 0, 4);

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);

我真的不知道为什么会这样,做一个没有着色器的纹理会导致它崩溃,绑定一个没有纹理的着色器会导致它崩溃。有什么帮助或建议吗?

【问题讨论】:

  • 你能在调试模式下编译你的程序,在调试器中运行它,并从崩溃中得到回溯吗?
  • 您应该能够准确地看到它在哪一行崩溃。

标签: opengl textures shader vbo


【解决方案1】:

在核心 opengl 配置文件中,您需要使用 VAO 才能处理 glDrawArrays 和 glDrawElements 等调用。 VAO(顶点数组对象)是 VBO 的绑定点列表,它封装了绑定到它的每个 VBO 的数据格式和组件数量等信息。在代码中它看起来像这样。

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3, &QuadVertextData, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

glGenBuffers(1, &vbot);
glBindBuffer(GL_ARRAY_BUFFER, vbot);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*2, &QuadTextureData, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);

glBindVertexArray(0);

0 和 1(glVertexAttribPointer 的第一个参数)指定着色器中的通用顶点属性索引。 2 和 3(第二个参数)指定组件的数量。为了使用这个 VAO,你的输入应该在着色器中这样定义:

layout(location=0) in vec3 position;
layout(location=1) in vec2 textureCoordinates;

在绘制任何东西之前,你只需要使用着色器程序,绑定你的纹理并绑定 VAO:

glUseProgram(shader);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(vao);
glDrawArrays(GL_QUADS, 0, 4);

不要忘记在着色器中设置 sampler2D uniform 的纹理位置。

如果您想了解更多关于切换到 OpenGL 核心配置文件的信息,我推荐来自 http://www.opengl-tutorial.org/ 的教程

【讨论】:

  • 为什么在我看到的使用 VBO 的教程中,他们不必修改着色器来使用布局等?
  • 这假设 OP 想要使用核心配置文件,这在问题的任何地方都没有说明。此外,不使用 VAO 不会导致崩溃。
  • 虽然这大部分是真的(GL_QUADS 在核心配置文件中不存在),但我看不出它与问题有何关系。 OP 显然没有使用核心配置文件。
  • @ColonelThirtyTwo 所以,我应该忽略这个答案,因为它无效?
  • @BlueSpud 主要是。虽然 IMO 值得学习它为您提供的灵活性的核心配置文件,但此答案实际上并不能解决您遇到的问题,也不太可能解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多