[Code] QTOpenGL flackert bzw. keine richtige Darstellung

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von C4rc4ss, 15. September 2009 .

  1. 15. September 2009
    QTOpenGL flackert bzw. keine richtige Darstellung

    Hi Leute,
    ich bin grad an einem größeren Projekt dran und habe jetzt auf Grund von Umstellungen das ganze auf Qt portiert.
    Eigentlich funktioniert bis jetzt auch alles. Nur das OpenGLWidget macht mir zu schaffen.
    Und zwar werden meine Objekte nicht richtig dargestellt. Nur das obere Drittel des Objekts wird richtig dargestellt, der Rest wird entweder mit einem schwarzen Dreicksmuster oder manchmal auch garnicht dargestellt.

    Meine QT-Headerdatei:
    PHP:
    #ifndef DMainWindow_h
    #define DMainWindow_h

    //////////////////////////////////////////////////////
    //        QT-Headers
    #include <QWidget>
    #include <QMainWindow>
    #include <QFrame>
    #include <QTextEdit>
    #include <QAction>
    #include <QMenu>            
    #include <QLayout>    
    #include <QTimer>    
    #include <Qt>
    #include <QFileDialog>


    //////////////////////////////////////////////////////
    //        QT-OpenGL-Header
    #include <QtOpenGL>                                    //QT - OpenGL - Header

    //////////////////////////////////////////////////////
    //        GL-Headers
    #include <GL/gl.h>                                    //OpenGL - Header
    #include <GL/glu.h>                                    //GLU - Header

    /////////////////////////////////////////////////////
    //        Deformer Headers
    #include "DAction.h"
    #include "DPhysics.h"

    /////////////////////////////////////////////////////
    //        Pragma - Comments
    #ifndef GL_MULTISAMPLE
    #define GL_MULTISAMPLE  0x809D
    #endif

    //////////////////////////////////////////////////////
    //                OpenGL - Class

    class  DOpenGL  : public  QGLWidget
    {
        
    Q_OBJECT

        
    public:
            
            
    DOpenGL  QWidget  * _parent  );
            ~
    DOpenGL  ();
            
    int frames ;
            
    virtual void keyPressEvent  QKeyEvent  * );
                                                                
                                                        
    //World
            
    DWorld          * world ;
            
        protected:
            
            
    virtual void initializeGL  ();
            
    virtual void resizeGL  ( int _width int _height );
            
    virtual void paintGL  ();    
            
        public 
    slots :
            
    void Update  ();
    };

    //////////////////////////////////////////////////////
    //            Window - Class

    class  DMainWindow  : public  QMainWindow 
    {
        
    Q_OBJECT
                
        
    private:
            
    void BuildWindow  ();
                                                        
    //Window-Decoration
            
    QFrame          * frmLog ;
            
    QFrame          * frmOpenGl ;
            
    QTextEdit     * txteLog ;
            
    QTextEdit     * txteChange ;
            
    QMenu          * mnFile ;
            
    QMenu         * mnObject ;
            
    QAction         * actClose ;
            
    QAction         * actAdd ;
            
    DOpenGL         * dGLWidget ;
            
    QHBoxLayout  * blOpenGLWidget ;
            
    QTimer         * tiDraw ;
            
    QTimer         * tiFramesCount ;

        public:
                                                        
    //Constructor & Destructor
            
    DMainWindow  QWidget  * _parent  );
            ~
    DMainWindow  ();
                                                        
    //Print Text 
            
    void PrintText char  * _text QTextEdit  * _txteOutput  );
                                                        
    //Return Attributes
            
    QTextEdit TxteLog  ()  { return  txteLog ; }
            
    QTextEdit TxteChange  ()  { return  txteChange ; }
                                                        
    //EventHandels
            
    void paintEvent  QPaintEvent * );
            
    void mouseMoveEvent  QMouseEvent * );
            
    void mousePressEvent  QMouseEvent * );
            
    void mouseReleaseEvent  QMouseEvent * );
            
    void keyPressEvent  QKeyEvent * );

            
        private 
    slots :
            
    void AddObject  ();
            
    void Update  ();
            
    void FramesCount  ();
            
    void StopTimer  ();
            
    void StartTimer  ();
    };


    #endif                 //DMainWindow_h

    Und meine Cpp-Datei dazu:
    PHP:
    #include <QMenuBar>
    #include <QApplication>

    #include "DMainWindow.h"

    //////////////////////////////////////////////////////
    //            OpenGL - Class
    DOpenGL :: DOpenGL QWidget _parent  )
        : 
    QGLWidget QGLFormat QGL :: DoubleBuffer  /*| QGL::AlphaChannel*/  QGL :: DepthBuffer  ) , _parent  )
    {
        
    setAutoBufferSwap ( true );
        
    makeCurrent ();
        
    world  = new  DWorld (- 5 );
        
        
    world -> ground  = new  DObject );
        
    world -> ground -> LoadObject  "Data/ground.obj"  );
        
        
    frames  0 ;
    }

    DOpenGL ::~ DOpenGL  () 
    {
        
    delete world ;    
    }

    void DOpenGL :: initializeGL  ()
    {
        
    glShadeModel ( GL_SMOOTH );                             //Enable Smooth Shading
        
    glClearColor 0.0f 0.0f 0.0f 0.0f  );                 //Black Background
        
    glClearDepth ( 1.0f );                                     //Depth Buffer Setup
        
    glEnable ( GL_DEPTH_TEST );                             //Enables Depth Testing
        
    glDepthFunc ( GL_LEQUAL );                                 //The Type Of Depth Testing To Do
        
    glHint ( GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST );     //Really Nice Perspective Calculations    
                                                            //Initialization Went OK    
    }

    void DOpenGL :: resizeGL  ( int _width int _height )
    {
        if ( 
    _height  ==  )
            
    _height  1 ;
        
    glViewport ( 0 , 0 , _width _height );
        
        
    glMatrixMode ( GL_PROJECTION );                     //Select The Projection Matrix
        
    glLoadIdentity ();                                 //Reset The Projection Matrix

        
    gluPerspective ( 45.0f ,( GLfloat ) _width /( GLfloat ) _height , 0.1f , 100.0f );


        
    glMatrixMode ( GL_MODELVIEW );                         //Select The Modelview Matrix
        
    glLoadIdentity ();                                 //Reset The Modelview Matrix
        
    }

    void DOpenGL :: paintGL  ()
    {
        
        
    glMatrixMode  GL_MODELVIEW  );
        
    glColor3f 1.0f 1.0f 1.0f  );
        
    glClear ( GL_COLOR_BUFFER_BIT  GL_DEPTH_BUFFER_BIT );     //Clear Screen And Depth Buffer
        
    glLoadIdentity ();    
        
        
        
    glRotated  world -> RotationY  (),  1.0 0.0 0.0  );
        
    glRotated  world -> RotationX  (),  0.0 1.0 0.0  );
        
        
    glTranslatef world -> TranslationX (),  0.0f world -> TranslationZ () );
        
    world -> ground -> RenderObject ();
        
        
    glTranslatef 0.0f world -> TranslationY (),  0.0f  );
        
        
    world -> Culling () ?  glEnable GL_CULL_FACE  ) :  glDisable  GL_CULL_FACE  );
        
    world -> Light () ?  glEnable  GL_LIGHTING  ) :  glDisable  GL_LIGHTING  );
        
    world -> Wireframe () ?  glPolygonMode  GL_FRONT_AND_BACK GL_LINE  ) :  glPolygonMode  GL_FRONT_AND_BACK GL_FILL  );
        
        
    glBegin GL_QUADS  );
            
    glVertex3f  1.0f 1.0f 0.0f  );
            
    glVertex3f  1.0f , - 1.0f 0.0f  );
            
    glVertex3f  ( - 1.0f , - 1.0f 0.0f  );
            
    glVertex3f  ( - 1.0f 1.0f 0.0f  );
        
    glEnd  ();    
        
        
    glColor3f  1.0f 0.0f 0.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  ();
        
        if ( 
    world -> anchor  !=  NULL  ) {
            
    DObjectKnot  * tObject  world -> anchor ;
            while ( 
    tObject  !=  NULL  ) {
                
    tObject -> object -> RenderObject ();
                
    tObject  tObject -> next ;
            }
        }
        
            
        
    glDisable  GL_CULL_FACE  );
        
    glDisable  GL_LIGHTING  );
        
    glPolygonMode  GL_FRONT_AND_BACK GL_FILL  );
        
        
    frames ++;
    }

    void DOpenGL :: Update  ()
    {    
        
    updateGL  ();
    }

    void DOpenGL :: keyPressEvent QKeyEvent _event  )
    {
                                                        
    //Get Attributes from world
        
    float rotationX  world -> RotationX (),  rotationY  world -> RotationY ();
        
    float translationX  world -> TranslationX (),  translationY  world -> TranslationY (),  translationZ  world -> TranslationZ ();
        
    bool physic  world -> Physic (),  wireframe  world -> Wireframe (),  light  world -> Light (),  culling  world -> Culling ();
                                                        
    //Handle KeyCallbacks
        
    switch (  _event -> key () ) {
            
            case 
    Qt :: Key_W : {
                
    translationX  += (float) sin (- rotationX *( D_PI / 180 )) *  0.05f  * (float) cos ( rotationY *( D_PI / 180 ));
                
    translationZ  += (float) cos (- rotationX *( D_PI / 180 )) *  0.05f  * (float) cos ( rotationY *( D_PI / 180 ));
                if ( ( 
    translationY  <=  0.0  ) && (  translationY  >= - 150.0  ) )
                    
    translationY  -= (float) sin (- rotationY *( D_PI / 180 )) *  0.03f ;    
                break;
            }
            
            case 
    Qt :: Key_Up : {
                
    translationX  += (float) sin (- rotationX *( D_PI / 180 )) *  0.05f  * (float) cos ( rotationY *( D_PI / 180 ));
                
    translationZ  += (float) cos (- rotationX *( D_PI / 180 )) *  0.05f  * (float) cos ( rotationY *( D_PI / 180 ));
                if ( ( 
    translationY  <=  0.0  ) && (  translationY  >= - 150.0  ) )
                    
    translationY  -= (float) sin (- rotationY *( D_PI / 180 )) *  0.03f ;    
                break;
            }    
                
            case 
    Qt :: Key_S : {
                
    translationX  -= (float) sin (- rotationX *( D_PI / 180 )) *  0.05f  * (float) cos ( rotationY *( D_PI / 180 ));
                
    translationZ  -= (float) cos (- rotationX *( D_PI / 180 )) *  0.05f  * (float) cos ( rotationY *( D_PI / 180 ));
                if ( ( 
    translationY  <=  0.0  ) && (  translationY  >= - 150.0  ) )
                    
    translationY  += (float) sin (- rotationY *( D_PI / 180 )) *  0.03f ;
                break;
            }
            
            case 
    Qt :: Key_Down : {
                
    translationX  -= (float) sin (- rotationX *( D_PI / 180 )) *  0.05f  * (float) cos ( rotationY *( D_PI / 180 ));
                
    translationZ  -= (float) cos (- rotationX *( D_PI / 180 )) *  0.05f  * (float) cos ( rotationY *( D_PI / 180 ));
                if ( ( 
    translationY  <=  0.0  ) && (  translationY  >= - 150.0  ) )
                    
    translationY  += (float) sin (- rotationY *( D_PI / 180 )) *  0.03f ;
                break;
            }
            
            case 
    Qt :: Key_D : {
                
    translationX  -= (float) cos (- rotationX *( D_PI / 180 )) *  0.05f ;
                
    translationZ  += (float) sin (- rotationX *( D_PI / 180 )) *  0.05f ;
                break;
            }
            
            case 
    Qt :: Key_Right : {
                
    translationX  -= (float) cos (- rotationX *( D_PI / 180 )) *  0.05f ;
                
    translationZ  += (float) sin (- rotationX *( D_PI / 180 )) *  0.05f ;
                break;
            }
            
            case 
    Qt :: Key_A : {
                
    translationX  += (float) cos (- rotationX *( D_PI / 180 )) *  0.05f ;
                
    translationZ  -= (float) sin (- rotationX *( D_PI / 180 )) *  0.05f ;
                break;
            }
            
            case 
    Qt :: Key_Left : {
                
    translationX  += (float) cos (- rotationX *( D_PI / 180 )) *  0.05f ;
                
    translationZ  -= (float) sin (- rotationX *( D_PI / 180 )) *  0.05f ;
                break;
            }
            
            case 
    Qt :: Key_F1 : {
                
    light  = ! light ;
                break;
            }
            
            case 
    Qt :: Key_F2 : {
                
    culling  = ! culling ;
                break;
            }
            
            case 
    Qt :: Key_F3 : {
                
    wireframe  = ! wireframe ;
                break;
            }
                        
            case 
    Qt :: Key_F4 : {
                
    physic  = ! physic ;
                break;
            }
        }    
                                                        
    //Set Attributes again
        
    world -> SetTranslationX  translationX  );
        
    world -> SetTranslationY  translationY  );
        
    world -> SetTranslationZ  translationZ  );
        
    world -> SetCulling  culling  );
        
    world -> SetLight  light  );
        
    world -> SetWireframe  wireframe  );
        
    world -> SetPhysic  physic  );

        
    Update ();
    }


    //////////////////////////////////////////////////////
    //            Window - Class

    DMainWindow :: DMainWindow  QWidget  * _parent  ) :  QMainWindow  _parent 
    {
      
    move  0 0 );
      
    setFixedSize  1280 972 );
      
      
    BuildWindow  ();
    }

    DMainWindow ::~ DMainWindow  () 
    {
        
    delete dGLWidget ;
    }

    void DMainWindow :: BuildWindow  ()
    {
       
    frmOpenGl  = new  QFrame  this  );
       
    frmOpenGl -> setGeometry ( 0 , 20 , 1080 , 952 );    
       
    frmOpenGl -> setFrameStyle ( QFrame :: Panel  QFrame :: Sunken );
       
    frmOpenGl -> setLineWidth ( 0 );
      
       
    frmLog  = new  QFrame this  );
       
    frmLog -> setGeometry ( 1080 , 20 , 200 , 952 );
       
    frmLog -> setFrameStyle QFrame :: Panel  QFrame :: Sunken );
       
    frmLog -> setLineWidth ( 0 );

       
    txteLog  = new  QTextEdit frmLog  );
       
    txteLog -> setGeometry ( 0 , 0 , 200 , 552 );
       
    txteLog -> setReadOnly  true  );
       
    txteLog -> setFontUnderline true  );
       
    txteLog -> append  ( "Log" );
       
    txteLog -> setFontUnderline false  );

       
    txteChange  = new  QTextEdit frmLog  );
       
    txteChange -> setGeometry ( 0 , 552 , 200 , 400 );
       
    txteChange -> setReadOnly true  );
                                                    
    //Make Actions
       
    actAdd  = new  QAction  "&Add" this  );
       
    connect  actAdd SIGNAL triggered () ),  this SLOT  AddObject  () ) );
      
       
    actClose  = new  QAction  "&Close" this  );
       
    connect  actClose SIGNAL  triggered () ),  qApp SLOT  quit  () ) );
                                                  
                                                  
    //Make Menu
        
       
    mnFile  menuBar ()-> addMenu "&File"  );
       
    mnFile -> addAction ( actClose );
      
       
    mnObject  menuBar ()-> addMenu "&Object"  );
       
    mnObject -> addAction ( actAdd ); 
       
       
    connect  mnFile SIGNAL  aboutToShow () ),  this SLOT StopTimer () ) );
       
    connect  mnObject SIGNAL  aboutToShow () ),  this SLOT  StopTimer () ) );
       
    //connect ( this, SIGNAL ( setFocus() ), this, SLOT( StartTimer() ) );
       
       //Activate OpenGL   
       
    dGLWidget  = new  DOpenGL frmOpenGl  );
       
    blOpenGLWidget  = new  QHBoxLayout frmOpenGl  );
       
    blOpenGLWidget -> addWidget dGLWidget );
       
    dGLWidget -> setFocus Qt :: ActiveWindowFocusReason  );
       if ( 
    dGLWidget -> world -> ground -> NameVertexbuffer () !=  NULL  )
           
    txteLog -> append "Opened Ground"  );
       
    blOpenGLWidget -> setGeometry QRect ( 0 , 0 , 1080 , 952 ) );
       
    dGLWidget -> resize ( 1080 , 952 );
       
       
       
    //Start Timers
       
    tiDraw  = new  QTimer this  );
       
    connect  tiDraw SIGNAL  timeout () ),  this SLOT  Update () ) );
       
    tiDraw -> start ( 0 );
       
    tiFramesCount  = new  QTimer this  );
       
    connect  tiFramesCount SIGNAL timeout () ),  this SLOT  FramesCount () ) );
       
    tiFramesCount -> start ( 1000 ); 
    }

    void DMainWindow :: PrintText char  * _text QTextEdit  * _txteOutput  )
    {
        
    _txteOutput -> append  _text  );
        
    }

    ///////////////////////////////////////////////////////
    //        EventHandels

    void DMainWindow :: paintEvent  QPaintEvent _event  )
    {
        
    }

    void DMainWindow :: mouseMoveEvent  QMouseEvent _event  )
    {
        
    QPoint pos  _event -> pos ();
        
    dGLWidget -> world -> mouse . SetX pos . x () );
        
    dGLWidget -> world -> mouse . SetY pos . y () );
        
    dGLWidget -> world -> MouseCallback ();
        
    dGLWidget -> Update ();
    }

    void DMainWindow :: mousePressEvent  QMouseEvent _event  )
    {
        switch ( 
    _event -> button () ) {
            case 
    Qt :: LeftButton : {
                
    dGLWidget -> world -> mouse . SetButton dGLWidget -> world -> mouse . LEFT  );
                break;
            }
            case 
    Qt :: RightButton : {
                
    dGLWidget -> world -> mouse . SetButton dGLWidget -> world -> mouse . RIGHT  );
                break;
            }
            case 
    Qt :: MidButton : {
                
    dGLWidget -> world -> mouse . SetButton dGLWidget -> world -> mouse . MIDDLE  );
                break;
            }
            default: {
                
    dGLWidget -> world -> mouse . SetButton dGLWidget -> world -> mouse . NONE  );
                break;
            }
        }
    }

    void DMainWindow :: mouseReleaseEvent QMouseEvent * )
    {
        
    dGLWidget -> world -> mouse . SetButton dGLWidget -> world -> mouse . NONE  );
    }

    void DMainWindow :: keyPressEvent QKeyEvent _event  )
    {
        switch( 
    _event -> key () ) {
            case 
    Qt :: Key_Escape : {
                
    qApp -> quit ();
                break;
            }
            default: {
                
    dGLWidget -> keyPressEvent _event  );
                break;
            }
        }
    }

    //////////////////////////////////////////////////////
    //        Slots

    void DMainWindow :: AddObject  ()
    {
        
    txteLog -> append "Open Object"  );
        
    QString filepath  QFileDialog :: getOpenFileName this "Open Object" "/" "*.obj"  );
        if ( 
    filepath . isEmpty () )
            
    txteLog -> append "Nothing opened"  );
        else {
            
    QByteArray bafilepath  filepath . toAscii ();
            
    char  * cfilepath  bafilepath . data ();
            if ( !
    dGLWidget -> world -> OpenObject cfilepath  ) ) {
                
    filepath . prepend "Not able to open ["  );
                
    filepath . append "]"  );
            }
            else
                
    filepath . prepend "Open: "  );
            
    txteLog -> append filepath  );
        }
        
    StartTimer ();
    }

    void DMainWindow :: Update  ()
    {
        
    dGLWidget -> Update ();
    }

    void DMainWindow :: FramesCount  ()
    {
        
    QString strFrames ;
        
    QString strRotationX strRotationY ;
        
        
    strFrames . setNum  dGLWidget -> frames  );
        
    strFrames . prepend  "Frames: "  );
        
    dGLWidget -> frames  0 ;
        
        
    txteChange -> clear ();
        
    txteChange -> append strFrames  );
        
    strRotationX . setNum dGLWidget -> world -> RotationX () );
        
    strRotationY . setNum dGLWidget -> world -> RotationY () );
        
    strRotationX . prepend "RotationX: "  );
        
    strRotationX . append "\nRotationY: "  );
        
    strRotationX . append strRotationY  );
        
    txteChange -> append strRotationX  );
        
    strFrames . setNum dGLWidget -> world -> TranslationX () );
        
    strRotationX . setNum dGLWidget -> world -> TranslationY () );
        
    strRotationY . setNum dGLWidget -> world -> TranslationZ () );
        
    strFrames . prepend ( "TranslationX: "  );
        
    strRotationX . prepend "TranslationY: "  );
        
    strRotationY . prepend "TranslationZ: "  );
        
    txteChange -> append  strFrames  );
        
    txteChange -> append  strRotationX  );
        
    txteChange -> append  strRotationY  );
        
    dGLWidget -> world -> Culling () ?  txteChange -> append "Culling: ON"  ) :  txteChange -> append "Culling: OFF"  );
        
    dGLWidget -> world -> Light () ?  txteChange -> append "Light: ON"  ) :  txteChange -> append "Light: OFF"  );
        
    dGLWidget -> world -> Wireframe () ?  txteChange -> append "Wireframe: ON"  ) :  txteChange -> append  "Wireframe: OFF"  );
        
    dGLWidget -> world -> Physic () ?  txteChange -> append "Physic: ON"  ) :  txteChange -> append "Physic: OFF"  );
        
    }

    void DMainWindow :: StopTimer () 
    {
        
    tiDraw -> stop ();
    }

    void DMainWindow :: StartTimer ()
    {
        
    tiDraw -> start ( 0 );
    }
    Ich hoffe ihr könnt mir helfen!
    Danke schon mal im Vorhinaus.

    greece C4rc4ss
     
  2. 16. September 2009
    AW: QTOpenGL flackert bzw. keine richtige Darstellung

    Hab den Code jetzt schnell überfolgen und selbert mit QT noch net gearbeitet aber wahrschienlich liegt es daran dass das Bild nicht Double Buffered ist, also direkt auf den Bildschirm geziechnet wird und dadurch dieser "flacker" Effekt entsteht bzw. das Bild falsch gezeichnet angezeigt wird.

    Must mal schauen ob die QGLWidget-Klasse eine Eigenschaft dafür schon hat (müsste eigentlich) ansonste mal nach den Stichwörtern PFD_DOUBLEBUFFER und SwapBuffers googeln wobei das letztere wahrscheinlich automatisch bei der Update funktion gemacht wird wenn setAutoBufferSwap(true); gesetzt ist.

    Du hats inderekt ja gesagt das der Code vorher ging ohne QT, da hast du wahrscheinlich auch selbert die Eigenschaft DoubleBuffered zu gewiessen und jetzt halt bei QT nicht, also ich kann mir nicht vorstellen das es wegen etwas anderem ist.

    Mfg Rushh0ur
     
  3. 16. September 2009
    AW: QTOpenGL flackert bzw. keine richtige Darstellung

    Hi Rushh0ur,
    Danke für deine Antwort! Also es ging vorher mit native C++ unter Windoof. Und ja dort hab ich mich um alles selber gekümmert. Aber das müsste ja auch bei Qt funktionieren.

    Also das mit dem Doublebuffer ist es nicht. Siehe hier:
    PHP:
    DOpenGL :: DOpenGL QWidget _parent 
        : 
    QGLWidget QGLFormat QGL :: DoubleBuffer  /*| QGL::AlphaChannel*/  QGL :: DepthBuffer  ) , _parent 
    dort übergeb ich das Format Doublebuffer und ja mit
    PHP:
    setAutoSwapBuffer ( true );
    swapt Qt automatisch nach jedem zeichnen. Ich hab auch schon die Möglichkeit:
    PHP:
    setAutoSwapBuffer ( false );

    void DOpenGL :: PaintGL  void 
    {

    swapBuffers ();
    }
    versucht, aber das hat an der Sache leider nix geändert.

    BW bekommste trotzdem!

    Vielleicht noch wer anders ne Idee?

    greece
    C4rc4ss
     
  4. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.