Qt 6.7 and QOpenGLWidget issue
-
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(); }
-
Hi and welcome to devnet,
Which OS are you on ?
-
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.
-