This commit is contained in:
Shaun Reed 2023-04-01 12:43:30 -04:00
parent e889785b65
commit fc1ded833d
11 changed files with 286 additions and 287 deletions

View File

@ -46,14 +46,13 @@ include(GNUInstallDirs)
# Options # Options
################################################################################ ################################################################################
option(QTK_DEBUG "Enable debugger" OFF) option(QTK_DEBUG "Enable debugger" OFF)
option(QTK_UPDATE_SUBMODULES "Update external project (assimp) submodule" OFF) option(QTK_SUBMODULES "Update external project (assimp) submodule" OFF)
option(QTK_BUILD_GUI "Build the Qtk desktop application" ON) option(QTK_GUI "Build the Qtk desktop application" ON)
option(QTK_INSTALL_LIBRARY "Install libqtk to CMAKE_INSTALL_PREFIX path." ON) option(QTK_PLUGINS "Install Qtk plugins to Qt Creator path." OFF)
option(QTK_INSTALL_PLUGINS "Install Qtk plugin collection to Qt Creator." OFF) option(QTK_EXAMPLE "Build the Qtk example desktop application" ON)
option(QTK_BUILD_EXAMPLE "Build the Qtk example desktop application" ON) option(QTK_CCACHE "Enable ccache" ON)
option(QTK_ENABLE_CCACHE "Enable ccache" ON)
if (QTK_ENABLE_CCACHE) if (QTK_CCACHE)
set(CMAKE_CXX_COMPILER_LAUNCHER ccache) set(CMAKE_CXX_COMPILER_LAUNCHER ccache)
endif() endif()
@ -61,7 +60,7 @@ endif()
option(QTK_PREFIX_QTCREATOR "Install Qtk to Qt Creator. Untested." OFF) option(QTK_PREFIX_QTCREATOR "Install Qtk to Qt Creator. Untested." OFF)
# Option for bringing your own assimp installation; Otherwise not needed # Option for bringing your own assimp installation; Otherwise not needed
# + If assimp is available system-wide we can just set QTK_UPDATE_SUBMODULES OFF # + If assimp is available system-wide we can just set QTK_SUBMODULES OFF
option( option(
QTK_ASSIMP_NEW_INTERFACE QTK_ASSIMP_NEW_INTERFACE
"Use the assimp::assimp interface (WIN / OSX)" "Use the assimp::assimp interface (WIN / OSX)"
@ -76,6 +75,10 @@ endif()
# This should be set to your Qt6 installation directory. # This should be set to your Qt6 installation directory.
set(QT_INSTALL_DIR "$ENV{HOME}/Qt/6.5.0/gcc_64" CACHE PATH "Path to Qt6 install.") set(QT_INSTALL_DIR "$ENV{HOME}/Qt/6.5.0/gcc_64" CACHE PATH "Path to Qt6 install.")
set(Qt6_DIR "$ENV{HOME}/Qt/6.5.0/gcc_64/lib/")
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install")
endif ()
# Point CMAKE_PREFIX_PATH to Qt6 install directory # Point CMAKE_PREFIX_PATH to Qt6 install directory
# If Qtk is built within Qt Creator this is not required. # If Qtk is built within Qt Creator this is not required.
list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}") list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}")
@ -134,7 +137,7 @@ if(NOT Qt6_FOUND)
endif() endif()
# Find Assimp. # Find Assimp.
if(QTK_UPDATE_SUBMODULES) if(QTK_SUBMODULES)
# Required to statically link. # Required to statically link.
add_compile_options(-fPIC) add_compile_options(-fPIC)
set(BUILD_SHARED_LIBS OFF CACHE STRING "Build static assimp libs" FORCE) set(BUILD_SHARED_LIBS OFF CACHE STRING "Build static assimp libs" FORCE)
@ -166,7 +169,7 @@ endif()
################################################################################ ################################################################################
add_subdirectory(src) add_subdirectory(src)
if(QTK_BUILD_EXAMPLE) if(QTK_EXAMPLE)
# Create a namespaced alias for linking with qtk_library in the example. # Create a namespaced alias for linking with qtk_library in the example.
add_library(${PROJECT_NAME}::qtk_library ALIAS qtk_library) add_library(${PROJECT_NAME}::qtk_library ALIAS qtk_library)
add_subdirectory(example-app) add_subdirectory(example-app)

128
README.md
View File

