PDA

View Full Version : 3 Dimensions using opengl



vermarajeev
9th April 2007, 08:09
Hi all,

I have implemented basic shapes using QFrame ,using normal painting. I want to
achieve the same using opengl & I will have an option in the menu for opengl. If the
user selects that option I want to redraw all the items on QFrame using opengl. How to achieve it using qt4??? or first off is that possible.

Thanks

aamer4yu
9th April 2007, 08:36
How about using QAbstractScrollArea and using the function QAbstractScrollArea::setViewport ?? to set the viewport to QGLWidget....
see the chips demo...

will it solve ur purpose ??

vermarajeev
12th April 2007, 11:09
How about using QAbstractScrollArea and using the function QAbstractScrollArea::setViewport ?? to set the viewport to QGLWidget....
see the chips demo...

will it solve ur purpose ??

I wrote a program which reads some data(line circle, polygon etc) through buttons.
For this I subclassed QAbstractScrollArea, reimplemented paintEvent() on viewport() to draw the items. But when I click circle button the display on viewport is very slow. There is so much of lag between drawings.
Can anyone please tell me why?????

Thanks

aamer4yu
12th April 2007, 12:11
cant say much... i was thinking of QGraphicsView.... as it is derived from QAbstractScrollArea

but forgot u are trying for 3 Dimensions :(

vermarajeev
12th April 2007, 13:26
Hi guys,
Please help!!!

I'm really having problem with this and I cannot move ahead. Please throw some light.

Thanks

jacek
12th April 2007, 18:58
http://nehe.gamedev.net/lesson.asp?index=01

vermarajeev
13th April 2007, 05:17
http://nehe.gamedev.net/lesson.asp?index=01

I know that site and I'm using it to learn opengl. It is a fantastic tutorial for newbie. Here is the toturial link http://digitalfanatics.org/projects/qt_tutorial/chapter14.html

But I want to know, when I use a QAbstractScrollArea why there is so much lag between displaying of items. I think the paintEvent is not called and requires some other event to occur to call it.
I tried using QFrame but unable to proceed further. I now thought to use QGraphicsView to see how it goes.

If you can tell me why there is a lag between displaying of items when I use QFrame, I'll be thankful to you.

Thanks

jacek
13th April 2007, 20:05
I tried using QFrame but unable to proceed further. I now thought to use QGraphicsView to see how it goes.
I'm not sure if I undertand your problem properly. Do you want to display those objects on QFrame and QGLWidget at the same time, or do you want to replace QFrame with QGLWidget?

vermarajeev
16th April 2007, 05:33
I'm not sure if I undertand your problem properly. Do you want to display those objects on QFrame and QGLWidget at the same time, or do you want to replace QFrame with QGLWidget?

I draw some objects on QFrame, now on click of a button say '3D Viewer', I want to display those objects on QGLWidget with 3D representation. This means that I already have 2D represntation of objects now I want to get 3D representation.

I just tried using QGraphicsView instead of QFrame by seeing the chips demo. When you see the chips demo, the objects are in 2D representation. Then you click some button 'openGl' the result is again 2D representation. Instead of 2D I want 3D such that I can see the object in all directions by rotating it.

Please see the attached file for more details.

Thanks and eagerly waiting for a reply

aamer4yu
16th April 2007, 05:47
do u mean rotating 2D objects in 3D space ??
if yes, u need to check this (http://labs.trolltech.com/blogs/2007/03/01/perspective-transformations-on-a-qgraphicsview)


also saw the image u gave... well as far as i got it, u work in 2D and want to show them in 3D.... well if u have fixes number of items, and know what items will be drawn, u can create a different view and add 3D objects to it. i guess a 2D item doesnt have any info how to draw itself in 3D,,,, while a 3D object can be scaled down to 2D projection.
hope i am in right direction in understanding ur problem....

and yeah, is ur 3D view editable ??? i mean do u want items to be manipulated in 3D view, or just show a 3D view of the items ??

vermarajeev
16th April 2007, 06:28
Hi aamer4yu,
Thanks for your reply


also saw the image u gave... well as far as i got it, u work in 2D and want to show them in 3D....
Yes you are in right path. I already have some 2D objects and want to show them in 3D.


well if u have fixes number of items, and know what items will be drawn, u can create a different view and add 3D objects to it
Is different view a QGlwidget???. If yes I tried it. But get only 2D view.
Now here is the main issue. How do I create a different view and add 3D objects to it. My sense says something like this

//GraphicsView

void graphicsView::paintEvent( QPaintEvent * event ){
QPainter painter(this);
paint( &painter );
}

void graphicsView::paint( QPainter* painter ){
//Draw the object you want
}

void graphicsView::on3DViewerButtonClick(){
m_glWid = new myGLWidget( this ); //here this is QGraphicsView
m_glWid->show();
}

Now I got graphicsView object in QGLWidget. How do I proceed further. I know I need to override

paintGL()
resizeGL()
initializeGL()
I can even use paintEvent in GLWidget and the call paint member of GraphicsView like this


void GLWidget::paintEvent( QPaintEvent * event ){
QPainter painter;
painter.begin(this);
m_graphicsView->paint(&painter);
painter.end();
}
But now I get 2D on QGLWidget.
Did you mean something like this. Or Is there something else.



and yeah, is ur 3D view editable ??? i mean do u want items to be manipulated in 3D view, or just show a 3D view of the items ??[/QUOTE]
Yes in some scenario. First I would be interested in representing a 2D object to 3D. If I succeed then move ahead for editing.

Hope I made some sense now. PLease let me know if still there is any confusion.

I'll go through the link you have given and see if I can get it.
Thanks

//I want through the link and could not find QTransform in qt4.2.2.

aamer4yu
16th April 2007, 07:39
i cudnt check the link example.... i dont have admin rights to install it in office.. will chk later when i get home..
also QTransform is a feature of 4.3 I guess ??

and i think u will have to implement a method for drawing ur 2D objects in 3D...but as ur future requirements, i wud say draw and edit in 3D ... u can get a 2D projection frm 3D...
for eg, u draw the objects in 3D.... zoom out a little, and the drawing will appear 2D from far...

rest i will say after seeing that example

jacek
16th April 2007, 12:57
I draw some objects on QFrame, now on click of a button say '3D Viewer', I want to display those objects on QGLWidget with 3D representation.
Can't you simply draw them on QGLWidget once in 2D and once in 3D?

vermarajeev
16th April 2007, 16:10
Can't you simply draw them on QGLWidget once in 2D and once in 3D?

No! Basically the user has an option to draw in 2D and view the result in 3D. If I need to use QGLWidget for both 2D and 3D then I'll have so much of rework to do. Is it not possible to use what is already existing?
Something like Just send the graphicsView object to QGLwidget and let it draw using opengl APIs.

Waiting eagerly.
Thanks

fullmetalcoder
16th April 2007, 16:23
Something like Just send the graphicsView object to QGLwidget and let it draw using opengl APIs.
This is not a bad idea if you know how to handle the OpenGL-based 3D drawing but consider using the QGraphicsScene object instead. ;)

vermarajeev
17th April 2007, 05:14
This is not a bad idea if you know how to handle the OpenGL-based 3D drawing but consider using the QGraphicsScene object instead. ;)

