Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Qt OpenGL抽屉组件崩溃_C++_Qt_Opengl - Fatal编程技术网

C++ Qt OpenGL抽屉组件崩溃

C++ Qt OpenGL抽屉组件崩溃,c++,qt,opengl,C++,Qt,Opengl,我已经创建了一个包装好的QGLWidget类,并试图创建一个基本的sprite工厂风格的类来访问它。在我的SpriteMachine(想想sprite factory)类中,我尝试使用VBOs进行所有的sprite绘制,并调用一个GLDrainElements调用(在我的代码中,它只是DrainElements,访问父级中调用GLDrainElements的包装函数)。我在抽屉元素上遇到访问冲突,我不知道为什么 我检查了一下,几乎可以肯定我的顶点数据格式正确。另外,在绘制任何图形之前,我在父窗口

我已经创建了一个包装好的QGLWidget类,并试图创建一个基本的sprite工厂风格的类来访问它。在我的SpriteMachine(想想sprite factory)类中,我尝试使用VBOs进行所有的sprite绘制,并调用一个GLDrainElements调用(在我的代码中,它只是DrainElements,访问父级中调用GLDrainElements的包装函数)。我在抽屉元素上遇到访问冲突,我不知道为什么

我检查了一下,几乎可以肯定我的顶点数据格式正确。另外,在绘制任何图形之前,我在父窗口小部件的initializeGL方法中调用initializeGlFunctions,因此我认为我没有正确初始化所有内容。首先,以下是绘制图形的sprite类中的代码:

