From 87ec7cdd3951bad258f58c065b3a82861f104477 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 10 Jan 2025 14:54:40 +0200 Subject: [PATCH] move background to vertex buffer Signed-off-by: Trial97 --- .github/workflows/build.yml | 12 ++-- CMakeLists.txt | 3 +- launcher/CMakeLists.txt | 2 +- launcher/resources/shaders/fshader.glsl | 1 - .../ui/dialogs/skins/draw/BoxGeometry.cpp | 30 +++++++++- launcher/ui/dialogs/skins/draw/BoxGeometry.h | 2 + launcher/ui/dialogs/skins/draw/Scene.cpp | 1 + .../dialogs/skins/draw/SkinOpenGLWidget.cpp | 56 ++++++++----------- .../ui/dialogs/skins/draw/SkinOpenGLWidget.h | 7 ++- 9 files changed, 68 insertions(+), 46 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c574a335e..0770b66dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -60,14 +60,14 @@ jobs: qt_host: linux qt_arch: "" qt_version: "5.15.2" - qt_modules: "qtnetworkauth opengl openglwidgets" + qt_modules: "qtnetworkauth" - os: ubuntu-20.04 qt_ver: 6 qt_host: linux qt_arch: "" qt_version: "6.5.3" - qt_modules: "qt5compat qtimageformats qtnetworkauth opengl openglwidgets" + qt_modules: "qt5compat qtimageformats qtnetworkauth" - os: windows-2022 name: "Windows-MinGW-w64" @@ -83,7 +83,7 @@ jobs: qt_host: windows qt_arch: "" qt_version: "6.7.3" - qt_modules: "qt5compat qtimageformats qtnetworkauth opengl openglwidgets" + qt_modules: "qt5compat qtimageformats qtnetworkauth" nscurl_tag: "v24.9.26.122" nscurl_sha256: "AEE6C4BE3CB6455858E9C1EE4B3AFE0DB9960FA03FE99CCDEDC28390D57CCBB0" @@ -96,7 +96,7 @@ jobs: qt_host: windows qt_arch: "win64_msvc2019_arm64" qt_version: "6.7.3" - qt_modules: "qt5compat qtimageformats qtnetworkauth opengl openglwidgets" + qt_modules: "qt5compat qtimageformats qtnetworkauth" nscurl_tag: "v24.9.26.122" nscurl_sha256: "AEE6C4BE3CB6455858E9C1EE4B3AFE0DB9960FA03FE99CCDEDC28390D57CCBB0" @@ -107,7 +107,7 @@ jobs: qt_host: mac qt_arch: "" qt_version: "6.7.3" - qt_modules: "qt5compat qtimageformats qtnetworkauth opengl openglwidgets" + qt_modules: "qt5compat qtimageformats qtnetworkauth" - os: macos-14 name: macOS-Legacy @@ -115,7 +115,7 @@ jobs: qt_ver: 5 qt_host: mac qt_version: "5.15.2" - qt_modules: "qtnetworkauth opengl openglwidgets" + qt_modules: "qtnetworkauth" runs-on: ${{ matrix.os }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 59be32133..9d59f83ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -298,7 +298,7 @@ endif() include(QtVersionlessBackport) if(Launcher_QT_VERSION_MAJOR EQUAL 5) set(QT_VERSION_MAJOR 5) - find_package(Qt5 REQUIRED COMPONENTS Core Widgets Concurrent Network Test Xml NetworkAuth OpenGL OpenGLWidgets) + find_package(Qt5 REQUIRED COMPONENTS Core Widgets Concurrent Network Test Xml NetworkAuth OpenGL) find_package(Qt5 COMPONENTS DBus) list(APPEND Launcher_QT_DBUS Qt5::DBus) @@ -318,6 +318,7 @@ elseif(Launcher_QT_VERSION_MAJOR EQUAL 6) find_package(Qt6 COMPONENTS DBus) list(APPEND Launcher_QT_DBUS Qt6::DBus) list(APPEND Launcher_QT_LIBS Qt6::Core5Compat) + list(APPEND Launcher_QT_OpenGL Qt6::OpenGLWidgets) if(NOT Launcher_FORCE_BUNDLED_LIBS) find_package(QuaZip-Qt6 1.3 QUIET) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index daea70a2c..c79f5e600 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1305,7 +1305,7 @@ target_link_libraries(Launcher_logic Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::NetworkAuth Qt${QT_VERSION_MAJOR}::OpenGL - Qt${QT_VERSION_MAJOR}::OpenGLWidgets + ${Launcher_QT_OpenGL} ${Launcher_QT_DBUS} ${Launcher_QT_LIBS} ) diff --git a/launcher/resources/shaders/fshader.glsl b/launcher/resources/shaders/fshader.glsl index 7bdf6c178..d6a93db5d 100644 --- a/launcher/resources/shaders/fshader.glsl +++ b/launcher/resources/shaders/fshader.glsl @@ -14,7 +14,6 @@ varying vec2 v_texcoord; void main() { // Set fragment color from texture - // gl_FragColor = texture2D(texture, v_texcoord); vec4 texColor = texture2D(texture, v_texcoord); if (texColor.a < 0.1) discard; // Optional: Discard fully transparent pixels gl_FragColor = texColor; diff --git a/launcher/ui/dialogs/skins/draw/BoxGeometry.cpp b/launcher/ui/dialogs/skins/draw/BoxGeometry.cpp index 9d2a5614d..507c13e86 100644 --- a/launcher/ui/dialogs/skins/draw/BoxGeometry.cpp +++ b/launcher/ui/dialogs/skins/draw/BoxGeometry.cpp @@ -68,6 +68,16 @@ static const QVector indices = { 20, 20, 21, 22, 23 // Face 5 - triangle strip (v20, v21, v22, v23) }; +static const QVector planeVertices = { + { QVector4D(-1.0f, -1.0f, -0.5f, 1.0f), QVector2D(0.0f, 0.0f) }, // Bottom-left + { QVector4D(1.0f, -1.0f, -0.5f, 1.0f), QVector2D(1.0f, 0.0f) }, // Bottom-right + { QVector4D(-1.0f, 1.0f, -0.5f, 1.0f), QVector2D(0.0f, 1.0f) }, // Top-left + { QVector4D(1.0f, 1.0f, -0.5f, 1.0f), QVector2D(1.0f, 1.0f) }, // Top-right +}; +static const QVector planeIndices = { + 0, 1, 2, 3, 3 // Face 0 - triangle strip ( v0, v1, v2, v3) +}; + QVector transformVectors(const QMatrix4x4& matrix, const QVector& vectors) { QVector transformedVectors; @@ -117,7 +127,6 @@ QVector getCubeUVs(float u, float v, float width, float height, float left[2], }; auto uvTop = { - top[0], top[1], top[3], @@ -198,7 +207,7 @@ void BoxGeometry::draw(QOpenGLShaderProgram* program) program->setAttributeBuffer(texcoordLocation, GL_FLOAT, offset, 2, sizeof(VertexData)); // Draw cube geometry using indices from VBO 1 - glDrawElements(GL_TRIANGLE_STRIP, indices.size(), GL_UNSIGNED_SHORT, nullptr); + glDrawElements(GL_TRIANGLE_STRIP, m_indecesCount, GL_UNSIGNED_SHORT, nullptr); } void BoxGeometry::initGeometry(float u, float v, float width, float height, float depth, float textureWidth, float textureHeight) @@ -226,10 +235,27 @@ void BoxGeometry::initGeometry(float u, float v, float width, float height, floa // Transfer index data to VBO 1 m_indexBuf.bind(); m_indexBuf.allocate(indices.constData(), indices.size() * sizeof(GLushort)); + m_indecesCount = indices.size(); } void BoxGeometry::rotate(float angle, const QVector3D& vector) { m_matrix.rotate(angle, vector); } + +BoxGeometry* BoxGeometry::Plane() +{ + auto b = new BoxGeometry(QVector3D(), QVector3D()); + + // Transfer vertex data to VBO 0 + b->m_vertexBuf.bind(); + b->m_vertexBuf.allocate(planeVertices.constData(), planeVertices.size() * sizeof(VertexData)); + + // Transfer index data to VBO 1 + b->m_indexBuf.bind(); + b->m_indexBuf.allocate(planeIndices.constData(), planeIndices.size() * sizeof(GLushort)); + b->m_indecesCount = planeIndices.size(); + + return b; +} } // namespace opengl \ No newline at end of file diff --git a/launcher/ui/dialogs/skins/draw/BoxGeometry.h b/launcher/ui/dialogs/skins/draw/BoxGeometry.h index c3a7d9a40..d706edc6f 100644 --- a/launcher/ui/dialogs/skins/draw/BoxGeometry.h +++ b/launcher/ui/dialogs/skins/draw/BoxGeometry.h @@ -11,6 +11,7 @@ class BoxGeometry : protected QOpenGLFunctions { public: BoxGeometry(QVector3D size, QVector3D position); BoxGeometry(QVector3D size, QVector3D position, QPoint uv, QVector3D textureDim, QSize textureSize = { 64, 64 }); + static BoxGeometry* Plane(); virtual ~BoxGeometry(); void draw(QOpenGLShaderProgram* program); @@ -24,5 +25,6 @@ class BoxGeometry : protected QOpenGLFunctions { QVector3D m_size; QVector3D m_position; QMatrix4x4 m_matrix; + GLsizei m_indecesCount; }; } // namespace opengl diff --git a/launcher/ui/dialogs/skins/draw/Scene.cpp b/launcher/ui/dialogs/skins/draw/Scene.cpp index 48f2d9800..4512b0c83 100644 --- a/launcher/ui/dialogs/skins/draw/Scene.cpp +++ b/launcher/ui/dialogs/skins/draw/Scene.cpp @@ -56,6 +56,7 @@ Scene::~Scene() } } delete m_cape; + m_skinTexture->destroy(); delete m_skinTexture; diff --git a/launcher/ui/dialogs/skins/draw/SkinOpenGLWidget.cpp b/launcher/ui/dialogs/skins/draw/SkinOpenGLWidget.cpp index 7a1eeac44..ac8fd94f5 100644 --- a/launcher/ui/dialogs/skins/draw/SkinOpenGLWidget.cpp +++ b/launcher/ui/dialogs/skins/draw/SkinOpenGLWidget.cpp @@ -6,6 +6,7 @@ #include #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() @@ -14,7 +15,9 @@ SkinOpenGLWidget::~SkinOpenGLWidget() // and the buffers. makeCurrent(); delete m_scene; - glDeleteTextures(1, &m_chessboardTexture); + delete m_background; + m_backgroundTexture->destroy(); + delete m_backgroundTexture; doneCurrent(); } @@ -38,7 +41,7 @@ void SkinOpenGLWidget::mouseMoveEvent(QMouseEvent* event) update(); // Trigger a repaint } } -void SkinOpenGLWidget::mouseReleaseEvent(QMouseEvent* e) +void SkinOpenGLWidget::mouseReleaseEvent([[maybe_unused]] QMouseEvent* e) { m_isMousePressed = false; } @@ -51,7 +54,7 @@ void SkinOpenGLWidget::initializeGL() initShaders(); - m_chessboardTexture = generateChessboardTexture(512, 512, 16); + generateBackgroundTexture(32, 32, 1); QImage skin, cape; bool slim = false; @@ -64,6 +67,7 @@ void SkinOpenGLWidget::initializeGL() } m_scene = new opengl::Scene(skin, slim, cape); + m_background = opengl::BoxGeometry::Plane(); glEnable(GL_TEXTURE_2D); } @@ -115,10 +119,9 @@ void SkinOpenGLWidget::paintGL() glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - renderBackground(); - m_program.bind(); + renderBackground(); // Calculate model view transformation QMatrix4x4 matrix; matrix.translate(0.0, 6.0, -50.); @@ -149,47 +152,36 @@ void SkinOpenGLWidget::updateCape(const QImage& cape) } } -GLuint SkinOpenGLWidget::generateChessboardTexture(int width, int height, int tileSize) +QImage generateChessboardImage(int width, int height, int tileSize) { - std::vector textureData(width * height * 3); + QImage image(width, height, QImage::Format_RGB888); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { bool isWhite = ((x / tileSize) % 2) == ((y / tileSize) % 2); unsigned char color = isWhite ? 100 : 50; - int index = (y * width + x) * 3; - textureData[index] = color; // Red - textureData[index + 1] = color; // Green - textureData[index + 2] = color; // Blue + image.setPixelColor(x, y, QColor(color, color, color)); } } + return image; +} - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData.data()); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - return texture; +void SkinOpenGLWidget::generateBackgroundTexture(int width, int height, int tileSize) +{ + m_backgroundTexture = new QOpenGLTexture(generateChessboardImage(width, height, tileSize)); + m_backgroundTexture->setMinificationFilter(QOpenGLTexture::Nearest); + m_backgroundTexture->setMagnificationFilter(QOpenGLTexture::Nearest); } void SkinOpenGLWidget::renderBackground() { glDepthMask(GL_FALSE); // Disable depth buffer writing - glBindTexture(GL_TEXTURE_2D, m_chessboardTexture); - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); - glVertex3f(-1.0f, -1.0f, -0.5f); // Bottom-left - glTexCoord2f(1.0f, 0.0f); - glVertex3f(1.0f, -1.0f, -0.5f); // Bottom-right - glTexCoord2f(1.0f, 1.0f); - glVertex3f(1.0f, 1.0f, -0.5f); // Top-right - glTexCoord2f(0.0f, 1.0f); - glVertex3f(-1.0f, 1.0f, -0.5f); // Top-left - glEnd(); + m_backgroundTexture->bind(); + QMatrix4x4 matrix; + m_program.setUniformValue("mvp_matrix", matrix); + m_program.setUniformValue("texture", 0); + m_background->draw(&m_program); + m_backgroundTexture->release(); glDepthMask(GL_TRUE); // Re-enable depth buffer writing } diff --git a/launcher/ui/dialogs/skins/draw/SkinOpenGLWidget.h b/launcher/ui/dialogs/skins/draw/SkinOpenGLWidget.h index 2c56cc278..6a3f68637 100644 --- a/launcher/ui/dialogs/skins/draw/SkinOpenGLWidget.h +++ b/launcher/ui/dialogs/skins/draw/SkinOpenGLWidget.h @@ -7,6 +7,7 @@ #include #include #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 { @@ -30,7 +31,7 @@ class SkinOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions { void initShaders(); - GLuint generateChessboardTexture(int width, int height, int tileSize); + void generateBackgroundTexture(int width, int height, int tileSize); void renderBackground(); private: @@ -44,6 +45,6 @@ class SkinOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions { bool m_isMousePressed = false; int m_rotationX = 0, m_rotationY = 0; - // background - GLuint m_chessboardTexture; + opengl::BoxGeometry* m_background = nullptr; + QOpenGLTexture* m_backgroundTexture = nullptr; };