OpenGL 缓冲区问题
OpenGL buffer woes
过渡到 linux 后,我最近又回到了 OpenGL。出于某种原因,像 glGenBuffers
、glBindBuffer
等的东西在正常的 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_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);
过渡到 linux 后,我最近又回到了 OpenGL。出于某种原因,像 glGenBuffers
、glBindBuffer
等的东西在正常的 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_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);