为什么以下 GLES 代码会在 Windows CE 6.0 上生成 DataAbort?
Why following GLES code generates DataAbort on Windows CE 6.0?
我正在使用 Qt 4.8 和 Open GL ES 1.0 开发 Windows CE OpenGL 应用程序。
问题是以下代码导致不可预测的 DataAbort Exception(不可预测,因为它可能在启动后几秒钟或几小时内发生)。
可能是驱动程序问题还是我做错了什么?
P.S。在没有 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
很抱歉提出此类问题 ("What's wrong with the code?!"),但我大约一个月都找不到任何解决方案。
P.S。
使用官方 Texas Instruments sdk 中的 GLES 1.0 lib。
硬件是带有 PowerVR 的 DM3730。
P.P.S。
发现这种行为仅在 D1 电源状态下发生(在 D0 中工作正常,在 D2 中绘图因 SystemIdle 而停止)。
已编辑:
我将代码更改为以下但仍然遇到同样的崩溃。现在它变得更加罕见了。
#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);
}
似乎没有颜色一切都很好(或者只是需要更多时间才能崩溃)。
GLES 1.0 仅不支持 VBO "Vertex Arrays"。
您的代码是 VBO 和 Vertex Array 之间的大杂烩,您没有正确绑定任何一个。
更多信息请咨询GLES。
我正在使用 Qt 4.8 和 Open GL ES 1.0 开发 Windows CE OpenGL 应用程序。 问题是以下代码导致不可预测的 DataAbort Exception(不可预测,因为它可能在启动后几秒钟或几小时内发生)。 可能是驱动程序问题还是我做错了什么? P.S。在没有 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
很抱歉提出此类问题 ("What's wrong with the code?!"),但我大约一个月都找不到任何解决方案。
P.S。 使用官方 Texas Instruments sdk 中的 GLES 1.0 lib。 硬件是带有 PowerVR 的 DM3730。 P.P.S。 发现这种行为仅在 D1 电源状态下发生(在 D0 中工作正常,在 D2 中绘图因 SystemIdle 而停止)。
已编辑: 我将代码更改为以下但仍然遇到同样的崩溃。现在它变得更加罕见了。
#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);
}
似乎没有颜色一切都很好(或者只是需要更多时间才能崩溃)。
GLES 1.0 仅不支持 VBO "Vertex Arrays"。
您的代码是 VBO 和 Vertex Array 之间的大杂烩,您没有正确绑定任何一个。
更多信息请咨询GLES。