Fix integration with Qt Creator
Add cmake build options in format of `QTK_*` + `QTK_UPDATE_SUBMODULES` to include Assimp as a git submodule + `QTK_BUILD_SHARED_LIBS` to toggle building Qtk as Shared / Static
This commit is contained in:
parent
6cdf906065
commit
0ed53f1f69
|
@ -15,10 +15,83 @@ jobs:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH="/home/runner/work/qtk/Qt/6.3.1/gcc_64/"
|
cmake: -DCMAKE_PREFIX_PATH="/home/runner/work/qtk/Qt/6.3.1/gcc_64/"
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH="D:/a/qtk/qtk/Qt/6.3.1/mingw81_64/"
|
cmake: -DCMAKE_PREFIX_PATH="D:/a/qtk/qtk/Qt/6.3.1/mingw81_64/" -DASSIMP_WARNINGS_AS_ERRORS=OFF
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH="/home/runner/work/qtk/Qt/6.3.1/gcc_64/"
|
cmake: -DCMAKE_PREFIX_PATH="/home/runner/work/qtk/Qt/6.3.1/gcc_64/"
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install Qt
|
||||||
|
uses: jurplel/install-qt-action@v2
|
||||||
|
with:
|
||||||
|
version: '6.3.1'
|
||||||
|
|
||||||
|
- name: Chocolatey Action
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
uses: crazy-max/ghaction-chocolatey@v2.0.0
|
||||||
|
with:
|
||||||
|
args: install pkgconfiglite
|
||||||
|
|
||||||
|
- name: Build Qtk
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cmake -S . -B build/ ${{ matrix.cmake }} && cmake --build build/ \
|
||||||
|
--target qtk-main
|
||||||
|
|
||||||
|
|
||||||
|
Build-Qtk-Assimp-Targets:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest]
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
cmake: -DCMAKE_PREFIX_PATH="/home/runner/work/qtk/Qt/6.3.1/gcc_64/" -DQTK_UPDATE_SUBMODULES=OFF
|
||||||
|
- os: macos-latest
|
||||||
|
cmake: -DCMAKE_PREFIX_PATH="/home/runner/work/qtk/Qt/6.3.1/gcc_64/" -DASSIMP_NEW_INTERFACE=ON -DQTK_UPDATE_SUBMODULES=OFF
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install Qt
|
||||||
|
uses: jurplel/install-qt-action@v2
|
||||||
|
with:
|
||||||
|
version: '6.3.1'
|
||||||
|
|
||||||
|
- name: Install Assimp MacOS
|
||||||
|
if: matrix.os == 'macos-latest'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
brew install assimp
|
||||||
|
|
||||||
|
- name: Install Assimp Ubuntu
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt install libassimp-dev
|
||||||
|
|
||||||
|
- name: Build Qtk
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cmake -S . -B build/ ${{ matrix.cmake }} && cmake --build build/ \
|
||||||
|
--target qtk-main
|
||||||
|
|
||||||
|
Build-Qtk-Static:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
cmake: -DCMAKE_PREFIX_PATH="/home/runner/work/qtk/Qt/6.3.1/gcc_64/" -DQTK_BUILD_SHARED_LIBS=OFF
|
||||||
|
- os: windows-latest
|
||||||
|
cmake: -DCMAKE_PREFIX_PATH="D:/a/qtk/qtk/Qt/6.3.1/mingw81_64/" -DQTK_BUILD_SHARED_LIBS=OFF
|
||||||
|
- os: macos-latest
|
||||||
|
cmake: -DCMAKE_PREFIX_PATH="/home/runner/work/qtk/Qt/6.3.1/gcc_64/" -DQTK_BUILD_SHARED_LIBS=OFF
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
@ -31,4 +104,5 @@ jobs:
|
||||||
- name: Build Qtk
|
- name: Build Qtk
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
cmake -S . -B build/ ${{ matrix.cmake }} && cmake --build build/
|
cmake -S . -B build/ ${{ matrix.cmake }} && cmake --build build/ \
|
||||||
|
--target qtk-main
|
||||||
|
|
|
@ -19,22 +19,35 @@ set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
#if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
add_compile_options(/wd4131 /wd4127)
|
# add_compile_options(/wd4131 /wd4127)
|
||||||
endif()
|
#endif()
|
||||||
message(STATUS "[Qtk]: Compiling with ${CMAKE_CXX_COMPILER_ID}")
|
message(STATUS "[Qtk] Compiling with ${CMAKE_CXX_COMPILER_ID}")
|
||||||
|
|
||||||
# Qtk build options
|
# Qtk build options
|
||||||
option(QTK_DEBUG "Enable debugger" ON)
|
option(QTK_DEBUG "Enable debugger" ON)
|
||||||
option(BUILD_SHARED_LIBS "Build shared library" ON)
|
message(STATUS "[Qtk] Compiling with QTK_DEBUG=${QTK_DEBUG}")
|
||||||
|
option(QTK_BUILD_SHARED_LIBS "Build shared library" ON)
|
||||||
|
message(
|
||||||
|
STATUS
|
||||||
|
"[Qtk] Compiling with QTK_BUILD_SHARED_LIBS=${QTK_BUILD_SHARED_LIBS}"
|
||||||
|
)
|
||||||
|
option(QTK_UPDATE_SUBMODULES "Update external project (assimp) submodule" ON)
|
||||||
|
message(
|
||||||
|
STATUS
|
||||||
|
"[Qtk] Compiling with QTK_UPDATE_SUBMODULES=${QTK_UPDATE_SUBMODULES}"
|
||||||
|
)
|
||||||
|
|
||||||
# Qt options
|
# Qt options
|
||||||
set(QT_DIR "$ENV{HOME}/Code/Clones/Qt/6.3.1/gcc_64/" CACHE PATH "Path to Qt6")
|
set(QT_DIR "$ENV{HOME}/Code/Clones/Qt/6.3.1/gcc_64/" CACHE PATH "Path to Qt6")
|
||||||
|
|
||||||
# Options for bringing your own assimp installation; Otherwise not needed
|
# Options for bringing your own assimp installation; Otherwise not needed
|
||||||
# + If assimp is available system-wide we can just set UPDATE_SUBMODULES OFF
|
# + If assimp is available system-wide we can just set QTK_UPDATE_SUBMODULES OFF
|
||||||
option(UPDATE_SUBMODULES "Update external project (assimp) git submodule" ON)
|
|
||||||
option(ASSIMP_NEW_INTERFACE "Use the assimp::assimp interface (WIN / OSX)" OFF)
|
option(ASSIMP_NEW_INTERFACE "Use the assimp::assimp interface (WIN / OSX)" OFF)
|
||||||
|
message(
|
||||||
|
STATUS
|
||||||
|
"[Qtk] Compiling with ASSIMP_NEW_INTERFACE=${ASSIMP_NEW_INTERFACE}"
|
||||||
|
)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# External Libraries
|
# External Libraries
|
||||||
|
@ -47,15 +60,25 @@ list(APPEND CMAKE_PREFIX_PATH "${QT_DIR}")
|
||||||
# Find Qt
|
# Find Qt
|
||||||
find_package(Qt6 COMPONENTS OpenGLWidgets)
|
find_package(Qt6 COMPONENTS OpenGLWidgets)
|
||||||
if (NOT Qt6_FOUND)
|
if (NOT Qt6_FOUND)
|
||||||
message(SEND_ERROR "[Qtk] Error: Unable to find Qt6 at CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
|
message(
|
||||||
message(FATAL_ERROR "[Qtk] Error: Specify path to Qt6 with `cmake -DCMAKE_PREFIX_PATH=/path/to/Qt/6.x.x/gcc_64 -S /path/to/qtk -B /path/to/qtk/build && cmake --build /path/to/qtk/build -j $(nprocs)`")
|
SEND_ERROR "[Qtk] Error: Unable to find Qt6 at CMAKE_PREFIX_PATH: "
|
||||||
|
"${CMAKE_PREFIX_PATH}"
|
||||||
|
)
|
||||||
|
message(
|
||||||
|
FATAL_ERROR
|
||||||
|
"[Qtk] Error: Specify path to Qt6 with `cmake "
|
||||||
|
"-DCMAKE_PREFIX_PATH=/path/to/Qt/6.x.x/gcc_64 -S /path/to/qtk -B "
|
||||||
|
"/path/to/qtk/build && cmake --build /path/to/qtk/build -j $(nprocs)`"
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (UPDATE_SUBMODULES)
|
if (QTK_UPDATE_SUBMODULES)
|
||||||
message(STATUS "[Qtk]: Updating submodules...")
|
message(STATUS "[Qtk] Updating submodules...")
|
||||||
include("${CMAKE_SOURCE_DIR}/cmake/include/git_submodule.cmake")
|
include("${CMAKE_SOURCE_DIR}/cmake/include/git_submodule.cmake")
|
||||||
submodule_update(extern/assimp/assimp/)
|
submodule_update("${CMAKE_CURRENT_SOURCE_DIR}/extern/assimp/assimp/")
|
||||||
add_subdirectory(extern/assimp/assimp)
|
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/extern/assimp/assimp/")
|
||||||
|
else()
|
||||||
|
find_package(assimp REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +88,7 @@ endif()
|
||||||
|
|
||||||
set(
|
set(
|
||||||
PUBLIC_HEADERS
|
PUBLIC_HEADERS
|
||||||
src/mainwidget.h
|
src/qtkwidget.h
|
||||||
src/abstractscene.h
|
src/abstractscene.h
|
||||||
src/camera3d.h
|
src/camera3d.h
|
||||||
src/mesh.h
|
src/mesh.h
|
||||||
|
@ -79,7 +102,7 @@ set(
|
||||||
|
|
||||||
set(
|
set(
|
||||||
SOURCE_FILES
|
SOURCE_FILES
|
||||||
src/mainwidget.cpp
|
src/qtkwidget.cpp
|
||||||
src/abstractscene.cpp
|
src/abstractscene.cpp
|
||||||
src/camera3d.cpp
|
src/camera3d.cpp
|
||||||
src/input.cpp
|
src/input.cpp
|
||||||
|
@ -95,7 +118,12 @@ set(
|
||||||
)
|
)
|
||||||
|
|
||||||
include(GenerateExportHeader)
|
include(GenerateExportHeader)
|
||||||
qt_add_library(qtk-widget STATIC ${PUBLIC_HEADERS} ${SOURCE_FILES})
|
|
||||||
|
if (QTK_BUILD_SHARED_LIBS)
|
||||||
|
add_library(qtk-widget SHARED ${PUBLIC_HEADERS} ${SOURCE_FILES})
|
||||||
|
else()
|
||||||
|
add_library(qtk-widget STATIC ${PUBLIC_HEADERS} ${SOURCE_FILES})
|
||||||
|
endif()
|
||||||
target_include_directories(qtk-widget PRIVATE src/ app/)
|
target_include_directories(qtk-widget PRIVATE src/ app/)
|
||||||
|
|
||||||
set_target_properties(qtk-widget PROPERTIES
|
set_target_properties(qtk-widget PROPERTIES
|
||||||
|
@ -104,15 +132,16 @@ set_target_properties(qtk-widget PROPERTIES
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(qtk-widget PUBLIC Qt6::OpenGLWidgets)
|
target_link_libraries(qtk-widget PUBLIC Qt6::OpenGLWidgets)
|
||||||
|
target_link_libraries(qtk-widget PUBLIC Qt6::Widgets)
|
||||||
|
|
||||||
if (UPDATE_SUBMODULES OR NOT ASSIMP_NEW_INTERFACE)
|
if (QTK_UPDATE_SUBMODULES OR NOT ASSIMP_NEW_INTERFACE)
|
||||||
target_link_libraries(qtk-widget PUBLIC assimp)
|
target_link_libraries(qtk-widget PUBLIC assimp)
|
||||||
elseif(ASSIMP_NEW_INTERFACE)
|
elseif(ASSIMP_NEW_INTERFACE)
|
||||||
target_link_libraries(qtk-widget PUBLIC assimp::assimp)
|
target_link_libraries(qtk-widget PUBLIC assimp::assimp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(QTK_DEBUG)
|
if(QTK_DEBUG)
|
||||||
message(STATUS "[Qtk]: Building with QTK_DEBUG=${QTK_DEBUG}")
|
message(STATUS "[Qtk] Building with QTK_DEBUG=${QTK_DEBUG}")
|
||||||
target_compile_definitions(qtk-widget PUBLIC QTK_DEBUG)
|
target_compile_definitions(qtk-widget PUBLIC QTK_DEBUG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -122,7 +151,6 @@ if(WIN32)
|
||||||
target_link_libraries(qtk-widget PUBLIC OpenGL::GL)
|
target_link_libraries(qtk-widget PUBLIC OpenGL::GL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
generate_export_header(qtk-widget)
|
|
||||||
# Install files
|
# Install files
|
||||||
install(TARGETS qtk-widget
|
install(TARGETS qtk-widget
|
||||||
# Associate qtk-widget target with qtk-export
|
# Associate qtk-widget target with qtk-export
|
||||||
|
@ -156,8 +184,8 @@ configure_file(
|
||||||
|
|
||||||
# Add our Qt resources.qrc file to our application
|
# Add our Qt resources.qrc file to our application
|
||||||
set(QTK_APP_SOURCES app/main.cpp
|
set(QTK_APP_SOURCES app/main.cpp
|
||||||
|
app/examplescene.cpp app/examplescene.h
|
||||||
app/mainwindow.cpp app/mainwindow.h app/mainwindow.ui
|
app/mainwindow.cpp app/mainwindow.h app/mainwindow.ui
|
||||||
app/scene.cpp app/scene.h
|
|
||||||
app/resourcemanager.h
|
app/resourcemanager.h
|
||||||
src/qtkresources.h.in
|
src/qtkresources.h.in
|
||||||
)
|
)
|
||||||
|
@ -167,7 +195,7 @@ qt_add_executable(qtk-main ${QTK_APP_SOURCES})
|
||||||
target_include_directories(qtk-main PRIVATE src/ app/)
|
target_include_directories(qtk-main PRIVATE src/ app/)
|
||||||
|
|
||||||
# Link qtk-main executable to main qtk-widget library
|
# Link qtk-main executable to main qtk-widget library
|
||||||
target_link_libraries(qtk-main PRIVATE qtk-widget)
|
target_link_libraries(qtk-main PUBLIC qtk-widget)
|
||||||
|
|
||||||
set_target_properties(qtk-main PROPERTIES
|
set_target_properties(qtk-main PROPERTIES
|
||||||
WIN32_EXECUTABLE TRUE
|
WIN32_EXECUTABLE TRUE
|
||||||
|
@ -180,6 +208,7 @@ install(TARGETS qtk-main
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
generate_export_header(qtk-widget)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
get_target_property(_qt6_qmake_location Qt6::qmake IMPORTED_LOCATION)
|
get_target_property(_qt6_qmake_location Qt6::qmake IMPORTED_LOCATION)
|
||||||
execute_process(COMMAND "${_qt6_qmake_location}" -query QT_INSTALL_PREFIX RESULT_VARIABLE return_code OUTPUT_VARIABLE qt6_install_prefix OUTPUT_STRIP_TRAILING_WHITESPACE)
|
execute_process(COMMAND "${_qt6_qmake_location}" -query QT_INSTALL_PREFIX RESULT_VARIABLE return_code OUTPUT_VARIABLE qt6_install_prefix OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
64
README.md
64
README.md
|
@ -3,18 +3,18 @@
|
||||||
Practice project for learning about using OpenGL in Qt widget applications.
|
Practice project for learning about using OpenGL in Qt widget applications.
|
||||||
Model loader using [Assimp](https://assimp.org/) within a Qt widget application.
|
Model loader using [Assimp](https://assimp.org/) within a Qt widget application.
|
||||||
|
|
||||||
You can import your own models within `mainwdget.cpp`, inside the
|
You can import your own models within `app/examplescene.cpp`, inside the
|
||||||
`MainWidget::initObjects()` function. I've commented throughout the code there
|
`ExampleScene::init()` function. Rotations and translations
|
||||||
to explain which model or example I'm modifying. Rotations and translations
|
happen in `ExampleScene::update()`.
|
||||||
happen in `MainWidget::update()`, to get textures loading on models look into
|
|
||||||
[material files](http://www.paulbourke.net/dataformats/mtl/) and see some
|
|
||||||
examples in the `resources/models/` directory. For more in-depth examples, see
|
|
||||||
`scene.h` and `scene.cpp`
|
|
||||||
|
|
||||||
Can be built with cmake manually or using
|
To get textures loading on models look into [material files](http://www.paulbourke.net/dataformats/mtl/)
|
||||||
[Qt Creator](https://github.com/qt-creator/qt-creator).
|
and see some examples in the `resources/models/` directory.
|
||||||
For the build to be successful, I've found through testing on VMs that the system requires around 6GB of RAM.
|
|
||||||
This is mostly due to the large .obj files that are built into the project using [Qt Resource System](https://doc.qt.io/qt-6/resources.html)
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
Builds are configured for CLion or [Qt Creator](https://github.com/qt-creator/qt-creator).
|
||||||
|
Simply open the root `CMakeLists.txt` with either of these editors and configurations will be loaded.
|
||||||
|
|
||||||
This project has been ported to Qt6, which is not yet available in Ubuntu apt repositories.
|
This project has been ported to Qt6, which is not yet available in Ubuntu apt repositories.
|
||||||
To run this project, you will *need* to install [Qt6 Open Source Binaries](https://www.qt.io/download-qt-installer) for your system.
|
To run this project, you will *need* to install [Qt6 Open Source Binaries](https://www.qt.io/download-qt-installer) for your system.
|
||||||
|
@ -24,8 +24,21 @@ Once Qt6 is installed, to build and run `qtk` on Ubuntu -
|
||||||
```bash
|
```bash
|
||||||
sudo apt update -y && sudo apt install freeglut3-dev libassimp-dev cmake build-essential git
|
sudo apt update -y && sudo apt install freeglut3-dev libassimp-dev cmake build-essential git
|
||||||
git clone https://gitlab.com/shaunrd0/qtk
|
git clone https://gitlab.com/shaunrd0/qtk
|
||||||
cmake -DCMAKE_PREFIX_PATH=$HOME/Qt/6.3.1/gcc_64 -S qtk/ -B qtk/build/ && cmake --build qtk/build/ -j $(nprocs)
|
cmake -DCMAKE_PREFIX_PATH=$HOME/Qt/6.3.1/gcc_64 -S qtk/ -B qtk/build/ && cmake --build qtk/build/ -j $(nproc --ignore=2) --target qtk-main
|
||||||
./qtk/build/qtk
|
./qtk/build/qtk-main
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, the build will initialize Assimp as a git submodule and build from source.
|
||||||
|
We can turn this off by setting the `-DQTK_UPDATE_SUBMODULES=OFF` flag when running CMake.
|
||||||
|
This will greatly increase build speed, but we will need to make sure Assimp is available either system-wide or using a custom `CMAKE_PREFIX_PATH`.
|
||||||
|
Using `-DQTK_UPDATE_SUBMODULES=ON` supports providing assimp on cross-platform builds (Windows / Mac / Linux) and may be easier to configure.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update -y && sudo apt install freeglut3-dev libassimp-dev cmake build-essential git
|
||||||
|
git clone https://gitlab.com/shaunrd0/qtk
|
||||||
|
cmake -DQTK_UPDATE_SUBMODULES=OFF -DCMAKE_PREFIX_PATH=$HOME/Qt/6.3.1/gcc_64 -S qtk/ -B qtk/build/ && cmake --build qtk/build/ -j $(nproc --ignore=2) --target qtk-main
|
||||||
|
#cmake -DQTK_UPDATE_SUBMODULES=OFF -DCMAKE_PREFIX_PATH=$HOME/Qt/6.3.1/gcc_64;/path/to/assimp/dir -S qtk/ -B qtk/build/ && cmake --build qtk/build/ -j $(nproc --ignore=2) --target qtk-main
|
||||||
|
./qtk/build/qtk-main
|
||||||
```
|
```
|
||||||
|
|
||||||
You can fly around the scene if you hold the right mouse button and use WASD.
|
You can fly around the scene if you hold the right mouse button and use WASD.
|
||||||
|
@ -43,8 +56,30 @@ Spartan with normals -
|
||||||
|
|
||||||
![](resources/spartan-normals.png)
|
![](resources/spartan-normals.png)
|
||||||
|
|
||||||
## Model Artists
|
|
||||||
|
|
||||||
|
### QtkWidget in Qt Creator
|
||||||
|
|
||||||
|
The `QtkWidget` class is exported as a shared library for use in Qt Creator's design mode.
|
||||||
|
We can add more QtkWidgets to view and render the scene from multiple perspectives.
|
||||||
|
There is still some work to be done here, so there isn't a builtin way to add an additional view within the application.
|
||||||
|
|
||||||
|
![](resources/qtk-views.png)
|
||||||
|
|
||||||
|
After building Qtk, we can drag and drop an `OpenGL Widget` onto the `mainwindow.ui`.
|
||||||
|
Then right-click the new OpenGLWidget and `Promote To->QtkWidget` to add a second view.
|
||||||
|
|
||||||
|
![](resources/qtk-views-setup.png)
|
||||||
|
|
||||||
|
If we demote or delete all widgets in `mainwindow.ui` and rebuild the project, Qt Creator will drop `QtkWidget` from the list of possible promoted widgets.
|
||||||
|
Add an `OpenGL Widget` to the UI, right-click it and navigate to `Promote Widget...` and enter the information below.
|
||||||
|
|
||||||
|
![](resources/qtk-reference.png)
|
||||||
|
|
||||||
|
After you fill out the `New Promoted Class` form, click `Add` *and*`Promote`, then rebuild.
|
||||||
|
After following these steps Qt Creator will list `QtkWidget` as an option to promote `OpenGL Widgets` again.
|
||||||
|
|
||||||
|
|
||||||
|
## Model Artists
|
||||||
|
|
||||||
"Alien Hominid" (https://skfb.ly/onStx) by Nwilly_art is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
|
"Alien Hominid" (https://skfb.ly/onStx) by Nwilly_art is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
|
||||||
|
|
||||||
|
@ -59,4 +94,3 @@ Modified (learnopengl.com) material assignment (Joey de Vries) for easier load i
|
||||||
"Terror-bird (NHMW-Geo 2012/0007/0001)" (https://skfb.ly/onAWy) by Natural History Museum Vienna is licensed under Creative Commons Attribution-NonCommercial (http://creativecommons.org/licenses/by-nc/4.0/).
|
"Terror-bird (NHMW-Geo 2012/0007/0001)" (https://skfb.ly/onAWy) by Natural History Museum Vienna is licensed under Creative Commons Attribution-NonCommercial (http://creativecommons.org/licenses/by-nc/4.0/).
|
||||||
|
|
||||||
"Golden Lion Sitting OBJ Low Poly FREE" (https://skfb.ly/onZAH) by LordSamueliSolo is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
|
"Golden Lion Sitting OBJ Low Poly FREE" (https://skfb.ly/onZAH) by LordSamueliSolo is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <meshrenderer.h>
|
#include <meshrenderer.h>
|
||||||
#include <model.h>
|
#include <model.h>
|
||||||
#include <resourcemanager.h>
|
#include <resourcemanager.h>
|
||||||
#include <scene.h>
|
#include <examplescene.h>
|
||||||
#include <texture.h>
|
#include <texture.h>
|
||||||
|
|
||||||
using namespace Qtk;
|
using namespace Qtk;
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
|
|
||||||
class ExampleScene : public Qtk::Scene {
|
class ExampleScene : public Qtk::Scene {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExampleScene();
|
ExampleScene();
|
||||||
~ExampleScene();
|
~ExampleScene();
|
|
@ -9,7 +9,7 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
||||||
#include <mainwidget.h>
|
#include <qtkwidget.h>
|
||||||
#include <mainwindow.h>
|
#include <mainwindow.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
#include <mainwindow.h>
|
#include <mainwindow.h>
|
||||||
#include <ui_mainwindow.h>
|
#include <qtkwidget.h>
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) :
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
ui(new Ui::MainWindow)
|
ui(new Ui::MainWindow)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
mScene = new ExampleScene();
|
// For use in design mode using Qt Creator
|
||||||
ui->openGLWidget->setScene(mScene);
|
// + We can use the `ui` member to access nested widgets by name
|
||||||
|
for (const auto widget : ui->qWidget->children()) {
|
||||||
|
auto qtkWidget = dynamic_cast<Qtk::QtkWidget*>(widget);
|
||||||
|
if (qtkWidget != nullptr) {
|
||||||
|
std::string key = qtkWidget->objectName().toStdString();
|
||||||
|
if (mScenes[key] == nullptr) {
|
||||||
|
mScenes[qtkWidget->objectName().toStdString()] = new ExampleScene();
|
||||||
|
}
|
||||||
|
qtkWidget->setScene(mScenes[qtkWidget->objectName().toStdString()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
setWindowIcon(QIcon("../resources/icon.png"));
|
setWindowIcon(QIcon("../resources/icon.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#ifndef MAINWINDOW_H
|
#ifndef MAINWINDOW_H
|
||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
||||||
#include <qtk-widget_export.h>
|
#include "qtk-widget_export.h"
|
||||||
#include <scene.h>
|
#include <examplescene.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -21,7 +23,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
Qtk::Scene * mScene;
|
std::unordered_map<std::string, Qtk::Scene*> mScenes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|
|
@ -14,15 +14,25 @@
|
||||||
<string>Qtk - MainWindow</string>
|
<string>Qtk - MainWindow</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<widget class="Qtk::MainWidget" name="openGLWidget" native="true">
|
<widget class="QWidget" name="qWidget" native="true">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>0</x>
|
||||||
<y>10</y>
|
<y>0</y>
|
||||||
<width>775</width>
|
<width>801</width>
|
||||||
<height>550</height>
|
<height>561</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="Qtk::QtkWidget" name="openGLWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>10</y>
|
||||||
|
<width>781</width>
|
||||||
|
<height>541</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenuBar" name="menubar">
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
@ -94,9 +104,9 @@
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>Qtk::MainWidget</class>
|
<class>Qtk::QtkWidget</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QOpenGLWidget</extends>
|
||||||
<header>mainwidget.h</header>
|
<header>qtkwidget.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|
|
@ -10,7 +10,7 @@ find_package(Git)
|
||||||
# _PATH: Path to git submodule location that we want to update
|
# _PATH: Path to git submodule location that we want to update
|
||||||
# + submodule_update(extern/assimp)
|
# + submodule_update(extern/assimp)
|
||||||
function(submodule_update _PATH)
|
function(submodule_update _PATH)
|
||||||
if (NOT UPDATE_SUBMODULES)
|
if (NOT QTK_UPDATE_SUBMODULES)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -19,12 +19,14 @@ function(submodule_update _PATH)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} submodule update --init "${_PATH}"
|
COMMAND ${GIT_EXECUTABLE} submodule update --init --force "${_PATH}"
|
||||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
RESULT_VARIABLE result
|
||||||
RESULT_VARIABLE result
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT result EQUAL 0)
|
if (NOT result EQUAL 0)
|
||||||
message(FATAL_ERROR "[Qtk] Error: Unable to update git submodule at ${_PATH}")
|
message(
|
||||||
|
FATAL_ERROR
|
||||||
|
"[Qtk] Error: Unable to update git submodule at ${_PATH}"
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
Binary file not shown.
After Width: | Height: | Size: 263 KiB |
|
@ -13,10 +13,11 @@
|
||||||
#include <Qt>
|
#include <Qt>
|
||||||
|
|
||||||
#include <qtkapi.h>
|
#include <qtkapi.h>
|
||||||
|
#include <qtkwidget.h>
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk {
|
||||||
class QTKAPI Input {
|
class QTKAPI Input {
|
||||||
friend class MainWidget;
|
friend class Qtk::QtkWidget;
|
||||||
public:
|
public:
|
||||||
// Possible key states
|
// Possible key states
|
||||||
enum InputState
|
enum InputState
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
|
||||||
#include <input.h>
|
#include <input.h>
|
||||||
#include <mainwidget.h>
|
#include <qtkwidget.h>
|
||||||
#include <mesh.h>
|
#include <mesh.h>
|
||||||
#include <abstractscene.h>
|
#include <abstractscene.h>
|
||||||
|
|
||||||
|
@ -19,26 +19,26 @@ using namespace Qtk;
|
||||||
* Constructors, Destructors
|
* Constructors, Destructors
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
MainWidget::MainWidget() : mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
|
QtkWidget::QtkWidget() : mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
|
||||||
{
|
{
|
||||||
initializeWidget();
|
initializeWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor for using this widget in QtDesigner
|
// Constructor for using this widget in QtDesigner
|
||||||
MainWidget::MainWidget(QWidget *parent) : QOpenGLWidget(parent),
|
QtkWidget::QtkWidget(QWidget *parent) : QOpenGLWidget(parent),
|
||||||
mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
|
mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
|
||||||
{
|
{
|
||||||
initializeWidget();
|
initializeWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWidget::MainWidget(const QSurfaceFormat &format)
|
QtkWidget::QtkWidget(const QSurfaceFormat &format)
|
||||||
: mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
|
: mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
|
||||||
{
|
{
|
||||||
setFormat(format);
|
setFormat(format);
|
||||||
setFocusPolicy(Qt::ClickFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWidget::~MainWidget()
|
QtkWidget::~QtkWidget()
|
||||||
{
|
{
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
teardownGL();
|
teardownGL();
|
||||||
|
@ -49,7 +49,7 @@ MainWidget::~MainWidget()
|
||||||
* Private Member Functions
|
* Private Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void MainWidget::teardownGL()
|
void QtkWidget::teardownGL()
|
||||||
{
|
{
|
||||||
// Nothing to teardown yet...
|
// Nothing to teardown yet...
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ void MainWidget::teardownGL()
|
||||||
* Inherited Virtual Member Functions
|
* Inherited Virtual Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void MainWidget::paintGL()
|
void QtkWidget::paintGL()
|
||||||
{
|
{
|
||||||
// Clear buffers
|
// Clear buffers
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
|
@ -68,7 +68,7 @@ void MainWidget::paintGL()
|
||||||
if (mScene != Q_NULLPTR) mScene->draw();
|
if (mScene != Q_NULLPTR) mScene->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::initializeGL()
|
void QtkWidget::initializeGL()
|
||||||
{
|
{
|
||||||
initializeOpenGLFunctions();
|
initializeOpenGLFunctions();
|
||||||
// Connect the frameSwapped signal to call the update() function
|
// Connect the frameSwapped signal to call the update() function
|
||||||
|
@ -98,7 +98,7 @@ void MainWidget::initializeGL()
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::resizeGL(int width, int height)
|
void QtkWidget::resizeGL(int width, int height)
|
||||||
{
|
{
|
||||||
Scene::Projection().setToIdentity();
|
Scene::Projection().setToIdentity();
|
||||||
Scene::Projection().perspective(45.0f,
|
Scene::Projection().perspective(45.0f,
|
||||||
|
@ -111,7 +111,7 @@ void MainWidget::resizeGL(int width, int height)
|
||||||
* Protected Slots
|
* Protected Slots
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void MainWidget::update()
|
void QtkWidget::update()
|
||||||
{
|
{
|
||||||
updateCameraInput();
|
updateCameraInput();
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ void MainWidget::update()
|
||||||
QWidget::update();
|
QWidget::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::messageLogged(const QOpenGLDebugMessage &msg)
|
void QtkWidget::messageLogged(const QOpenGLDebugMessage &msg)
|
||||||
{
|
{
|
||||||
QString error;
|
QString error;
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ void MainWidget::messageLogged(const QOpenGLDebugMessage &msg)
|
||||||
* Protected Helpers
|
* Protected Helpers
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void MainWidget::keyPressEvent(QKeyEvent *event)
|
void QtkWidget::keyPressEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
if (event->isAutoRepeat()) {
|
if (event->isAutoRepeat()) {
|
||||||
// Do not repeat input while a key is held down
|
// Do not repeat input while a key is held down
|
||||||
|
@ -195,7 +195,7 @@ void MainWidget::keyPressEvent(QKeyEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::keyReleaseEvent(QKeyEvent *event)
|
void QtkWidget::keyReleaseEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
if (event->isAutoRepeat()) {
|
if (event->isAutoRepeat()) {
|
||||||
event->ignore();
|
event->ignore();
|
||||||
|
@ -204,12 +204,12 @@ void MainWidget::keyReleaseEvent(QKeyEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::mousePressEvent(QMouseEvent *event)
|
void QtkWidget::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
Input::registerMousePress(event->button());
|
Input::registerMousePress(event->button());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::mouseReleaseEvent(QMouseEvent *event)
|
void QtkWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
Input::registerMouseRelease(event->button());
|
Input::registerMouseRelease(event->button());
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ void MainWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||||
* Private Helpers
|
* Private Helpers
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void MainWidget::initializeWidget()
|
void QtkWidget::initializeWidget()
|
||||||
{
|
{
|
||||||
QSurfaceFormat format;
|
QSurfaceFormat format;
|
||||||
format.setRenderableType(QSurfaceFormat::OpenGL);
|
format.setRenderableType(QSurfaceFormat::OpenGL);
|
||||||
|
@ -237,7 +237,7 @@ void MainWidget::initializeWidget()
|
||||||
setFocusPolicy(Qt::ClickFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::printContextInformation()
|
void QtkWidget::printContextInformation()
|
||||||
{
|
{
|
||||||
QString glType;
|
QString glType;
|
||||||
QString glVersion;
|
QString glVersion;
|
||||||
|
@ -273,7 +273,7 @@ void MainWidget::printContextInformation()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::updateCameraInput()
|
void QtkWidget::updateCameraInput()
|
||||||
{
|
{
|
||||||
Input::update();
|
Input::update();
|
||||||
// Camera Transformation
|
// Camera Transformation
|
|
@ -5,8 +5,8 @@
|
||||||
## ##
|
## ##
|
||||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
#ifndef QTK_MAINWIDGET_H
|
#ifndef QTK_QTKWIDGET_H
|
||||||
#define QTK_MAINWIDGET_H
|
#define QTK_QTKWIDGET_H
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -18,18 +18,17 @@
|
||||||
#include <qtkapi.h>
|
#include <qtkapi.h>
|
||||||
#include <abstractscene.h>
|
#include <abstractscene.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk {
|
||||||
class QTKAPI MainWidget : public QOpenGLWidget,
|
class QTKAPI QtkWidget : public QOpenGLWidget,
|
||||||
protected QOpenGLFunctions {
|
protected QOpenGLFunctions {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
MainWidget();
|
QtkWidget();
|
||||||
explicit MainWidget(QWidget *parent);
|
explicit QtkWidget(QWidget *parent);
|
||||||
explicit MainWidget(const QSurfaceFormat &format);
|
explicit QtkWidget(const QSurfaceFormat &format);
|
||||||
~MainWidget() override;
|
~QtkWidget() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void teardownGL();
|
void teardownGL();
|
||||||
|
@ -40,8 +39,8 @@ namespace Qtk {
|
||||||
void initializeGL() override;
|
void initializeGL() override;
|
||||||
void resizeGL(int width, int height) override;
|
void resizeGL(int width, int height) override;
|
||||||
|
|
||||||
inline Scene * getScene() {return mScene;}
|
inline Qtk::Scene * getScene() {return mScene;}
|
||||||
inline void setScene(Scene * scene) {
|
inline void setScene(Qtk::Scene * scene) {
|
||||||
if (mScene != Q_NULLPTR) delete mScene;
|
if (mScene != Q_NULLPTR) delete mScene;
|
||||||
mScene = scene;
|
mScene = scene;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +63,7 @@ namespace Qtk {
|
||||||
void initializeWidget();
|
void initializeWidget();
|
||||||
void updateCameraInput();
|
void updateCameraInput();
|
||||||
|
|
||||||
Scene * mScene;
|
Qtk::Scene * mScene;
|
||||||
#ifdef QTK_DEBUG
|
#ifdef QTK_DEBUG
|
||||||
void printContextInformation();
|
void printContextInformation();
|
||||||
QOpenGLDebugLogger * mDebugLogger;
|
QOpenGLDebugLogger * mDebugLogger;
|
||||||
|
@ -72,4 +71,4 @@ namespace Qtk {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // QTK_MAINWIDGET_H
|
#endif // QTK_QTKWIDGET_H
|
Loading…
Reference in New Issue