OpenGL缓冲区问题

3

最近我在从Windows转移到Linux后重新开始学习OpenGL。但不知何故,glGenBuffersglBindBuffer等函数不在普通的GL头文件中,并且使用GLEW时会导致我的程序崩溃。为了解决这个问题,我一直在使用GLES2。

现在遇到的问题是:

#include <SFML/Graphics.hpp>
#include <GLES2/gl2.h>
#include <GL/gl.h>

int main() {
  sf::RenderWindow window(sf::VideoMode(640, 480), "OpenGL Tests");

  glOrtho(0, 640, 0, 480, -1, 1);
  glEnable(GL_TEXTURE_2D);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_BLEND);
  glClearColor(0, 0, 0, 0);

  //x, y, r, g, b
  GLfloat triangleVertices[15] = {
    10, 10, 1, 0, 0,
    110, 10, 0, 1, 0,
    60, 96.6f, 0, 0, 1
  };
  GLuint triangleBuf;

  glGenBuffers(1, &triangleBuf);
  glBindBuffer(GL_VERTEX_ARRAY, triangleBuf);
  glBufferData(GL_VERTEX_ARRAY, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW);
  glBindBuffer(GL_VERTEX_ARRAY, 0);

  while(window.isOpen()) {
    sf::Event event;

    while(window.pollEvent(event)) {
      if(event.type == sf::Event::Closed) window.close();
    }

    glClear(GL_COLOR_BUFFER_BIT);

    glBindBuffer(GL_VERTEX_ARRAY, triangleBuf);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 3, 0);
    glEnableClientState(GL_COLOR_ARRAY);
    glColorPointer(3, GL_FLOAT, 2, (GLfloat*) 2);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    window.display();
    sf::sleep(sf::milliseconds(50));
  }

  glDeleteBuffers(1, &triangleBuf);
}

这是我记得使用缓冲区的方式,但说实话,我不太相信我的记忆。看来这是有充分理由的,因为窗口一打开就崩溃了。
我尝试将glDrawArrays的最后一个参数从3改为1。我还尝试过两次绑定缓冲区,第一次作为GL_VERTEX_ARRAY,然后是glVertexPointer,第二次作为GL_COLOR_ARRAY,然后是glColorPointer。但都没用。

1
我认为您只是在混淆一些常量。glBindBuffer不能与GL_VERTEX_ARRAY一起使用。可以参考这里。您是否意味着GL_ARRAY_BUFFER - Lukas-T
1个回答

0
glVertexPointer的第三个参数和glColorPointer的第三个参数都是连续两个元素之间的偏移量(stride)。如果已绑定缓存对象,则第四个参数也会被视为一个偏移量。
stride参数必须为5 * sizeof(GLfloat),因为每个属性元组由5个(GLfloat)组成(X、Y、R、G、B)。顶点坐标的偏移量为0,因为它们在开头。颜色的偏移量为2 * sizeof(GLfloat),因为颜色在顶点坐标的2个分量之后。
此外,GL_VERTEX_ARRAY 不是有效的缓冲区目标。顶点属性的缓冲区目标是 GL_ARRAY_BUFFER。错误使用 GL_VERTEX_ARRAY 将导致 INVALID_ENUM 错误。可以通过 glGetError 获取错误信息。
请进行以下更改:
glGenBuffers(1, &triangleBuf);
glBindBuffer(GL_ARRAY_BUFFER, triangleBuf);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindBuffer(GL_ARRAY_BUFFER, triangleBuf);

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 5*sizeof(GLfloat), 0);

glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 5*sizeof(GLfloat), (GLfloat*)(2*sizeof(GLfloat)));

由于您没有绑定纹理,也没有指定纹理坐标,请不要启用二维纹理:

glEnable(GL_TEXTURE_2D);


1
谢谢!在Khronos页面上看到“如果步幅为0,则理解顶点紧密打包”,让我想到它指的是一个顶点结束和另一个顶点开始之间的空间。 - Hal Gee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接