shaunrd0 / qtk

Practice using OpenGL in Qt widget applications
GNU General Public License v3.0
1 stars 1 forks source link

Windows #2

Closed OgreTransporter closed 2 years ago

OgreTransporter commented 2 years ago

I've put together a few bug fixes here to make the code run on Windows.

Unfortunately, I cannot create pull requests at this time. I have problems with the access tokens from GitHub and SSH doesn't work either.

Fix resource path on Windows

Under Windows, a \ is used instead of / in paths, so searching for src/ does not work.

diff --git a/src/resourcemanager.cpp b/src/resourcemanager.cpp
index 71ffbf6..1bef4bf 100644
--- a/src/resourcemanager.cpp
+++ b/src/resourcemanager.cpp
@@ -7,7 +7,17 @@
 ##############################################################################*/

 #include "resourcemanager.h"
+#include <algorithm>
+#include <string>
+#include <QtGlobal>
+
+static std::string nixPath(std::string path)
+{
+#ifdef Q_OS_WINDOWS
+   std::replace(path.begin(), path.end(), '\\', '/');
+#endif
+   return path;
+}

 std::string RM::resourcesDir =
-    std::string(__FILE__).substr(0, std::string(__FILE__).find("src/"))
-    + "resources/";
+   std::string(__FILE__).substr(0, nixPath(__FILE__).find("src/")) + "resources/";

Fix for missing OpenGL functions on Windows (error C3861: "glActiveTexture": identifier not found.)

