C++ 调用gldrawArray后的SegFault
我正在尝试编写一个sprite批处理程序。 最初,我将以下数据上传到openGL,以查看是否可以在屏幕上显示任何内容:C++ 调用gldrawArray后的SegFault,c++,opengl,sprite,C++,Opengl,Sprite,我正在尝试编写一个sprite批处理程序。 最初,我将以下数据上传到openGL,以查看是否可以在屏幕上显示任何内容: static GLfloat const vertexData[] = { //Position //Color //UV Coords 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
static GLfloat const vertexData[] = {
//Position //Color //UV Coords
0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f
};
以下是我的顶点和片段着色器:
const char* vert = "#version 330 core\n"
"layout (location = 0) in vec2 vPos;\n"
"layout (location = 1) in vec4 vColor;\n"
"layout (location = 2) in vec2 vTexPos;\n"
"\n"
"out vec4 fColor;\n"
"out vec2 fTexPos;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(vPos.xy, 0.0, 1.0);\n"
" fColor = vColor;\n"
" fTexPos = vec2(vTexPos.s, 1.0 - vTexPos.t);\n"
"}";
const char* frag = "#version 330 core\n"
"in vec4 fColor;\n"
"in vec2 fTexPos;\n"
"out vec4 finalColor;\n"
"\n"
"uniform sampler2D textureUniform;\n"
"\n"
"void main() {\n"
" vec4 textureColor = texture(textureUniform, fTexPos);"
" finalColor = fColor * textureColor;\n"
"}";
我将VAO和VBO设置为:
auto vaoID_ = 0;
auto vboID_ = 0;
glGenVertexArrays(1, &vaoID_);
glGenBuffers(1, &vboID_);
glBindVertexArray(vaoID_);
glBindBuffer(GL_ARRAY_BUFFER, vboID_);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8, (void*)0); // Screen Position
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 8, (void*)(2 *sizeof(GL_FLOAT)); //Color
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8, (void*)(6 * sizeof(GL_FLOAT)); //UV
最后,在每个循环中,我将孤立缓冲区,然后将数据分为子循环
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), nullptr, GL_DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertexData), vertexData);
glDrawArrays(GL_TRIANGLES, 0, 6);
这很有效!
因此,我试图开始编写一个基本的sprite批处理。
我将顶点数据分组到POD结构中:
struct VertexData {
struct {
GLfloat screenx;
GLfloat screeny;
} position;
struct {
GLfloat r;
GLfloat g;
GLfloat b;
GLfloat a;
} color;
struct {
GLfloat texu;
GLfloat texv;
} uv;
}
并使用一个向量将所有内容批处理在一起:
向量spritebatch_
我更改了对glvertexattributepointer的调用以匹配此结构,尽管我认为不需要进行此更改
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, position)); // Screen Position
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, color)); //Color
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uv)); //UV
为了测试它,我将在每个循环上向它提供静态GLfloat数组中的相同数据:
然后尝试孤立缓冲区并将数据分为:
glBufferData(GL_VERTEX_ARRAY, spritebatch_.size() * sizeof(VertexData), nullptr, GL_DYNAMIC_DRAW);
glBufferSubData(GL_VERTEX_ARRAY, 0, spritebatch_.size() * sizeof(VertexData), spritebatch_.data());
glDrawArrays(GL_TRIANGLES, 0, spritebatch_.size());
最后,我将重置spritebatch\ u0:spritebatch\ u0.clear
然而,这是错误的。当我孤立缓冲区并将数据分入时,我是否做了一些不正确的事情?数据格式仍然匹配VertexData POD成员仍然都是GLfloats,spritebatch_uu的大小仍然是6个顶点以形成正方形,并且该数据在每个顶点内的位置仍然相同 的第5个参数是步长,即连续通用顶点属性之间的字节偏移量
所以从
到
很重要,因为sizeofVertexData不是8,而是8*sizeofGL\u FLOAT
分别的第一个参数必须是目标的枚举数常量,它是GL_数组_缓冲区、GL_元素_数组_缓冲区、。
GL_VERTEX_ARRAY为固定功能客户端功能标识顶点数组-请参阅
更改:
glBufferDataGL_顶点_数组。。。;
glBufferDataGL_数组_缓冲区
GLBUFFERSUBDATA GLU顶点数组。。。;
glBufferSubDataGL_数组_缓冲区
注意,如果您要检查OpenGL错误或,您将得到一个GL_INVALID_ENUM错误。
未创建数组缓冲区的数据存储,这会导致段错误。GL\U VERTEX\U数组是否应为GL\U array\U buffer?在调用GLVertexAttributePointer时,请确保已绑定缓冲区。的第5个参数是步长,即连续通用顶点属性之间的字节偏移量。因此,更改很重要,因为sizeofVertexData不是8,而是8*sizeofGL\u FLOAT
glBufferData(GL_VERTEX_ARRAY, spritebatch_.size() * sizeof(VertexData), nullptr, GL_DYNAMIC_DRAW);
glBufferSubData(GL_VERTEX_ARRAY, 0, spritebatch_.size() * sizeof(VertexData), spritebatch_.data());
glDrawArrays(GL_TRIANGLES, 0, spritebatch_.size());
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8, (void*)0); // Screen Position
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 8, (void*)(2 *sizeof(GL_FLOAT)); //Color
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8, (void*)(6 * sizeof(GL_FLOAT)); //UV
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, position)); // Screen Position
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, color)); //Color
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uv)); //UV