void Machine::sync(){
#define ADD_ATTRIBUTE_LOCATION(ATTRNAME, ASIZE, OFFSET)                                                                         \
    (                                                                                                                           \
        (attrLoc = flat_shader.attributeLocation(ATTRNAME)),                                                                    \
        (flat_shader.enableAttributeArray(attrLoc)),                                                                            \
        (parent->vertexAttribPointer(attrLoc, ASIZE, GL_FLOAT, GL_FALSE, sizeof(VertexAttribArray), (const void*) offset)),     \
        (offset += OFFSET),                                                                                                     \
        (void)0                                                                                                                 \
    )

    int i;
    int q;
    int oldSize;
    int size;
    int width;
    int height;
    qreal texInvW;
    qreal texInvH;
    qreal scaledCoords[4];
    GLuint vbo[2];
    quintptr offset;
    int attrLoc;
    QPair<SpriteProperties*, BoundingBox> spriteData;
    VertexAttribArray* verts;
    GLushort*          indices;

    parent->makeCurrent();

    glEnable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    offset = 0;

    flat_shader.bind();
    flat_shader.setUniformValue("mvp_matrix", parent->getOrtho());
    flat_shader.setUniformValue("texture", 0);
    ADD_ATTRIBUTE_LOCATION("a_position", 3, sizeof(float) * 3);
    ADD_ATTRIBUTE_LOCATION("a_texcoord", 2, sizeof(float) * 2);
    ADD_ATTRIBUTE_LOCATION("a_scale", 2, sizeof(float) * 2);
    ADD_ATTRIBUTE_LOCATION("a_scale_lo", 2, sizeof(float) * 2);
    ADD_ATTRIBUTE_LOCATION("a_scale_hi", 2, sizeof(float) * 2);

    parent->genBuffers(2, vbo);
    oldSize = 0;
    for(i = 0; i < spriteToSync.size(); i++){
        size = spriteToSync[i].size();
        if(size > 0){
            parent->bindTexture(atlasList[i]);

            texInvW = 1.0 / atlasList[i].width();
            texInvH = 1.0 / atlasList[i].height();
            if(size > oldSize){
                if(oldSize != 0){
                    delete[] verts;
                    delete[] indices;
                }
                verts   = new VertexAttribArray[4 * size];
                indices = new GLushort[4 * size];
            }
            for(q = 0; q < size; q++){
                spriteData = spriteToSync[i][q];
                width  = spriteData.first->location.x1 - spriteData.first->location.x0;
                height = spriteData.first->location.y1 - spriteData.first->location.y0;
                scaledCoords[0] = spriteData.first->location.x0 * texInvW;
                scaledCoords[1] = spriteData.first->location.y0 * texInvH;
                scaledCoords[2] = spriteData.first->location.x1 * texInvW;
                scaledCoords[3] = spriteData.first->location.y1 * texInvH;

                if(spriteData.first->flags & DRAW_TILED){
                    verts[q * 4 + 0].p = QVector3D(spriteData.second.x1, spriteData.second.y0,UNIFORM_DEPTH);
                    verts[q * 4 + 0].t = QVector2D(scaledCoords[2], scaledCoords[1]);
                    verts[q * 4 + 0].s = QVector2D(((qreal) (spriteData.second.x1 - spriteData.second.x0)) / width,
                                                   ((qreal) (spriteData.second.y1 - spriteData.second.y0)) / height);
                    verts[q * 4 + 0].s_lo = QVector2D(scaledCoords[0], scaledCoords[1]);
                    verts[q * 4 + 0].s_hi = QVector2D(scaledCoords[2] - scaledCoords[0], scaledCoords[3] - scaledCoords[1]);

                    verts[q * 4 + 1].p = QVector3D(spriteData.second.x0, spriteData.second.y0, UNIFORM_DEPTH);
                    verts[q * 4 + 1].t = QVector2D(scaledCoords[0], scaledCoords[1]);
                    verts[q * 4 + 1].s = verts[q * 4 + 0].s;
                    verts[q * 4 + 1].s_lo = verts[q * 4 + 0].s_lo;
                    verts[q * 4 + 1].s_hi = verts[q * 4 + 0].s_hi;

                    verts[q * 4 + 2].p = QVector3D(spriteData.second.x0, spriteData.second.y1, UNIFORM_DEPTH);
                    verts[q * 4 + 2].t = QVector2D(scaledCoords[0], scaledCoords[3]);
                    verts[q * 4 + 2].s = verts[q * 4 + 0].s;
                    verts[q * 4 + 2].s_lo = verts[q * 4 + 0].s_lo;
                    verts[q * 4 + 2].s_hi = verts[q * 4 + 0].s_hi;

                    verts[q * 4 + 3].p = QVector3D(spriteData.second.x1, spriteData.second.y1, UNIFORM_DEPTH);
                    verts[q * 4 + 3].t = QVector2D(scaledCoords[2], scaledCoords[3]);
                    verts[q * 4 + 3].s = verts[q * 4 + 0].s;
                    verts[q * 4 + 3].s_lo = verts[q * 4 + 0].s_lo;
                    verts[q * 4 + 3].s_hi = verts[q * 4 + 0].s_hi;
                }
                else{
                    verts[q * 4 + 0].p = QVector3D(spriteData.second.x0 + width, spriteData.second.y0,UNIFORM_DEPTH);
                    verts[q * 4 + 0].t = QVector2D(scaledCoords[2], scaledCoords[1]);
                    verts[q * 4 + 0].s = QVector2D(1, 1);
                    verts[q * 4 + 0].s_lo = QVector2D(scaledCoords[0], scaledCoords[1]);
                    verts[q * 4 + 0].s_hi = QVector2D(scaledCoords[2] - scaledCoords[0], scaledCoords[3] - scaledCoords[1]);

                    verts[q * 4 + 1].p = QVector3D(spriteData.second.x0, spriteData.second.y0, UNIFORM_DEPTH);
                    verts[q * 4 + 1].t = QVector2D(scaledCoords[0], scaledCoords[1]);
                    verts[q * 4 + 1].s = verts[q * 4 + 0].s;
                    verts[q * 4 + 1].s_lo = verts[q * 4 + 0].s_lo;
                    verts[q * 4 + 1].s_hi = verts[q * 4 + 0].s_hi;

                    verts[q * 4 + 2].p = QVector3D(spriteData.second.x0, spriteData.second.y0 + height, UNIFORM_DEPTH);
                    verts[q * 4 + 2].t = QVector2D(scaledCoords[0], scaledCoords[3]);
                    verts[q * 4 + 2].s = verts[q * 4 + 0].s;
                    verts[q * 4 + 2].s_lo = verts[q * 4 + 0].s_lo;
                    verts[q * 4 + 2].s_hi = verts[q * 4 + 0].s_hi;

                    verts[q * 4 + 3].p = QVector3D(spriteData.second.x0 + width, spriteData.second.y0 + height, UNIFORM_DEPTH);
                    verts[q * 4 + 3].t = QVector2D(scaledCoords[2], scaledCoords[3]);
                    verts[q * 4 + 3].s = verts[q * 4 + 0].s;
                    verts[q * 4 + 3].s_lo = verts[q * 4 + 0].s_lo;
                    verts[q * 4 + 3].s_hi = verts[q * 4 + 0].s_hi;
                }
                indices[q * 4 + 0] = q * 4 + 0;
                indices[q * 4 + 1] = q * 4 + 1;
                indices[q * 4 + 2] = q * 4 + 2;
                indices[q * 4 + 3] = q * 4 + 3;
            }

            parent->bindBuffer(GL_ARRAY_BUFFER, vbo[0]);
            parent->bufferData(GL_ARRAY_BUFFER, size * 4 * sizeof(VertexAttribArray), verts, GL_STATIC_DRAW);
            parent->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[1]);
            parent->bufferData(GL_ELEMENT_ARRAY_BUFFER, size * 4 * sizeof(GLushort), indices, GL_STATIC_DRAW);

            parent->drawElements(GL_QUADS, 4 * size, GL_UNSIGNED_SHORT, 0);

            oldSize = size;
            spriteToSync[i].clear();
        }
    }
    parent->deleteBuffers(2, vbo);
    if(oldSize > 0){
        delete[] verts;
        delete[] indices;
    }
}
我已经验证了我的顶点数组是否使用浮点正确格式化,以及着色器是否正确链接和加载。我知道这里的很多类结构是不可见的,但我的GL有什么明显的错误吗

更新


事实上,我没有任何类型的glEnableClientState调用,我有类似的代码在我从未使用过它们的地方工作,这是否相关

您不需要
glEnableClientState
GlenableVertexAttributeArray
就足够了。但是,您应该确保只启用了您实际需要的属性数组。这至少是一个开始!我还应该提到,我认识到在paintGL中加载一个文件是愚蠢的,但它现在就在那里,只是为了看看代码是否能够实现它(它没有做到)。此文件已验证为加载。
void MyGLWidget::paintGL(){
    SpriteMachine::Machine spriteDraw(this);
    SpriteMachine::key     atlas;
    SpriteMachine::key     sprites[2];

    ortho.setToIdentity();
    ortho.ortho(0, width, height, 0, -1, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    atlas = spriteDraw.loadAtlas(":/gfx/gfx/hnight.png");

    sprites[0] = spriteDraw.create(atlas, SpriteMachine::BoundingBox(208, 64, 239, 95));
    sprites[1] = spriteDraw.create(atlas, SpriteMachine::BoundingBox(192, 96, 207, 111));

    spriteDraw.draw(sprites[0], SpriteMachine::BoundingBox(10, 10, 0, 0));

    spriteDraw.sync();
}