C++ 调用gldrawArray后的SegFault

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,

我正在尝试编写一个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,
        -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