If you do not explicitly search for OpenGL in Windows, OpenGL 2 is used. There functions like glActiveTexture do not exist yet. Under Qt there is as solution the class QOpenGLFunctions (https://doc.qt.io/qt-6/qopenglfunctions.html).

diff --git a/src/model.cpp b/src/model.cpp
index 5e32677..f814328 100644
--- a/src/model.cpp
+++ b/src/model.cpp
@@ -31,6 +31,8 @@ Model * Model::getInstance(const char * name)

 void ModelMesh::initMesh(const char * vert, const char * frag)
 {
+  initializeOpenGLFunctions();
+
   // Create VAO, VBO, EBO
   mVAO->create();
   mVBO->create();
diff --git a/src/model.h b/src/model.h
index 47c5124..6a0c2de 100644
--- a/src/model.h
+++ b/src/model.h
@@ -43,7 +43,7 @@ struct ModelTexture {

 class Model;

-class ModelMesh {
+class ModelMesh : protected QOpenGLFunctions {
 public:
   friend Model;
   typedef std::vector<ModelVertex> Vertices;
diff --git a/src/skybox.cpp b/src/skybox.cpp
index 87aa163..6b7db76 100644
--- a/src/skybox.cpp
+++ b/src/skybox.cpp
@@ -69,6 +69,8 @@ void Skybox::draw()

 void Skybox::init()
 {
+  initializeOpenGLFunctions();
+
   // Set up shader program
   mProgram.create();
   mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/skybox.vert");
diff --git a/src/skybox.h b/src/skybox.h
index 83ab04d..7ededd0 100644
--- a/src/skybox.h
+++ b/src/skybox.h
@@ -13,12 +13,13 @@
 #include <QOpenGLShaderProgram>
 #include <QOpenGLTexture>
 #include <QOpenGLVertexArrayObject>
+#include <QOpenGLFunctions>

 #include <camera3d.h>
 #include <mesh.h>

-class Skybox {
+class Skybox : protected QOpenGLFunctions {
 public:
   // Delegate this constructor to use default skybox images
   // + This allows creating a skybox with no arguments ( auto s = new Skybox; )

The library is STATIC

The created library is static and not shared! Q_DECL_EXPORT must be added to the declarations of symbols used when compiling a shared library (see https://doc.qt.io/qt-6/sharedlibrary.html).

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e7103cc..df7d238 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -50,7 +50,7 @@ find_package(assimp REQUIRED)

 # Mainwidget
 include(GenerateExportHeader)
-add_library(main-widget SHARED
+add_library(main-widget STATIC
     src/mainwidget.cpp src/mainwidget.h
     src/mainwindow.cpp src/mainwindow.h src/mainwindow.ui
     src/input.cpp src/input.h
@@ -73,6 +73,10 @@ else()
     target_link_libraries(main-widget PRIVATE assimp)
 endif()
 target_link_libraries(main-widget PUBLIC Qt6::OpenGLWidgets)
+if(WIN32)
+    find_package(OpenGL REQUIRED)
+    target_link_libraries(main-widget PUBLIC OpenGL::GL)
+endif()

 ################################################################################
 # Final Application

On Windows, the library also requires OpenGL.

CMake fix for newer assimp versions

In newer assimp versions the CMake target is no longer assimp but assimp::assimp.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 97ef03b..e7103cc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,8 +67,12 @@ add_library(main-widget SHARED
 )

 target_include_directories(main-widget PUBLIC src/)
-target_link_libraries(main-widget PRIVATE assimp)
-target_link_libraries(main-widget PUBLIC Qt${QT_VERSION_MAJOR}::OpenGLWidgets)
+if(TARGET assimp::assimp)
+    target_link_libraries(main-widget PRIVATE assimp::assimp)
+else()
+    target_link_libraries(main-widget PRIVATE assimp)
+endif()
+target_link_libraries(main-widget PUBLIC Qt6::OpenGLWidgets)

 ################################################################################
 # Final Application

After the small changes, loading models works very well. I have tried many other examples that do not work. The only thing that does not work is the skybox.

qtk-screenshot-win10
OgreTransporter commented 2 years ago

The patches also work in the texture branch

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9797af6..adb2b93 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -47,7 +47,7 @@ find_package(assimp REQUIRED)

 # Mainwidget
 include(GenerateExportHeader)
-add_library(main-widget SHARED
+add_library(main-widget STATIC
     src/mainwidget.cpp src/mainwidget.h
     src/mainwindow.cpp src/mainwindow.h src/mainwindow.ui
     src/input.cpp src/input.h
@@ -64,8 +64,16 @@ add_library(main-widget SHARED
 )

 target_include_directories(main-widget PUBLIC src/)
-target_link_libraries(main-widget PRIVATE assimp)
-target_link_libraries(main-widget PUBLIC Qt${QT_VERSION_MAJOR}::OpenGLWidgets)
+if(TARGET assimp::assimp)
+    target_link_libraries(main-widget PRIVATE assimp::assimp)
+else()
+    target_link_libraries(main-widget PRIVATE assimp)
+endif()
+target_link_libraries(main-widget PUBLIC Qt6::OpenGLWidgets)
+if(WIN32)
+    find_package(OpenGL REQUIRED)
+    target_link_libraries(main-widget PUBLIC OpenGL::GL)
+endif()

 ################################################################################
 # Final Application
diff --git a/src/model.cpp b/src/model.cpp
index d411d36..d8fb37c 100644
--- a/src/model.cpp
+++ b/src/model.cpp
@@ -31,6 +31,8 @@ Model * Model::getInstance(const char * name)

 void ModelMesh::initMesh(const char * vert, const char * frag)
 {
+  initializeOpenGLFunctions();
+
   // Create VAO, VBO, EBO
   mVAO->create();
   mVBO->create();
diff --git a/src/model.h b/src/model.h
index 89da513..50c7c26 100644
--- a/src/model.h
+++ b/src/model.h
@@ -16,6 +16,7 @@
 #include <QOpenGLShaderProgram>
 #include <QOpenGLTexture>
 #include <QOpenGLVertexArrayObject>
+#include <QOpenGLFunctions>

 // Assimp
 #include <assimp/Importer.hpp>
@@ -44,7 +45,7 @@ struct ModelTexture {

 class Model;

-class ModelMesh {
+class ModelMesh : protected QOpenGLFunctions {
 public:
   friend Model;
   typedef std::vector<ModelVertex> Vertices;
diff --git a/src/resourcemanager.cpp b/src/resourcemanager.cpp
index 71ffbf6..b1b6b60 100644
--- a/src/resourcemanager.cpp
+++ b/src/resourcemanager.cpp
@@ -7,7 +7,18 @@
 ##############################################################################*/

 #include "resourcemanager.h"
+#include <algorithm>
+#include <string>
+#include <QtGlobal>
+
+static std::string nixPath(std::string path)
+{
+#ifdef Q_OS_WINDOWS
+    std::replace(path.begin(), path.end(), '\\', '/');
+#endif
+    return path;
+}

 std::string RM::resourcesDir =
-    std::string(__FILE__).substr(0, std::string(__FILE__).find("src/"))
+    std::string(__FILE__).substr(0, nixPath(__FILE__).find("src/"))
     + "resources/";
diff --git a/src/skybox.cpp b/src/skybox.cpp
index 3b6ed23..a6e1225 100644
--- a/src/skybox.cpp
+++ b/src/skybox.cpp
@@ -69,6 +69,8 @@ void Skybox::draw()

 void Skybox::init()
 {
+  initializeOpenGLFunctions();
+
   // Set up shader program
   mProgram.create();
   mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/skybox.vert");
diff --git a/src/skybox.h b/src/skybox.h
index 83ab04d..7ededd0 100644
--- a/src/skybox.h
+++ b/src/skybox.h
@@ -13,12 +13,13 @@
 #include <QOpenGLShaderProgram>
 #include <QOpenGLTexture>
 #include <QOpenGLVertexArrayObject>
+#include <QOpenGLFunctions>

 #include <camera3d.h>
 #include <mesh.h>

-class Skybox {
+class Skybox : protected QOpenGLFunctions {
 public:
   // Delegate this constructor to use default skybox images
   // + This allows creating a skybox with no arguments ( auto s = new Skybox; )
shaunrd0 commented 2 years ago

This is great, thanks for the contribution - I'll push a commit with your patch and give attribution for your work. I can get some CI for Windows set up this week to make sure Windows builds pass moving forward.