OpenGL 缓冲区问题

OpenGL buffer woes

过渡到 linux 后,我最近又回到了 OpenGL。出于某种原因,像 glGenBuffersglBindBuffer 等的东西在正常的 GL headers 中不存在,并导致我的程序使用 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);
}

这就是我记忆中使用缓冲区的方式,不过老实说我不相信自己的记忆力。似乎有充分的理由,因为这在 window 打开后立即崩溃。

我尝试将 glDrawArrays 的最后一个参数更改为 1 而不是 3。我还尝试绑定缓冲区两次,首先是 GL_VERTEX_ARRAY,然后是 glVertexPointer ,第二个为 GL_COLOR_ARRAY,然后是 glColorPointer。没有骰子。

glVertexPointer respectively glColorPointer的第3个参数是连续(stride)之间的字节偏移量。如果绑定了命名缓冲区对象,则第 4 个参数也被视为字节偏移量。
stride 参数必须是 5 * sizeof(GLfloat),因为每个属性元组由 5 (GLfloat) 个组件(X、Y、R、G、B)组成。顶点坐标的偏移量为 0,因为它们位于开头。颜色的偏移量是 2 * sizeof(GLfloat),因为颜色在顶点坐标的 2 个分量之后。

此外 GL_VERTEX_ARRAY 不是有效的缓冲区目标。顶点属性的缓冲区目标是 GL_ARRAY_BUFFERGL_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);