Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. Small examples for game development in Qt, OpenGL, Box2D, Bullet Physics, and OpenAL

Small examples for game development in Qt, OpenGL, Box2D, Bullet Physics, and OpenAL

Scheduled Pinned Locked Moved Game Development
41 Posts 2 Posters 7.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 8Observer88 Offline
    8Observer88 Offline
    8Observer8
    wrote on last edited by 8Observer8
    #2

    Set up tools and packages

    Install all packages using this command: pip install PySide PyOpenGL numpy Box2D PyOpenAL

    Useful packages for development in Python: pip install isort and pip install pyflakes. Run them like this: isort . and pyflakes . The dot means that these commands will be applied to all files. isort . - sorts imports in the alphabet order. pyflakes . detects what imports are unused.

    Sublime Text 4 - very lightweight code editor for budget laptops. It can be used for Python, JavaScript, TypeScript, and even Qt C++.

    You can run applications from the command line like this:

    Python:

    python main.py

    JavaScript and TypeScript:

    npm run dev
    npm run release

    Qt C++:

    To build the Qt project from command like you need to run qmake.exe and mingw32-make.exe from the command line. qmake.exe is in this folder: C:\Qt\6.6.3\mingw_64\bin. You can find mingw32-make.exe is in this folder: C:\Qt\Tools\mingw1120_64\bin. These folder's paths must be added to the Path environment variable. You can open the Path environment variable dialog using this command: rundll32 sysdm.cpl,EditEnvironmentVariables Type the following commands from the root project folder to build and run the project:

    qmake -makefile
    mingw32-make
    "release/app"

    Note. You can type your application name instead of app above. You can set your EXE name by typing TARGET = app in the pro file like this:

    QT += core gui openglwidgets
    
    CONFIG += c++17
    
    SOURCES += \
        main.cpp
    
    TARGET = app
    

    This is the .gitignore file for Qt6 projects:

    build/
    debug/
    release/
    *.stash
    *.pro.user
    Makefile
    Makefile.Debug
    Makefile.Release
    
    1 Reply Last reply
    0
    • 8Observer88 8Observer8 marked this topic as a regular topic on
    • 8Observer88 Offline
      8Observer88 Offline
      8Observer8
      wrote on last edited by 8Observer8
      #3

      Set the background color to gray

      For WebAssembly you should call glClearColor inside of paintGL for QOpenGLWidget. For QOpenGLWindow the glClearColor can be called inside of initializeGL.

      • WebAssembly demo on free Netlify hosting (QOpenGLWindow)
      • WebAssembly demo on free Netlify hosting (QOpenGLWidget)

      0e82eed8-4d1a-40ea-a905-ea9613e8c4e1-image.png

      Source code for QOpenGLWidget :

      • Qt6 C++
      • PySide6
      • PyQt6

      Source code for QOpenGLWindow :

      • Qt6 C++
      • PySide6
      • PyQt6

      Pure WebGL, JavaScript, and TypeScript:

      • WebGL 1.0 JavaScript
      • WebGL 1.0 TypeScript
      • WebGL 2.0 JavaScript
      • WebGL 2.0 TypeScript
      1 Reply Last reply
      0
      • 8Observer88 Offline
        8Observer88 Offline
        8Observer8
        wrote on last edited by 8Observer8
        #4

        Simple triangle

        • WebAssembly demo on free Netlify hosting (QOpenGLWidget)
        • WebAssembly demo on free Netlify hosting (QOpenGLWindow)

        ae6aafef-78bf-4d90-8b93-f73fdffe511a-image.png

        Source code for QOpenGLWidget:

        • PyQt6
        • PySide6
        • Qt6 C++

        Source code for QOpenGLWindow:

        • PyQt6
        • PySide6
        • Qt6 C++

        WebGL 1.0 and JavaScript:

        • Playground
        • Source code

        Simple square

        WebGL demo

        1684421a-6014-4cd8-8494-db78c12ae199-image.png

        Source code for QOpenGLWidget:

        • PyQt6
        • PySide6
        • Qt6 C++

        Source code for QOpenGLWindow:

        • PyQt6
        • PySide6
        • Qt6 C++

        WebGL 1.0 and JavaScript:

        • Playground
        • Source code
        1 Reply Last reply
        0
        • 8Observer88 Offline
          8Observer88 Offline
          8Observer8
          wrote on last edited by 8Observer8
          #5

          Transformed rectangle

          WebGL demo

          73f0f57c-5ea2-4afc-8768-5442a019f7bf-image.png

          Source code for QOpenGLWidget:

          • PyQt6
          • PySide6
          • Qt6 C++

          Source code for QOpenGLWindow:

          • PyQt6
          • PySide6
          • Qt6 C++

          WebGL 1.0 and JavaScript:

          • Playground
          • Source code
          1 Reply Last reply
          0
          • 8Observer88 Offline
            8Observer88 Offline
            8Observer8
            wrote on last edited by 8Observer8
            #6

            Game loop and delta time with QOpenGLWindow

            PySide6, Python:

            217b3f61-c8cc-46b8-978e-c06b96a9f67c-image.png

            main.py

            import sys
            
            from OpenGL.GL import GL_COLOR_BUFFER_BIT, glClear, glClearColor
            from PySide6.QtCore import QElapsedTimer, Qt
            from PySide6.QtGui import QSurfaceFormat
            from PySide6.QtOpenGL import QOpenGLWindow
            from PySide6.QtWidgets import QApplication
            
            
            class OpenGLWindow(QOpenGLWindow):
            
                def __init__(self):
                    super().__init__()
            
                    self.setTitle("OpenGL ES 2.0, PySide6, Python")
                    self.resize(350, 350)
            
                    surfaceFormat = QSurfaceFormat()
                    surfaceFormat.setDepthBufferSize(24)
                    surfaceFormat.setSamples(4)
                    surfaceFormat.setSwapInterval(0)
                    self.frameSwapped.connect(self.update)
                    self.setFormat(surfaceFormat)
            
                def initializeGL(self):
                    glClearColor(0.1, 0.3, 0.2, 1)
                    self.elapsedTimer = QElapsedTimer()
                    self.elapsedTimer.start()
            
                def resizeGL(self, w, h):
                    pass
            
                def paintGL(self):
                    glClear(GL_COLOR_BUFFER_BIT)
                    dt = self.elapsedTimer.elapsed() / 1000
                    self.elapsedTimer.restart()
                    print("dt =", dt)
            
            if __name__ == "__main__":
                QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
                app = QApplication(sys.argv)
                w = OpenGLWindow()
                w.show()
                sys.exit(app.exec())
            

            Qt6, C++:

            aa1b257d-628a-4d02-ad6f-b8140ddc14a9-image.png

            main.cpp

            #include <QtCore/QElapsedTimer>
            #include <QtGui/QOpenGLFunctions>
            #include <QtGui/QSurfaceFormat>
            #include <QtOpenGL/QOpenGLWindow>
            #include <QtWidgets/QApplication>
            
            class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions
            {
            public:
                OpenGLWindow()
                {
                    setTitle("OpenGL ES 2.0, Qt6, C++");
                    resize(350, 350);
            
                    QSurfaceFormat surfaceFormat;
                    surfaceFormat.setDepthBufferSize(24);
                    surfaceFormat.setSamples(4);
                    surfaceFormat.setSwapInterval(0);
                    connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
                    setFormat(surfaceFormat);
                }
            
                void initializeGL() override
                {
                    initializeOpenGLFunctions();
                    glClearColor(0.1f, 0.3f, 0.2f, 1.f);
                    m_elapsedTimer.start();
                }
            
                void paintGL() override
                {
                    glClear(GL_COLOR_BUFFER_BIT);
                    float dt = m_elapsedTimer.elapsed() / 1000.f;
                    m_elapsedTimer.restart();
                    qDebug() << "dt =" << dt;
                }
            
            private:
                QElapsedTimer m_elapsedTimer;
            };
            
            int main(int argc, char *argv[])
            {
                QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
                QApplication app(argc, argv);
                OpenGLWindow w;
                w.show();
                return app.exec();
            }
            

            game-loop-dt-qopenglwindow-opengles2-qt6-cpp.pro

            QT += core gui openglwidgets
            
            CONFIG += c++17
            
            SOURCES += \
                main.cpp
            
            1 Reply Last reply
            0
            • 8Observer88 Offline
              8Observer88 Offline
              8Observer8
              wrote on last edited by 8Observer8
              #7

              Game loop and delta time with QOpenGLWidget

              PySide6, Python:

              42c7a285-9196-4004-9110-10ea71dafed9-image.png

              main.py

              import sys
              
              from OpenGL.GL import GL_COLOR_BUFFER_BIT, glClear, glClearColor
              from PySide6.QtCore import QElapsedTimer, Qt, QTimer
              from PySide6.QtOpenGLWidgets import QOpenGLWidget
              from PySide6.QtWidgets import QApplication
              
              
              class OpenGLWidget(QOpenGLWidget):
              
                  def __init__(self):
                      super().__init__()
              
                      self.setWindowTitle("OpenGL ES 2.0, PySide6, Python")
                      self.resize(350, 350)
              
                  def initializeGL(self):
                      glClearColor(0.1, 0.3, 0.2, 1)
              
                      self.elapsedTimer = QElapsedTimer()
                      self.elapsedTimer.start()
              
                      self.timer = QTimer()
                      self.timer.timeout.connect(self.update)
                      self.timer.start(1000//60)
              
                  def resizeGL(self, w, h):
                      pass
              
                  def paintGL(self):
                      glClear(GL_COLOR_BUFFER_BIT)
                      dt = self.elapsedTimer.elapsed() / 1000
                      self.elapsedTimer.restart()
                      print("dt =", dt)
              
              if __name__ == "__main__":
                  QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
                  app = QApplication(sys.argv)
                  w = OpenGLWidget()
                  w.show()
                  sys.exit(app.exec())
              

              Qt6, C++:

              f89f8bbe-f680-4448-86df-ec35d27311d6-image.png

              main.cpp

              #include <QtCore/QElapsedTimer>
              #include <QtCore/QTimer>
              #include <QtGui/QOpenGLFunctions>
              #include <QtOpenGLWidgets/QOpenGLWidget>
              #include <QtWidgets/QApplication>
              
              class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions
              {
              public:
                  OpenGLWidget()
                  {
                      setWindowTitle("OpenGL ES 2.0, Qt6, C++");
                      resize(350, 350);
                  }
              
                  void initializeGL() override
                  {
                      initializeOpenGLFunctions();
                      glClearColor(0.1f, 0.3f, 0.2f, 1.f);
              
                      // connect(&m_timer, &QTimer::timeout, &OpenGLWidget::update);
                      connect(&m_timer, SIGNAL(timeout()), this, SLOT(update()));
                      m_elapsedTimer.start();
                      m_timer.start();
                  }
              
                  void paintGL() override
                  {
                      glClear(GL_COLOR_BUFFER_BIT);
                      float dt = m_elapsedTimer.elapsed() / 1000.f;
                      m_elapsedTimer.restart();
                      qDebug() << "dt =" << dt;
                  }
              
              private:
                  QElapsedTimer m_elapsedTimer;
                  QTimer m_timer;
              };
              
              int main(int argc, char *argv[])
              {
                  QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
                  QApplication app(argc, argv);
                  OpenGLWidget w;
                  w.show();
                  return app.exec();
              }
              

              game-loop-dt-qopenglwidget-opengles2-qt6-cpp.pro

              QT += core gui openglwidgets
              
              CONFIG += c++17
              
              SOURCES += \
                  main.cpp
              
              1 Reply Last reply
              0
              • 8Observer88 Offline
                8Observer88 Offline
                8Observer8
                wrote on last edited by 8Observer8
                #8

                Keyboard handling

                PySide6, Python:

                076ed390-ce61-4028-8748-53169a75b85a-image.png

                main.py

                import sys
                
                from OpenGL.GL import GL_COLOR_BUFFER_BIT, glClear, glClearColor
                from PySide6.QtCore import QElapsedTimer, Qt
                from PySide6.QtGui import QSurfaceFormat
                from PySide6.QtOpenGL import QOpenGLWindow
                from PySide6.QtWidgets import QApplication
                
                
                class OpenGLWindow(QOpenGLWindow):
                
                    def __init__(self):
                        super().__init__()
                
                        self.setTitle("OpenGL ES 2.0, PySide6, Python")
                        self.resize(350, 350)
                
                        surfaceFormat = QSurfaceFormat()
                        surfaceFormat.setDepthBufferSize(24)
                        surfaceFormat.setSamples(4)
                        surfaceFormat.setSwapInterval(0)
                        self.frameSwapped.connect(self.update)
                        self.setFormat(surfaceFormat)
                
                        self.keys = { "up": False, "left": False,
                            "down": False, "right": False }
                
                    def initializeGL(self):
                        glClearColor(0.1, 0.3, 0.2, 1)
                        self.elapsedTimer = QElapsedTimer()
                        self.elapsedTimer.start()
                
                    def resizeGL(self, w, h):
                        pass
                
                    def paintGL(self):
                        glClear(GL_COLOR_BUFFER_BIT)
                        dt = self.elapsedTimer.elapsed() / 1000
                        self.elapsedTimer.restart()
                        # print("dt =", dt)
                        self.keyboardHandler()
                
                    def keyboardHandler(self):
                        if self.keys["up"]:
                            print("up")
                        if self.keys["left"]:
                            print("left")
                        if self.keys["down"]:
                            print("down")
                        if self.keys["right"]:
                            print("right")
                
                    def keyPressEvent(self, event):
                        if event.key() == Qt.Key.Key_W or event.key() == Qt.Key.Key_Up:
                            self.keys["up"] = True
                        if event.key() == Qt.Key.Key_A or event.key() == Qt.Key.Key_Left:
                            self.keys["left"] = True
                        if event.key() == Qt.Key.Key_S or event.key() == Qt.Key.Key_Down:
                            self.keys["down"] = True
                        if event.key() == Qt.Key.Key_D or event.key() == Qt.Key.Key_Right:
                            self.keys["right"] = True
                 
                    def keyReleaseEvent(self, event):
                        if event.key() == Qt.Key.Key_W or event.key() == Qt.Key.Key_Up:
                            self.keys["up"] = False
                        if event.key() == Qt.Key.Key_A or event.key() == Qt.Key.Key_Left:
                            self.keys["left"] = False
                        if event.key() == Qt.Key.Key_S or event.key() == Qt.Key.Key_Down:
                            self.keys["down"] = False
                        if event.key() == Qt.Key.Key_D or event.key() == Qt.Key.Key_Right:
                            self.keys["right"] = False
                
                if __name__ == "__main__":
                    QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
                    app = QApplication(sys.argv)
                    w = OpenGLWindow()
                    w.show()
                    sys.exit(app.exec())
                

                Qt6, C++:

                7ed6d07c-c3ea-43c9-a7b1-27fbf22d6758-image.png

                main.cpp

                #include <QtCore/QElapsedTimer>
                #include <QtCore/QMap>
                #include <QtGui/QKeyEvent>
                #include <QtGui/QOpenGLFunctions>
                #include <QtGui/QSurfaceFormat>
                #include <QtOpenGL/QOpenGLWindow>
                #include <QtWidgets/QApplication>
                
                class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions
                {
                public:
                    OpenGLWindow()
                    {
                        setTitle("OpenGL ES 2.0, Qt6, C++");
                        resize(350, 350);
                    }
                
                    void initializeGL() override
                    {
                        initializeOpenGLFunctions();
                        glClearColor(0.1f, 0.3f, 0.2f, 1.f);
                
                        QSurfaceFormat surfaceFormat;
                        surfaceFormat.setDepthBufferSize(24);
                        surfaceFormat.setSamples(4);
                        surfaceFormat.setSwapInterval(0);
                        connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
                        setFormat(surfaceFormat);
                
                        m_elapsedTimer.start();
                    }
                
                    void paintGL() override
                    {
                        glClear(GL_COLOR_BUFFER_BIT);
                        float dt = m_elapsedTimer.elapsed() / 1000.f;
                        m_elapsedTimer.restart();
                        // qDebug() << "dt =" << dt;
                        keyboardHandler();
                    }
                
                    void keyboardHandler()
                    {
                        if (m_keys["up"])
                        {
                            qDebug() << "up";
                        }
                        if (m_keys["left"])
                        {
                            qDebug() << "left";
                        }
                        if (m_keys["down"])
                        {
                            qDebug() << "down";
                        }
                        if (m_keys["right"])
                        {
                            qDebug() << "right";
                        }
                    }
                
                    void keyPressEvent(QKeyEvent *event) override
                    {
                        if (event->key() == Qt::Key::Key_W || event->key() == Qt::Key::Key_Up)
                        {
                            m_keys["up"] = true;
                        }
                        if (event->key() == Qt::Key::Key_A || event->key() == Qt::Key::Key_Left)
                        {
                            m_keys["left"] = true;
                        }
                        if (event->key() == Qt::Key::Key_S || event->key() == Qt::Key::Key_Down)
                        {
                            m_keys["down"] = true;
                        }
                        if (event->key() == Qt::Key::Key_D || event->key() == Qt::Key::Key_Right)
                        {
                            m_keys["right"] = true;
                        }
                    }
                
                    void keyReleaseEvent(QKeyEvent *event) override
                    {
                        if (event->key() == Qt::Key::Key_W || event->key() == Qt::Key::Key_Up)
                        {
                            m_keys["up"] = false;
                        }
                        if (event->key() == Qt::Key::Key_A || event->key() == Qt::Key::Key_Left)
                        {
                            m_keys["left"] = false;
                        }
                        if (event->key() == Qt::Key::Key_S || event->key() == Qt::Key::Key_Down)
                        {
                            m_keys["down"] = false;
                        }
                        if (event->key() == Qt::Key::Key_D || event->key() == Qt::Key::Key_Right)
                        {
                            m_keys["right"] = false;
                        }
                    }
                
                private:
                    QElapsedTimer m_elapsedTimer;
                    QMap<QString, bool> m_keys;
                };
                
                int main(int argc, char *argv[])
                {
                    QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
                    QApplication app(argc, argv);
                    OpenGLWindow w;
                    w.show();
                    return app.exec();
                }
                

                keyboard-handling-opengles2-qt6-cpp.pro

                QT += core gui openglwidgets
                
                CONFIG += c++17
                
                SOURCES += \
                    main.cpp
                
                1 Reply Last reply
                0
                • 8Observer88 Offline
                  8Observer88 Offline
                  8Observer8
                  wrote on last edited by 8Observer8
                  #9

                  Draw a few rectangles with different colors

                  I have replaced the following code in the Transformed rectangle example:

                      def paintGL(self):
                          glClear(GL_COLOR_BUFFER_BIT)
                          self.modelMatrix.setToIdentity()
                          self.modelMatrix.translate(QVector3D(50, 50, 0))
                          self.modelMatrix.rotate(10, QVector3D(0, 0, 1))
                          self.modelMatrix.scale(QVector3D(80, 10, 1))
                          self.mvpMatrix = self.projViewMatrix * self.modelMatrix
                          self.program.setUniformValue(self.uMvpMatrixLocation, self.mvpMatrix)
                          glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
                  

                  with this one:

                      def paintGL(self):
                          glClear(GL_COLOR_BUFFER_BIT)
                          self.drawRectangle(x = 50, y = 50, w = 80, h = 10, angle = 10,
                              color = QVector3D(0.62, 0.04, 0.18))
                          self.drawRectangle(x = 30, y = 20, w = 50, h = 20, angle = 0,
                              color = QVector3D(0.3, 0.07, 0.5))
                          self.drawRectangle(x = 50, y = 80, w = 40, h = 15, angle = -20,
                              color = QVector3D(0.2, 0.3, 0.1))
                  
                      def drawRectangle(self, x, y, w, h, angle, color):
                          self.modelMatrix.setToIdentity()
                          self.modelMatrix.translate(QVector3D(x, y, 0))
                          self.modelMatrix.rotate(angle, QVector3D(0, 0, 1))
                          self.modelMatrix.scale(QVector3D(w, h, 1))
                          self.mvpMatrix = self.projViewMatrix * self.modelMatrix
                          self.program.setUniformValue(self.uMvpMatrixLocation, self.mvpMatrix)
                          self.program.setUniformValue(self.uColorLocation, color)
                          glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
                  

                  PySide6, Python:

                  cbfc2063-187c-454a-a99e-b99ef52c615c-image.png

                  import sys
                  
                  import numpy as np
                  from OpenGL.GL import (GL_COLOR_BUFFER_BIT, GL_FLOAT, GL_TRIANGLE_STRIP,
                                         glClear, glClearColor, glDrawArrays)
                  from PySide6.QtCore import Qt
                  from PySide6.QtGui import QMatrix4x4, QSurfaceFormat, QVector3D
                  from PySide6.QtOpenGL import (QOpenGLBuffer, QOpenGLShader,
                                                QOpenGLShaderProgram, QOpenGLWindow)
                  from PySide6.QtWidgets import QApplication
                  
                  
                  class OpenGLWindow(QOpenGLWindow):
                  
                      def __init__(self):
                          super().__init__()
                  
                          self.setTitle("OpenGL ES 2.0, PySide6, Python")
                          self.initialWindowWidth = 380
                          self.initialWindowHeight = 380
                          self.resize(self.initialWindowWidth, self.initialWindowHeight)
                          self.worldWidth = 100
                          self.worldHeight = 100
                  
                          surfaceFormat = QSurfaceFormat()
                          surfaceFormat.setDepthBufferSize(24)
                          surfaceFormat.setSamples(4)
                          self.setFormat(surfaceFormat)
                  
                      def initializeGL(self):
                          glClearColor(0.04, 0.62, 0.48, 1)
                  
                          vertShaderSrc = """
                              attribute vec2 aPosition;
                              uniform mat4 uMvpMatrix;
                              void main()
                              {
                                  gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);
                              }
                          """
                  
                          fragShaderSrc = """
                              #ifdef GL_ES
                              precision mediump float;
                              #endif
                              uniform vec3 uColor;
                              void main()
                              {
                                  gl_FragColor = vec4(uColor, 1.0);
                              }
                          """
                  
                          self.program = QOpenGLShaderProgram()
                          self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Vertex, vertShaderSrc)
                          self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Fragment, fragShaderSrc)
                          self.program.link()
                          self.program.bind()
                  
                          vertPositions = np.array([
                              -0.5, -0.5,
                              0.5, -0.5,
                              -0.5, 0.5,
                              0.5, 0.5], dtype=np.float32)
                          self.vertPosBuffer = QOpenGLBuffer()
                          self.vertPosBuffer.create()
                          self.vertPosBuffer.bind()
                          self.vertPosBuffer.allocate(vertPositions, len(vertPositions) * 4)
                          self.program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2)
                          self.program.enableAttributeArray("aPosition")
                  
                          self.uColorLocation = self.program.uniformLocation("uColor")
                          self.uMvpMatrixLocation = self.program.uniformLocation("uMvpMatrix")
                  
                          self.viewMatrix = QMatrix4x4()
                          self.viewMatrix.lookAt(QVector3D(0, 0, 1), QVector3D(0, 0, 0),
                              QVector3D(0, 1, 0))
                  
                          self.projMatrix = QMatrix4x4()
                          self.projViewMatrix = QMatrix4x4()
                          self.modelMatrix = QMatrix4x4()
                          self.mvpMatrix = QMatrix4x4()
                  
                      def resizeGL(self, w, h):
                          coofWidth = w / self.initialWindowWidth
                          coofHeight = h / self.initialWindowHeight
                  
                          self.projMatrix.setToIdentity()
                          self.projMatrix.ortho(0, self.worldWidth * coofWidth,
                              0, self.worldHeight * coofHeight, 1, -1)
                          self.projViewMatrix = self.projMatrix * self.viewMatrix
                  
                      def paintGL(self):
                          glClear(GL_COLOR_BUFFER_BIT)
                          self.drawRectangle(x = 50, y = 50, w = 80, h = 10, angle = 10,
                              color = QVector3D(0.62, 0.04, 0.18))
                          self.drawRectangle(x = 30, y = 20, w = 50, h = 20, angle = 0,
                              color = QVector3D(0.3, 0.07, 0.5))
                          self.drawRectangle(x = 50, y = 80, w = 40, h = 15, angle = -20,
                              color = QVector3D(0.2, 0.3, 0.1))
                  
                      def drawRectangle(self, x, y, w, h, angle, color):
                          self.modelMatrix.setToIdentity()
                          self.modelMatrix.translate(QVector3D(x, y, 0))
                          self.modelMatrix.rotate(angle, QVector3D(0, 0, 1))
                          self.modelMatrix.scale(QVector3D(w, h, 1))
                          self.mvpMatrix = self.projViewMatrix * self.modelMatrix
                          self.program.setUniformValue(self.uMvpMatrixLocation, self.mvpMatrix)
                          self.program.setUniformValue(self.uColorLocation, color)
                          glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
                  
                  if __name__ == "__main__":
                      QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
                      app = QApplication(sys.argv)
                      w = OpenGLWindow()
                      w.show()
                      sys.exit(app.exec())
                  

                  Qt6, C++:

                  23e91e95-267a-4ea9-9068-c0cb10fa0298-image.png

                  main.cpp

                  #include <QtGui/QMatrix4x4>
                  #include <QtGui/QOpenGLFunctions>
                  #include <QtGui/QSurfaceFormat>
                  #include <QtGui/QVector3D>
                  #include <QtOpenGL/QOpenGLBuffer>
                  #include <QtOpenGL/QOpenGLShader>
                  #include <QtOpenGL/QOpenGLShaderProgram>
                  #include <QtOpenGL/QOpenGLWindow>
                  #include <QtWidgets/QApplication>
                  
                  class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions
                  {
                  public:
                      OpenGLWindow()
                      {
                          setTitle("OpenGL ES 2.0, Qt6, C++");
                          resize(380, 380);
                  
                          QSurfaceFormat surfaceFormat;
                          surfaceFormat.setDepthBufferSize(24);
                          surfaceFormat.setSamples(4);
                          setFormat(surfaceFormat);
                      }
                  
                      void initializeGL() override
                      {
                          initializeOpenGLFunctions();
                          glClearColor(0.04f, 0.62f, 0.48f, 1.f);
                  
                          QString vertShaderSrc =
                              "attribute vec2 aPosition;\n"
                              "uniform mat4 uMvpMatrix;"
                              "void main()\n"
                              "{\n"
                              "    gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);\n"
                              "}\n";
                  
                          QString fragShaderSrc =
                              "#ifdef GL_ES\n"
                              "precision mediump float;\n"
                              "#endif\n"
                              "uniform vec3 uColor;\n"
                              "void main()\n"
                              "{\n"
                              "    gl_FragColor = vec4(uColor, 1.0);\n"
                              "}\n";
                  
                          m_program.create();
                          m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertShaderSrc);
                          m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragShaderSrc);
                          m_program.link();
                          m_program.bind();
                  
                          float vertPositions[] = {
                              -0.5f, -0.5f,
                              0.5f, -0.5f,
                              -0.5f, 0.5f,
                              0.5f, 0.5f
                          };
                          m_vertPosBuffer.create();
                          m_vertPosBuffer.bind();
                          m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
                          m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2);
                          m_program.enableAttributeArray("aPosition");
                  
                          m_uColorLocation = m_program.uniformLocation("uColor");
                          m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");
                          m_viewMatrix.lookAt(QVector3D(0, 0, 1), QVector3D(0, 0, 0), QVector3D(0, 1, 0));
                      }
                  
                      void resizeGL(int w, int h) override
                      {
                          const float coofWidth = w / (float)m_initialWindowWidth;
                          const float coofHeight = h / (float)m_initialWindowHeight;
                  
                          m_projMatrix.setToIdentity();
                          m_projMatrix.ortho(0.f, m_worldWidth * coofWidth,
                              0.f, m_worldHeight * coofHeight, 1.f, -1.f);
                          m_projViewMatrix = m_projMatrix * m_viewMatrix;
                      }
                  
                      void paintGL() override
                      {
                          glClear(GL_COLOR_BUFFER_BIT);
                          drawRectangle(50, 50, 80, 10, 10, QVector3D(0.62, 0.04, 0.18));
                          drawRectangle(30, 20, 50, 20, 0, QVector3D(0.3, 0.07, 0.5));
                          drawRectangle(50, 80, 40, 15, -20, QVector3D(0.2, 0.3, 0.1));
                      }
                  
                      void drawRectangle(float x, float y, float w, float h,
                          float angle, const QVector3D& color)
                      {
                          m_modelMatrix.setToIdentity();
                          m_modelMatrix.translate(QVector3D(x, y, 0));
                          m_modelMatrix.rotate(angle, QVector3D(0, 0, 1));
                          m_modelMatrix.scale(QVector3D(w, h, 1));
                          m_mvpMatrix = m_projViewMatrix * m_modelMatrix;
                          m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
                          m_program.setUniformValue(m_uColorLocation, color);
                          glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
                      }
                  
                  private:
                      QOpenGLBuffer m_vertPosBuffer;
                      QOpenGLShaderProgram m_program;
                      int m_uColorLocation;
                      int m_uMvpMatrixLocation;
                      QMatrix4x4 m_mvpMatrix;
                      QMatrix4x4 m_projMatrix;
                      QMatrix4x4 m_viewMatrix;
                      QMatrix4x4 m_projViewMatrix;
                      QMatrix4x4 m_modelMatrix;
                      const int m_initialWindowWidth = 380;
                      const int m_initialWindowHeight = 380;
                      const float m_worldWidth = 100.f;
                      const float m_worldHeight = 100.f;
                  };
                  
                  int main(int argc, char *argv[])
                  {
                      QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
                      QApplication app(argc, argv);
                      OpenGLWindow w;
                      w.show();
                      return app.exec();
                  }
                  

                  draw-a-few-rectangles-opengles2-qt6-cpp.pro

                  QT += core gui openglwidgets
                  
                  CONFIG += c++17
                  
                  SOURCES += \
                      main.cpp
                  

                  WebAssembly demo on the free Netlify hosting

                  649cd735-7cd9-4e7a-ad15-a6f69d245acb-image.png

                  How it looks on Android 7 with scrcpy:

                  e9cdbec2-9f60-491e-99b0-f15bedc07014-image.png

                  2f7bcf63-1a99-4e2e-b223-e7f7ec6615ab-image.png

                  1 Reply Last reply
                  0
                  • 8Observer88 Offline
                    8Observer88 Offline
                    8Observer8
                    wrote on last edited by 8Observer8
                    #10

                    Fit scale

                    Scale the game world in the center of the screen.

                    WebAssembly demo on the free Netlify hosting

                    e655a73d-915a-4fe3-9a32-d86450bff84d-image.png

                    scale-the-world-in-the-center-opengles2-pyside6-python.gif

                    QOpenGLWidget:

                    • PyQt6
                    • PySide6
                    • Qt6 C++

                    QOpenGLWindow:

                    • PyQt6
                    • PySide6
                    • Qt6 C++

                    WebGL and JavaScript:

                    • Playground
                    • Source code

                    How it looks on Android:

                    ba632ca3-b4d3-415c-97b3-6c738f7cd5f3-image.png

                    a353713a-c272-4355-a4ce-cc701aa28ca1-image.png

                    1 Reply Last reply
                    0
                    • 8Observer88 Offline
                      8Observer88 Offline
                      8Observer8
                      wrote on last edited by 8Observer8
                      #11

                      Place QLabel over QOpenGLWidget

                      PySide6, Python:

                      fe2ce83d-3eb7-4144-9459-751fa9c9c565-image.png

                      main.py

                      import sys
                      
                      from OpenGL.GL import (GL_COLOR_BUFFER_BIT, GL_SCISSOR_TEST, glClear,
                                             glClearColor, glDisable, glEnable, glScissor,
                                             glViewport)
                      from PySide6.QtCore import Qt
                      from PySide6.QtGui import QSurfaceFormat
                      from PySide6.QtOpenGLWidgets import QOpenGLWidget
                      from PySide6.QtWidgets import QApplication, QLabel
                      
                      
                      class OpenGLWidget(QOpenGLWidget):
                      
                          def __init__(self):
                              super().__init__()
                      
                              self.setWindowTitle("OpenGL ES 2.0, PySide6, Python")
                              self.resize(380, 380)
                              self.worldWidth = 200
                              self.worldHeight = 100
                              self.worldAspect = self.worldHeight / self.worldWidth
                      
                              surfaceFormat = QSurfaceFormat()
                              surfaceFormat.setDepthBufferSize(24)
                              surfaceFormat.setSamples(4)
                              self.setFormat(surfaceFormat)
                      
                              self.scoreLabel = QLabel("Score: 0", self)
                              self.scoreLabel.setStyleSheet("font-size: 24px;")
                      
                          def initializeGL(self):
                              pass
                      
                          def resizeGL(self, w, h):
                              deviceW = w * self.devicePixelRatio()
                              deviceH = h * self.devicePixelRatio()
                              deviceAspect = deviceH / deviceW
                      
                              if deviceAspect > self.worldAspect:
                                  self.viewportWidth = int(deviceW)
                                  self.viewportHeight = int(deviceW * self.worldAspect)
                                  self.viewportX = 0
                                  self.viewportY = int((deviceH - self.viewportHeight) / 2)
                              else:
                                  self.viewportWidth = int(deviceH / self.worldAspect)
                                  self.viewportHeight = int(deviceH)
                                  self.viewportX = int((deviceW - self.viewportWidth) / 2)
                                  self.viewportY = 0
                      
                          def paintGL(self):
                              glClearColor(0.2, 0.2, 0.2, 1)
                              glClear(GL_COLOR_BUFFER_BIT)
                              glViewport(self.viewportX, self.viewportY, self.viewportWidth, self.viewportHeight)
                              glScissor(self.viewportX, self.viewportY, self.viewportWidth, self.viewportHeight)
                              glClearColor(0.04, 0.62, 0.48, 1)
                              glEnable(GL_SCISSOR_TEST)
                              glClear(GL_COLOR_BUFFER_BIT)
                              glDisable(GL_SCISSOR_TEST)
                      
                              self.scoreLabel.move(self.viewportX / self.devicePixelRatio() + 10,
                                  self.viewportY / self.devicePixelRatio() + 10);
                      
                      if __name__ == "__main__":
                          QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
                          app = QApplication(sys.argv)
                          w = OpenGLWidget()
                          w.show()
                          sys.exit(app.exec())
                      

                      Qt6, C++:

                      e6099583-2553-492d-965e-a9f63d9f4aeb-image.png

                      main.cpp

                      #include <QtGui/QOpenGLFunctions>
                      #include <QtGui/QSurfaceFormat>
                      #include <QtWidgets/QApplication>
                      #include <QtWidgets/QLabel>
                      #include <QtOpenGLWidgets/QOpenGLWidget>
                      
                      class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions
                      {
                      public:
                          OpenGLWidget()
                          {
                              setWindowTitle("OpenGL ES 2.0, Qt6, C++");
                              resize(380, 380);
                      
                              QSurfaceFormat surfaceFormat;
                              surfaceFormat.setDepthBufferSize(24);
                              surfaceFormat.setSamples(4);
                              setFormat(surfaceFormat);
                      
                              m_pScoreLabel = new QLabel("Score: 0", this);
                              m_pScoreLabel->setStyleSheet("font-size: 24px;");
                          }
                      
                          void initializeGL() override
                          {
                              initializeOpenGLFunctions();
                          }
                      
                          void resizeGL(int w, int h) override
                          {
                              int deviceW = w * devicePixelRatio();
                              int deviceH = h * devicePixelRatio();
                              float deviceAspect = deviceH / (float) deviceW;
                      
                              if (deviceAspect > m_worldAspect)
                              {
                                  m_viewportWidth = deviceW;
                                  m_viewportHeight = (int) deviceW * m_worldAspect;
                                  m_viewportX = 0;
                                  m_viewportY = (int) (deviceH - m_viewportHeight) / 2.f;
                                  qDebug() << deviceH << m_viewportHeight << m_viewportY;
                              }
                              else
                              {
                                  m_viewportWidth = (int) deviceH / m_worldAspect;
                                  m_viewportHeight = deviceH;
                                  m_viewportX = (int) (deviceW - m_viewportWidth) / 2.f;
                                  m_viewportY = 0;
                              }
                          }
                      
                          void paintGL() override
                          {
                              glClear(GL_COLOR_BUFFER_BIT);
                              glClearColor(0.2, 0.2, 0.2, 1);
                              glClear(GL_COLOR_BUFFER_BIT);
                              glViewport(m_viewportX, m_viewportY, m_viewportWidth, m_viewportHeight);
                              glScissor(m_viewportX, m_viewportY, m_viewportWidth, m_viewportHeight);
                              glClearColor(0.04, 0.62, 0.48, 1);
                              glEnable(GL_SCISSOR_TEST);
                              glClear(GL_COLOR_BUFFER_BIT);
                              glDisable(GL_SCISSOR_TEST);
                      
                              m_pScoreLabel->move(m_viewportX / devicePixelRatio() + 10,
                                  m_viewportY / devicePixelRatio() + 10);
                          }
                      
                      private:
                          const float m_worldWidth = 200.f;
                          const float m_worldHeight = 100.f;
                          float m_worldAspect = m_worldHeight / m_worldWidth;
                          int m_viewportX;
                          int m_viewportY;
                          int m_viewportWidth;
                          int m_viewportHeight;
                          QLabel *m_pScoreLabel;
                      };
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
                          QApplication app(argc, argv);
                          OpenGLWidget w;
                          w.show();
                          return app.exec();
                      }
                      

                      qlabel-over-qopenglwidget-opengles2-qt6-cpp.pro

                      QT += core gui openglwidgets
                      
                      CONFIG += c++17
                      
                      SOURCES += \
                          main.cpp
                      

                      It doesn't work on WebAssembly: see demo. Because of this bug: https://bugreports.qt.io/browse/QTBUG-120651 But you can use the patch from the "Gerrit Reviews" (read the comments on the bug report)

                      But it works on Android:

                      ada173ff-cfc0-4a44-86a5-be4e530c7cc7-image.png

                      f7c0e069-3337-4391-8232-cf0676306689-image.png

                      1 Reply Last reply
                      0
                      • BondrusiekB Offline
                        BondrusiekB Offline
                        Bondrusiek
                        wrote on last edited by Bondrusiek
                        #12

                        @8Observer8 Hi! I tested your example with QOpenGLWindow
                        For my Mac I can compile project using :

                        QT       += core gui openglwidgets
                        

                        instead of :

                        QT += core gui opengl widgets
                        
                        win32: LIBS += -lopengl32 # I don't set it for Mac
                        

                        I think it can be similar on Windows.

                        8Observer88 1 Reply Last reply
                        1
                        • BondrusiekB Bondrusiek

                          @8Observer8 Hi! I tested your example with QOpenGLWindow
                          For my Mac I can compile project using :

                          QT       += core gui openglwidgets
                          

                          instead of :

                          QT += core gui opengl widgets
                          
                          win32: LIBS += -lopengl32 # I don't set it for Mac
                          

                          I think it can be similar on Windows.

                          8Observer88 Offline
                          8Observer88 Offline
                          8Observer8
                          wrote on last edited by 8Observer8
                          #13

                          @Bondrusiek said in Small examples for game development in Qt, OpenGL, Box2D, Bullet Physics, and OpenAL:

                          I think it can be similar on Windows.

                          I confirm that it works on Windows. I'm guessing that the openglwidgets module includes the opengl and widgets modules. I've modified the examples to be the same for QOpenGLWindow and QOpenGLWidget. Thank you very much!

                          QT += core gui openglwidgets
                          
                          win32: LIBS += -lopengl32
                          
                          CONFIG += c++17
                          
                          SOURCES += \
                              main.cpp
                          

                          win32: means that it is used on Windows only and it will be ignored on other OS like Android, iOS, macOS and so on. When I use glDrawArrays in separated file and if I don't add this line win32: LIBS += -lopengl32, I have this error on Windows:

                          line_drawer.cpp:74: error: undefined reference to `__imp_glDrawArrays'
                          

                          It can be solved by adding this line of code to pro-file:

                          win32: LIBS += -lopengl32
                          

                          What is interesting, I can delete the line above after recompilation and it will run. But when I change something in the code and recompile it I will have the same error. So the win32: LIBS += -lopengl32 must be in pro-file if you don't call glDrawArrays in the same file.

                          1 Reply Last reply
                          0
                          • 8Observer88 Offline
                            8Observer88 Offline
                            8Observer8
                            wrote on last edited by 8Observer8
                            #14

                            I have made the next demo for WebAssembly, Android, and Desktop using: Qt C++, OpenGL ES 2.0, OpenAL-Soft (this is a library for music and sounds), Box2D (for jumps, collision detections, and ray casting), Hiero (this is an application to create a font with distance field from TTF), Free Texture Packer (to pack images to one texture atlas), and Tiled map editor (to position sprites and Box2D static colliders).

                            • Click to run in your browser (it is a link to itch where you can download EXE for Windows 10 64 bit and APK for Android 7-14)
                            • Click to run in your browser (it is a link to the Netlify free hosting)

                            All resources (sprites, music and sounds) have been replaced with free ones. You can see a list of free resources here. For example, I took the sprites here: https://webfussel.itch.io/more-bit-8-bit-mario

                            I have made a custom joystick for Android in pure OpenGL ES 2.0 (this is an animation from the real phone that I made using scrcpy):

                            mario-2d-jumps-webfussel-opengles2-qt6-cpp-android.gif

                            1 Reply Last reply
                            0
                            • 8Observer88 Offline
                              8Observer88 Offline
                              8Observer8
                              wrote on last edited by
                              #15

                              Setting English as system language

                              If a user system language is not English it will not work:

                              void OpenGLWindow::keyPressEvent(QKeyEvent *event)
                              {
                                  switch (event->key())
                                  {
                                      case Qt::Key::Key_W:
                                      case Qt::Key::Key_Up:
                                      {
                                              break;
                                      {
                              

                              The following command is a solution for Windows. You can set English as system language:

                              OpenGLWindow::OpenGLWindow()
                              {
                                  setTitle("OpenGL ES 2.0, Qt6, C++");
                                  resize(400, 400);
                              
                              // Set English as system language
                              #ifdef _WIN32
                                  PostMessage(GetForegroundWindow(), WM_INPUTLANGCHANGEREQUEST, 1, 0x04090409);
                              #endif
                              

                              You don't need to include <windows.h> because Qt is included it by default:

                              #ifdef _WIN32
                              #include <windows.h>
                              #endif
                              
                              1 Reply Last reply
                              0
                              • 8Observer88 Offline
                                8Observer88 Offline
                                8Observer8
                                wrote on last edited by 8Observer8
                                #16

                                Printing OpenGL version to the Debug console

                                The following commands print OpenGL and GLSL version and vendor:

                                qDebug() << "OpenGL version:" << (const char*) glGetString(GL_VERSION);
                                qDebug() << "GLSL version: " << (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
                                qDebug() << "Vendor: " << (const char*) glGetString(GL_VENDOR);
                                

                                or

                                std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;
                                std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
                                std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl;
                                

                                Qt by default runs programs with integrated video card on laptop:

                                OpenGL version: 3.1.0 - Build 9.17.10.4459
                                GLSL version:  1.40 - Intel Build 9.17.10.4459
                                Vendor:  Intel
                                
                                1 Reply Last reply
                                0
                                • 8Observer88 Offline
                                  8Observer88 Offline
                                  8Observer8
                                  wrote on last edited by 8Observer8
                                  #17

                                  Loading 3D models from DAE COLLADA

                                  This example shows how to parse XML (.dae) using QDomDocument. It was tested on Android 7.1.1, Windows 10, and WebAssembly.

                                  • Click this link to run the demo in your browser
                                  • QOpenGLWindow: Source code on GitHub
                                  • QOpenGLWidget: Source code on GitHub

                                  Note. antialiasing works for WebAssembly with QOpenGLWindow for Qt 6.6.3 but it doesn't work for QOpenGLWidget. It was fixed in Qt 6.7.0. See the bug report: https://bugreports.qt.io/browse/QTBUG-123816

                                  fd06b132-c804-445f-ac4f-bb91687ff5aa-image.png

                                  1 Reply Last reply
                                  0
                                  • 8Observer88 Offline
                                    8Observer88 Offline
                                    8Observer8
                                    wrote on last edited by 8Observer8
                                    #18

                                    Pick color of a pixel with glReadPixels by mouse click or by touching on Mobile

                                    glReadPixels requires the following parameters:

                                    GLubyte pixel[4];
                                    glReadPixels(m_mouseX, m_mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
                                    

                                    Where m_mouseX and m_mouseY are the mouse click coordinates. You should recalculate them before of calling glReadPixels because glReadPixels uses bottom left corner as (0, 0) but Qt uses top left corner as (0, 0). You should add QWindow::devicePixelRatio() because Windows has devicePixelRatio = 1 but Android and macOS (maybe) has devicePixelRatio = 2:

                                    void mousePressEvent(QMouseEvent *event) override
                                    {
                                        m_mouseX = event->pos().x() * devicePixelRatio();
                                        m_mouseY = (height() - event->pos().y() - 1) * devicePixelRatio();
                                        m_mouseClicked = true;
                                        update();
                                    }
                                    

                                    pick-color-with-mouse-opengles2-qt6-cpp.gif

                                    pick-color-of-simple-triangle-qopenglwindow-qt6-cpp.pro

                                    QT += core gui openglwidgets
                                    
                                    CONFIG += c++17
                                    
                                    SOURCES += \
                                        main.cpp
                                    

                                    main.cpp

                                    #include <QtGui/QMouseEvent>
                                    #include <QtGui/QOpenGLFunctions>
                                    #include <QtOpenGL/QOpenGLBuffer>
                                    #include <QtOpenGL/QOpenGLShaderProgram>
                                    #include <QtOpenGL/QOpenGLWindow>
                                    #include <QtWidgets/QApplication>
                                    
                                    class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions
                                    {
                                    public:
                                        OpenGLWindow()
                                        {
                                            setTitle("OpenGL ES 2.0, Qt6, C++");
                                            resize(380, 380);
                                        }
                                    
                                    private:
                                        void initializeGL() override
                                        {
                                            initializeOpenGLFunctions();
                                            glClearColor(0.2f, 0.2f, 0.2f, 1.f);
                                            qDebug() << "Device pixel ratio:" << devicePixelRatio();
                                    
                                            QString vertexShaderSource =
                                                "attribute vec2 aPosition;\n"
                                                "void main()\n"
                                                "{\n"
                                                "    gl_Position = vec4(aPosition, 0.0, 1.0);\n"
                                                "}\n";
                                    
                                            QString fragmentShaderSource =
                                                "#ifdef GL_ES\n"
                                                "precision mediump float;\n"
                                                "#endif\n"
                                                "void main()\n"
                                                "{\n"
                                                "    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
                                                "}\n";
                                    
                                            m_program.create();
                                            m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex,
                                                                              vertexShaderSource);
                                            m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment,
                                                                              fragmentShaderSource);
                                            m_program.link();
                                            m_program.bind();
                                    
                                            float vertPositions[] = {
                                                -0.5f, -0.5f,
                                                0.5f, -0.5f,
                                                0.f, 0.5f
                                            };
                                            m_vertPosBuffer.create();
                                            m_vertPosBuffer.bind();
                                            m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
                                    
                                            m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2);
                                            m_program.enableAttributeArray("aPosition");
                                        }
                                    
                                        void paintGL() override
                                        {
                                            glClear(GL_COLOR_BUFFER_BIT);
                                            glDrawArrays(GL_TRIANGLES, 0, 3);
                                    
                                            if (m_mouseClicked)
                                            {
                                                // Read the pixel
                                                GLubyte pixel[4];
                                                glReadPixels(m_mouseX, m_mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
                                                // Print a color
                                                qDebug() << pixel[0] / 255.f << pixel[1] / 255.f << pixel[2] / 255.f;
                                                m_mouseClicked = false;
                                            }
                                        }
                                    
                                        void mousePressEvent(QMouseEvent *event) override
                                        {
                                            m_mouseX = event->pos().x() * devicePixelRatio();
                                            m_mouseY = (height() - event->pos().y() - 1) * devicePixelRatio();
                                            m_mouseClicked = true;
                                            update();
                                        }
                                    
                                    private:
                                        int m_mouseX;
                                        int m_mouseY;
                                        bool m_mouseClicked = false;
                                        QOpenGLBuffer m_vertPosBuffer;
                                        QOpenGLShaderProgram m_program;
                                    };
                                    
                                    int main(int argc, char *argv[])
                                    {
                                        QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
                                        QApplication app(argc, argv);
                                        OpenGLWindow w;
                                        w.show();
                                        return app.exec();
                                    }
                                    
                                    1 Reply Last reply
                                    0
                                    • 8Observer88 Offline
                                      8Observer88 Offline
                                      8Observer8
                                      wrote on last edited by 8Observer8
                                      #19

                                      Perspective camera

                                      1273b633-a79a-41c0-bab9-16adca1581ac-image.png

                                      perspective-camera-opengles2-qt6-cpp.pro

                                      QT += core gui openglwidgets
                                      
                                      CONFIG += c++17
                                      
                                      SOURCES += \
                                          main.cpp
                                      

                                      main.cpp

                                      #include <QtGui/QMatrix4x4>
                                      #include <QtGui/QOpenGLFunctions>
                                      #include <QtGui/QSurfaceFormat>
                                      #include <QtGui/QVector3D>
                                      #include <QtOpenGL/QOpenGLBuffer>
                                      #include <QtOpenGL/QOpenGLShader>
                                      #include <QtOpenGL/QOpenGLShaderProgram>
                                      #include <QtOpenGL/QOpenGLWindow>
                                      #include <QtWidgets/QApplication>
                                      
                                      class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions
                                      {
                                      public:
                                          OpenGLWindow()
                                          {
                                              setTitle("OpenGL ES 2.0, Qt6, C++");
                                              resize(500, 500);
                                      
                                              QSurfaceFormat surfaceFormat;
                                              surfaceFormat.setDepthBufferSize(24);
                                              surfaceFormat.setSamples(4);
                                              setFormat(surfaceFormat);
                                          }
                                      
                                          void initializeGL() override
                                          {
                                              initializeOpenGLFunctions();
                                              glClearColor(153.f/255.f, 220.f/255.f, 236.f/255.f, 1.f);
                                      
                                              QString vertShaderSrc =
                                                  "attribute vec2 aPosition;\n"
                                                  "uniform mat4 uMvpMatrix;"
                                                  "void main()\n"
                                                  "{\n"
                                                  "    gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);\n"
                                                  "}\n";
                                      
                                              QString fragShaderSrc =
                                                  "#ifdef GL_ES\n"
                                                  "precision mediump float;\n"
                                                  "#endif\n"
                                                  "void main()\n"
                                                  "{\n"
                                                  "    gl_FragColor = vec4(0.058, 0.615, 0.345, 1.0);\n"
                                                  "}\n";
                                      
                                              m_program.create();
                                              m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertShaderSrc);
                                              m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragShaderSrc);
                                              m_program.link();
                                              m_program.bind();
                                      
                                              float vertPositions[] = {
                                                  -0.5f, -0.5f,
                                                  0.5f, -0.5f,
                                                  -0.5f, 0.5f,
                                                  0.5f, 0.5f
                                              };
                                              m_vertPosBuffer.create();
                                              m_vertPosBuffer.bind();
                                              m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
                                              m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2);
                                              m_program.enableAttributeArray("aPosition");
                                      
                                              m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");
                                              m_viewMatrix.lookAt(QVector3D(0, 3, 5), QVector3D(0, 0, 0), QVector3D(0, 1, 0));
                                          }
                                      
                                          void resizeGL(int w, int h) override
                                          {
                                              m_projMatrix.setToIdentity();
                                              m_projMatrix.perspective(50.f, w / (float) h, 0.1f, 100.f);
                                              m_projViewMatrix = m_projMatrix * m_viewMatrix;
                                          }
                                      
                                          void paintGL() override
                                          {
                                              glClear(GL_COLOR_BUFFER_BIT);
                                              m_modelMatrix.setToIdentity();
                                              m_modelMatrix.translate(QVector3D(0, 0, 0));
                                              m_modelMatrix.rotate(90, QVector3D(1, 0, 0));
                                              m_modelMatrix.scale(QVector3D(3, 3, 1));
                                              m_mvpMatrix = m_projViewMatrix * m_modelMatrix;
                                              m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
                                              glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
                                          }
                                      
                                      private:
                                          QOpenGLBuffer m_vertPosBuffer;
                                          QOpenGLShaderProgram m_program;
                                          int m_uMvpMatrixLocation;
                                          QMatrix4x4 m_mvpMatrix;
                                          QMatrix4x4 m_projMatrix;
                                          QMatrix4x4 m_viewMatrix;
                                          QMatrix4x4 m_projViewMatrix;
                                          QMatrix4x4 m_modelMatrix;
                                      };
                                      
                                      int main(int argc, char *argv[])
                                      {
                                          QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
                                          QApplication app(argc, argv);
                                          OpenGLWindow w;
                                          w.show();
                                          return app.exec();
                                      }
                                      
                                      1 Reply Last reply
                                      0
                                      • 8Observer88 Offline
                                        8Observer88 Offline
                                        8Observer8
                                        wrote on last edited by
                                        #20

                                        Rotate and zoom camera

                                        Click here to test WebAssembly demo in the browser

                                        rotate-and-zoom-camera-opengles2-qt6-cpp-desktop.gif

                                        On Android only rotation works. Some work must be made with touch events for zooming:

                                        rotate-and-zoom-camera-opengles2-qt6-cpp.gif

                                        rotate-and-zoom-camera-opengles2-qt6-cpp.pro

                                        QT += core gui openglwidgets
                                        
                                        CONFIG += c++17
                                        
                                        SOURCES += \
                                            main.cpp
                                        

                                        main.cpp

                                        #include <QtGui/QMatrix4x4>
                                        #include <QtGui/QOpenGLFunctions>
                                        #include <QtGui/QSurfaceFormat>
                                        #include <QtGui/QVector3D>
                                        #include <QtGui/QMouseEvent>
                                        #include <QtOpenGL/QOpenGLBuffer>
                                        #include <QtOpenGL/QOpenGLShader>
                                        #include <QtOpenGL/QOpenGLShaderProgram>
                                        #include <QtOpenGL/QOpenGLWindow>
                                        #include <QtWidgets/QApplication>
                                        
                                        class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions
                                        {
                                        public:
                                            OpenGLWindow()
                                            {
                                                setTitle("OpenGL ES 2.0, Qt6, C++");
                                                resize(500, 500);
                                                m_degreesPerPixelX = 90.f / (float) width();
                                                m_degreesPerPixelY = 180.f / (float) height();
                                        
                                                QSurfaceFormat surfaceFormat;
                                                surfaceFormat.setDepthBufferSize(24);
                                                surfaceFormat.setSamples(4);
                                                setFormat(surfaceFormat);
                                            }
                                        
                                            void initializeGL() override
                                            {
                                                initializeOpenGLFunctions();
                                                glClearColor(153.f/255.f, 220.f/255.f, 236.f/255.f, 1.f);
                                        
                                                QString vertShaderSrc =
                                                    "attribute vec2 aPosition;\n"
                                                    "uniform mat4 uMvpMatrix;"
                                                    "void main()\n"
                                                    "{\n"
                                                    "    gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);\n"
                                                    "}\n";
                                        
                                                QString fragShaderSrc =
                                                    "#ifdef GL_ES\n"
                                                    "precision mediump float;\n"
                                                    "#endif\n"
                                                    "void main()\n"
                                                    "{\n"
                                                    "    gl_FragColor = vec4(0.058, 0.615, 0.345, 1.0);\n"
                                                    "}\n";
                                        
                                                m_program.create();
                                                m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertShaderSrc);
                                                m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragShaderSrc);
                                                m_program.link();
                                                m_program.bind();
                                        
                                                float vertPositions[] = {
                                                    -0.5f, -0.5f,
                                                    0.5f, -0.5f,
                                                    -0.5f, 0.5f,
                                                    0.5f, 0.5f
                                                };
                                                m_vertPosBuffer.create();
                                                m_vertPosBuffer.bind();
                                                m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
                                                m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2);
                                                m_program.enableAttributeArray("aPosition");
                                        
                                                m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");
                                                m_viewMatrix = getViewMatrix();
                                            }
                                        
                                            void resizeGL(int w, int h) override
                                            {
                                                m_projMatrix.setToIdentity();
                                                m_projMatrix.perspective(50.f, w / (float)h, 0.1f, 100.f);
                                            }
                                        
                                            void paintGL() override
                                            {
                                                glClear(GL_COLOR_BUFFER_BIT);
                                                m_modelMatrix.setToIdentity();
                                                m_modelMatrix.translate(QVector3D(0, 0, 0));
                                                m_modelMatrix.rotate(90, QVector3D(1, 0, 0));
                                                m_modelMatrix.scale(QVector3D(3, 3, 1));
                                                m_projViewMatrix = m_projMatrix * m_viewMatrix;
                                                m_mvpMatrix = m_projViewMatrix * m_modelMatrix;
                                                m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
                                                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
                                            }
                                        
                                            void mousePressEvent(QMouseEvent *event) override
                                            {
                                                switch (event->button())
                                                {
                                                    case Qt::MouseButton::LeftButton:
                                                    {
                                                        if (m_mouseHolding)
                                                            return;
                                        
                                                        m_mouseHolding = true;
                                                        m_mousePrevX = (float) event->pos().x();
                                                        m_mousePrevY = (float) event->pos().y();
                                                        break;
                                                    }
                                                    default:
                                                        break;
                                                }
                                            }
                                        
                                            void mouseMoveEvent(QMouseEvent *event) override
                                            {
                                                if (!m_mouseHolding)
                                                    return;
                                        
                                                float x = (float) event->pos().x();
                                                float y = (float) event->pos().y();
                                        
                                                float newCameraRotX = m_cameraRotX + m_degreesPerPixelX * (y - m_mousePrevY);
                                                newCameraRotX = qMax(-85.f, qMin(85.f, newCameraRotX));
                                                float newCameraRotY = m_cameraRotY + m_degreesPerPixelY * (x - m_mousePrevX);
                                                m_mousePrevX = x;
                                                m_mousePrevY = y;
                                                m_cameraRotX = newCameraRotX;
                                                m_cameraRotY = newCameraRotY;
                                        
                                                m_viewMatrix = getViewMatrix();
                                                update();
                                            }
                                        
                                            void mouseReleaseEvent(QMouseEvent *event) override
                                            {
                                                Q_UNUSED(event);
                                                m_mouseHolding = false;
                                            }
                                        
                                            void wheelEvent(QWheelEvent *event) override
                                            {
                                                float delta = event->angleDelta().y();
                                                m_viewDistance += -delta / 500.f;
                                                m_viewMatrix = getViewMatrix();
                                                update();
                                            }
                                        
                                            QMatrix4x4 getViewMatrix()
                                            {
                                                QMatrix4x4 mat;
                                        
                                                const float cosX = qCos(m_cameraRotX / 180.f * M_PI);
                                                const float sinX = qSin(m_cameraRotX / 180.f * M_PI);
                                                const float cosY = qCos(m_cameraRotY / 180.f * M_PI);
                                                const float sinY = qSin(m_cameraRotY / 180.f * M_PI);
                                        
                                                mat.setColumn(0, QVector4D(cosY, sinX * sinY, -cosX * sinY, 0.f));
                                                mat.setColumn(1, QVector4D(0.f, cosX, sinX, 0.f));
                                                mat.setColumn(2, QVector4D(sinY, -sinX * cosY, cosX * cosY, 0.f));
                                                mat.setColumn(3, QVector4D(0, 0, -m_viewDistance, 1.f));
                                        
                                                return mat;
                                            }
                                        
                                        private:
                                            QOpenGLBuffer m_vertPosBuffer;
                                            QOpenGLShaderProgram m_program;
                                            int m_uMvpMatrixLocation;
                                            QMatrix4x4 m_mvpMatrix;
                                            QMatrix4x4 m_projMatrix;
                                            QMatrix4x4 m_viewMatrix;
                                            QMatrix4x4 m_projViewMatrix;
                                            QMatrix4x4 m_modelMatrix;
                                            bool m_mouseHolding = false;
                                            float m_mousePrevX = 0.f;
                                            float m_mousePrevY = 0.f;
                                            float m_cameraRotX = 30.f;
                                            float m_cameraRotY = 0.f;
                                            float m_viewDistance = 5.f;
                                            float m_degreesPerPixelX;
                                            float m_degreesPerPixelY;
                                        };
                                        
                                        int main(int argc, char *argv[])
                                        {
                                            QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
                                            QApplication app(argc, argv);
                                            OpenGLWindow w;
                                            w.show();
                                            return app.exec();
                                        }
                                        
                                        1 Reply Last reply
                                        0
                                        • 8Observer88 Offline
                                          8Observer88 Offline
                                          8Observer8
                                          wrote on last edited by 8Observer8
                                          #21

                                          A circle (disk) is inscribed in a square

                                          WebAssembly demo on free Netlify hosting

                                          7839944d-05e1-4f20-881c-5ad2e41d8519-image.png

                                          disk-opengles2-qt6-cpp.pro

                                          QT += core gui openglwidgets
                                          
                                          CONFIG += c++17
                                          
                                          SOURCES += \
                                              main.cpp
                                          

                                          main.cpp

                                          #include <QtMath>
                                          #include <QtGui/QMatrix4x4>
                                          #include <QtGui/QOpenGLFunctions>
                                          #include <QtGui/QSurfaceFormat>
                                          #include <QtGui/QVector3D>
                                          #include <QtOpenGL/QOpenGLBuffer>
                                          #include <QtOpenGL/QOpenGLShader>
                                          #include <QtOpenGL/QOpenGLShaderProgram>
                                          #include <QtOpenGL/QOpenGLWindow>
                                          #include <QtWidgets/QApplication>
                                          
                                          class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions
                                          {
                                          public:
                                              OpenGLWindow()
                                              {
                                                  setTitle("OpenGL ES 2.0, Qt6, C++");
                                                  resize(380, 380);
                                          
                                                  QSurfaceFormat surfaceFormat;
                                                  surfaceFormat.setDepthBufferSize(24);
                                                  surfaceFormat.setSamples(4);
                                                  setFormat(surfaceFormat);
                                              }
                                          
                                              void initializeGL() override
                                              {
                                                  initializeOpenGLFunctions();
                                                  glClearColor(0.04f, 0.62f, 0.48f, 1.f);
                                          
                                                  QString vertShaderSrc =
                                                      "attribute vec2 aPosition;\n"
                                                      "uniform mat4 uMvpMatrix;"
                                                      "void main()\n"
                                                      "{\n"
                                                      "    gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);\n"
                                                      "}\n";
                                          
                                                  QString fragShaderSrc =
                                                      "#ifdef GL_ES\n"
                                                      "precision mediump float;\n"
                                                      "#endif\n"
                                                      "uniform vec3 uColor;\n"
                                                      "void main()\n"
                                                      "{\n"
                                                      "    gl_FragColor = vec4(uColor, 1.0);\n"
                                                      "}\n";
                                          
                                                  m_program.create();
                                                  m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertShaderSrc);
                                                  m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragShaderSrc);
                                                  m_program.link();
                                                  m_program.bind();
                                          
                                                  float vertPositions[m_amountOfDiskVertices * 2 + 8]; // Disk + Square
                                                  float radius = 0.5f;
                                                  float angle = 0.f;
                                          
                                                  int index = 0;
                                                  // Disk center
                                                  vertPositions[index++] = 0.f;
                                                  vertPositions[index++] = 0.f;
                                          
                                                  // Disk
                                                  for (int i = 0; i < m_amountOfDiskVertices - 1; i++)
                                                  {
                                                      float radians = qDegreesToRadians(angle);
                                                      float x = radius * qCos(radians);
                                                      float y = radius * qSin(radians);
                                                      vertPositions[index++] = x;
                                                      vertPositions[index++] = y;
                                                      angle += m_angleStep;
                                                  }
                                                  // Square
                                                  vertPositions[index++] = -0.5f;
                                                  vertPositions[index++] = -0.5f;
                                                  vertPositions[index++] = 0.5f;
                                                  vertPositions[index++] = -0.5f;
                                                  vertPositions[index++] = -0.5f;
                                                  vertPositions[index++] = 0.5f;
                                                  vertPositions[index++] = 0.5f;
                                                  vertPositions[index++] = 0.5f;
                                                  m_vertPosBuffer.create();
                                                  m_vertPosBuffer.bind();
                                                  m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
                                                  m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2);
                                                  m_program.enableAttributeArray("aPosition");
                                          
                                                  m_uColorLocation = m_program.uniformLocation("uColor");
                                                  m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");
                                                  m_viewMatrix.lookAt(QVector3D(0, 0, 1), QVector3D(0, 0, 0), QVector3D(0, 1, 0));
                                              }
                                          
                                              void resizeGL(int w, int h) override
                                              {
                                                  int deviceW = w * devicePixelRatio();
                                                  int deviceH = h * devicePixelRatio();
                                                  float deviceAspect = deviceH / (float) deviceW;
                                          
                                                  if (deviceAspect > m_worldAspect)
                                                  {
                                                      m_viewportWidth = deviceW;
                                                      m_viewportHeight = (int) deviceW * m_worldAspect;
                                                      m_viewportX = 0;
                                                      m_viewportY = (int) (deviceH - m_viewportHeight) / 2.f;
                                                  }
                                                  else
                                                  {
                                                      m_viewportWidth = (int) deviceH / m_worldAspect;
                                                      m_viewportHeight = deviceH;
                                                      m_viewportX = (int) (deviceW - m_viewportWidth) / 2.f;
                                                      m_viewportY = 0;
                                                  }
                                                  m_projMatrix.setToIdentity();
                                                  m_projMatrix.ortho(0.f, m_worldWidth, 0.f, m_worldHeight, 1.f, -1.f);
                                                  m_projViewMatrix = m_projMatrix * m_viewMatrix;
                                              }
                                          
                                              void paintGL() override
                                              {
                                                  glClear(GL_COLOR_BUFFER_BIT);
                                                  glClearColor(0.2, 0.2, 0.2, 1);
                                                  glClear(GL_COLOR_BUFFER_BIT);
                                                  glViewport(m_viewportX, m_viewportY, m_viewportWidth, m_viewportHeight);
                                                  glScissor(m_viewportX, m_viewportY, m_viewportWidth, m_viewportHeight);
                                                  glClearColor(0.04, 0.62, 0.48, 1);
                                                  glEnable(GL_SCISSOR_TEST);
                                                  glClear(GL_COLOR_BUFFER_BIT);
                                                  glDisable(GL_SCISSOR_TEST);
                                          
                                                  // Square
                                                  drawRectangle(100, 50, 50, 50, 0, QVector3D(0.3, 0.07, 0.5));
                                                  // Disk
                                                  drawDisk(100, 50, 50, QVector3D(0.8, 0.8, 0.5));
                                                  // Left border
                                                  drawRectangle(5, 50, 5, 85, 0, QVector3D(0.62, 0.04, 0.18));
                                                  // Right border
                                                  drawRectangle(195, 50, 5, 85, 0, QVector3D(0.62, 0.04, 0.18));
                                                  // Top border
                                                  drawRectangle(100, 95, 185, 5, 0, QVector3D(0.62, 0.04, 0.18));
                                                  // Bottom border
                                                  drawRectangle(100, 5, 185, 5, 0, QVector3D(0.62, 0.04, 0.18));
                                              }
                                          
                                              void drawDisk(float x, float y, float diameter, const QVector3D& color)
                                              {
                                                  m_modelMatrix.setToIdentity();
                                                  m_modelMatrix.translate(QVector3D(x, y, 0));
                                                  m_modelMatrix.scale(QVector3D(diameter, diameter, 1));
                                                  m_mvpMatrix = m_projViewMatrix * m_modelMatrix;
                                                  m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
                                                  m_program.setUniformValue(m_uColorLocation, color);
                                                  glDrawArrays(GL_TRIANGLE_FAN, 0, m_amountOfDiskVertices);
                                              }
                                          
                                              void drawRectangle(float x, float y, float w, float h,
                                                  float angle, const QVector3D& color)
                                              {
                                                  m_modelMatrix.setToIdentity();
                                                  m_modelMatrix.translate(QVector3D(x, y, 0));
                                                  m_modelMatrix.rotate(angle, QVector3D(0, 0, 1));
                                                  m_modelMatrix.scale(QVector3D(w, h, 1));
                                                  m_mvpMatrix = m_projViewMatrix * m_modelMatrix;
                                                  m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
                                                  m_program.setUniformValue(m_uColorLocation, color);
                                                  glDrawArrays(GL_TRIANGLE_STRIP, m_amountOfDiskVertices, 4);
                                              }
                                          
                                          private:
                                              QOpenGLBuffer m_vertPosBuffer;
                                              QOpenGLShaderProgram m_program;
                                              int m_uColorLocation;
                                              int m_uMvpMatrixLocation;
                                              QMatrix4x4 m_mvpMatrix;
                                              QMatrix4x4 m_projMatrix;
                                              QMatrix4x4 m_viewMatrix;
                                              QMatrix4x4 m_projViewMatrix;
                                              QMatrix4x4 m_modelMatrix;
                                              const float m_worldWidth = 200.f;
                                              const float m_worldHeight = 100.f;
                                              float m_worldAspect = m_worldHeight / m_worldWidth;
                                              int m_viewportX;
                                              int m_viewportY;
                                              int m_viewportWidth;
                                              int m_viewportHeight;
                                              float m_angleStep = 10.f;
                                              int m_amountOfDiskVertices = 360.f / m_angleStep + 2;
                                          };
                                          
                                          int main(int argc, char *argv[])
                                          {
                                              QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
                                              QApplication app(argc, argv);
                                              OpenGLWindow w;
                                              w.show();
                                              return app.exec();
                                          }
                                          
                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved