fix the freeze with openglwidget

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97
2025-01-21 23:36:40 +02:00
parent d2516cbecc
commit 7010b8acb6
8 changed files with 81 additions and 66 deletions

View File

@@ -182,8 +182,6 @@ QVector<QVector2D> getCubeUVs(float u, float v, float width, float height, float
namespace opengl {
BoxGeometry::BoxGeometry(QVector3D size, QVector3D position) : m_indexBuf(QOpenGLBuffer::IndexBuffer), m_size(size), m_position(position)
{
initializeOpenGLFunctions();
// Generate 2 VBOs
m_vertexBuf.create();
m_indexBuf.create();

View File

@@ -25,7 +25,7 @@
#include <QVector3D>
namespace opengl {
class BoxGeometry : protected QOpenGLFunctions {
class BoxGeometry {
public:
BoxGeometry(QVector3D size, QVector3D position);
BoxGeometry(QVector3D size, QVector3D position, QPoint uv, QVector3D textureDim, QSize textureSize = { 64, 64 });

View File

@@ -26,34 +26,54 @@
#include <cmath>
#include "minecraft/skins/SkinModel.h"
#include "ui/dialogs/skins/SkinManageDialog.h"
#include "ui/dialogs/skins/draw/BoxGeometry.h"
#include "ui/dialogs/skins/draw/Scene.h"
SkinOpenGLWidget::~SkinOpenGLWidget()
SkinOpenGLWindow::SkinOpenGLWindow(SkinProvider* parent, QColor color)
: QOpenGLWindow(), QOpenGLFunctions(), m_baseColor(color), m_parent(parent)
{
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
format.setDepthBufferSize(24);
setFormat(format);
}
SkinOpenGLWindow::~SkinOpenGLWindow()
{
// Make sure the context is current when deleting the texture
// and the buffers.
makeCurrent();
delete m_scene;
delete m_background;
m_backgroundTexture->destroy();
delete m_backgroundTexture;
if (m_program->isLinked()) {
m_program->release();
// double check if resources were initialized because they are not
// initialized together with the object
if (m_scene) {
delete m_scene;
}
if (m_background) {
delete m_background;
}
if (m_backgroundTexture) {
if (m_backgroundTexture->isCreated()) {
m_backgroundTexture->destroy();
}
delete m_backgroundTexture;
}
if (m_program) {
if (m_program->isLinked()) {
m_program->release();
}
m_program->removeAllShaders();
delete m_program;
}
m_program->removeAllShaders();
delete m_program;
doneCurrent();
}
void SkinOpenGLWidget::mousePressEvent(QMouseEvent* e)
void SkinOpenGLWindow::mousePressEvent(QMouseEvent* e)
{
// Save mouse press position
m_mousePosition = QVector2D(e->pos());
m_isMousePressed = true;
}
void SkinOpenGLWidget::mouseMoveEvent(QMouseEvent* event)
void SkinOpenGLWindow::mouseMoveEvent(QMouseEvent* event)
{
if (m_isMousePressed) {
int dx = event->x() - m_mousePosition.x();
@@ -72,12 +92,13 @@ void SkinOpenGLWidget::mouseMoveEvent(QMouseEvent* event)
update(); // Trigger a repaint
}
}
void SkinOpenGLWidget::mouseReleaseEvent([[maybe_unused]] QMouseEvent* e)
void SkinOpenGLWindow::mouseReleaseEvent([[maybe_unused]] QMouseEvent* e)
{
m_isMousePressed = false;
}
void SkinOpenGLWidget::initializeGL()
void SkinOpenGLWindow::initializeGL()
{
initializeOpenGLFunctions();
@@ -89,11 +110,11 @@ void SkinOpenGLWidget::initializeGL()
QImage skin, cape;
bool slim = false;
if (auto p = dynamic_cast<SkinManageDialog*>(parent()); p) {
if (auto s = p->getSelectedSkin()) {
if (m_parent) {
if (auto s = m_parent->getSelectedSkin()) {
skin = s->getTexture();
slim = s->getModel() == SkinModel::SLIM;
cape = p->capes().value(s->getCapeId(), {});
cape = m_parent->capes().value(s->getCapeId(), {});
}
}
@@ -102,7 +123,7 @@ void SkinOpenGLWidget::initializeGL()
glEnable(GL_TEXTURE_2D);
}
void SkinOpenGLWidget::initShaders()
void SkinOpenGLWindow::initShaders()
{
m_program = new QOpenGLShaderProgram(this);
// Compile vertex shader
@@ -122,7 +143,7 @@ void SkinOpenGLWidget::initShaders()
close();
}
void SkinOpenGLWidget::resizeGL(int w, int h)
void SkinOpenGLWindow::resizeGL(int w, int h)
{
// Calculate aspect ratio
qreal aspect = qreal(w) / qreal(h ? h : 1);
@@ -136,7 +157,7 @@ void SkinOpenGLWidget::resizeGL(int w, int h)
m_projection.perspective(fov, aspect, zNear, zFar);
}
void SkinOpenGLWidget::paintGL()
void SkinOpenGLWindow::paintGL()
{
// Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -171,7 +192,7 @@ void SkinOpenGLWidget::paintGL()
m_program->release();
}
void SkinOpenGLWidget::updateScene(SkinModel* skin)
void SkinOpenGLWindow::updateScene(SkinModel* skin)
{
if (skin && m_scene) {
m_scene->setMode(skin->getModel() == SkinModel::SLIM);
@@ -179,7 +200,7 @@ void SkinOpenGLWidget::updateScene(SkinModel* skin)
update();
}
}
void SkinOpenGLWidget::updateCape(const QImage& cape)
void SkinOpenGLWindow::updateCape(const QImage& cape)
{
if (m_scene) {
m_scene->setCapeVisible(!cape.isNull());
@@ -236,16 +257,16 @@ QImage generateChessboardImage(int width, int height, int tileSize, QColor baseC
return image;
}
void SkinOpenGLWidget::generateBackgroundTexture(int width, int height, int tileSize)
void SkinOpenGLWindow::generateBackgroundTexture(int width, int height, int tileSize)
{
m_backgroundTexture =
new QOpenGLTexture(generateChessboardImage(width, height, tileSize, palette().color(QPalette::Normal, QPalette::Base)));
m_backgroundTexture = new QOpenGLTexture(generateChessboardImage(width, height, tileSize, m_baseColor));
m_backgroundTexture->setMinificationFilter(QOpenGLTexture::Nearest);
m_backgroundTexture->setMagnificationFilter(QOpenGLTexture::Nearest);
}
void SkinOpenGLWidget::renderBackground()
void SkinOpenGLWindow::renderBackground()
{
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE); // Disable depth buffer writing
m_backgroundTexture->bind();
QMatrix4x4 matrix;
@@ -254,9 +275,10 @@ void SkinOpenGLWidget::renderBackground()
m_background->draw(m_program);
m_backgroundTexture->release();
glDepthMask(GL_TRUE); // Re-enable depth buffer writing
glEnable(GL_DEPTH_TEST);
}
void SkinOpenGLWidget::wheelEvent(QWheelEvent* event)
void SkinOpenGLWindow::wheelEvent(QWheelEvent* event)
{
// Adjust distance based on scroll
int delta = event->angleDelta().y(); // Positive for scroll up, negative for scroll down

View File

@@ -22,18 +22,23 @@
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QOpenGLWidget>
#include <QOpenGLWindow>
#include <QVector2D>
#include "minecraft/skins/SkinModel.h"
#include "ui/dialogs/skins/draw/BoxGeometry.h"
#include "ui/dialogs/skins/draw/Scene.h"
class SkinOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions {
class SkinProvider {
public:
virtual SkinModel* getSelectedSkin() = 0;
virtual QHash<QString, QImage> capes() = 0;
};
class SkinOpenGLWindow : public QOpenGLWindow, protected QOpenGLFunctions {
Q_OBJECT
public:
SkinOpenGLWidget(QWidget* parent = nullptr) : QOpenGLWidget(parent), QOpenGLFunctions() {}
virtual ~SkinOpenGLWidget();
SkinOpenGLWindow(SkinProvider* parent, QColor color);
virtual ~SkinOpenGLWindow();
void updateScene(SkinModel* skin);
void updateCape(const QImage& cape);
@@ -68,4 +73,6 @@ class SkinOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions {
opengl::BoxGeometry* m_background = nullptr;
QOpenGLTexture* m_backgroundTexture = nullptr;
QColor m_baseColor;
SkinProvider* m_parent = nullptr;
};