PDA

View Full Version : Qt and OpenGl (I'm lost)



anon789
14th September 2010, 03:01
Hi,

I am trying to create a really simple application but I can't seem to understand what is going wrong or if what I am trying to do is possible at all (the way I want it, maybe there is a better way).

Basically I want to make an application that draws vectors on the screen. I started by reading the hellogl example provided by trolltech and then started coding. I Created a class GLWidget, which inherits from QGLWidget, redefined painGL, resizeGL, initializeGL, etc.

Everything works fine as long as I use paintGL for the OpenGL API calls, this is a big problem because I wanted to use a class Vector that would contain a method draw() which would draw the vector on the GLWidget. Is this possible? In the Qt4.6 doc it says :


Your widget's OpenGL rendering context is made current when paintGL(), resizeGL(), or initializeGL() is called. If you need to call the standard OpenGL API functions from other places (e.g. in your widget's constructor or in your own paint functions), you must call makeCurrent() first.


void QGLWidget::makeCurrent ()
Makes this widget the current widget for OpenGL operations, i.e. makes the widget's rendering context the current OpenGL rendering context.

Where I am supposed to call makeCurrent? Inside the GLWidget? Outside right before calling vector.draw()? Nothing seems to works.

I read somewhere else that you have to call swapBuffers, but that does not work either. So what I am doing wrong?

I have not been able to find much info concerning Qt + OpenGL on internet. Any help would be greatly appreciated. Thanks in advance.

tbscope
14th September 2010, 05:55
Example:


void GLWidget::paintEvent(QPaintEvent *event)
{
makeCurrent();

// Your gl painting

myGlItem->drawSomeCoolGlGraphics();
}

anon789
14th September 2010, 22:47
Hi,

Thank you for your answer tbscope, unfortunately I have still not been able to make it work. Here is my code so far, maybe you or someone else can check it and tell me what I am doing wrong.

Thanks a lot.

GLWidget.h :


#ifndef HEADER_GLWIDGET
#define HEADER_GLWIDGET

#include <QGLWidget>

class GLWidget : public QGLWidget
{
Q_OBJECT

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

protected :
void paintEvent(QMouseEvent *event);
void initializeGL();
void paintGL();
void resizeGL( int width, int height );
QSize minimumSizeHint() const;
QSize sizeHint() const;

private :

};

#endif

GLWidget.cpp :



#include <QtGui>
#include <QtOpenGL>
#include "GLWidget.h"

static int WINDOW_WIDTH = 400;
static int WINDOW_HEIGHT = 400;

using namespace std;

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

}

GLWidget::~GLWidget()
{

}

void GLWidget::initializeGL()
{
// Background color
glClearColor(1.0f, 0.0f, 0.0f, 1.0f );

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode( GL_PROJECTION );
glLoadIdentity();

gluPerspective(70,(double)WINDOW_WIDTH/WINDOW_HEIGHT,1,1000);
gluLookAt(0,0,5,0,0,0,0,1,0);

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

}

void GLWidget::paintGL()
{

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

glColor3fv (m_color);
glBegin(GL_QUADS);
glVertex3f (0.25, 0.25, 0.0);
glVertex3f (0.75, 0.25, 0.0);
glVertex3f (0.75, 0.75, 0.0);
glVertex3f (0.25, 0.75, 0.0);
glEnd();

}

void GLWidget::paintEvent(QMouseEvent *event)
{
makeCurrent();

// Your gl painting

glBegin(GL_LINES);
// x (blue)
glColor3ub(0,0,255);
glVertex3i(0,0,0);
glVertex3i(1,0,0);
// y (green)
glColor3ub(0,255,0);
glVertex3i(0,0,0);
glVertex3i(0,1,0);
// z (red)
glColor3ub(255,0,0);
glVertex3i(0,0,0);
glVertex3i(0,0,1);
glEnd();

}

void GLWidget::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
}

QSize GLWidget::minimumSizeHint() const
{
return QSize(50, 50);
}

QSize GLWidget::sizeHint() const
{
return QSize(WINDOW_WIDTH, WINDOW_HEIGHT);
}


I changed the
QPaintEvent *event for
QMouseEvent *event to make it work for my test, otherwise nothing was showing up. Now the code inside painGL() works, but not the one inside paintEvent().

anon789
16th September 2010, 19:51
Sorry to bump this, I really need help figuring this out otherwise I can't even get started.

Maybe if you don't feel like answering my question, please reply with a link to some tutorial or example that would help me understand why my opengl calls are not working outside paintGL.

Sorry again for the bump and thanks in advance.

JohannesMunk
16th September 2010, 20:08
Hi!

To my knowledge that's exactly how it's supposed to work. Why do you want to mix philosophies here? paintGL is fine for pure raw openGL.

Use a widgets paintevent if you want to use QPainter. BTW: Qt's OpenGL QPainter implementation is quite good. So it might be a lot easier and more portable to use QPainter and use QGraphicsView with an OpenGL Viewport.

Have a look at this: http://www.qtcentre.org/threads/29995-QGraphicsScene-with-lots-of-static-items?p=140754&highlight=#post140754

Maybe you should describe what you want to do, and then we can find a solution.

Johannes

anon789
17th September 2010, 19:39
Hi JohannesMunk,

Basically I want to create an application to illustrate certain aspects of linear algebra : draw vectors, planes, vector/dot product, point closer to a line, etc. I am mostly doing this to learn, I love math et want to learn Qt and OpenGL to a higher level (this is the reason for mixing the philosophies).

I will have a look at the link you posted as soon as I get home and post back. Thanks a lot.

JohannesMunk
17th September 2010, 20:09
Ok! Then I would highly recommend to use the comfortable opengl wrapping that QPainter allows:

In another thread just yesterday I set up a simple OpenGL GraphicsView:

http://www.qtcentre.org/threads/34245-Render-QWidget-within-QGLWidget?p=158476#post158476

Instead of a button-widget you will add lots of custom QGraphicsItems for the different mathematical objects.

Use scene->addItem(new Vector(QVector3D(..)));



class Vector : public QGraphicsItem
{
public:
Vector(QVector3D a);
QRectF boundingRect() const{ return QRectF( ... ); }

void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
{
painter->drawLine(.. );
}
};


Let me know if you run into more problems!

Joh