Jacek--> Can you please tell me how do I use QTranform as specified in the link above in qt4.2.2. I think QTranform should make work easier.

fullmetalcoder--> I have written a sample program can you please help me to represent a 2D object to 3D.

//GraphicsView

graphicsView::graphicsView(QGraphicsScene* s, QWidget *parent)
: QGraphicsView(s, parent), m_scene(s){
s->setItemIndexMethod(QGraphicsScene::NoIndex);
s->setSceneRect(-200, -200, 400, 400);

QPushButton* btnOPenGl = new QPushButton("OpenGL", this);
btnOPenGl->setGeometry( 300, 300, 50, 30 );
connect( btnOPenGl, SIGNAL( clicked() ), this, SLOT( onbtnOPenGlClick() ) );
}

graphicsView::~graphicsView()
{}

void graphicsView::onbtnOPenGlClick(){
GLWidget* GLwid = new GLWidget(this);
GLwid->show();
}

void graphicsView::drawBackground(QPainter *painter, const QRectF &rect){
Q_UNUSED(rect);
paint(painter);
}
void graphicsView::paint(QPainter* painter){
static const QPoint points[6] = {
QPoint(-30, -20),
QPoint(-70, 30),
QPoint(-30, 80),
QPoint(30, 80),
QPoint(70, 30),
QPoint(30, -20)
};
painter->drawPolygon(points, 6);
}

