Resizing a widget !!



  • I have subclassed QGLWidget. I m showing it from the main itself.
    But when I maximize the window the graphics that i have created wipes out.
    I tried using resize as well... But it din seem to work.
    Where might I have gone wrong??



  • What is in your resizeGL, paintGL AND initializeGL methods?
    Not sure, Need to see your code, but it seems the problem is that you are not drawing anything or you are doing something wrong when resizeGL is called.



  • @#include <QtOpenGL/qgl.h>
    #include <QtCore/qvector.h>
    #include <QtGui/qmatrix4x4.h>
    #include <QtGui/qvector3d.h>
    #include <QtGui/qvector2d.h>
    #include <QApplication>

    #include "mainwindow.h"

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    OGLPort w;
    w.resize(640,480);
    w.show();
    return a.exec();
    }
    @

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QPushButton>
    #include <QGridLayout>
    #include <QtOpenGL>
    #include <QDialog>

    class OGLPort : public QGLWidget
    {
    Q_OBJECT

    public:
    OGLPort(QWidget *parent = 0);

    protected:
    void paintGL();
    void resizeGL(int w,int h);
    void timerEvent(QTimerEvent *);

    private:
    QPushButton *button;
    QGLFramebufferObject *render_fbo;
    QGLFramebufferObject *texture_fbo;
    };

    #endif // MAINWINDOW_H
    @

    @#include "mainwindow.h"
    #include <GL/glut.h>

    OGLPort::OGLPort(QWidget *parent) :
    QGLWidget(parent)
    {
    setWindowTitle("My OpenGL Trial");
    }

    void OGLPort::paintGL()
    {
    glColor3f (1.0, 1.0, 1.0);
    glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);

    glBegin(GL_POLYGON);
    {
        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 OGLPort::resizeGL(int w, int h)
    {
    int side = qMin(w, h);
    glViewport(((w - side)/2), ((h -side)/2), side, side);
    }

    void OGLPort::timerEvent(QTimerEvent *)
    {
    update();
    }
    @



  • Hello,

    I have tested your code. It seems that you are not setting the matrix appropriately...

    Try this, worked here:
    @void OGLPort::resizeGL(int w, int h)
    {
    int side = qMin(w, h);
    glViewport(((w - side)/2), ((h -side)/2), side, side);
    //Reconfig model view and projection matrixes
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, 1.0, 0.0, 1.0, 1.0, -1.0f);
    glMatrixMode(GL_MODELVIEW);
    }

    void OGLPort::initializeGL()
    {
    //Reconfig model view and projection matrixes
    glViewport(0, 0, 640, 480);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, 1.0, 0.0, 1.0, 1.0, -1.0f);
    glMatrixMode(GL_MODELVIEW);
    }@

    Also, you don't need to use glut, remember you now have Qt. If something is missing, use glu and opengl libs (or gl_es if you are not using desktop).

    Finally, remember that if you need you can separate QMainWindow and OGLPort implementations (testing purposes, comparisons, different OGLPorts with different stuff, etc).

    Regards,



  • Well.., Resizing in the sense, whatever is rendered is going off when I try to reduce/increase the window size. I dont see much change with reference to that. I am sure it's something to do with Qt functions and not GL. And Yeah, Glut was redundant :-) Thanks.



  • Now that is weird... your code wasn't also working here.
    Make sure you have made all the changes. I am not sure that the problem is Qt, things are working here with this changes and a few others solve the problem:

    First, but not that important:
    Use updateGL() instead of update(), this does not make difference in my code here, but updateGL calls paintGL in the documentation.

    glViewport has to do with the pixels and where are they.
    glOrtho is about how they translate into coordinates of your drawing, i.e., how they project your drawing on the screen the screen.

    • You seem to understand that, but you are not calling the correct matrix at the right times.

    Remember that this functions are applied to the current matrix you are using. In opengl there are states, and one of these states is the current matrix in use. It implies what is the current matrix, the two of highest importance are GL_PROJECTION and GL_MODELVIEW.

    The projection matrix has to do with the choice of perspective/orthographic transformation (EDIT: and their projection on the screen how to project the cube/view you have specified on the screen) and the modelview has to do with objects ( EDIT: postition, rotation, etc.->applied to your vertex in object space). If you do not change the matrix to modelview, for instance, problems are going to happen since you will move objects using wrong matrix/transformation, That is, your points are going to be transformed according to the transformation you did, going to somewhere you did not intended.

    Also, in your original code you did not instanced a initializeGL method as required by the specification.

    I know, annoying and probably predictable bla bla bla sorry for that. Anyway, put down your new code here again and I will compare it to mine and see what is wrong.



  • @#include "mainwindow.h"
    //#include <GL/glut.h>

    OGLPort::OGLPort(QWidget *parent) :
    QGLWidget(parent)
    {
    setWindowTitle("My OpenGL Trial");
    }

    void OGLPort::paintGL()
    {
    glColor3f (1.0, 1.0, 1.0);
    glBegin(GL_POLYGON);
    {
    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 OGLPort::resizeGL(int w, int h)
    {
    int side = qMin(w, h);
    glViewport(((w - side)/2), ((h -side)/2), side, side);
    //Reconfig model view and projection matrixes
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, 1.0, 0.0, 1.0, 1.0, -1.0f);
    glMatrixMode(GL_MODELVIEW);
    }

    void OGLPort::initializeGL()
    {
    //Reconfig model view and projection matrixes
    glViewport(0, 0, 640, 480);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, 1.0, 0.0, 1.0, 1.0, -1.0f);
    glMatrixMode(GL_MODELVIEW);
    }

    void OGLPort::timerEvent(QTimerEvent *)
    {
    updateGL();
    }@



  • @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QPushButton>
    #include <QGridLayout>
    #include <QtOpenGL>
    #include <QDialog>

    class OGLPort : public QGLWidget
    {
    Q_OBJECT

    public:
    OGLPort(QWidget *parent = 0);

    protected:
    void paintGL();
    void resizeGL(int w, int h);
    void initializeGL();
    void timerEvent(QTimerEvent *);
    //void resizeEvent(QResizeEvent *Event);

    private:
    QPushButton *button;
    QGLFramebufferObject *render_fbo;
    QGLFramebufferObject *texture_fbo;
    };

    #endif // MAINWINDOW_H@



  • @#include <QtOpenGL/qgl.h>
    #include <QtCore/qvector.h>
    #include <QtGui/qmatrix4x4.h>
    #include <QtGui/qvector3d.h>
    #include <QtGui/qvector2d.h>
    #include <QApplication>

    #include "mainwindow.h"

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    OGLPort w;
    w.resize(640,480);
    w.show();
    return a.exec();
    }@



  • I am posting your code with my changes, please check if you and I are missing something. It surely works here.



  • Dear Friend, I m sorry, I changed simple square to a complex cube.., The GL_PROJECTION and GL_MODELVIEW is making it more complicated... updateGL makes no difference..
    Are you sure that the Object is being resized with the window size? :-o :-o ????

    My present code is as follows

    @#include "mainwindow.h"
    #include <GL/glut.h>

    OGLPort::OGLPort(QWidget *parent) :
    QGLWidget(parent)
    {
    setWindowTitle("My OpenGL Trial");
    }

    void OGLPort::paintGL()
    {
    GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. /
    GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /
    Infinite light location. /
    GLfloat n[6][3] = { /
    Normals for the 6 faces of a cube. /
    {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
    {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} };
    GLint faces[6][4] = { /
    Vertex indices for the 6 faces of a cube. */
    {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
    {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} };
    GLfloat v[8][3];

        /* Setup cube vertex data. */
        v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
        v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
        v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
        v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
        v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
        v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
    
    
    
        /* Enable a single OpenGL light. */
        glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
        glLightfv(GL_LIGHT0, GL_POSITION, light_position);
        glEnable(GL_LIGHT0);
        glEnable(GL_LIGHTING);
    
        /* Use depth buffering for hidden surface elimination. */
        glEnable(GL_DEPTH_TEST);
    
        /* Setup the view of the cube. */
        glMatrixMode(GL_PROJECTION);
        gluPerspective( /* field of view in degree */ 40.0,
        /* aspect ratio */ 1.0,
        /* Z near */ 1.0, /* Z far */ 10.0);
        glMatrixMode(GL_MODELVIEW);
        gluLookAt(0.0, 0.0, 4.0,  /* eye is at (0,0,5) */
        0.0, 0.0, 0.0,      /* center is at (0,0,0) */
        0.0, 1.0, 0.);      /* up is in positive Y direction */
    
        /* Adjust cube position to be asthetic angle. */
        glTranslatef(0.0, 0.0, -1.0);
        glRotatef(60, 1.0, 0.0, 0.0);
        glRotatef(-20, 0.0, 0.0, 1.0);
        glRotatef(-50, 0.0, 0.0, 1.0);
    
    
    
    
        for (int i = 0; i < 6; i++)
        {
        glBegin(GL_QUADS);
            {
                glNormal3fv(&n[i][0]);
                glVertex3fv(&v[faces[i][0]][0]);
                glVertex3fv(&v[faces[i][1]][0]);
                glVertex3fv(&v[faces[i][2]][0]);
                glVertex3fv(&v[faces[i][3]][0]);
                glEnd();
            }
        }
    

    }

    void OGLPort::resizeGL(int w, int h)
    {
    int side = qMin(w, h);
    glViewport(((w - side)/2), ((h -side)/2), side, side);
    }

    void OGLPort::initializeGL()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    }

    void OGLPort::resizeEvent(QTimerEvent *)
    {
    updateGL();
    }
    @



  • My requirement is that the cube that is seen has to remain at least intact ,if not resize with the window size!! :-)



  • If you have not done that, please copy and paste my code into your environment and see if it works for you. And tell me.

    The matrix stuff is important. Your previous code was showing the EXACT behavior you mentioned in my environment. After my changes over here, things really started to work (the square does not disappear anymore and it is now always a square independently of the window resizing size. To document it in case it is a platform bug I am placing the resulting image in the forum, this is a test with Windows 64 msvc-2010 build "here":http://www.cwldalgorithm.com/other-stuff
    As you probably might see, the square makes exactly as you want here...

    Your new code also DOES NOT work in my environment either. But in this new scenario there are lots of new details to check (light, normals, vertex transformations, etc.), so lets keep it simple ok? First let's see if your bug persists with the first example.

    Once we resolve the former problem, we will move to next, ok?



  • Also forgot to mention. Since you don't have a timer started, you don't need to catch this event. yet.

    Also, your matrix, if not set, will have OS/driver default values (don't know what value) for those matrix... so please, do not forget to set
    @glLoadIdentity();@
    to clean all the matrix data, otherwise you might probably load garbage and transform your vertex using it :-)



  • Could not resist the temptation...

    @#include "mainwindow.h"

    OGLPort::OGLPort(QWidget *parent) :
    QGLWidget(parent)
    {
    setWindowTitle("My OpenGL Trial");
    }

    void OGLPort::paintGL()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0};  /* Red diffuse light. */
        GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};  /* Infinite light location. */
        GLfloat n[6][3] = {  /* Normals for the 6 faces of a cube. */
        {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
        {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} };
        GLint faces[6][4] = {  /* Vertex indices for the 6 faces of a cube. */
        {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
        {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} };
        GLfloat v[8][3];
    
    
        /* Setup cube vertex data. */
        v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
        v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
        v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
        v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
        v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
        v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
    
    
    
        /* Enable a single OpenGL light. */
        glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
        glLightfv(GL_LIGHT0, GL_POSITION, light_position);
        glEnable(GL_LIGHT0);
        glEnable(GL_LIGHTING);
    
        /* Setup the view of the cube. */
        glMatrixMode(GL_PROJECTION);
    

    glLoadIdentity();
    gluPerspective( /* field of view in degree / 40.0,
    /
    aspect ratio / 1.0,
    /
    Z near / 1.0, / Z far / 10.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0, 0.0, 4.0, /
    eye is at (0,0,5) /
    0.0, 0.0, 0.0, /
    center is at (0,0,0) /
    0.0, 1.0, 0.); /
    up is in positive Y direction */

        /* Adjust cube position to be asthetic angle. */
        glTranslatef(0.0, 0.0, -1.0);
        glRotatef(60, 1.0, 0.0, 0.0);
        glRotatef(-20, 0.0, 0.0, 1.0);
        glRotatef(-50, 0.0, 0.0, 1.0);
    
    
    
    
        for (int i = 0; i < 6; i++)
        {
        glBegin(GL_QUADS);
            {
                glNormal3fv(&n[i][0]);
                glVertex3fv(&v[faces[i][0]][0]);
                glVertex3fv(&v[faces[i][1]][0]);
                glVertex3fv(&v[faces[i][2]][0]);
                glVertex3fv(&v[faces[i][3]][0]);
                glEnd();
            }
        }
    

    }

    void OGLPort::resizeGL(int w, int h)
    {
    int side = qMin(w, h);
    glViewport(((w - side)/2), ((h -side)/2), side, side);
    }

    void OGLPort::initializeGL()
    {
    /* Use depth buffering for hidden surface elimination. */
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    }@

    See if it works....



  • Finally, your normals do not seem to be correct:
    Try that:
    @ GLfloat n[6][3] = { /* Normals for the 6 faces of a cube. */
    {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
    {0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}, {0.0, 0.0, 1.0} };@

    And for your light, try this, will provide better results:
    @
    GLfloat light_diffuse[] = {0.60, 0.0, 0.0, 1.0}; /* Red diffuse light. /
    GLfloat light_ambient[] = {0.10, 0.0, 0.0, 1.0}; /
    Red ambient light. /
    GLfloat light_specular[] = {0.30, 0.0, 0.0, 1.0}; /
    Red especular light. /
    GLfloat light_position[] = {5.0, 5.0, 15.0, 1.0}; /
    Infinite light location. better to see your cube*/

        /* Enable a single OpenGL light. */
        glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    

    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glEnable(GL_LIGHT0);
    @

    My result is shown "here":https://sites.google.com/a/cwldalgorithm.com/www/other-stuff:

    Very Best Regards,



  • Yeah It worked. I should have known the weight of glLoadIdentity() and glClear() :P

    Thank you so much VitorAMJ for the help....

    But tell me why the same application on OpenSolaris is crashing...?? How can i be sure that my OpenSoalris supports OpenGL Applications...?? What Libraries should I look for??



  • Hey, this is something I really don't thing it's easy to discover.

    The one thing you must be careful is the render context. You can only call
    @ glSomething(etc, etc)@
    if you are inside a GL render context. In Qt you are sure you are inside a render context when inside resizeGL, initializeGL and PaintGL. Otherwise you will experience errors. If you want to call GL functions outside these specialized methods you must first call:
    @QGLWidget::makeCurrent()@
    otherwise you must do that yourself, and then
    @QGLWidget::doneCurrent()@
    when finished.

    I am not a OpenSolaris user... in fact, I gave up Unix like systems some time ago. But from what I know, at least for Linux there is a thing called glx (the opengl extensions created by nvidia I think). I believe you must have a packet manager that is able to download it

    But first check if you already have it, type glxgears in the command line.

    I also googled your question and found this "website":http://www.sunshack.org/data/sh/2.1.2/infoserver.central/data/syshbk/collections/intinfodoc/22171.html

    Remember OpenGL is now using version 4.2, and it has changed a lot these last ~2 years (going from version 2->3->4). Many of the features of opengl (including function calls, defines, etc.) are only available through extension packages. Also, some old cards do not support later versions of OpenGL, unless you upgrade the driver, other cards do not support these later versions at all (too old).

    Also, there is always the Khronos Group "OpenGL website":http://www.opengl.org/ for further reference.

    Finally, as you can see there are plenty of stuff that might be going wrong. You must first make sure you are using a good card, a recent driver, calling the correct OpenSolaris/Unix libs and also making sure your card supports the things you are doing.

    I hope this helps.



  • Hi,
    I have problem:
    I would like to use mouse to resize QWidget which have set parent = MainWindow like it have set parent = 0 . How I can do this?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Please open a new thread rather than posting on an old one (2 years+) that is not directly related to your question.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.