PDA

View Full Version : Can't see grahpicsitem



lpfxyww
4th April 2014, 11:49
I've reimplemented QGraphicsscene::drawBackground() with calling Opengl functions, and call QGraphicsView::setviewport(QGLWidget*). This works fine. Then I added some Qgraphicsitems(drawing pictures, text, etc.) to the scene, but only the gl codes works, no item could be seen though QGraphicsItem::paint() was called. So what's wrong with my code? Thanks a lot.

My code is like this:
////////////////////////item//////////////////


ImageItem : public QGraphicItem
{
...
}
ImageItem::paint()
{
//draw some thing, such as painter.drawpixmap();
}

////////////////////////scene///////////////

MyScene : public QGraphicsscene
{
...
}
MyScene::MyScene()
{
...
connect(timer,SIGNALS(timeout()),this,SLOT(update( )));
}
MyScene::drawBackground()
{
// call gl functions....
}

///////////////////main////

QGraphicsView view;
QGLWidget* widget = new QGLWidget;
view.setviewport(widget);
widget.makeCurrent();
MyScene scene;
view.setscene(&scene);
ImageItem item;
scene.additem(item);// I can't see the item, but the QGraphicsScene::itemAt() can find the item
...

/////////////////////////////

lpfxyww
8th April 2014, 05:03
Hi. I found the example boxes in qt examples and I tried to do the same thing with reimplementing the example hellogl . But after I add a item(QGraphocsItem) to the scene, I can't see where it is. Can anybody help me? Thanks. Here is my code:
///////////////////////////////////////The Scene(example hellogl)/////////////////////////////////////
//the code and header file can be found in example hellogl


#include "qtlogo.h"
class TestScene : public QGraphicsScene
{

public:
TestScene(int w, int h);

public:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
protected:
virtual void drawBackground(QPainter *painter, const QRectF &rect);
private:
QtLogo *logo;
int xRot;
int yRot;
int zRot;
QPoint lastPos;
QColor qtGreen;
QColor qtPurple;

};

static void qNormalizeAngle(int &angle)
{
while (angle < 0)
angle += 360 * 16;
while (angle > 360 * 16)
angle -= 360 * 16;
}
TestScene::TestScene(int w, int h)
{
setSceneRect(0,0,w,h);
logo = 0;
xRot = 15;
yRot = 345;
zRot = 0;

qtGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0);
qtPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0);
initializeGL();
}


//#include <QtOpenGL/qgl.h>
void TestScene::initializeGL()
{
//qglClearColor(qtPurple.dark());

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

logo = new QtLogo(this, 64);
logo->setColor(qtGreen.dark());

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_MULTISAMPLE);
static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
}

void TestScene::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
glRotatef(xRot / 16.0, 1.0, 0.0, 0.0);
glRotatef(yRot / 16.0, 0.0, 1.0, 0.0);
glRotatef(zRot / 16.0, 0.0, 0.0, 1.0);
logo->draw();
}

void TestScene::resizeGL(int width, int height)
{
setSceneRect(0,0,width,height);
int side = qMin(width, height);
glViewport((width - side) / 2, (height - side) / 2, side, side);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef QT_OPENGL_ES_1
glOrthof(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0);
#else
glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0);
#endif
glMatrixMode(GL_MODELVIEW);
update();
}

void TestScene::drawBackground(QPainter *painter, const QRectF &rect)
{
painter->beginNativePainting();
paintGL();
painter->endNativePainting();
}


///////////////////////////////////////The View/////////////////////////////////////

class TestView : public QGraphicsView
{
Q_OBJECT
public:
TestView(){}

void setUpScene(TestScene* t);
protected:
void resizeEvent(QResizeEvent *event);
TestScene* testscene;
};

void TestView::setUpScene(TestScene* t)
{
testscene = t;
setScene(testscene);
}

void TestView::resizeEvent(QResizeEvent *event)
{
testscene->setSceneRect(0,0,event->size().width(),event->size().height());
testscene->resizeGL(event->size().width(),event->size().height());
}


///////////////////////////////////////the item/////////////////////////////////////

class testItem : public QGraphicsItem
{
public:
testItem ();

QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};

QRectF testItem ::boundingRect() const
{
QRectF rect(0,0,64,64);
return rect;
}
void testItem ::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->setPen(QPen(Qt::black));
painter->setBrush(QBrush(QColor(Qt::green)));
painter->drawRect(0,0,64,64);
}


///////////////////////////////////////loop in ui/////////////////////////////////////

ClientWindow::ClientWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
QGLWidget* widget = new QGLWidget(QGLFormat(QGL::SampleBuffers));
widget->makeCurrent();
TestScene* testscene = new TestScene(1022,687);


testItem * citem = new testItem ();
citem->setPos(20,20);
testscene->addItem(citem);
view = new TestView();
view->setViewport(widget);
view->setViewportUpdateMode(QGraphicsView::FullViewportU pdate);
view->setUpScene(testscene);

//add view to ui
setCentralWidget(view);
}


//////////////////////////////////////main loop/////////////////////////////////////

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//QTextCodec::setCodecForLocale(QTextCodec::codecFor Name("UTF-8"));
ClientWindow w;
w.show();
return a.exec();
}

lpfxyww
8th April 2014, 10:40
So I'm wondering that if reimplement the QGraphicsscene::drawbackground(), will things drew by opengl affect the visiblity of newly added items(painted by painter)?

wysota
8th April 2014, 11:58
I think the problem might be with your manipulation of the matrices in initializeGL and family. I would start by emptying your drawBackground() call and checking if things magically start working.

lpfxyww
8th April 2014, 14:26
Thanks. I tried to draw some line strips and I saw the Item. The code is as follows:
////////////////////TestScene::initializeGL()/////////////////////


glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glLineWidth(30.0);
glLineStipple(1, 0xAAAA);
glEnable(GL_LINE_STIPPLE);

////////////////////TestScene::paintGL()/////////////////////


glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
glColor3f(0.80, 0.0, 0.0);
glVertex2f(-1.0, -0.5);
glColor3f(0.0, 0.80, 0.0);
glVertex2f(-0.5, 0.5);
glColor3f(0.0, 0.0, 0.80);
glVertex2f(0.45, 0.5);
glColor3f(0.80, 0.80, 0.0);
glVertex2f(0.5, -0.5);
glColor3f(0.80, 0.0, 0.0);
glVertex2f(1.0, -0.5);
glEnd();
glFlush();

/////////////////////TestScene::resizeGL()//////////////////////////

setSceneRect(0,0,width,height);


glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
update();


/////////////////////////////////////////////////////////////
In my mind, what the opengl draws is the background of the scene and the item are in the foreground. So they are indepent with each other, am I right?And I have another questions : what decides the visibilty of the items besides its zvalue (set by item->setZvalue()) or its pos( set by item->setPos())?

wysota
8th April 2014, 15:09
So they are indepent with each other, am I right?
Yes.


And I have another questions : what decides the visibilty of the items besides its zvalue (set by item->setZvalue()) or its pos( set by item->setPos())?

Z-order value does not influence item visibility. Regardless of its z-order value the item is visible if it fits in the current view. The item can be painted over if another opaque item is on top of it.