klou
20th January 2011, 06:03
QGraphicsItem has a code to render itself using OpenGL. When I use Buffer Objects and add simple QGraphicsItem program simetimes crashes, sometimes not.
main.h:
#include <QtGui/QApplication>
#include "myQGraphicsView.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
myQGraphicsView w;
w.show();
return a.exec();
}
myQGraphicsView:
#ifndef MYQGRAPHICSVIEW_H_
#define MYQGRAPHICSVIEW_H_
#include <QGLWidget>
#include <QGraphicsView>
#include <QResizeEvent>
class itemWrap;
class myQGraphicsView: public QGraphicsView
{
friend itemWrap;
public:
myQGraphicsView(QWidget *parent = 0);
~myQGraphicsView();
private:
void updateMap();
GLuint vbo;
};
#endif
myQGraphicsView.cpp:
#include "myQGraphicsView.h"
#include <QGraphicsRectItem>
#include <QPointer>
#include <gl/GL.h>
#include <gl/glext.h>
PFNGLGENBUFFERSPROC glGenBuffers = 0;
PFNGLBINDBUFFERPROC glBindBuffer = 0;
PFNGLBUFFERDATAPROC glBufferData = 0;
PFNGLDELETEBUFFERSPROC glDeleteBuffers = 0;
GLfloat vboVerticies2[4 * 3] =
{
-1.0, -1.0, 0.0,
0.0, -1.0, 0.0,
-1.0, 0.0, 0.0,
0.0, 0.0, 0.0
};
class itemWrap: public QGraphicsRectItem
{
QPointer<myQGraphicsView> view_;
public:
itemWrap(myQGraphicsView * obj){view_ = obj;}
~itemWrap(){};
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /* = 0 */)
{
GLint proj[16];
GLfloat model[16];
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetIntegerv(GL_PROJECTION_MATRIX,proj);
glGetFloatv(GL_MODELVIEW_MATRIX,model);
if(!view_.isNull())
{
painter->beginNativePainting();
view_->updateMap();
painter->endNativePainting();
}
}
};
myQGraphicsView::myQGraphicsView( QWidget *parent /*= 0*/ )
:QGraphicsView(parent)
{
setViewport(new QGLWidget);
setScene(new QGraphicsScene(QRect(0,0,100,100), this));
QGraphicsRectItem * ri = new itemWrap(this);
ri->setRect(0,0, 100, 100);
ri->setBrush(QBrush(QColor(0,0,0,0)));
scene()->addItem(ri);
ri = new QGraphicsRectItem();
ri->setRect(50, 50, 100, 100);
ri->setBrush(QBrush(QColor(Qt::red)));
ri->setZValue(10);
scene()->addItem(ri);
}
myQGraphicsView::~myQGraphicsView()
{
glDeleteBuffers(1,&vbo);
}
void myQGraphicsView::updateMap()
{
if (!glGenBuffers)
{
glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,0);
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
//glBufferData(GL_ARRAY_BUFFER,12*sizeof(GLfloat),vb oVerticies2,GL_STATIC_DRAW);
glVertexPointer(3,GL_FLOAT,0,0);
}
GLuint glErr = glGetError();
char* gluErrStr = (char*)gluErrorString(glErr);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/*glColor3f(1.0,0.5,0.0);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glVertexPointer(3,GL_FLOAT,0,0);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);*/
glBegin(GL_TRIANGLES);
glVertex3f( 0.1,-0.1,0.0);
glVertex3f( 0.5, 0.2,0.0);
glVertex3f( 0.4, 1.0,0.0);
glEnd();
}
If I uncomment lines in myQGraphicsView.cpp:
glBufferData(GL_ARRAY_BUFFER,12*sizeof(GLfloat),vb oVerticies2,GL_STATIC_DRAW);
....
glColor3f(1.0,0.5,0.0);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glVertexPointer(3,GL_FLOAT,0,0);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
almost everytime program crashes.
Is it bug or I made something wrong? :confused:
p.s. sources in attachment too
Added after 4 minutes:
Under Debugger it crashes in qpaintengineex_opengl2.cpp:
void QGL2PaintEngineExPrivate::composite(const QGLRect& boundingRect)
{
setCoords(staticVertexCoordinateArray, boundingRect);
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, staticVertexCoordinateArray);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
on line
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
main.h:
#include <QtGui/QApplication>
#include "myQGraphicsView.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
myQGraphicsView w;
w.show();
return a.exec();
}
myQGraphicsView:
#ifndef MYQGRAPHICSVIEW_H_
#define MYQGRAPHICSVIEW_H_
#include <QGLWidget>
#include <QGraphicsView>
#include <QResizeEvent>
class itemWrap;
class myQGraphicsView: public QGraphicsView
{
friend itemWrap;
public:
myQGraphicsView(QWidget *parent = 0);
~myQGraphicsView();
private:
void updateMap();
GLuint vbo;
};
#endif
myQGraphicsView.cpp:
#include "myQGraphicsView.h"
#include <QGraphicsRectItem>
#include <QPointer>
#include <gl/GL.h>
#include <gl/glext.h>
PFNGLGENBUFFERSPROC glGenBuffers = 0;
PFNGLBINDBUFFERPROC glBindBuffer = 0;
PFNGLBUFFERDATAPROC glBufferData = 0;
PFNGLDELETEBUFFERSPROC glDeleteBuffers = 0;
GLfloat vboVerticies2[4 * 3] =
{
-1.0, -1.0, 0.0,
0.0, -1.0, 0.0,
-1.0, 0.0, 0.0,
0.0, 0.0, 0.0
};
class itemWrap: public QGraphicsRectItem
{
QPointer<myQGraphicsView> view_;
public:
itemWrap(myQGraphicsView * obj){view_ = obj;}
~itemWrap(){};
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /* = 0 */)
{
GLint proj[16];
GLfloat model[16];
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetIntegerv(GL_PROJECTION_MATRIX,proj);
glGetFloatv(GL_MODELVIEW_MATRIX,model);
if(!view_.isNull())
{
painter->beginNativePainting();
view_->updateMap();
painter->endNativePainting();
}
}
};
myQGraphicsView::myQGraphicsView( QWidget *parent /*= 0*/ )
:QGraphicsView(parent)
{
setViewport(new QGLWidget);
setScene(new QGraphicsScene(QRect(0,0,100,100), this));
QGraphicsRectItem * ri = new itemWrap(this);
ri->setRect(0,0, 100, 100);
ri->setBrush(QBrush(QColor(0,0,0,0)));
scene()->addItem(ri);
ri = new QGraphicsRectItem();
ri->setRect(50, 50, 100, 100);
ri->setBrush(QBrush(QColor(Qt::red)));
ri->setZValue(10);
scene()->addItem(ri);
}
myQGraphicsView::~myQGraphicsView()
{
glDeleteBuffers(1,&vbo);
}
void myQGraphicsView::updateMap()
{
if (!glGenBuffers)
{
glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,0);
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
//glBufferData(GL_ARRAY_BUFFER,12*sizeof(GLfloat),vb oVerticies2,GL_STATIC_DRAW);
glVertexPointer(3,GL_FLOAT,0,0);
}
GLuint glErr = glGetError();
char* gluErrStr = (char*)gluErrorString(glErr);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/*glColor3f(1.0,0.5,0.0);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glVertexPointer(3,GL_FLOAT,0,0);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);*/
glBegin(GL_TRIANGLES);
glVertex3f( 0.1,-0.1,0.0);
glVertex3f( 0.5, 0.2,0.0);
glVertex3f( 0.4, 1.0,0.0);
glEnd();
}
If I uncomment lines in myQGraphicsView.cpp:
glBufferData(GL_ARRAY_BUFFER,12*sizeof(GLfloat),vb oVerticies2,GL_STATIC_DRAW);
....
glColor3f(1.0,0.5,0.0);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glVertexPointer(3,GL_FLOAT,0,0);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
almost everytime program crashes.
Is it bug or I made something wrong? :confused:
p.s. sources in attachment too
Added after 4 minutes:
Under Debugger it crashes in qpaintengineex_opengl2.cpp:
void QGL2PaintEngineExPrivate::composite(const QGLRect& boundingRect)
{
setCoords(staticVertexCoordinateArray, boundingRect);
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, staticVertexCoordinateArray);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
on line
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);