@ -48,80 +48,51 @@ your system, **version 6.5.0** or later.
Be sure to take note of the Qt6 installation directory, as we will need it to Be sure to take note of the Qt6 installation directory, as we will need it to
correctly set our `CMAKE_PREFIX_PATH` in the next steps. correctly set our `CMAKE_PREFIX_PATH` in the next steps.
If you are building on **Windows / Mac**, consider setting
the `-DASSIMP_NEW_INTERFACE` build flag.
If the build is configured with all options enabled, we can subsequently install If the build is configured with all options enabled, we can subsequently install
individual components as needed with cmake. individual components as needed with cmake.
```bash ```bash
cmake -B build-all/ -DQTK_BUILD_GUI=ON -DQTK_INSTALL_LIBRARY=ON -DQTK_INSTALL_PLUGINS=ON sudo apt update -y && sudo apt install libassimp-dev cmake build-essential git ccache libgl1-mesa-dev libglvnd-dev -y
``` git clone https://github.com/shaunrd0/qtk
cd qtk
# Configure the build with all components enabled
cmake -B build-all -DQTK_GUI=ON -DQTK_PLUGINS=ON -DQTK_EXAMPLE=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64
# Build all targets
cmake --build build-all/
````
By default, the build will not initialize Assimp as a git submodule and build
from source.
We can turn this on by setting the `-DQTK_SUBMODULES=ON` flag when running
CMake.
Building using this option will fetch and build Assimp for us, but builds will
take longer as a result.
Using `-DQTK_SUBMODULES=ON` supports providing assimp on cross-platform builds (
Windows / Mac / Linux) and may be easier
to configure.
```bash ```bash
# Install libqtk only cmake -B build-all -DQTK_GUI=ON -DQTK_PLUGINS=ON -DQTK_EXAMPLE=ON -DQTK_SUBMODULES=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64
cmake --install build-all/ --prefix=$(pwd)/install --component libqtk
-- Install configuration: "Release"
-- Up-to-date: /home/shaun/Code/qtk/install/lib/cmake/Qtk/QtkConfig.cmake
-- Up-to-date: /home/shaun/Code/qtk/install/lib/cmake/Qtk/QtkConfigVersion.cmake
-- Up-to-date: /home/shaun/Code/qtk/install/lib/cmake/Qtk/QtkTargets.cmake
-- Up-to-date: /home/shaun/Code/qtk/install/lib/cmake/Qtk/QtkTargets-release.cmake
-- Up-to-date: /home/shaun/Code/qtk/install/lib/static/libqtk_library.a
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/camera3d.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/input.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/meshrenderer.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/model.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/modelmesh.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/object.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/qtkapi.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/qtkiostream.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/qtkiosystem.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/scene.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/shape.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/skybox.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/texture.h
-- Up-to-date: /home/shaun/Code/qtk/install/include/qtk/transform3D.h
# Install Qtk widget collection to use Qt Designer
cmake --install build-all/ --prefix=$(pwd)/install --component collection
-- Install configuration: "Release"
-- Up-to-date: /home/shaun/Qt/6.5.0/gcc_64/../../Tools/QtCreator/lib/Qt/lib/libqtk_library.a
-- Up-to-date: /home/shaun/Qt/6.5.0/gcc_64/../../Tools/QtCreator/lib/Qt/lib/libqtk_plugin_library.a
-- Up-to-date: /home/shaun/Qt/6.5.0/gcc_64/../../Tools/QtCreator/lib/Qt/plugins/designer/libqtk_collection.so
# Install Qtk desktop application (output removed)
cmake --install build-all/ --prefix=$(pwd)/install --component qtk
``` ```
#### Qtk GUI #### Qtk GUI
Once Qt6 is installed, to build and run `qtk` on Ubuntu -
```bash ```bash
sudo apt update -y && sudo apt install libassimp-dev cmake build-essential git ccache -y cmake --build build-all/ --target qtk_gui -- -j $(nproc)
git clone https://github.com/shaunrd0/qtk # Install Qtk desktop application (output removed)
cmake -S qtk/ -B qtk/build/ -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64 # Installation prefix path must be absolute, since Qtk uses Qt deploy tools.
cmake --build qtk/build/ -j $(nproc --ignore=2) cmake --install build-all/ --component qtk_gui --prefix=$(pwd)/install
./qtk/build/bin/qtk-main ./install/bin/qtk_gui
```
By default, the build will not initialize Assimp as a git submodule and build
from source.
We can turn this on by setting the `-DQTK_UPDATE_SUBMODULES=ON` flag when
running CMake.
Building using this option will fetch and build Assimp for us, but builds will
take longer as a result.
Using `-DQTK_UPDATE_SUBMODULES=ON` supports providing assimp on cross-platform
builds (Windows / Mac / Linux) and may be easier to configure.
```bash
cmake -S qtk/ -B qtk/build/ -DQTK_UPDATE_SUBMODULES=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64
cmake --build qtk/build/ -j $(nproc --ignore=2)
./qtk/build/bin/qtk-main
``` ```
If any errors are encountered loading plugins, we can debug plugin loading by If any errors are encountered loading plugins, we can debug plugin loading by
setting the following environment variable - setting the following environment variable -
```bash ```bash
QT_DEBUG_PLUGINS=1 ./qtk-main QT_DEBUG_PLUGINS=1 ./install/bin/qtk_gui
``` ```
#### Qtk Library #### Qtk Library
@ -131,12 +102,10 @@ We can install this library on a system path or a custom path and then
set `CMAKE_PREFIX_PATH` to point to this location when building an application set `CMAKE_PREFIX_PATH` to point to this location when building an application
using libqtk. using libqtk.
Below is an example of installing on a system path.
```bash ```bash
cmake -S qtk/ -B qtk/build/ -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64 -DQTK_BUILD_GUI=OFF -DQTK_INSTALL_PLUGINS=OFF -DQTK_DEBUG=OFF # Install libqtk only
cmake --build qtk/build/ -j $(nproc --ignore=2) cmake --build build-all/ --target qtk_library -- -j $(nproc)
sudo cmake --install . --prefix=/usr/local cmake --install build-all/ --component qtk_library --prefix=/usr/local
-- Install configuration: "Release" -- Install configuration: "Release"
-- Installing: /usr/local/lib/cmake/Qtk/QtkConfig.cmake -- Installing: /usr/local/lib/cmake/Qtk/QtkConfig.cmake
-- Installing: /usr/local/lib/cmake/Qtk/QtkConfigVersion.cmake -- Installing: /usr/local/lib/cmake/Qtk/QtkConfigVersion.cmake
@ -175,9 +144,14 @@ interfaces.
To build and install the Qtk plugin collection - To build and install the Qtk plugin collection -
```bash ```bash
cmake -S /path/to/qtk -B /path/to/qtk/build -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64 -DQTK_INSTALL_PLUGINS=ON -DQTK_BUILD_GUI=OFF -DQTK_INSTALL_LIBRARY=OFF cmake --build build-all/ --target qtk_plugins -- -j $(nproc)
cmake --build /path/to/qtk/build # Install Qtk widget collection to use Qt Designer
cmake --install /path/to/qtk/build # The path here should be initialized during build configuration, so no need for --prefix
cmake --install build-all/ --component qtk_plugins
-- Install configuration: "Release"
-- Up-to-date: /home/shaun/Qt/6.5.0/gcc_64/../../Tools/QtCreator/lib/Qt/lib/libqtk_library.a
-- Up-to-date: /home/shaun/Qt/6.5.0/gcc_64/../../Tools/QtCreator/lib/Qt/lib/libqtk_plugin_library.a
-- Up-to-date: /home/shaun/Qt/6.5.0/gcc_64/../../Tools/QtCreator/lib/Qt/plugins/designer/libqtk_collection.so
``` ```
To uninstall after a previous installation, we can run the following command To uninstall after a previous installation, we can run the following command
@ -187,16 +161,22 @@ from the root of the repository.
xargs rm < build/install_manifest.txt xargs rm < build/install_manifest.txt
``` ```
#### Windows / MacOS #### Qtk Example
If you are building on **Windows / Mac**, consider setting There is a simple example of using libqtk in the [example-app/](example-app)
the `-DASSIMP_NEW_INTERFACE` build flag. directory. The example can be built standalone using `find_package` or as a
target within any qtk build.
```bash ```bash
cmake -S qtk/ -B qtk/build/ -DASSIMP_NEW_INTERFACE=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64;/path/to/assimp/ # Build the example from a configured qtk build tree
cmake --build qtk/build/ -j $(nproc --ignore=2) cmake --build build-all/ --target qtk_example -- -j $(nproc)
cmake --install build-all/ --component qtk_example --prefix=install
./install/bin/qtk_example
``` ```
See the README in the [example-app/](example-app) subdirectory for instructions
on standalone builds.
### Controls ### Controls
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.
@ -253,7 +233,7 @@ CLion automatically.
# Move to the root of the repo # Move to the root of the repo
cd qtk cd qtk
# Build # Build
cmake -B build && cmake --build build cmake -B build && cmake --build build -- -j $(nproc)
clang-tidy -p build/ --fix --config-file=.clang-tidy src/*.cpp src/*.h app/*.cpp app/*.h clang-tidy -p build/ --fix --config-file=.clang-tidy src/*.cpp src/*.h app/*.cpp app/*.h
``` ```
@ -320,12 +300,8 @@ Any of the above options can be appended with `--trace-expand` to debug package
generation issues. generation issues.
The contents of all packages will depend on how the build was configured. The contents of all packages will depend on how the build was configured.
If we are generating packages for *only* libqtk, we
set `-DQTK_INSTALL_LIBRARY=ON`
during the cmake configuration step.
To generate packages for Qtk desktop application, we should To generate packages for Qtk desktop application, we should
set `-DQTK_BUILD_GUI=ON`, and optionally `-DQTK_INSTALL_LIBRARY=ON` if we would set `-DQTK_GUI=ON`. If this option is not set we will only package libqtk.
like to bundle libqtk with the desktop application.
The NSIS installer will allow component-specific path modification for all of The NSIS installer will allow component-specific path modification for all of
these installation components through a GUI install application. these installation components through a GUI install application.

View File

@ -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 QTK_UPDATE_SUBMODULES) if (NOT QTK_SUBMODULES)
return() return()
endif() endif()

View File

@ -2,7 +2,7 @@
include("${CMAKE_CURRENT_LIST_DIR}/QtkTargets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/QtkTargets.cmake")
set_and_check(QTK_EXECUTABLE "${PACKAGE_PREFIX_DIR}/bin/qtk_app") set_and_check(QTK_EXECUTABLE "${PACKAGE_PREFIX_DIR}/bin/qtk_gui")
set_and_check(QTK_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include") set_and_check(QTK_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")
set_and_check(QTK_LIBRARIES "${PACKAGE_PREFIX_DIR}/lib") set_and_check(QTK_LIBRARIES "${PACKAGE_PREFIX_DIR}/lib")

View File

@ -22,7 +22,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
endif() endif()
# If you did not install Qtk on a system path, point cmake to installation. # If you did not install Qtk on a system path, point cmake to installation.
set(QTK_PATH /usr/local CACHE PATH "Path to installation of Qtk") set(QTK_PATH ../build/install/lib/cmake/Qtk CACHE PATH "Path to installation of Qtk" FORCE)
# If you did not install Qt6 on a system path, point cmake to installation. # If you did not install Qt6 on a system path, point cmake to installation.
set(QT_INSTALL_DIR "$ENV{HOME}/Qt/6.5.0/gcc_64/" CACHE PATH "Path to Qt6") set(QT_INSTALL_DIR "$ENV{HOME}/Qt/6.5.0/gcc_64/" CACHE PATH "Path to Qt6")
@ -40,12 +40,6 @@ project(
list(APPEND CMAKE_PREFIX_PATH "${QTK_PATH}") list(APPEND CMAKE_PREFIX_PATH "${QTK_PATH}")
list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}") list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}")
# Allow add_subdirectory on this project to use target ALIAS if available.
# If this example project is opened standalone we will use find_package.
if(NOT TARGET Qtk::qtk_library)
find_package(Qtk 0.2 REQUIRED)
endif()
# Print all QTK variables # Print all QTK variables
if (NOT Qtk_IS_TOP_LEVEL) if (NOT Qtk_IS_TOP_LEVEL)
get_cmake_property(VAR_NAMES VARIABLES) get_cmake_property(VAR_NAMES VARIABLES)
@ -56,6 +50,12 @@ if (NOT Qtk_IS_TOP_LEVEL)
endforeach() endforeach()
endif() endif()
# Allow add_subdirectory on this project to use target ALIAS if available.
# If this example project is opened standalone we will use find_package.
if(NOT TARGET Qtk::qtk_library)
find_package(Qtk 0.2 REQUIRED)
endif()
find_package(Qt6 COMPONENTS Core Widgets OpenGLWidgets REQUIRED) find_package(Qt6 COMPONENTS Core Widgets OpenGLWidgets REQUIRED)
set( set(
@ -65,6 +65,22 @@ set(
examplewidget.cpp examplewidget.h examplewidget.cpp examplewidget.h
) )
add_executable(example_app ${EXAMPLE_SOURCES}) configure_file(
target_link_libraries(example_app PUBLIC Qt6::Widgets Qt6::OpenGLWidgets Qt6::Core) #[[INPUT]] "${CMAKE_CURRENT_SOURCE_DIR}/resources.h.in"
target_link_libraries(example_app PUBLIC Qtk::qtk_library) #[[OUTPUT]] "${CMAKE_CURRENT_BINARY_DIR}/resources.h"
@ONLY
)
add_executable(qtk_example ${EXAMPLE_SOURCES})
target_link_libraries(qtk_example PUBLIC Qt6::Widgets Qt6::OpenGLWidgets Qt6::Core)
target_link_libraries(qtk_example PUBLIC Qtk::qtk_library)
target_include_directories(qtk_example PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
install(
TARGETS qtk_example
COMPONENT qtk_example
BUNDLE DESTINATION .
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static
RUNTIME DESTINATION bin
)

View File

@ -7,10 +7,11 @@
##############################################################################*/ ##############################################################################*/
#include "examplescene.h" #include "examplescene.h"
#include <resources.h>
using namespace Qtk; using namespace Qtk;
ExampleScene::ExampleScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) { ExampleScene::ExampleScene(Qtk::Scene *scene) : Qtk::SceneInterface(scene) {
setSceneName("Example Scene"); setSceneName("Example Scene");
getCamera().getTransform().setTranslation(-8.0f, 0.0f, 10.0f); getCamera().getTransform().setTranslation(-8.0f, 0.0f, 10.0f);
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f); getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
@ -23,8 +24,10 @@ void ExampleScene::init() {
setSkybox(skybox); setSkybox(skybox);
auto spartan = new Model( auto spartan = new Model(
"spartan", "/home/kapper/Code/qtk/resources/models/spartan/spartan.obj"); "spartan", std::string(QTK_EXAMPLE_SOURCE_DIR) +
"/../resources/models/spartan/spartan.obj");
addObject(spartan); addObject(spartan);
spartan->getTransform().setTranslation(-4.0f, 0.0f, 0.0f);
auto mesh = addObject( auto mesh = addObject(
new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ARRAYS))); new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ARRAYS)));

View File

@ -13,14 +13,14 @@ install(
FILES FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
COMPONENT libqtk COMPONENT qtk_library
DESTINATION lib/cmake/${PROJECT_NAME} DESTINATION lib/cmake/${PROJECT_NAME}
) )
install( install(
EXPORT qtk_export EXPORT qtk_export
FILE ${PROJECT_NAME}Targets.cmake FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}:: NAMESPACE ${PROJECT_NAME}::
COMPONENT libqtk COMPONENT qtk_library
DESTINATION lib/cmake/${PROJECT_NAME} DESTINATION lib/cmake/${PROJECT_NAME}
) )
# System install for qtk_library # System install for qtk_library
@ -28,7 +28,7 @@ install(
TARGETS qtk_library TARGETS qtk_library
# Associate qtk_library target with qtk-export # Associate qtk_library target with qtk-export
EXPORT qtk_export EXPORT qtk_export
COMPONENT libqtk COMPONENT qtk_library
FILE_SET HEADERS DESTINATION include FILE_SET HEADERS DESTINATION include
INCLUDES DESTINATION include INCLUDES DESTINATION include
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
@ -37,32 +37,32 @@ install(
) )
# Qtk Application # Qtk Application
if(QTK_BUILD_GUI OR QTK_INSTALL_PLUGINS) if(QTK_GUI OR QTK_PLUGINS)
add_subdirectory(app) add_subdirectory(app)
endif() endif()
if(QTK_INSTALL_PLUGINS) if(QTK_PLUGINS)
# Optionally install custom Qtk plugins for Qt Designer. # Optionally install custom Qtk plugins for Qt Designer.
install( install(
TARGETS qtk_library qtk_plugin_library TARGETS qtk_library qtk_plugin_library
COMPONENT collection COMPONENT qtk_plugins
LIBRARY DESTINATION "${QTK_PLUGIN_LIBRARY_DIR}" LIBRARY DESTINATION "${QTK_PLUGIN_LIBRARY_DIR}"
ARCHIVE DESTINATION "${QTK_PLUGIN_LIBRARY_DIR}" ARCHIVE DESTINATION "${QTK_PLUGIN_LIBRARY_DIR}"
RUNTIME DESTINATION "${QTK_PLUGIN_LIBRARY_DIR}" RUNTIME DESTINATION "${QTK_PLUGIN_LIBRARY_DIR}"
) )
install( install(
TARGETS qtk_collection TARGETS qtk_plugins
COMPONENT collection COMPONENT qtk_plugins
LIBRARY DESTINATION "${QTK_PLUGIN_INSTALL_DIR}" LIBRARY DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
ARCHIVE DESTINATION "${QTK_PLUGIN_INSTALL_DIR}" ARCHIVE DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
RUNTIME DESTINATION "${QTK_PLUGIN_INSTALL_DIR}" RUNTIME DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
) )
endif() endif()
if(QTK_BUILD_GUI) if(QTK_GUI)
install( install(
TARGETS qtk_app TARGETS qtk_gui
COMPONENT qtk COMPONENT qtk_gui
BUNDLE DESTINATION . BUNDLE DESTINATION .
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static ARCHIVE DESTINATION lib/static
@ -70,11 +70,11 @@ if(QTK_BUILD_GUI)
) )
qt_generate_deploy_app_script( qt_generate_deploy_app_script(
TARGET qtk_app TARGET qtk_gui
OUTPUT_SCRIPT QTK_DEPLOY_SCRIPT OUTPUT_SCRIPT QTK_DEPLOY_SCRIPT
NO_UNSUPPORTED_PLATFORM_ERROR NO_UNSUPPORTED_PLATFORM_ERROR
) )
install(SCRIPT ${QTK_DEPLOY_SCRIPT} COMPONENT qtk) install(SCRIPT ${QTK_DEPLOY_SCRIPT} COMPONENT qtk_gui)
if(WIN32) if(WIN32)
if(MSVC AND TARGET Qt6::qmake) if(MSVC AND TARGET Qt6::qmake)
@ -87,7 +87,7 @@ if(QTK_BUILD_GUI)
) )
file(TO_NATIVE_PATH "${QT6_INSTALL_PREFIX}/bin" QT6_INSTALL_PREFIX) file(TO_NATIVE_PATH "${QT6_INSTALL_PREFIX}/bin" QT6_INSTALL_PREFIX)
set(VSUSER_FILE "${CMAKE_CURRENT_BINARY_DIR}/qtk_app.vcxproj.user") set(VSUSER_FILE "${CMAKE_CURRENT_BINARY_DIR}/qtk_gui.vcxproj.user")
file(WRITE ${VSUSER_FILE} "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n") file(WRITE ${VSUSER_FILE} "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
file(APPEND ${VSUSER_FILE} "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n") file(APPEND ${VSUSER_FILE} "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n")
file(APPEND ${VSUSER_FILE} " <PropertyGroup>\n") file(APPEND ${VSUSER_FILE} " <PropertyGroup>\n")
@ -124,7 +124,7 @@ set(CPACK_THREADS 0)
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Qtk") set(CPACK_PACKAGE_INSTALL_DIRECTORY "Qtk")
# Remove any assimp components if defined by submodule. # Remove any assimp components if defined by submodule.
if (QTK_UPDATE_SUBMODULES) if (QTK_SUBMODULES)
get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
list(FILTER CPACK_COMPONENTS_ALL EXCLUDE REGEX .*assimp.*) list(FILTER CPACK_COMPONENTS_ALL EXCLUDE REGEX .*assimp.*)
list(REMOVE_ITEM CPACK_COMPONENTS_ALL Unspecified) list(REMOVE_ITEM CPACK_COMPONENTS_ALL Unspecified)
@ -136,7 +136,7 @@ set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
# https://nsis.sourceforge.io/Reference/CreateShortCut # https://nsis.sourceforge.io/Reference/CreateShortCut
set( set(
CPACK_NSIS_CREATE_ICONS_EXTRA CPACK_NSIS_CREATE_ICONS_EXTRA
"CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Qtk.lnk' '$INSTDIR\\\\bin\\\\qtk_app.exe'" "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Qtk.lnk' '$INSTDIR\\\\bin\\\\qtk_gui.exe'"
) )
set( set(
CPACK_NSIS_DELETE_ICONS_EXTRA CPACK_NSIS_DELETE_ICONS_EXTRA
@ -152,7 +152,7 @@ set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
# OSX # OSX
set(CPACK_BUNDLE_NAME ${PROJECT_NAME}) set(CPACK_BUNDLE_NAME ${PROJECT_NAME})
set(CPACK_BUNDLE_PLIST $<TARGET_BUNDLE_CONTENT_DIR:qtk_app>/Info.plist) set(CPACK_BUNDLE_PLIST $<TARGET_BUNDLE_CONTENT_DIR:qtk_gui>/Info.plist)
set(CPACK_BUNDLE_ICON ${QTK_OSX_ICONS}) set(CPACK_BUNDLE_ICON ${QTK_OSX_ICONS})
# Platform defaults for source bundles. # Platform defaults for source bundles.

View File

@ -33,32 +33,32 @@ target_sources(
target_link_libraries(qtk_plugin_library PUBLIC Qt6::UiPlugin qtk_library) target_link_libraries(qtk_plugin_library PUBLIC Qt6::UiPlugin qtk_library)
################################################################################ ################################################################################
# Qtk Widget Collection Plugin # Qtk Widget Plugins
################################################################################ ################################################################################
# Create a Qt Designer plugin for a collection of widgets from our library. # Create a Qt Designer plugin for a collection of widgets from our library.
qt_add_plugin(qtk_collection SHARED) qt_add_plugin(qtk_plugins SHARED)
target_sources( target_sources(
qtk_collection PRIVATE qtk_plugins PRIVATE
widgetplugincollection.cpp widgetplugincollection.h widgetplugincollection.cpp widgetplugincollection.h
widgetplugin.cpp widgetplugin.h widgetplugin.cpp widgetplugin.h
) )
target_link_libraries(qtk_collection PUBLIC qtk_plugin_library) target_link_libraries(qtk_plugins PUBLIC qtk_plugin_library)
################################################################################ ################################################################################
# Final Qtk Application # Final Qtk Application
################################################################################ ################################################################################
set( set(
QTK_APP_SOURCES QTK_GUI_SOURCES
qtkscene.cpp qtkscene.h qtkscene.cpp qtkscene.h
main.cpp main.cpp
) )
qt_add_executable(qtk_app ${QTK_APP_SOURCES}) qt_add_executable(qtk_gui ${QTK_GUI_SOURCES})
target_link_libraries(qtk_app PRIVATE qtk_plugin_library) target_link_libraries(qtk_gui PRIVATE qtk_plugin_library)
set_target_properties( set_target_properties(
qtk_app PROPERTIES qtk_gui PROPERTIES
WIN32_EXECUTABLE TRUE WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_BUNDLE_NAME Qtk MACOSX_BUNDLE_BUNDLE_NAME Qtk

View File

@ -1,6 +0,0 @@
#ifndef QTK_RESOURCES_H_IN_H
#define QTK_RESOURCES_H_IN_H
// Not currently in use, but will be in the future.
#endif // QTK_RESOURCES_H_IN_H

View File

@ -68,7 +68,7 @@ target_link_libraries(
Qt6::Core Qt6::OpenGLWidgets Qt6::Widgets Qt6::Core Qt6::OpenGLWidgets Qt6::Widgets
) )
if(QTK_UPDATE_SUBMODULES OR NOT ASSIMP_NEW_INTERFACE) if(QTK_SUBMODULES OR NOT ASSIMP_NEW_INTERFACE)
target_link_libraries(qtk_library PUBLIC assimp) target_link_libraries(qtk_library PUBLIC assimp)
elseif(ASSIMP_NEW_INTERFACE) elseif(ASSIMP_NEW_INTERFACE)
target_link_libraries(qtk_library PUBLIC assimp::assimp) target_link_libraries(qtk_library PUBLIC assimp::assimp)

View File

@ -27,177 +27,184 @@ namespace Qtk {
* Top-level object that represents 3D models stored within a scene. * Top-level object that represents 3D models stored within a scene.
*/ */
class QTKAPI Model : public Object { class QTKAPI Model : public Object {
public: public:
/************************************************************************* /*************************************************************************
* Typedefs * Typedefs
************************************************************************/ ************************************************************************/
/** ModelManager typedef that will manage global model access. */ /** ModelManager typedef that will manage global model access. */
typedef QHash<QString, Model *> ModelManager; typedef QHash<QString, Model *> ModelManager;
/************************************************************************* /*************************************************************************
* Constructors, Destructors * Constructors, Destructors
************************************************************************/ ************************************************************************/
/** /**
* Constructs a Model * Constructs a Model
* If no shaders are provided we will use default shaders. * If no shaders are provided we will use default shaders.
* *
* @param name Name to use for the Model's objectName. * @param name Name to use for the Model's objectName.
* @param path Path to the model to load for construction. * @param path Path to the model to load for construction.
* @param vertexShader Optional path to custom vertex shader. * @param vertexShader Optional path to custom vertex shader.
* @param fragmentShader Optional path to custom fragment shader. * @param fragmentShader Optional path to custom fragment shader.
*/ */
inline Model( inline Model(
const char * name, const char * path, const char *name, const char *path,
const char * vertexShader = ":/shaders/model-basic.vert", const char *vertexShader = ":/shaders/model-basic.vert",
const char * fragmentShader = ":/shaders/model-basic.frag") : const char *fragmentShader = ":/shaders/model-basic.frag") :
Object(name, QTK_MODEL), Object(name, QTK_MODEL),
mModelPath(path), mVertexShader(vertexShader), mModelPath(path), mVertexShader(vertexShader),
mFragmentShader(fragmentShader) { mFragmentShader(fragmentShader) {
loadModel(mModelPath); loadModel(mModelPath);
}
inline Model(
std::string name, std::string path,
std::string vertexShader = ":/shaders/model-basic.vert",
std::string fragmentShader = ":/shaders/model-basic.frag") :
Model(name.c_str(), path.c_str(), vertexShader.c_str(),
fragmentShader.c_str()) {}
inline ~Model() override { mManager.remove(getName().c_str()); }
/*************************************************************************
* Public Methods
************************************************************************/
/**
* Draws the model using attached shader program.
*/
void draw();
/**
* Draws the model using a custom shader program.
*
* @param shader Shader program to use to draw the model.
*/
void draw(QOpenGLShaderProgram &shader);
/**
* Flip a texture associated with this model
*
* @param fileName The name of the texture to flip as it is stored on disk
* @param flipX Flip the texture along the X axis
* @param flipY Flip the texture along the Y axis
*/
void flipTexture(
const std::string &fileName, bool flipX = false, bool flipY = true);
/*************************************************************************
* Setters
************************************************************************/
/**
* Sets a uniform value for each ModelMesh within this Model.
*
* @tparam T The type of the value we are settings
* @param location The uniform location
* @param value The value to assign to the uniform
*/
template<typename T>
inline void setUniform(const char *location, T value) {
for (auto &mesh: mMeshes) {
mesh.mProgram->bind();
mesh.mProgram->setUniformValue(location, value);
mesh.mProgram->release();
} }
}
inline ~Model() override { mManager.remove(getName().c_str()); } /*************************************************************************
* Accessors
************************************************************************/
/************************************************************************* /**
* Public Methods * Accessor function for retrieving a ModelMesh globally.
************************************************************************/ * The mesh is retrieved from the mManager private member.
*
* @param name The name of the model to load as it was constructed.
* @return Pointer to the model stored within the scene.
*/
[[nodiscard]] static Model *getInstance(const char *name);
/** /**
* Draws the model using attached shader program. * @return Transform3D attached to this Model.
*/ */
void draw(); inline Transform3D &getTransform() { return mTransform; }
/** private:
* Draws the model using a custom shader program. /*************************************************************************
* * Private Methods
* @param shader Shader program to use to draw the model. ************************************************************************/
*/
void draw(QOpenGLShaderProgram & shader);
/** /**
* Flip a texture associated with this model * Loads a model in .obj, .fbx, .gltf, and other formats.
* * For a full list of formats see assimp documentation:
* @param fileName The name of the texture to flip as it is stored on disk * https://github.com/assimp/assimp/blob/master/doc/Fileformats.md
* @param flipX Flip the texture along the X axis *
* @param flipY Flip the texture along the Y axis * Large models should not be loaded into Qt resource system.
*/ * Instead pass an *absolute* path to this function.
void flipTexture( * Relative paths will break if Qtk is executed from different locations.
const std::string & fileName, bool flipX = false, bool flipY = true); *
* @param path Absolute path to a model in .obj or another format accepted
* by assimp.
*/
void loadModel(const std::string &path);
/************************************************************************* /**
* Setters * Process a node in the model's geometry using Assimp.
************************************************************************/ *
* @param node The Assimp node to process.
* @param scene The Assimp scene for the loaded model.
*/
void processNode(aiNode *node, const aiScene *scene);
/** /**
* Sets a uniform value for each ModelMesh within this Model. * Process a mesh within a node using Assimp.
* *
* @tparam T The type of the value we are settings * @param mesh The Assimp mesh to process.
* @param location The uniform location * @param scene The Assimp scene for the loaded model.
* @param value The value to assign to the uniform * @return
*/ */
template <typename T> ModelMesh processMesh(aiMesh *mesh, const aiScene *scene);
inline void setUniform(const char * location, T value) {
for(auto & mesh : mMeshes) {
mesh.mProgram->bind();
mesh.mProgram->setUniformValue(location, value);
mesh.mProgram->release();
}
}
/************************************************************************* /**
* Accessors * Load a collection of material texture using Assimp.
************************************************************************/ * This function loads diffuse, specular, and narmal material textures.
* A Mesh may have many of any or all of the texture types above.
* Models can have many Meshes attached.
* This function returns all textures for a single Mesh within a Model.
*
* @param mat Loaded Assimp material.
* @param type Type of the material.
* @param typeName Texture type name in string format.
* @return Collection of all textures for a single ModelMesh.
*/
ModelMesh::Textures loadMaterialTextures(
aiMaterial *mat, aiTextureType type, const std::string &typeName);
/** /**
* Accessor function for retrieving a ModelMesh globally. * Sorts each mesh in the Model based on distance from the camera.
* The mesh is retrieved from the mManager private member. * This is for efficient drawing in OpenGL by preventing the drawing of
* * objects not visible due to being partially or entirely behind another
* @param name The name of the model to load as it was constructed. * object.
* @return Pointer to the model stored within the scene. */
*/ void sortModelMeshes();
[[nodiscard]] static Model * getInstance(const char * name);
/** /*************************************************************************
* @return Transform3D attached to this Model. * Private Members
*/ ************************************************************************/
inline Transform3D & getTransform() { return mTransform; }
private: /** Static QHash used to store and access models globally. */
/************************************************************************* static ModelManager mManager;
* Private Methods
************************************************************************/
/** /** Container to store N loaded textures for this model. */
* Loads a model in .obj, .fbx, .gltf, and other formats. ModelMesh::Textures mTexturesLoaded{};
* For a full list of formats see assimp documentation: /** Container to store N loaded meshes for this model. */
* https://github.com/assimp/assimp/blob/master/doc/Fileformats.md std::vector<ModelMesh> mMeshes{};
* /** The directory this model and it's textures are stored. */
* Large models should not be loaded into Qt resource system. std::string mDirectory{};
* Instead pass an *absolute* path to this function. /** File names for shaders and 3D model on disk. */
* Relative paths will break if Qtk is executed from different locations. std::string mVertexShader, mFragmentShader, mModelPath;
*
* @param path Absolute path to a model in .obj or another format accepted
* by assimp.
*/
void loadModel(const std::string & path);
/**
* Process a node in the model's geometry using Assimp.
*
* @param node The Assimp node to process.
* @param scene The Assimp scene for the loaded model.
*/
void processNode(aiNode * node, const aiScene * scene);
/**
* Process a mesh within a node using Assimp.
*
* @param mesh The Assimp mesh to process.
* @param scene The Assimp scene for the loaded model.
* @return
*/
ModelMesh processMesh(aiMesh * mesh, const aiScene * scene);
/**
* Load a collection of material texture using Assimp.
* This function loads diffuse, specular, and narmal material textures.
* A Mesh may have many of any or all of the texture types above.
* Models can have many Meshes attached.
* This function returns all textures for a single Mesh within a Model.
*
* @param mat Loaded Assimp material.
* @param type Type of the material.
* @param typeName Texture type name in string format.
* @return Collection of all textures for a single ModelMesh.
*/
ModelMesh::Textures loadMaterialTextures(
aiMaterial * mat, aiTextureType type, const std::string & typeName);
/**
* Sorts each mesh in the Model based on distance from the camera.
* This is for efficient drawing in OpenGL by preventing the drawing of
* objects not visible due to being partially or entirely behind another
* object.
*/
void sortModelMeshes();
/*************************************************************************
* Private Members
************************************************************************/
/** Static QHash used to store and access models globally. */
static ModelManager mManager;
/** Container to store N loaded textures for this model. */
ModelMesh::Textures mTexturesLoaded {};
/** Container to store N loaded meshes for this model. */
std::vector<ModelMesh> mMeshes {};
/** The directory this model and it's textures are stored. */
std::string mDirectory {};
/** File names for shaders and 3D model on disk. */
std::string mVertexShader, mFragmentShader, mModelPath;
}; };
} // namespace Qtk } // namespace Qtk