Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt 6.7 and QOpenGLWidget issue
Forum Updated to NodeBB v4.3 + New Features

Qt 6.7 and QOpenGLWidget issue

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 707 Views 1 Watching
  • 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.
  • D Offline
    D Offline
    Dmitry44
    wrote on 9 May 2024, 09:39 last edited by
    #1

    Hello everyone, I try to render the Rubiks Cube in qt with using of opengl. But I have the problem, it outputs me black screen window and nothing else. According to the output there is no issues. Maybe someone can help me with this? I spend at least 2 weeks finding the errors and still nothing works.

    This is my openglwidget.cpp

    #include "openglwidget.h"
    
    OpenGLWidget::OpenGLWidget(QWidget *parent)
        : QOpenGLWidget(parent)
    {
        //setFocusPolicy(Qt::StrongFocus);
        colors = {
            QVector3D(1.0f, 0.0f, 0.0f),
            QVector3D(0.0f, 1.0f, 0.0f),
            QVector3D(0.0f, 0.0f, 1.0f),
            QVector3D(1.0f, 1.0f, 0.0f),
            QVector3D(1.0f, 0.5f, 0.0f),
            QVector3D(1.0f, 1.0f, 1.0f)
        };
    }
    
    void OpenGLWidget::initializeGL()
    {
        makeCurrent();
    
        initializeOpenGLFunctions();
    
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glEnable(GL_DEPTH_TEST);
        //glEnable(GL_CULL_FACE);
    
        setElementsOfCube(cubes, colors);
    }
    
    void OpenGLWidget::resizeGL(int w, int h)
    {
        makeCurrent();
        // Calculate aspect ratio
        qreal aspect = qreal(w) / qreal(h ? h : 1);
    
        // Set near plane to 3.0, far plane to 50.0, field of view 45 degrees
        const qreal zNear = 0.1, zFar = 100.0, fov = 45.0;
    
        // Reset projection
        projection.setToIdentity();
    
        // Set perspective projection
        projection.perspective(fov, aspect, zNear, zFar);
    }
    
    void OpenGLWidget::paintGL()
    {
        makeCurrent();
        // Clear color and depth buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        // Calculate model view transformation
        QMatrix4x4 view;
    
        // Camera setup
        QVector3D cameraPos(3.0f, 3.0f, 3.0f);
        QVector3D cameraFront = QVector3D(-0.525f, -0.525f, 0.525f) - cameraPos;
        cameraFront.normalize();
        QVector3D cameraUp(0.0f, 1.0f, 0.0f);
    
        view.lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
    
        // view.translate(30.0f, 30.0f, 30.0f);
        // view.rotate(30.0f, QVector3D(1.0f, 0.0f, 0.0f)); // Rotate 30 degrees around the x-axis
        // view.rotate(-45.0f, QVector3D(0.0f, 1.0f, 0.0f)); // Rotate -45 degrees around the y-axis
    
        QMatrix4x4 model;
    
    
        // Draw cube geometry
        for (auto &cube : cubes)
        {
            model.translate(cube.GetPosition());
    
            cube.drawCubeGeometry(projection, view, model);
        }
        update();
    }
    
    void OpenGLWidget::setElementsOfCube(QVector<CubeGeometry> &cubes, QVector<QVector3D> &colors)
    {
        makeCurrent();
        for (int x = 0; x < 3; ++x) {
            for (int y = 0; y < 3; ++y) {
                for (int z = 0; z < 3; ++z) {
                    QVector3D cubeColors[6];
                    for (int i = 0; i < 6; ++i)
                    {
                        cubeColors[i] = QVector3D(0.3f, 0.3f, 0.3f);
                    }
                    // Assign colors based on the position of the cube
                    if (x == 0) cubeColors[4] = colors[0]; // Red - left
                    if (x == 2) cubeColors[3] = colors[4]; // Orange - right
                    if (y == 0) cubeColors[2] = colors[3]; // Yellow - bottom
                    if (y == 2) cubeColors[1] = colors[5]; // White - top
                    if (z == 0) cubeColors[0] = colors[2]; // Blue - front
                    if (z == 2) cubeColors[5] = colors[1]; // Green - back
                    CubeGeometry cube(0.25f, cubeColors);
                    QVector3D position(x * 0.525f - 0.525f, y * 0.525f - 0.525f, z * 0.525f - 0.525f);
                    cube.SetPosition(position);
                    cubes.push_back(cube);
                }
            }
        }
    }
    

    and my openglwidget.h

    #ifndef OPENGLWIDGET_H
    #define OPENGLWIDGET_H
    
    #include <QOpenGLWidget>
    #include <QOpenGLFunctions_3_3_Core>
    #include <QOpenGLShaderProgram>
    #include <QOpenGLShader>
    #include <QOpenGLContext>
    #include <QMatrix4x4>
    #include <QQuaternion>
    
    #include "cubegeometry.h"
    
    class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
    {
    public:
        explicit OpenGLWidget(QWidget *parent = nullptr);
    
    protected:
        void initializeGL() override;
        void resizeGL(int w, int h) override;
        void paintGL() override;
    
        void setElementsOfCube(QVector<CubeGeometry> &cubes, QVector<QVector3D> &colors);
    
    private:
        QVector<CubeGeometry> cubes;
        QVector<QVector3D> colors;
    
        QMatrix4x4 projection;
        //QQuaternion rotation;
    };
    
    #endif // OPENGLWIDGET_H
    

    CubeGeometry.cpp

    #include "cubegeometry.h"
    
    #include <QDebug>
    
    CubeGeometry::CubeGeometry(float size, QVector3D color[6])
    {
    
        initializeOpenGLFunctions();
    
        // Initializes cube geometry and transfers it to VBOs
        initCubeGeometry(size, color);
        initShader();
    
        prepareModel();
    }
    
    CubeGeometry::~CubeGeometry()
    {
        vertBuff->destroy();
        indBuff->destroy();
    }
    
    void CubeGeometry::initShader()
    {
        program = new QOpenGLShaderProgram();
        program->addShaderFromSourceFile(QOpenGLShader::Vertex, "C:/Users/Dima/Documents/RubiksCube/vertexShader.vert");
        program->addShaderFromSourceFile(QOpenGLShader::Fragment, "C:/Users/Dima/Documents/RubiksCube/fragmentShader.frag");
        program->link();
        if (program->isLinked())
        {
            qDebug() << "program is linked";
        }
        qDebug() << program->log();
        // qDebug() << program->uniformLocation("projection");
        // qDebug() << program->uniformLocation("view");
        // qDebug() << program->uniformLocation("model");
    }
    
    void CubeGeometry::prepareModel()
    {
        vao = new QOpenGLVertexArrayObject();
        vao->create();
        vao->bind();
    
        vertBuff = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
        vertBuff->create();
        vertBuff->bind();
        vertBuff->setUsagePattern(QOpenGLBuffer::StaticDraw);
        vertBuff->allocate(&vertices, (int)vertices.size() * sizeof(GLfloat));
    
        quintptr offset = 0;
    
        int vertexLocation = program->attributeLocation("aPos");
        program->enableAttributeArray(vertexLocation);
        program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, 6 * sizeof(GLfloat));
    
        offset += 3 * sizeof(GLfloat);
    
        int colorLocation = program->attributeLocation("aColor");
        program->enableAttributeArray(colorLocation);
        program->setAttributeBuffer(colorLocation, GL_FLOAT, offset, 3, 6 * sizeof(GLfloat));
    
        indBuff = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
        indBuff->create();
        indBuff->bind();
        indBuff->setUsagePattern(QOpenGLBuffer::StaticDraw);
        indBuff->allocate(&indices, (int)indices.size() * sizeof(GLushort));
        vao->release();
        qDebug() << "Model prepared";
    }
    
    void CubeGeometry::initCubeGeometry(float size, QVector3D color[6])
    {
        vertices = {
            // positions          // colors
            // front side
            -size, -size, -size,  color[0].x(), color[0].y(), color[0].z(),  // front bottom left 0
            size, -size, -size,  color[0].x(), color[0].y(), color[0].z(),  // front bottom right 1
            size,  size, -size,  color[0].x(), color[0].y(), color[0].z(),  // front top right 2
            -size,  size, -size,  color[0].x(), color[0].y(), color[0].z(),  // front top left 3
            // top side
            size,  size, -size,  color[1].x(), color[1].y(), color[1].z(),  // front top right 2
            -size,  size, -size,  color[1].x(), color[1].y(), color[1].z(),  // front top left 3
            -size,  size,  size,  color[1].x(), color[1].y(), color[1].z(),  // back top left 7
            size,  size,  size,  color[1].x(), color[1].y(), color[1].z(),  // back top right 6
            // bottom side
            -size, -size, -size,  color[2].x(), color[2].y(), color[2].z(),  // front bottom left 0
            size, -size, -size,  color[2].x(), color[2].y(), color[2].z(),  // front bottom right 1
            size, -size,  size,  color[2].x(), color[2].y(), color[2].z(),  // back bottom right 5
            -size, -size,  size,  color[2].x(), color[2].y(), color[2].z(),  // back bottom left 4
            // right side
            size, -size, -size,   color[3].x(), color[3].y(), color[3].z(),  // front bottom right 1
            size,  size, -size,   color[3].x(), color[3].y(), color[3].z(),  // front top right 2
            size,  size,  size,   color[3].x(), color[3].y(), color[3].z(),  // back top right 6
            size, -size,  size,   color[3].x(), color[3].y(), color[3].z(),  // back bottom right 5
            // left side
            -size, -size, -size,  color[4].x(), color[4].y(), color[4].z(),  // front bottom left 0
            -size,  size, -size,  color[4].x(), color[4].y(), color[4].z(),  // front top left 3
            -size,  size,  size,  color[4].x(), color[4].y(), color[4].z(),  // back top left 7
            -size, -size,  size,  color[4].x(), color[4].y(), color[4].z(),  // back bottom left 4
            // back side
            -size, -size,  size,  color[5].x(), color[5].y(), color[5].z(),  //   back bottom left 4
            size, -size,  size,  color[5].x(), color[5].y(), color[5].z(),  // back bottom right 5
            size,  size,  size,  color[5].x(), color[5].y(), color[5].z(),  // back top right 6
            -size,  size,  size,  color[5].x(), color[5].y(), color[5].z()  // back top left 7
        };
    
        indices = {
            0, 1, 2, 2, 3, 0, // front
            4, 5, 6, 6, 7, 4, // top
            8, 9, 10, 10, 11, 8, // bottom
            12, 13, 14, 14, 15, 12, // right
            16, 17, 18, 18, 19, 16, // left
            20, 21, 22, 22, 23, 20 // back
        };
    }
    
    void CubeGeometry::drawCubeGeometry(QMatrix4x4 &projection, QMatrix4x4 &view, QMatrix4x4 &model)
    {
        QOpenGLContext::currentContext()->makeCurrent(QOpenGLContext::currentContext()->surface());
    
        program->setUniformValue("model", model);
        program->setUniformValue("view", view);
        program->setUniformValue("projection", projection);
    
        vao->bind();
        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, nullptr);
        vao->release();
    }
    
    void CubeGeometry::SetPosition(QVector3D position)
    {
        this->position = position;
    }
    
    QVector3D CubeGeometry::GetPosition()
    {
        return position;
    }
    

    And CubeGeometry.h

    #ifndef CUBEGEOMETRY_H
    #define CUBEGEOMETRY_H
    
    #include <QOpenGLFunctions>
    #include <QOpenGLShaderProgram>
    #include <QOpenGLVertexArrayObject>
    #include <QOpenGLBuffer>
    
    class CubeGeometry : protected QOpenGLFunctions
    {
    public:
        CubeGeometry(float size, QVector3D color[6]);
        virtual ~CubeGeometry();
    
        void initShader();
        void prepareModel();
        void drawCubeGeometry(QMatrix4x4 &projection, QMatrix4x4 &view, QMatrix4x4 &model);
        void SetPosition(QVector3D position);
        QVector3D GetPosition();
    
    private:
        void initCubeGeometry(float size, QVector3D color[6]);
    
        QOpenGLShaderProgram *program;
        QOpenGLBuffer *vertBuff;
        QOpenGLBuffer *indBuff;
        QOpenGLVertexArrayObject *vao = nullptr;
    
        QVector3D position;
    
        QVector<GLfloat> vertices;
        QVector<GLushort> indices;
    };
    
    #endif // CUBEGEOMETRY_H
    

    Main.cpp

    #include "mainwindow.h"
    
    #include <QApplication>
    #include <QSurfaceFormat>
    
    #include "openglwidget.h"
    
    int main(int argc, char *argv[])
    {
        qputenv("QSG_RHI_BACKEND", "opengl");
        QApplication a(argc, argv);
        QSurfaceFormat format;
        format.setDepthBufferSize(24);
        format.setStencilBufferSize(8);
        format.setVersion(3, 3);
        format.setProfile(QSurfaceFormat::CoreProfile);
        QSurfaceFormat::setDefaultFormat(format);
    
        OpenGLWidget widget;
        widget.show();
        return a.exec();
    }
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on 9 May 2024, 10:24 last edited by
      #2

      Hi and welcome to devnet,

      Which OS are you on ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      D 1 Reply Last reply 9 May 2024, 12:26
      0
      • S Offline
        S Offline
        SamiV123
        wrote on 9 May 2024, 10:32 last edited by SamiV123 5 Sept 2024, 10:47
        #3

        Where's your call to set the depth buffer clear value? Where's your call to use the program ?

        Anyway, my advice to you is thta you have to start with something simpler, get something working and then build from there. Looks like you copy/pasted this code from somewhere and now expect other people to solve the bug for you. There's a lot of code here with potential for many subtle bugs.

        First just make sure your widget and context setup is correct

        • check your context version that it's what you expect. I haven't used QOpenGLWidget in ages so I can't remember how it setups up the context under the hood, so check the docs!
        • do a simple test, i.e. just change the clear color and see if that works
        • render a triangle the simplest possible way, vertex + fragment shader, element array (vertex buffer)

        When everything above works you can start building more complicated stuff step by step.

        D 1 Reply Last reply 9 May 2024, 12:45
        0
        • SGaistS SGaist
          9 May 2024, 10:24

          Hi and welcome to devnet,

          Which OS are you on ?

          D Offline
          D Offline
          Dmitry44
          wrote on 9 May 2024, 12:26 last edited by
          #4

          @SGaist I'm use Windows 11

          1 Reply Last reply
          0
          • S SamiV123
            9 May 2024, 10:32

            Where's your call to set the depth buffer clear value? Where's your call to use the program ?

            Anyway, my advice to you is thta you have to start with something simpler, get something working and then build from there. Looks like you copy/pasted this code from somewhere and now expect other people to solve the bug for you. There's a lot of code here with potential for many subtle bugs.

            First just make sure your widget and context setup is correct

            • check your context version that it's what you expect. I haven't used QOpenGLWidget in ages so I can't remember how it setups up the context under the hood, so check the docs!
            • do a simple test, i.e. just change the clear color and see if that works
            • render a triangle the simplest possible way, vertex + fragment shader, element array (vertex buffer)

            When everything above works you can start building more complicated stuff step by step.

            D Offline
            D Offline
            Dmitry44
            wrote on 9 May 2024, 12:45 last edited by
            #5

            @SamiV123 Ok, thank you, I will try with smth simpler.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              Dmitry44
              wrote on 11 May 2024, 10:39 last edited by
              #6

              I found the error in this lines:

              vertBuff->allocate(&vertices[0], (int)(vertices.size() * sizeof(QVector3D)));
                                        ~~~^~~~
              indBuff->allocate(&indices[0], (int)(indices.size() * sizeof(GLushort)));
                                      ~~~^~~~
              

              Now all works correctly:
              Снимок экрана 2024-05-11 133901.png

              1 Reply Last reply
              0
              • D Dmitry44 has marked this topic as solved on 11 May 2024, 10:39

              1/6

              9 May 2024, 09:39

              • Login

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