为什么以下GLES代码在Windows CE 6.0上生成DataAbort?

时间:2017-10-27 10:19:31

标签: c++ qt opengl-es windows-ce

我正在使用Qt 4.8和Open GL ES 1.0开发Windows CE OpenGL应用程序。 问题是以下代码导致不可预测的DataAbort异常(不可预测,因为它可能在启动后几秒钟或几小时内发生)。 可能是司机问题还是我做错了什么? 附:没有Qt测试此代码 - 相同的行为。

// GLWidget.hpp

#pragma pack(push, 1)
struct drPoint {

    GLfloat x;
    GLfloat y;
    GLfloat R;
    GLfloat G;
    GLfloat B;
    GLfloat A;

};
#pragma pack(pop)

class GLWidget : public QGLWidget {

    Q_OBJECT

public:
    GLWidget(QWidget *parent = 0);
    ~GLWidget();


private:

    drPoint*    arr;
    unsigned int ui32Vbo;

    void initializeGL();
    void paintGL();
    void resizeGL(int width, int height);

};

// GLWidget.cpp

GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent) {}

void GLWidget::initializeGL() {

        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glPointSize(1.0);

        arr = new drPoint[this->height()];

        for (int i = 0; i < this->height(); ++i) {

            arr[i].x    = 0;
            arr[i].y    = i;
            arr[i].R    = 1.0f;
            arr[i].G    = 0.0f;
            arr[i].B    = 0.0f;
            arr[i].A    = 1.0f;

        }

        glEnable(GL_VERTEX_ARRAY);
        glEnable(GL_COLOR_ARRAY);

        glGenBuffers(1, &ui32Vbo);
        glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(drPoint) * this->height(), arr, GL_DYNAMIC_DRAW);
        glVertexPointer(2, GL_FLOAT, sizeof(GLfloat) * 6, (void*)0);
        glColorPointer(4, GL_FLOAT, sizeof(GLfloat) * 6, (void*)(sizeof(GLfloat) * 2));
        glBindBuffer(GL_ARRAY_BUFFER, 0);

    }

void GLWidget::paintGL() {

    // Some buffer filling code

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(drPoint) * this->height(), arr);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDrawArrays(GL_POINTS, 0, this->height());

    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

}

void GLWidget::resizeGL(int width, int height)
{

    glViewport(0, 0, width, height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    float halfWidth  = width * 0.5f;
    float halfHeight = height * 0.5f;

    glOrthof(-halfWidth, halfWidth, -halfHeight, halfHeight, 0.0f, 10.0f);
    glTranslatef(-halfWidth, -halfHeight, 0.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

}

GLWidget::~GLWidget() {

    glDeleteBuffers(1, &ui32Vbo);

    delete [] arr;

}

异常如下:

13:08:40.534>  Exception 'Data Abort'(4) Thread-Id=04930016(pth=8674ec28) PC=81221700 BVA=b6200040, dwInfo = 00001008
13:08:40.534>  R0=00000049  R1=00000001  R2=82f994e8  R3=00000000
13:08:40.534>  R4=00000000  R5=00000001  R6=00000049  R7=82f99978
13:08:40.534>  R8=82f9ac38  R9=82f9df0c R10=82f9df0c R11=000007e0
13:08:40.534> R12=00000000  SP=d354f840  Lr=8121edf8 Psr=6000011f
13:08:40.574>  R7=81235608
13:08:40.574>  R8=00000001  R9=00000002 R10=82f9df0c R11=82f9df0c
13:08:40.574> R12=812360e0  SP=ffffc634  Lr=812360f8 Psr=60000193
13:08:40.574> Exception 'Data Abort' (4): Thread-Id=04930016(pth=8674ec28), Proc-Id=00400002(pprc=82fa1448) 'NK.EXE', VM-active=04920016(pprc=8674e9ac) 'opengl_hello.exe'
13:08:40.574> PC=8121a6d8(NK.EXE+0x0001a6d8) RA=812360f8(kernel.dll+0x0000e0f8) SP=ffffc634, BVA=00000000
13:08:40.534> 360f8(kernel.dll+0x0000e0f8) SP=ffffc634, BVA=00000000
13:08:40.534> e4) PC=8121a6d8 BVA=b6200040, dwInfo = 00001008
13:08:40.534>  R0=81235608  R1=60000113  R2=b6200000  R3=82f9ac38
13:08:40.659>  R4=82f9d424  R5=00000000  R6=82f9ecc0 Proc-Id=00400002(pprc=82fa1448) 'NK.EXE', VM-active=04920016(pprc=8674e9ac) 'opengl_hello.exe'
13:08:40.659> PC=c00bb9a4(k.coredll.dll+0x0001b9a4) RA=812354c4(kernel.dll+0x0000d4c4) SP=d354f558, BVA=ffffffff

很抱歉发布此类问题(“代码有什么问题?!”),但我找不到大约一个月左右的任何解决方案。

P.S。 使用官方Texas Instruments sdk的GLES 1.0 lib。 硬件是带有PowerVR的DM3730。 P.P.S. 发现这种行为仅在D1电源状态下发生(在D0工作正常,在D2绘图中由于SystemIdle而停止)。

EDITED: 我将代码更改为以下但仍然遭遇同样的崩溃。现在它变得更加罕见。

#pragma pack(push, 1)
struct drPoint {

    GLfloat x;
    GLfloat y;

};
struct clrPoint {

    GLfloat R;
    GLfloat G;
    GLfloat B;
    GLfloat A;

};
#pragma pack(pop)

void GLWidget::initializeGL() {

        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glPointSize(1.0);

        arr = new drPoint[this->height()];
        clr = new clrPoint[this->height()];

        for (int i = 0; i < this->height(); ++i) {

            arr[i].x    = 0;
            arr[i].y    = i;
            clr[i].R    = 1.0f;
            clr[i].G    = 0.0f;
            clr[i].B    = 0.0f;
            clr[i].A    = 1.0f;

        }

        glEnable(GL_VERTEX_ARRAY);
        glEnable(GL_COLOR_ARRAY);

    }

void GLWidget::paintGL() {

    // Some buffer filling code

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    glVertexPointer(2, GL_FLOAT, 0, arr);
    glColorPointer(4, GL_FLOAT, 0, clr);
    glDrawArrays(GL_POINTS, 0, this->height());

    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

}

似乎没有颜色一切都很好(或者它只需要更多的时间来崩溃)。

1 个答案:

答案 0 :(得分:1)

GLES 1.0不仅仅支持VBO&#34; Vertex Arrays&#34;。

你的代码是VBO和Vertex Array之间的混合,你没有正确绑定任何一个。

有关详细信息,请参阅GLES