//QGLWidget

#include <QGLWidget>
#include "graphicsview.h"

class graphicsView;
class GLWidget : public QGLWidget
{
public:
GLWidget(graphicsView* gv, QWidget *parent=0 )
: QGLWidget( parent ), m_graphicsView(gv)
{}

protected:
void paintEvent( QPaintEvent* event ){
QPainter paint;
paint.begin(this);
m_graphicsView->paint(&paint);
paint.end();
}
/*void initializeGL()
{
glShadeModel(GL_SMOOTH);

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

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
void resizeGL( int width, int height )
{
height = height?height:1;

glViewport( 0, 0, (GLint)width, (GLint)height );

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glTranslatef(-1.5f,0.0f,-6.0f);

glBegin(GL_TRIANGLES);
glVertex3f( 0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd();
}*/
private:
graphicsView* m_graphicsView;
};

Thanks

minimoog
18th April 2007, 01:26
What kind of 2D objects do you want to represent with 3D version?

jacek
18th April 2007, 01:41
Can you please tell me how do I use QTranform as specified in the link above in qt4.2.2. I think QTranform should make work easier.
If I understand your problem correctly, QTransform won't help you --- after you apply QTransform your object still will be flat.

minimoog
18th April 2007, 13:35
Lines in 2D can be represented in 3D with simple lines or cylinder.

For simple lines you can use glBegin(GL_LINES), glBegin(GL_LINESTRIP) or glBegin(GL_LINE_LOOP).


glBegin(GL_LINE_STRIP);
glVertex2f(from_x, from_y);
glVertex2f(to1_x, to1_y);
glVertex2f(to2_x, to2_y);
....
glEnd();

This will draw simple connected line, which can be easily rotated.

vermarajeev
18th April 2007, 14:09
Lines in 2D can be represented in 3D with simple lines or cylinder.

For simple lines you can use glBegin(GL_LINES), glBegin(GL_LINESTRIP) or glBegin(GL_LINE_LOOP).


glBegin(GL_LINE_STRIP);
glVertex2f(from_x, from_y);
glVertex2f(to1_x, to1_y);
glVertex2f(to2_x, to2_y);
....
glEnd();

This will draw simple connected line, which can be easily rotated.

So you mean to say, I need to redraw the objects again in 3D.
Actually I dont want to redraw the things again.
Anyway since I'm not able to get the what I want I should atleast see how your logic works. Can you please help me to achieve what you have suggested in the above sample program that I have posted.

Thanks

jacek
18th April 2007, 21:42
Actually I dont want to redraw the things again.
It won't happen all by itself. It's much easier to simply draw that molecule again in 3D than convert a 2D image to 3D one. First you need some kind of a representation, for example a set of segments. Then you can draw it in whatever form you like.

minimoog
19th April 2007, 02:16
Well, you have to draw it again.

QPainter when is using OpenGl is doing the similar thing like in my code example. It's just sends triangles to opengl using orthographic projection. But you cannot access QPainter OpenGL projection and modelview matrix (of course, you can change the source code if you want it), so you must redraw in 3D all that stuff. That's why I asked you what kind of 2D objects you want to represent in 3D.


void paintGL()
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

static const QPoint points[6] = {
QPointF(-3, -2),
QPointF(-7, 3),
QPointF(-3, 8),
QPointF(3, 8),
QPointF(7, 3),
QPointF(3, -0) };

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glTranslatef(0.0, 0.0, -5.0);

glBegin(GL_LINE_LIST);

for(int i = 0 ; i < 6; i++){
glVertex2f(points[i].x, points[i].y);
}

glEnd();
}

Maybe there are some errors...

vermarajeev
19th April 2007, 05:30
It won't happen all by itself. It's much easier to simply draw that molecule again in 3D than convert a 2D image to 3D one. First you need some kind of a representation, for example a set of segments. Then you can draw it in whatever form you like.

Ok Here is the class representation of 2D objects drawn on QGraphicsView.


class DrawMolecule : public ChemObject
{}
class DrawAtom : public ChemObject
{}//
class DrawBond : public ChemObject
{}//
Here ChemObject is a pure Virtual class inherited from QObject which provides an interface to draw an atom, bonds. The combination of atoms and bonds forms a molecule.
Jacek I think you were talking about this. Please suggest.

minimoog--> Thanks for your sample program but there are some errors as you mentioned. M trying to rectify. Thanks again

Jacek, you are a multitasking human being (really good at chemistry too). Fabulous!!!

jacek
20th April 2007, 02:21
Jacek I think you were talking about this.
Yes, now you have to add routines that will draw each of those objects. Take a look at gluSphere() and gluCylinder() functions.

You can add QGraphicsView and QGLWidget to QStackedWidget, so you can switch between the 2D and 3D view easily.

vermarajeev
20th April 2007, 05:11
Yes, now you have to add routines that will draw each of those objects. Take a look at gluSphere() and gluCylinder() functions.

You can add QGraphicsView and QGLWidget to QStackedWidget, so you can switch between the 2D and 3D view easily.

Hi jackek,
Thanks for your suggestions. I'll take a look at those examples and see how I can solve the problem. Thanks a lot. Will keep you updating.

Thanks

vermarajeev
20th April 2007, 12:29
Hi Jacek,
I did a sample program to convert 2D to 3D. I have not used any representation but just a sample. I'll make use of DrawAtom, DrawBond and DrawMolecule classes once I'm perfect with what I have to do. Anyway below is the code. Please tell me if I'm going anywhere wrong. Also when I draw two or more polygons, they are not displayed in exact positions as they appear in 2D.

I have a zipped file.

Steps to follow once the progrma is executed:
1) Click on 'Draw Poly'.
2) Release the mouse on GraphicsView. It will draw a polygon. If you want two or more
polygon then again click 'Draw Poly' and then release mouse and so on.
3) Once there are polygons on GraphicsView click 'opengl' to get the 3D View.

Please help me to improve my code. Also the positions of polygons in 3D are not same as 2D
Thanks

pdolbey
20th April 2007, 19:38
I've put the QGraphicsView/Scene into a consistent coordinate system with OpenGL i.e.

Y
^
|
+---> X

I've switched you to a orthographic projection - always better for scientific stuff. The OpenGL viewport coordinates are mapped to the scenegraph, and I've changed the graphics object to use a 2:1 ratio triangle - much easier to see the mappings with this.

Seems to work.

Pete

vermarajeev
21st April 2007, 06:24
Hi Pete,
Thanks a lot.

Good one. Now since I have a orthigraphic projection view it is also possible to create actual 3D view from 2D. Wow!!!!

Thanks
Any more comments. :rolleyes:

But there is one flaw. When I move the triangle in 360 degrees, some portion is not displayed. What is it so?

pdolbey
21st April 2007, 10:46
It'll be because I've set an arbitratry near and far plane of -100 to 100. The -100 should be behind the view point, its probably the far plane thats clipping try 1000.

The near and far planes help OpenGL clamp the depth calcuations.

But in terms of comments, have you considered using a scene graph component instead just using raw OpenGL - for instance VTK (http://www.kitware.com), Coin3D (http://www.coin3d.org), OpenSG, Open SceneGraph (no they're not the same) and so on. There a vid presetantion in Coin3d on the TrollTech site at http://www.trolltech.com/company/newsroom/events/allevents/devdays2006/videolinks - its the "High-Level 3D Programming using Open Inventor API and Qt" link.

One final thing - if you have lots of specific OpenGL questions, its worth joing the forum at http://www.opengl.org as well (if you haven't already).

Pete

vermarajeev
23rd April 2007, 05:42
Hi pete,
Thanks for your information.

pdolbey
23rd April 2007, 12:31
I took another look at my sample this morning and its still not quite right wrt coordinate systems. I'll have another play with it this evening.

Pete