Compare commits
7 Commits
52521dc331
...
0f372f71f4
Author | SHA1 | Date |
---|---|---|
Shaun Reed | 0f372f71f4 | |
Shaun Reed | ad4d4636a4 | |
Shaun Reed | 86b3f78368 | |
Shaun Reed | 44d9092306 | |
Shaun Reed | f3406ee749 | |
Shaun Reed | 249a2b4446 | |
Shaun Reed | 432bf9919c |
|
@ -10,12 +10,14 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest]
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
CMAKE_PARAMS: -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
|
||||||
|
cmake: -DCMAKE_PREFIX_PATH="D:/a/qtk/qtk/Qt/6.3.1/mingw81_64/"
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
CMAKE_PARAMS: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/6.3.1/gcc_64/ -DASSIMP_NEW_INTERFACE=on
|
cmake: -DCMAKE_PREFIX_PATH="/home/runner/work/qtk/Qt/6.3.1/gcc_64/"
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
|
@ -26,11 +28,37 @@ jobs:
|
||||||
with:
|
with:
|
||||||
version: '6.3.1'
|
version: '6.3.1'
|
||||||
|
|
||||||
- name: Install Assimp Linux
|
- name: Chocolatey Action
|
||||||
if: matrix.os == 'ubuntu-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
|
uses: crazy-max/ghaction-chocolatey@v2.0.0
|
||||||
|
with:
|
||||||
|
args: install pkgconfiglite
|
||||||
|
|
||||||
|
- name: Build Qtk
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sudo apt install libassimp-dev -y
|
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
|
- name: Install Assimp MacOS
|
||||||
if: matrix.os == 'macos-latest'
|
if: matrix.os == 'macos-latest'
|
||||||
|
@ -38,8 +66,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
brew install assimp
|
brew install assimp
|
||||||
|
|
||||||
|
- name: Install Assimp Ubuntu
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt install libassimp-dev
|
||||||
|
|
||||||
- name: Build Qtk
|
- name: Build Qtk
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
mkdir build && cd build
|
cmake -S . -B build/ ${{ matrix.cmake }} && cmake --build build/ \
|
||||||
cmake .. ${{ matrix.CMAKE_PARAMS }} && cmake --build .
|
--target qtk-main
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "extern/assimp/assimp"]
|
||||||
|
path = extern/assimp/assimp
|
||||||
|
url = https://github.com/assimp/assimp.git
|
232
CMakeLists.txt
232
CMakeLists.txt
|
@ -3,7 +3,7 @@
|
||||||
## ##
|
## ##
|
||||||
## Project for working with OpenGL and Qt6 widgets ##
|
## Project for working with OpenGL and Qt6 widgets ##
|
||||||
################################################################################
|
################################################################################
|
||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
|
||||||
project(
|
project(
|
||||||
#[[NAME]] Qtk
|
#[[NAME]] Qtk
|
||||||
|
@ -16,72 +16,212 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# For CLion builds, point CMAKE_PREFIX_PATH to Qt6 install directory
|
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
list(APPEND CMAKE_PREFIX_PATH $ENV{HOME}/Code/Clones/Qt/6.3.1/gcc_64/)
|
add_compile_options(/wd4131 /wd4127)
|
||||||
find_package(Qt6 COMPONENTS OpenGLWidgets)
|
|
||||||
if (NOT Qt6_FOUND)
|
|
||||||
message(SEND_ERROR "Unable to find Qt6 at CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
|
|
||||||
message(FATAL_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()
|
||||||
|
message(STATUS "[Qtk] Compiling with ${CMAKE_CXX_COMPILER_ID}")
|
||||||
|
|
||||||
|
# Qtk build options
|
||||||
|
option(QTK_DEBUG "Enable debugger" ON)
|
||||||
|
message(STATUS "[Qtk] Compiling with QTK_DEBUG=${QTK_DEBUG}")
|
||||||
|
option(QTK_UPDATE_SUBMODULES "Update external project (assimp) submodule" ON)
|
||||||
|
message(
|
||||||
|
STATUS
|
||||||
|
"[Qtk] Compiling with QTK_UPDATE_SUBMODULES=${QTK_UPDATE_SUBMODULES}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Qt options
|
||||||
|
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
|
||||||
|
# + If assimp is available system-wide we can just set QTK_UPDATE_SUBMODULES 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
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# https://github.com/assimp/assimp/commit/6ac8279977c3a54118551e549d77329497116f66
|
# For CLion builds, point CMAKE_PREFIX_PATH to Qt6 install directory
|
||||||
find_package(assimp REQUIRED)
|
# + QtCreator will handle this for you if that is used instead
|
||||||
option(ASSIMP_NEW_INTERFACE "Use assimp::assimp as target instead of assimp" OFF)
|
list(APPEND CMAKE_PREFIX_PATH "${QT_DIR}")
|
||||||
|
|
||||||
|
# Find Qt
|
||||||
|
find_package(Qt6 COMPONENTS OpenGLWidgets)
|
||||||
|
if (NOT Qt6_FOUND)
|
||||||
|
message(
|
||||||
|
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()
|
||||||
|
|
||||||
|
if (QTK_UPDATE_SUBMODULES)
|
||||||
|
message(STATUS "[Qtk] Updating submodules...")
|
||||||
|
include("${CMAKE_SOURCE_DIR}/cmake/include/git_submodule.cmake")
|
||||||
|
submodule_update("${CMAKE_CURRENT_SOURCE_DIR}/extern/assimp/assimp/")
|
||||||
|
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/extern/assimp/assimp/")
|
||||||
|
else()
|
||||||
|
find_package(assimp REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Qtk
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
set(
|
||||||
|
PUBLIC_HEADERS
|
||||||
|
src/qtkwidget.h
|
||||||
|
src/abstractscene.h
|
||||||
|
src/camera3d.h
|
||||||
|
src/mesh.h
|
||||||
|
src/meshrenderer.h
|
||||||
|
src/model.h
|
||||||
|
src/object.h
|
||||||
|
src/skybox.h
|
||||||
|
src/texture.h
|
||||||
|
src/transform3D.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(
|
||||||
|
SOURCE_FILES
|
||||||
|
src/qtkwidget.cpp
|
||||||
|
src/abstractscene.cpp
|
||||||
|
src/camera3d.cpp
|
||||||
|
src/input.cpp
|
||||||
|
src/input.h
|
||||||
|
src/mesh.cpp
|
||||||
|
src/meshrenderer.cpp
|
||||||
|
src/model.cpp
|
||||||
|
src/object.cpp
|
||||||
|
src/qtkapi.h
|
||||||
|
src/skybox.cpp
|
||||||
|
src/texture.cpp
|
||||||
|
src/transform3D.cpp
|
||||||
|
)
|
||||||
|
|
||||||
include(GenerateExportHeader)
|
include(GenerateExportHeader)
|
||||||
|
|
||||||
|
add_library(qtk-widget STATIC ${PUBLIC_HEADERS} ${SOURCE_FILES})
|
||||||
|
target_include_directories(qtk-widget PRIVATE src/ app/)
|
||||||
|
|
||||||
|
set_target_properties(qtk-widget PROPERTIES
|
||||||
|
PUBLIC_HEADER "${PUBLIC_HEADERS}"
|
||||||
|
VERSION ${PROJECT_VERSION}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(qtk-widget PUBLIC Qt6::OpenGLWidgets)
|
||||||
|
target_link_libraries(qtk-widget PUBLIC Qt6::Widgets)
|
||||||
|
|
||||||
|
if (QTK_UPDATE_SUBMODULES OR NOT ASSIMP_NEW_INTERFACE)
|
||||||
|
target_link_libraries(qtk-widget PUBLIC assimp)
|
||||||
|
elseif(ASSIMP_NEW_INTERFACE)
|
||||||
|
target_link_libraries(qtk-widget PUBLIC assimp::assimp)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(QTK_DEBUG)
|
||||||
|
message(STATUS "[Qtk] Building with QTK_DEBUG=${QTK_DEBUG}")
|
||||||
|
target_compile_definitions(qtk-widget PUBLIC QTK_DEBUG)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
target_link_libraries(qtk-widget PUBLIC OpenGL::GL)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Install files
|
||||||
|
install(TARGETS qtk-widget
|
||||||
|
# Associate qtk-widget target with qtk-export
|
||||||
|
EXPORT qtk-export
|
||||||
|
# <prefix>/bin on DLL systems and <prefix>/lib on non-dll systems
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
ARCHIVE DESTINATION lib/static
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
PUBLIC_HEADER DESTINATION include
|
||||||
|
)
|
||||||
|
|
||||||
|
# Install export
|
||||||
|
# qtkTargets.cmake will only be installed when one of the CONFIGURATIONS is installed
|
||||||
|
# + The generated import will only reference that qtk configuration
|
||||||
|
install(EXPORT qtk-export
|
||||||
|
FILE qtkTargets.cmake
|
||||||
|
CONFIGURATIONS Debug|Release
|
||||||
|
DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake
|
||||||
|
)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Final Application
|
# Final Application
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# Add our Qt resources.qrc file to our application
|
set(QTK_RESOURCES "${CMAKE_SOURCE_DIR}/resources")
|
||||||
set(SOURCES app/main.cpp)
|
configure_file(
|
||||||
qt6_add_big_resources(SOURCES resources.qrc)
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/qtkresources.h.in"
|
||||||
qt_add_executable(qtk ${SOURCES})
|
"${CMAKE_CURRENT_BINARY_DIR}/src/qtkresources.h"
|
||||||
|
@ONLY
|
||||||
set(SOURCES
|
|
||||||
src/mainwidget.cpp src/mainwidget.h
|
|
||||||
src/mainwindow.cpp src/mainwindow.h src/mainwindow.ui
|
|
||||||
src/input.cpp src/input.h
|
|
||||||
src/mesh.cpp src/mesh.h
|
|
||||||
src/texture.cpp src/texture.h
|
|
||||||
src/object.cpp src/object.h
|
|
||||||
src/meshrenderer.cpp src/meshrenderer.h
|
|
||||||
src/camera3d.cpp src/camera3d.h
|
|
||||||
src/skybox.cpp src/skybox.h
|
|
||||||
src/transform3D.cpp src/transform3D.h
|
|
||||||
src/model.cpp src/model.h
|
|
||||||
src/scene.cpp src/scene.h
|
|
||||||
src/resourcemanager.cpp src/resourcemanager.h
|
|
||||||
)
|
)
|
||||||
qt_add_library(main-widget STATIC ${SOURCES})
|
|
||||||
|
|
||||||
target_include_directories(main-widget PUBLIC src/)
|
# Add our Qt resources.qrc file to our application
|
||||||
if(ASSIMP_NEW_INTERFACE)
|
set(QTK_APP_SOURCES app/main.cpp
|
||||||
target_link_libraries(main-widget PRIVATE assimp::assimp)
|
app/examplescene.cpp app/examplescene.h
|
||||||
else()
|
app/mainwindow.cpp app/mainwindow.h app/mainwindow.ui
|
||||||
target_link_libraries(main-widget PRIVATE assimp)
|
app/resourcemanager.h
|
||||||
endif()
|
src/qtkresources.h.in
|
||||||
target_link_libraries(main-widget PUBLIC Qt6::OpenGLWidgets)
|
)
|
||||||
if(WIN32)
|
qt6_add_big_resources(QTK_APP_SOURCES resources.qrc)
|
||||||
find_package(OpenGL REQUIRED)
|
|
||||||
target_link_libraries(main-widget PUBLIC OpenGL::GL)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_link_libraries(qtk PUBLIC main-widget)
|
qt_add_executable(qtk-main ${QTK_APP_SOURCES})
|
||||||
|
target_include_directories(qtk-main PRIVATE src/ app/)
|
||||||
|
|
||||||
# Link qtk executable to main main-widget library
|
# Link qtk-main executable to main qtk-widget library
|
||||||
set_target_properties(qtk PROPERTIES
|
target_link_libraries(qtk-main PUBLIC qtk-widget)
|
||||||
|
|
||||||
|
set_target_properties(qtk-main PROPERTIES
|
||||||
WIN32_EXECUTABLE TRUE
|
WIN32_EXECUTABLE TRUE
|
||||||
MACOSX_BUNDLE TRUE
|
MACOSX_BUNDLE TRUE
|
||||||
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
||||||
)
|
)
|
||||||
|
install(TARGETS qtk-main
|
||||||
|
BUNDLE DESTINATION .
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
)
|
||||||
|
|
||||||
generate_export_header(main-widget)
|
generate_export_header(qtk-widget)
|
||||||
|
if(WIN32)
|
||||||
|
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)
|
||||||
|
file(TO_NATIVE_PATH "${qt6_install_prefix}/bin" qt6_install_prefix)
|
||||||
|
if(TARGET Qt6::windeployqt)
|
||||||
|
add_custom_command(TARGET qtk-main
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND set PATH=%PATH%$<SEMICOLON>${qt6_install_prefix}
|
||||||
|
COMMAND Qt6::windeployqt --dir "${CMAKE_BINARY_DIR}/windeployqt" "$<TARGET_FILE_DIR:qtk-main>/$<TARGET_FILE_NAME:qtk-main>"
|
||||||
|
)
|
||||||
|
install(DIRECTORY "${CMAKE_BINARY_DIR}/windeployqt/" DESTINATION bin)
|
||||||
|
endif()
|
||||||
|
if(MSVC AND TARGET Qt6::qmake)
|
||||||
|
set(VSUSER_FILE ${CMAKE_CURRENT_BINARY_DIR}/qtk-main.vcxproj.user)
|
||||||
|
file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/extern/assimp/assimp/bin" assimp_bin)
|
||||||
|
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} " <PropertyGroup>\n")
|
||||||
|
file(APPEND ${VSUSER_FILE} " <LocalDebuggerEnvironment>Path=$(SolutionDir)\\lib\\$(Configuration);${qt6_install_prefix};${assimp_bin};$(Path)\n")
|
||||||
|
file(APPEND ${VSUSER_FILE} "$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>\n")
|
||||||
|
file(APPEND ${VSUSER_FILE} " <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\n")
|
||||||
|
file(APPEND ${VSUSER_FILE} " </PropertyGroup>\n")
|
||||||
|
file(APPEND ${VSUSER_FILE} "</Project>\n")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
73
README.md
73
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)
|
|
||||||
|
### Source Builds
|
||||||
|
|
||||||
|
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,10 +24,32 @@ 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
|
||||||
|
# We can also provide a path to assimp -
|
||||||
|
#cmake -DQTK_UPDATE_SUBMODULES=OFF -DCMAKE_PREFIX_PATH=$HOME/Qt/6.3.1/gcc_64;/path/to/assimp/ -S qtk/ -B qtk/build/ && cmake --build qtk/build/ -j $(nproc --ignore=2) --target qtk-main
|
||||||
|
./qtk/build/qtk-main
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are building on **Windows / Mac** and bringing your own installation of Assimp, consider setting the `-DASSIMP_NEW_INTERFACE` build flag.
|
||||||
|
```bash
|
||||||
|
cmake -DASSIMP_NEW_INTERFACE=ON -DQTK_UPDATE_SUBMODULES=OFF -DCMAKE_PREFIX_PATH=$HOME/Qt/6.3.1/gcc_64;/path/to/assimp/ -S qtk/ -B qtk/build/ && cmake --build qtk/build/ -j $(nproc --ignore=2) --target qtk-main
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 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.
|
||||||
If you see a small triangle floating by a model it represents the light source
|
If you see a small triangle floating by a model it represents the light source
|
||||||
that is being used for the shader rendering the model. These appear on models
|
that is being used for the shader rendering the model. These appear on models
|
||||||
|
@ -43,8 +65,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 +103,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/).
|
||||||
|
|
||||||
|
|
|
@ -6,32 +6,27 @@
|
||||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
|
#include <abstractscene.h>
|
||||||
#include <camera3d.h>
|
#include <camera3d.h>
|
||||||
#include <texture.h>
|
|
||||||
#include <meshrenderer.h>
|
#include <meshrenderer.h>
|
||||||
#include <model.h>
|
#include <model.h>
|
||||||
#include <resourcemanager.h>
|
#include <resourcemanager.h>
|
||||||
|
#include <examplescene.h>
|
||||||
|
#include <texture.h>
|
||||||
|
|
||||||
#include <scene.h>
|
using namespace Qtk;
|
||||||
|
|
||||||
|
|
||||||
Camera3D Scene::mCamera;
|
|
||||||
QMatrix4x4 Scene::mProjection;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Constructors, Destructors
|
* Constructors, Destructors
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
Scene::Scene()
|
ExampleScene::ExampleScene()
|
||||||
{
|
{
|
||||||
mCamera.transform().setTranslation(0.0f, 0.0f, 20.0f);
|
Camera().transform().setTranslation(0.0f, 0.0f, 20.0f);
|
||||||
mCamera.transform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
Camera().transform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene()
|
ExampleScene::~ExampleScene()
|
||||||
{
|
{
|
||||||
delete mTestPhong;
|
delete mTestPhong;
|
||||||
delete mTestSpecular;
|
delete mTestSpecular;
|
||||||
|
@ -39,6 +34,7 @@ Scene::~Scene()
|
||||||
delete mTestAmbient;
|
delete mTestAmbient;
|
||||||
for (auto & mesh : mMeshes) delete mesh;
|
for (auto & mesh : mMeshes) delete mesh;
|
||||||
for (auto & model : mModels) delete model;
|
for (auto & model : mModels) delete model;
|
||||||
|
delete mSkybox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,10 +42,13 @@ Scene::~Scene()
|
||||||
* Public Member Functions
|
* Public Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void Scene::init()
|
void ExampleScene::init()
|
||||||
{
|
{
|
||||||
|
Qtk::Skybox * sb = new Qtk::Skybox("Skybox");
|
||||||
|
setSkybox(sb);
|
||||||
|
|
||||||
// Initialize Phong example cube
|
// Initialize Phong example cube
|
||||||
mTestPhong = new MeshRenderer("phong", Cube());
|
mTestPhong = new Qtk::MeshRenderer("phong", Qtk::Cube());
|
||||||
mTestPhong->mTransform.setTranslation(3.0f, 0.0f, -2.0f);
|
mTestPhong->mTransform.setTranslation(3.0f, 0.0f, -2.0f);
|
||||||
mTestPhong->setShaders(":/solid-phong.vert", ":/solid-phong.frag");
|
mTestPhong->setShaders(":/solid-phong.vert", ":/solid-phong.frag");
|
||||||
mTestPhong->init();
|
mTestPhong->init();
|
||||||
|
@ -76,7 +75,7 @@ void Scene::init()
|
||||||
|
|
||||||
|
|
||||||
// Initialize Ambient example cube
|
// Initialize Ambient example cube
|
||||||
mTestAmbient = new MeshRenderer("ambient", Cube());
|
mTestAmbient = new Qtk::MeshRenderer("ambient", Cube());
|
||||||
mTestAmbient->mTransform.setTranslation(7.0f, 0.0f, -2.0f);
|
mTestAmbient->mTransform.setTranslation(7.0f, 0.0f, -2.0f);
|
||||||
mTestAmbient->setShaders(":/solid-ambient.vert", ":/solid-ambient.frag");
|
mTestAmbient->setShaders(":/solid-ambient.vert", ":/solid-ambient.frag");
|
||||||
mTestAmbient->init();
|
mTestAmbient->init();
|
||||||
|
@ -100,7 +99,7 @@ void Scene::init()
|
||||||
mTestAmbient->mProgram.release();
|
mTestAmbient->mProgram.release();
|
||||||
|
|
||||||
// Initialize Diffuse example cube
|
// Initialize Diffuse example cube
|
||||||
mTestDiffuse = new MeshRenderer("diffuse", Cube());
|
mTestDiffuse = new Qtk::MeshRenderer("diffuse", Cube());
|
||||||
mTestDiffuse->mTransform.setTranslation(9.0f, 0.0f, -2.0f);
|
mTestDiffuse->mTransform.setTranslation(9.0f, 0.0f, -2.0f);
|
||||||
mTestDiffuse->setShaders(":/solid-diffuse.vert", ":/solid-diffuse.frag");
|
mTestDiffuse->setShaders(":/solid-diffuse.vert", ":/solid-diffuse.frag");
|
||||||
mTestDiffuse->init();
|
mTestDiffuse->init();
|
||||||
|
@ -124,7 +123,7 @@ void Scene::init()
|
||||||
mTestDiffuse->mProgram.release();
|
mTestDiffuse->mProgram.release();
|
||||||
|
|
||||||
// Initialize Specular example cube
|
// Initialize Specular example cube
|
||||||
mTestSpecular = new MeshRenderer("specular", Cube());
|
mTestSpecular = new Qtk::MeshRenderer("specular", Cube());
|
||||||
mTestSpecular->mTransform.setTranslation(11.0f, 0.0f, -2.0f);
|
mTestSpecular->mTransform.setTranslation(11.0f, 0.0f, -2.0f);
|
||||||
mTestSpecular->setShaders(":/solid-specular.vert", ":/solid-specular.frag");
|
mTestSpecular->setShaders(":/solid-specular.vert", ":/solid-specular.frag");
|
||||||
mTestSpecular->init();
|
mTestSpecular->init();
|
||||||
|
@ -152,31 +151,31 @@ void Scene::init()
|
||||||
//
|
//
|
||||||
// Model loading
|
// Model loading
|
||||||
|
|
||||||
mModels.push_back(new Model("backpack", ":/models/backpack/backpack.obj"));
|
mModels.push_back(new Qtk::Model("backpack", ":/models/backpack/backpack.obj"));
|
||||||
// Sometimes model textures need flipped in certain directions
|
// Sometimes model textures need flipped in certain directions
|
||||||
mModels.back()->flipTexture("diffuse.jpg", false, true);
|
mModels.back()->flipTexture("diffuse.jpg", false, true);
|
||||||
mModels.back()->mTransform.setTranslation(0.0f, 0.0f, -10.0f);
|
mModels.back()->mTransform.setTranslation(0.0f, 0.0f, -10.0f);
|
||||||
|
|
||||||
mModels.push_back(new Model("bird", ":/models/bird/bird.obj"));
|
mModels.push_back(new Qtk::Model("bird", ":/models/bird/bird.obj"));
|
||||||
mModels.back()->mTransform.setTranslation(2.0f, 2.0f, -10.0f);
|
mModels.back()->mTransform.setTranslation(2.0f, 2.0f, -10.0f);
|
||||||
// Sometimes the models are very large
|
// Sometimes the models are very large
|
||||||
mModels.back()->mTransform.scale(0.0025f);
|
mModels.back()->mTransform.scale(0.0025f);
|
||||||
mModels.back()->mTransform.rotate(-110.0f, 0.0f, 1.0f, 0.0f);
|
mModels.back()->mTransform.rotate(-110.0f, 0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
mModels.push_back(new Model("lion", ":/models/lion/lion.obj"));
|
mModels.push_back(new Qtk::Model("lion", ":/models/lion/lion.obj"));
|
||||||
mModels.back()->mTransform.setTranslation(-3.0f, -1.0f, -10.0f);
|
mModels.back()->mTransform.setTranslation(-3.0f, -1.0f, -10.0f);
|
||||||
mModels.back()->mTransform.scale(0.15f);
|
mModels.back()->mTransform.scale(0.15f);
|
||||||
|
|
||||||
mModels.push_back(new Model("alien", ":/models/alien-hominid/alien.obj"));
|
mModels.push_back(new Qtk::Model("alien", ":/models/alien-hominid/alien.obj"));
|
||||||
mModels.back()->mTransform.setTranslation(2.0f, -1.0f, -5.0f);
|
mModels.back()->mTransform.setTranslation(2.0f, -1.0f, -5.0f);
|
||||||
mModels.back()->mTransform.scale(0.15f);
|
mModels.back()->mTransform.scale(0.15f);
|
||||||
|
|
||||||
mModels.push_back(new Model("scythe", ":/models/scythe/scythe.obj"));
|
mModels.push_back(new Qtk::Model("scythe", ":/models/scythe/scythe.obj"));
|
||||||
mModels.back()->mTransform.setTranslation(-6.0f, 0.0f, -10.0f);
|
mModels.back()->mTransform.setTranslation(-6.0f, 0.0f, -10.0f);
|
||||||
mModels.back()->mTransform.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
|
mModels.back()->mTransform.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
|
||||||
mModels.back()->mTransform.rotate(90.0f, 0.0f, 1.0f, 0.0f);
|
mModels.back()->mTransform.rotate(90.0f, 0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
mModels.push_back(new Model("masterChief", ":/models/spartan/spartan.obj"));
|
mModels.push_back(new Qtk::Model("masterChief", ":/models/spartan/spartan.obj"));
|
||||||
mModels.back()->mTransform.setTranslation(-1.5f, 0.5f, -2.0f);
|
mModels.back()->mTransform.setTranslation(-1.5f, 0.5f, -2.0f);
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,7 +185,7 @@ void Scene::init()
|
||||||
// Render an alien with specular
|
// Render an alien with specular
|
||||||
// Test alien Model with phong lighting and specular mapping
|
// Test alien Model with phong lighting and specular mapping
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("alienTestLight", Triangle(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("alienTestLight", Triangle(Qtk::QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(4.0f, 1.5f, 10.0f);
|
mMeshes.back()->mTransform.setTranslation(4.0f, 1.5f, 10.0f);
|
||||||
mMeshes.back()->mTransform.scale(0.25f);
|
mMeshes.back()->mTransform.scale(0.25f);
|
||||||
// This function changes values we have allocated in a buffer, so init() after
|
// This function changes values we have allocated in a buffer, so init() after
|
||||||
|
@ -194,7 +193,7 @@ void Scene::init()
|
||||||
mMeshes.back()->init();
|
mMeshes.back()->init();
|
||||||
|
|
||||||
mModels.push_back(
|
mModels.push_back(
|
||||||
new Model("alienTest", ":/models/alien-hominid/alien.obj",
|
new Qtk::Model("alienTest", ":/models/alien-hominid/alien.obj",
|
||||||
":/model-specular.vert", ":/model-specular.frag")
|
":/model-specular.vert", ":/model-specular.frag")
|
||||||
);
|
);
|
||||||
mModels.back()->mTransform.setTranslation(3.0f, -1.0f, 10.0f);
|
mModels.back()->mTransform.setTranslation(3.0f, -1.0f, 10.0f);
|
||||||
|
@ -214,7 +213,7 @@ void Scene::init()
|
||||||
|
|
||||||
// Test spartan Model with phong lighting, specular and normal mapping
|
// Test spartan Model with phong lighting, specular and normal mapping
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("spartanTestLight", Triangle(QTK_DRAW_ELEMENTS))
|
new Qtk::MeshRenderer("spartanTestLight", Triangle(QTK_DRAW_ELEMENTS))
|
||||||
);
|
);
|
||||||
mMeshes.back()->mTransform.setTranslation(1.0f, 1.5f, 10.0f);
|
mMeshes.back()->mTransform.setTranslation(1.0f, 1.5f, 10.0f);
|
||||||
mMeshes.back()->mTransform.scale(0.25f);
|
mMeshes.back()->mTransform.scale(0.25f);
|
||||||
|
@ -223,7 +222,7 @@ void Scene::init()
|
||||||
mMeshes.back()->init();
|
mMeshes.back()->init();
|
||||||
|
|
||||||
mModels.push_back(
|
mModels.push_back(
|
||||||
new Model("spartanTest", ":/models/spartan/spartan.obj",
|
new Qtk::Model("spartanTest", ":/models/spartan/spartan.obj",
|
||||||
":/model-normals.vert", ":/model-normals.frag")
|
":/model-normals.vert", ":/model-normals.frag")
|
||||||
);
|
);
|
||||||
mModels.back()->mTransform.setTranslation(0.0f, -1.0f, 10.0f);
|
mModels.back()->mTransform.setTranslation(0.0f, -1.0f, 10.0f);
|
||||||
|
@ -242,7 +241,7 @@ void Scene::init()
|
||||||
|
|
||||||
// Test basic cube with phong.vert and phong.frag shaders
|
// Test basic cube with phong.vert and phong.frag shaders
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("testLight", Triangle(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("testLight", Triangle(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(5.0f, 1.25f, 10.0f);
|
mMeshes.back()->mTransform.setTranslation(5.0f, 1.25f, 10.0f);
|
||||||
mMeshes.back()->mTransform.scale(0.25f);
|
mMeshes.back()->mTransform.scale(0.25f);
|
||||||
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
||||||
|
@ -251,7 +250,7 @@ void Scene::init()
|
||||||
mMeshes.back()->init();
|
mMeshes.back()->init();
|
||||||
|
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("testPhong", Cube(QTK_DRAW_ARRAYS)));
|
new Qtk::MeshRenderer("testPhong", Cube(QTK_DRAW_ARRAYS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 10.0f);
|
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 10.0f);
|
||||||
mMeshes.back()->setShaders(":/phong.vert", ":/phong.frag");
|
mMeshes.back()->setShaders(":/phong.vert", ":/phong.frag");
|
||||||
mMeshes.back()->setColor(QVector3D(0.0f, 0.25f, 0.0f));
|
mMeshes.back()->setColor(QVector3D(0.0f, 0.25f, 0.0f));
|
||||||
|
@ -291,25 +290,25 @@ void Scene::init()
|
||||||
// Create simple shapes using MeshRenderer class and data in mesh.h
|
// Create simple shapes using MeshRenderer class and data in mesh.h
|
||||||
|
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(-5.0f, 0.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(-5.0f, 0.0f, -2.0f);
|
||||||
|
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("centerCube", Cube(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("centerCube", Cube(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(-7.0f, 0.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(-7.0f, 0.0f, -2.0f);
|
||||||
|
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("leftTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("leftTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(-9.0f, 0.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(-9.0f, 0.0f, -2.0f);
|
||||||
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
||||||
|
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("topTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("topTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(-7.0f, 2.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(-7.0f, 2.0f, -2.0f);
|
||||||
mMeshes.back()->mTransform.scale(0.25f);
|
mMeshes.back()->mTransform.scale(0.25f);
|
||||||
|
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("bottomTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("bottomTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(-7.0f, -2.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(-7.0f, -2.0f, -2.0f);
|
||||||
mMeshes.back()->mTransform.scale(0.25f);
|
mMeshes.back()->mTransform.scale(0.25f);
|
||||||
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
||||||
|
@ -322,7 +321,7 @@ void Scene::init()
|
||||||
|
|
||||||
// RGB Normals cube to show normals are correct with QTK_DRAW_ARRAYS
|
// RGB Normals cube to show normals are correct with QTK_DRAW_ARRAYS
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("rgbNormalsCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
|
new Qtk::MeshRenderer("rgbNormalsCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 4.0f);
|
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 4.0f);
|
||||||
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
||||||
mMeshes.back()->init();
|
mMeshes.back()->init();
|
||||||
|
@ -344,7 +343,7 @@ void Scene::init()
|
||||||
|
|
||||||
// RGB Normals cube to show normals are correct with QTK_DRAW_ELEMENTS_NORMALS
|
// RGB Normals cube to show normals are correct with QTK_DRAW_ELEMENTS_NORMALS
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("rgbNormalsCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
new Qtk::MeshRenderer("rgbNormalsCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 2.0f);
|
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 2.0f);
|
||||||
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
||||||
mMeshes.back()->init();
|
mMeshes.back()->init();
|
||||||
|
@ -369,7 +368,7 @@ void Scene::init()
|
||||||
// + UVs required duplicating element position data from QTK_DRAW_ELEMENTS
|
// + UVs required duplicating element position data from QTK_DRAW_ELEMENTS
|
||||||
// + This is because the same position must use different UV coordinates
|
// + This is because the same position must use different UV coordinates
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("uvCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
|
new Qtk::MeshRenderer("uvCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(-3.0f, 0.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(-3.0f, 0.0f, -2.0f);
|
||||||
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
||||||
mMeshes.back()->init();
|
mMeshes.back()->init();
|
||||||
|
@ -397,7 +396,7 @@ void Scene::init()
|
||||||
|
|
||||||
// Test drawing a cube with texture coordinates using glDrawElements
|
// Test drawing a cube with texture coordinates using glDrawElements
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("uvCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
new Qtk::MeshRenderer("uvCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(-1.7f, 0.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(-1.7f, 0.0f, -2.0f);
|
||||||
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
||||||
mMeshes.back()->init();
|
mMeshes.back()->init();
|
||||||
|
@ -423,7 +422,7 @@ void Scene::init()
|
||||||
// Texturing a cube using a cube map
|
// Texturing a cube using a cube map
|
||||||
// + Cube map texturing works with both QTK_DRAW_ARRAYS and QTK_DRAW_ELEMENTS
|
// + Cube map texturing works with both QTK_DRAW_ARRAYS and QTK_DRAW_ELEMENTS
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(-3.0f, 1.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(-3.0f, 1.0f, -2.0f);
|
||||||
mMeshes.back()->mTransform.setRotation(45.0f, 0.0f, 1.0f, 0.0f);
|
mMeshes.back()->mTransform.setRotation(45.0f, 0.0f, 1.0f, 0.0f);
|
||||||
mMeshes.back()->setShaders(":/texture-cubemap.vert", ":/texture-cubemap.frag");
|
mMeshes.back()->setShaders(":/texture-cubemap.vert", ":/texture-cubemap.frag");
|
||||||
|
@ -450,7 +449,7 @@ void Scene::init()
|
||||||
// Create a cube with custom shaders
|
// Create a cube with custom shaders
|
||||||
// + Apply RGB normals shader and spin the cube for a neat effect
|
// + Apply RGB normals shader and spin the cube for a neat effect
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("rgbNormalsCube", Cube(QTK_DRAW_ARRAYS)));
|
new Qtk::MeshRenderer("rgbNormalsCube", Cube(QTK_DRAW_ARRAYS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(5.0f, 2.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(5.0f, 2.0f, -2.0f);
|
||||||
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
||||||
mMeshes.back()->init();
|
mMeshes.back()->init();
|
||||||
|
@ -472,7 +471,7 @@ void Scene::init()
|
||||||
|
|
||||||
// RGB Normals triangle to show normals are correct with QTK_DRAW_ARRAYS
|
// RGB Normals triangle to show normals are correct with QTK_DRAW_ARRAYS
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("rgbTriangleArraysTest", Triangle(QTK_DRAW_ARRAYS)));
|
new Qtk::MeshRenderer("rgbTriangleArraysTest", Triangle(QTK_DRAW_ARRAYS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(7.0f, 0.0f, 2.0f);
|
mMeshes.back()->mTransform.setTranslation(7.0f, 0.0f, 2.0f);
|
||||||
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
||||||
mMeshes.back()->init();
|
mMeshes.back()->init();
|
||||||
|
@ -493,7 +492,7 @@ void Scene::init()
|
||||||
|
|
||||||
// RGB Normals triangle to show normals are correct with QTK_DRAW_ELEMENTS
|
// RGB Normals triangle to show normals are correct with QTK_DRAW_ELEMENTS
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("rgbTriangleElementsTest",
|
new Qtk::MeshRenderer("rgbTriangleElementsTest",
|
||||||
Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(7.0f, 0.0f, 4.0f);
|
mMeshes.back()->mTransform.setTranslation(7.0f, 0.0f, 4.0f);
|
||||||
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
||||||
|
@ -515,7 +514,7 @@ void Scene::init()
|
||||||
|
|
||||||
// Test drawing triangle with glDrawArrays with texture coordinates
|
// Test drawing triangle with glDrawArrays with texture coordinates
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("testTriangleArraysUV", Triangle(QTK_DRAW_ARRAYS)));
|
new Qtk::MeshRenderer("testTriangleArraysUV", Triangle(QTK_DRAW_ARRAYS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(-3.0f, 2.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(-3.0f, 2.0f, -2.0f);
|
||||||
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
||||||
mMeshes.back()->init();
|
mMeshes.back()->init();
|
||||||
|
@ -543,7 +542,7 @@ void Scene::init()
|
||||||
|
|
||||||
// Test drawing triangle with glDrawElements with texture coordinates
|
// Test drawing triangle with glDrawElements with texture coordinates
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("testTriangleElementsUV",
|
new Qtk::MeshRenderer("testTriangleElementsUV",
|
||||||
Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(-2.5f, 0.0f, -1.0f);
|
mMeshes.back()->mTransform.setTranslation(-2.5f, 0.0f, -1.0f);
|
||||||
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
||||||
|
@ -575,7 +574,7 @@ void Scene::init()
|
||||||
|
|
||||||
// Example of a cube with no lighting applied
|
// Example of a cube with no lighting applied
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("noLight", Cube(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("noLight", Cube(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, -2.0f);
|
||||||
mMeshes.back()->setShaders(":/solid-perspective.vert",
|
mMeshes.back()->setShaders(":/solid-perspective.vert",
|
||||||
":/solid-perspective.frag");
|
":/solid-perspective.frag");
|
||||||
|
@ -586,28 +585,24 @@ void Scene::init()
|
||||||
|
|
||||||
// Create objects that represent light sources for lighting examples
|
// Create objects that represent light sources for lighting examples
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("phongLight", Triangle(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("phongLight", Triangle(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(3.0f, 2.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(3.0f, 2.0f, -2.0f);
|
||||||
mMeshes.back()->mTransform.scale(0.25f);
|
mMeshes.back()->mTransform.scale(0.25f);
|
||||||
|
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("diffuseLight", Triangle(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("diffuseLight", Triangle(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(9.0f, 2.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(9.0f, 2.0f, -2.0f);
|
||||||
mMeshes.back()->mTransform.scale(0.25f);
|
mMeshes.back()->mTransform.scale(0.25f);
|
||||||
|
|
||||||
mMeshes.push_back(
|
mMeshes.push_back(
|
||||||
new MeshRenderer("specularLight", Triangle(QTK_DRAW_ELEMENTS)));
|
new Qtk::MeshRenderer("specularLight", Triangle(QTK_DRAW_ELEMENTS)));
|
||||||
mMeshes.back()->mTransform.setTranslation(11.0f, 2.0f, -2.0f);
|
mMeshes.back()->mTransform.setTranslation(11.0f, 2.0f, -2.0f);
|
||||||
mMeshes.back()->mTransform.scale(0.25f);
|
mMeshes.back()->mTransform.scale(0.25f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::draw()
|
void ExampleScene::draw()
|
||||||
{
|
{
|
||||||
mSkybox.draw();
|
Scene::draw();
|
||||||
|
|
||||||
for (auto & model : mModels) model->draw();
|
|
||||||
|
|
||||||
for (const auto &mesh : mMeshes) mesh->draw();
|
|
||||||
|
|
||||||
mTestPhong->mProgram.bind();
|
mTestPhong->mProgram.bind();
|
||||||
mTestPhong->setUniform("uModelInverseTransposed",
|
mTestPhong->setUniform("uModelInverseTransposed",
|
||||||
|
@ -616,13 +611,13 @@ void Scene::draw()
|
||||||
"uLightPosition",
|
"uLightPosition",
|
||||||
MeshRenderer::getInstance("phongLight")->mTransform.translation());
|
MeshRenderer::getInstance("phongLight")->mTransform.translation());
|
||||||
mTestPhong->setUniform("uCameraPosition",
|
mTestPhong->setUniform("uCameraPosition",
|
||||||
Scene::Camera().transform().translation());
|
ExampleScene::Camera().transform().translation());
|
||||||
mTestPhong->mProgram.release();
|
mTestPhong->mProgram.release();
|
||||||
mTestPhong->draw();
|
mTestPhong->draw();
|
||||||
|
|
||||||
mTestAmbient->mProgram.bind();
|
mTestAmbient->mProgram.bind();
|
||||||
mTestAmbient->setUniform("uCameraPosition",
|
mTestAmbient->setUniform("uCameraPosition",
|
||||||
Scene::Camera().transform().translation());
|
ExampleScene::Camera().transform().translation());
|
||||||
mTestAmbient->mProgram.release();
|
mTestAmbient->mProgram.release();
|
||||||
mTestAmbient->draw();
|
mTestAmbient->draw();
|
||||||
|
|
||||||
|
@ -632,7 +627,7 @@ void Scene::draw()
|
||||||
mTestDiffuse->setUniform(
|
mTestDiffuse->setUniform(
|
||||||
"uLightPosition",
|
"uLightPosition",
|
||||||
MeshRenderer::getInstance("diffuseLight")->mTransform.translation());
|
MeshRenderer::getInstance("diffuseLight")->mTransform.translation());
|
||||||
mTestDiffuse->setUniform("uCameraPosition", Scene::Camera().transform().translation());
|
mTestDiffuse->setUniform("uCameraPosition", ExampleScene::Camera().transform().translation());
|
||||||
mTestDiffuse->mProgram.release();
|
mTestDiffuse->mProgram.release();
|
||||||
mTestDiffuse->draw();
|
mTestDiffuse->draw();
|
||||||
|
|
||||||
|
@ -643,43 +638,43 @@ void Scene::draw()
|
||||||
mTestSpecular->setUniform(
|
mTestSpecular->setUniform(
|
||||||
"uLightPosition",
|
"uLightPosition",
|
||||||
MeshRenderer::getInstance("specularLight")->mTransform.translation());
|
MeshRenderer::getInstance("specularLight")->mTransform.translation());
|
||||||
mTestSpecular->setUniform("uCameraPosition", Scene::Camera().transform().translation());
|
mTestSpecular->setUniform("uCameraPosition", ExampleScene::Camera().transform().translation());
|
||||||
mTestSpecular->mProgram.release();
|
mTestSpecular->mProgram.release();
|
||||||
mTestSpecular->draw();
|
mTestSpecular->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::update()
|
void ExampleScene::update()
|
||||||
{
|
{
|
||||||
auto position = MeshRenderer::getInstance("alienTestLight")->mTransform.translation();
|
auto position = MeshRenderer::getInstance("alienTestLight")->mTransform.translation();
|
||||||
Model::getInstance("alienTest")->setUniform(
|
Model::getInstance("alienTest")->setUniform(
|
||||||
"uLight.position", position);
|
"uLight.position", position);
|
||||||
Model::getInstance("alienTest")->setUniform(
|
Model::getInstance("alienTest")->setUniform(
|
||||||
"uCameraPosition", Scene::Camera().transform().translation());
|
"uCameraPosition", ExampleScene::Camera().transform().translation());
|
||||||
auto posMatrix = Model::getInstance("alienTest")->mTransform.toMatrix();
|
auto posMatrix = Model::getInstance("alienTest")->mTransform.toMatrix();
|
||||||
Model::getInstance("alienTest")->setUniform(
|
Model::getInstance("alienTest")->setUniform(
|
||||||
"uMVP.normalMatrix", posMatrix.normalMatrix());
|
"uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||||
Model::getInstance("alienTest")->setUniform(
|
Model::getInstance("alienTest")->setUniform(
|
||||||
"uMVP.model", posMatrix);
|
"uMVP.model", posMatrix);
|
||||||
Model::getInstance("alienTest")->setUniform(
|
Model::getInstance("alienTest")->setUniform(
|
||||||
"uMVP.view", Scene::Camera().toMatrix());
|
"uMVP.view", ExampleScene::Camera().toMatrix());
|
||||||
Model::getInstance("alienTest")->setUniform(
|
Model::getInstance("alienTest")->setUniform(
|
||||||
"uMVP.projection", Scene::Projection());
|
"uMVP.projection", ExampleScene::Projection());
|
||||||
Model::getInstance("alienTest")->mTransform.rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
Model::getInstance("alienTest")->mTransform.rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
position = MeshRenderer::getInstance("spartanTestLight")->mTransform.translation();
|
position = MeshRenderer::getInstance("spartanTestLight")->mTransform.translation();
|
||||||
Model::getInstance("spartanTest")->setUniform(
|
Model::getInstance("spartanTest")->setUniform(
|
||||||
"uLight.position", position);
|
"uLight.position", position);
|
||||||
Model::getInstance("spartanTest")->setUniform(
|
Model::getInstance("spartanTest")->setUniform(
|
||||||
"uCameraPosition", Scene::Camera().transform().translation());
|
"uCameraPosition", ExampleScene::Camera().transform().translation());
|
||||||
posMatrix = Model::getInstance("spartanTest")->mTransform.toMatrix();
|
posMatrix = Model::getInstance("spartanTest")->mTransform.toMatrix();
|
||||||
Model::getInstance("spartanTest")->setUniform(
|
Model::getInstance("spartanTest")->setUniform(
|
||||||
"uMVP.normalMatrix", posMatrix.normalMatrix());
|
"uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||||
Model::getInstance("spartanTest")->setUniform(
|
Model::getInstance("spartanTest")->setUniform(
|
||||||
"uMVP.model", posMatrix);
|
"uMVP.model", posMatrix);
|
||||||
Model::getInstance("spartanTest")->setUniform(
|
Model::getInstance("spartanTest")->setUniform(
|
||||||
"uMVP.view", Scene::Camera().toMatrix());
|
"uMVP.view", ExampleScene::Camera().toMatrix());
|
||||||
Model::getInstance("spartanTest")->setUniform(
|
Model::getInstance("spartanTest")->setUniform(
|
||||||
"uMVP.projection", Scene::Projection());
|
"uMVP.projection", ExampleScene::Projection());
|
||||||
Model::getInstance("spartanTest")->mTransform.rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
Model::getInstance("spartanTest")->mTransform.rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
|
|
||||||
|
@ -691,16 +686,16 @@ void Scene::update()
|
||||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||||
"uLight.position", position);
|
"uLight.position", position);
|
||||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||||
"uCameraPosition", Scene::Camera().transform().translation());
|
"uCameraPosition", ExampleScene::Camera().transform().translation());
|
||||||
posMatrix = MeshRenderer::getInstance("testPhong")->mTransform.toMatrix();
|
posMatrix = MeshRenderer::getInstance("testPhong")->mTransform.toMatrix();
|
||||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||||
"uMVP.normalMatrix", posMatrix.normalMatrix());
|
"uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||||
"uMVP.model", posMatrix);
|
"uMVP.model", posMatrix);
|
||||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||||
"uMVP.view", Scene::Camera().toMatrix());
|
"uMVP.view", ExampleScene::Camera().toMatrix());
|
||||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||||
"uMVP.projection", Scene::Projection());
|
"uMVP.projection", ExampleScene::Projection());
|
||||||
MeshRenderer::getInstance("testPhong")->mProgram.release();
|
MeshRenderer::getInstance("testPhong")->mProgram.release();
|
||||||
|
|
||||||
// Rotate lighting example cubes
|
// Rotate lighting example cubes
|
|
@ -6,40 +6,31 @@
|
||||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
#ifndef QTK_SCENE_H
|
#ifndef QTK_EXAMPLE_SCENE_H
|
||||||
#define QTK_SCENE_H
|
#define QTK_EXAMPLE_SCENE_H
|
||||||
|
|
||||||
|
#include <abstractscene.h>
|
||||||
#include <camera3d.h>
|
#include <camera3d.h>
|
||||||
#include <skybox.h>
|
#include <skybox.h>
|
||||||
|
|
||||||
#include <QMatrix4x4>
|
#include <QMatrix4x4>
|
||||||
|
|
||||||
class MeshRenderer;
|
|
||||||
class Model;
|
|
||||||
|
|
||||||
class Scene {
|
class ExampleScene : public Qtk::Scene {
|
||||||
public:
|
public:
|
||||||
Scene();
|
ExampleScene();
|
||||||
~Scene();
|
~ExampleScene();
|
||||||
|
|
||||||
void init();
|
virtual void init();
|
||||||
void draw();
|
virtual void draw() override;
|
||||||
void update();
|
virtual void update();
|
||||||
|
|
||||||
static Camera3D & Camera() { return mCamera;}
|
|
||||||
static QMatrix4x4 View() { return mCamera.toMatrix();}
|
|
||||||
static QMatrix4x4 & Projection() { return mProjection;}
|
|
||||||
private:
|
private:
|
||||||
static Camera3D mCamera;
|
|
||||||
static QMatrix4x4 mProjection;
|
|
||||||
|
|
||||||
Skybox mSkybox;
|
Qtk::MeshRenderer * mTestPhong;
|
||||||
MeshRenderer * mTestPhong;
|
Qtk::MeshRenderer * mTestSpecular;
|
||||||
MeshRenderer * mTestSpecular;
|
Qtk::MeshRenderer * mTestDiffuse;
|
||||||
MeshRenderer * mTestDiffuse;
|
Qtk::MeshRenderer * mTestAmbient;
|
||||||
MeshRenderer * mTestAmbient;
|
|
||||||
std::vector<MeshRenderer *> mMeshes;
|
|
||||||
std::vector<Model *> mModels;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QTK_SCENE_H
|
#endif // QTK_EXAMPLE_SCENE_H
|
|
@ -9,7 +9,7 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
||||||
#include <mainwidget.h>
|
#include <qtkwidget.h>
|
||||||
#include <mainwindow.h>
|
#include <mainwindow.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#include <mainwindow.h>
|
||||||
|
#include <qtkwidget.h>
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
QMainWindow(parent),
|
||||||
|
ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
// For use in design mode using Qt Creator
|
||||||
|
// + 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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
|
@ -1,15 +1,19 @@
|
||||||
#ifndef MAINWINDOW_H
|
#ifndef MAINWINDOW_H
|
||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
||||||
#include "main-widget_export.h"
|
#include "qtk-widget_export.h"
|
||||||
|
#include <examplescene.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MAIN_WIDGET_EXPORT MainWindow : public QMainWindow
|
class QTK_WIDGET_EXPORT MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -19,6 +23,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
std::unordered_map<std::string, Qtk::Scene*> mScenes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
|
@ -14,17 +14,27 @@
|
||||||
<string>Qtk - MainWindow</string>
|
<string>Qtk - MainWindow</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<widget class="MainWidget" name="openGLWidget">
|
<widget class="QWidget" name="qWidget" native="true">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>801</width>
|
||||||
|
<height>561</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<widget class="Qtk::QtkWidget" name="openGLWidget">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>10</y>
|
<y>10</y>
|
||||||
<width>775</width>
|
<width>781</width>
|
||||||
<height>550</height>
|
<height>541</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
</widget>
|
||||||
<widget class="QMenuBar" name="menubar">
|
<widget class="QMenuBar" name="menubar">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
|
@ -94,9 +104,9 @@
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>MainWidget</class>
|
<class>Qtk::QtkWidget</class>
|
||||||
<extends>QOpenGLWidget</extends>
|
<extends>QOpenGLWidget</extends>
|
||||||
<header>mainwidget.h</header>
|
<header>qtkwidget.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <src/qtkresources.h>
|
||||||
|
|
||||||
#ifndef QTK_RESOURCEMANAGER_H
|
#ifndef QTK_RESOURCEMANAGER_H
|
||||||
#define QTK_RESOURCEMANAGER_H
|
#define QTK_RESOURCEMANAGER_H
|
||||||
|
|
||||||
|
@ -26,10 +28,8 @@ public:
|
||||||
*/
|
*/
|
||||||
static std::string getPath(const std::string & path) {
|
static std::string getPath(const std::string & path) {
|
||||||
// Only construct qtk resource path if in qrc format; else return it as-is
|
// Only construct qtk resource path if in qrc format; else return it as-is
|
||||||
return path[0] == ':' ? resourcesDir + path.substr(2) : path;
|
return path[0] == ':' ? QTK_RESOURCES + path.substr(1) : path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string resourcesDir;
|
|
||||||
} RM;
|
} RM;
|
||||||
|
|
||||||
#endif //QTK_RESOURCEMANAGER_H
|
#endif //QTK_RESOURCEMANAGER_H
|
|
@ -0,0 +1,32 @@
|
||||||
|
################################################################################
|
||||||
|
## Author: Shaun Reed | Contact: shaunrd0@gmail.com | URL: www.shaunreed.com ##
|
||||||
|
## ##
|
||||||
|
## CMake function to update git submodules ##
|
||||||
|
################################################################################
|
||||||
|
include_guard()
|
||||||
|
|
||||||
|
find_package(Git)
|
||||||
|
|
||||||
|
# _PATH: Path to git submodule location that we want to update
|
||||||
|
# + submodule_update(extern/assimp)
|
||||||
|
function(submodule_update _PATH)
|
||||||
|
if (NOT QTK_UPDATE_SUBMODULES)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT GIT_FOUND)
|
||||||
|
message(FATAL_ERROR "[Qtk] Error: No git executable found")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} submodule update --init --force "${_PATH}"
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
)
|
||||||
|
|
||||||
|
if (NOT result EQUAL 0)
|
||||||
|
message(
|
||||||
|
FATAL_ERROR
|
||||||
|
"[Qtk] Error: Unable to update git submodule at ${_PATH}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit bd64cc88dff17f118ecf32ebcbacaf566f6b6449
|
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 |
|
@ -0,0 +1,48 @@
|
||||||
|
/*##############################################################################
|
||||||
|
## Author: Shaun Reed ##
|
||||||
|
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
||||||
|
## About: Classes for managing objects and data within a scene ##
|
||||||
|
## ##
|
||||||
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
|
##############################################################################*/
|
||||||
|
|
||||||
|
#include <abstractscene.h>
|
||||||
|
#include <camera3d.h>
|
||||||
|
#include <resourcemanager.h>
|
||||||
|
#include <texture.h>
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
|
Camera3D Scene::mCamera;
|
||||||
|
QMatrix4x4 Scene::mProjection;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Constructors, Destructors
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
Scene::Scene()
|
||||||
|
{
|
||||||
|
mCamera.transform().setTranslation(0.0f, 0.0f, 20.0f);
|
||||||
|
mCamera.transform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene::~Scene()
|
||||||
|
{
|
||||||
|
for (auto & mesh : mMeshes) delete mesh;
|
||||||
|
for (auto & model : mModels) delete model;
|
||||||
|
if (mSkybox != Q_NULLPTR) delete mSkybox;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::privDraw()
|
||||||
|
{
|
||||||
|
if (!mInit) {
|
||||||
|
initializeOpenGLFunctions();
|
||||||
|
init();
|
||||||
|
mInit = true;
|
||||||
|
}
|
||||||
|
if (mSkybox != Q_NULLPTR) mSkybox->draw();
|
||||||
|
for (auto & model : mModels) model->draw();
|
||||||
|
for (const auto & mesh : mMeshes) mesh->draw();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*##############################################################################
|
||||||
|
## Author: Shaun Reed ##
|
||||||
|
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
||||||
|
## About: Classes for managing objects and data within a scene ##
|
||||||
|
## ##
|
||||||
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
|
##############################################################################*/
|
||||||
|
|
||||||
|
#ifndef QTK_SCENE_H
|
||||||
|
#define QTK_SCENE_H
|
||||||
|
|
||||||
|
#include <camera3d.h>
|
||||||
|
#include <meshrenderer.h>
|
||||||
|
#include <model.h>
|
||||||
|
#include <skybox.h>
|
||||||
|
|
||||||
|
#include <QMatrix4x4>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Qtk {
|
||||||
|
class Scene : protected QOpenGLFunctions {
|
||||||
|
friend class MainWidget;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Scene();
|
||||||
|
~Scene();
|
||||||
|
|
||||||
|
virtual void init() = 0;
|
||||||
|
virtual void draw() { privDraw(); };
|
||||||
|
virtual void update() = 0;
|
||||||
|
|
||||||
|
static Camera3D & Camera() { return mCamera;}
|
||||||
|
static QMatrix4x4 View() { return mCamera.toMatrix();}
|
||||||
|
static QMatrix4x4 & Projection() { return mProjection;}
|
||||||
|
|
||||||
|
inline Skybox * getSkybox() {return mSkybox;}
|
||||||
|
inline void setSkybox(Skybox * skybox) {
|
||||||
|
mSkybox = skybox;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Camera3D mCamera;
|
||||||
|
static QMatrix4x4 mProjection;
|
||||||
|
bool mInit = false;
|
||||||
|
|
||||||
|
void privDraw();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Skybox * mSkybox;
|
||||||
|
std::vector<MeshRenderer *> mMeshes;
|
||||||
|
std::vector<Model *> mModels;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QTK_SCENE_H
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <camera3d.h>
|
#include <camera3d.h>
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
const QVector3D Camera3D::LocalForward(0.0f, 0.0f, -1.0f);
|
const QVector3D Camera3D::LocalForward(0.0f, 0.0f, -1.0f);
|
||||||
const QVector3D Camera3D::LocalUp(0.0f, 1.0f, 0.0f);
|
const QVector3D Camera3D::LocalUp(0.0f, 1.0f, 0.0f);
|
||||||
|
|
|
@ -12,10 +12,11 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include <transform3D.h>
|
#include <transform3D.h>
|
||||||
|
#include <qtkapi.h>
|
||||||
|
|
||||||
|
namespace Qtk {
|
||||||
class Camera3D {
|
class QTKAPI Camera3D {
|
||||||
public:
|
public:
|
||||||
// Constants
|
// Constants
|
||||||
static const QVector3D LocalForward;
|
static const QVector3D LocalForward;
|
||||||
static const QVector3D LocalUp;
|
static const QVector3D LocalUp;
|
||||||
|
@ -37,7 +38,7 @@ public:
|
||||||
inline QVector3D up() const
|
inline QVector3D up() const
|
||||||
{ return mTransform.rotation().rotatedVector(LocalUp);}
|
{ return mTransform.rotation().rotatedVector(LocalUp);}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Transform3D mTransform;
|
Transform3D mTransform;
|
||||||
QMatrix4x4 mWorld;
|
QMatrix4x4 mWorld;
|
||||||
|
|
||||||
|
@ -45,18 +46,19 @@ private:
|
||||||
friend QDataStream & operator<<(QDataStream & out, Camera3D & transform);
|
friend QDataStream & operator<<(QDataStream & out, Camera3D & transform);
|
||||||
friend QDataStream & operator>>(QDataStream & in, Camera3D & transform);
|
friend QDataStream & operator>>(QDataStream & in, Camera3D & transform);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_TYPEINFO(Camera3D, Q_MOVABLE_TYPE);
|
|
||||||
|
|
||||||
// Qt Streams
|
// Qt Streams
|
||||||
#ifndef QT_NO_DATASTREAM
|
#ifndef QT_NO_DATASTREAM
|
||||||
QDataStream & operator<<(QDataStream & out, const Camera3D & transform);
|
QDataStream & operator<<(QDataStream & out, const Camera3D & transform);
|
||||||
QDataStream & operator>>(QDataStream & in, Camera3D & transform);
|
QDataStream & operator>>(QDataStream & in, Camera3D & transform);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
QDebug operator<<(QDebug dbg, const Camera3D & transform);
|
QDebug operator<<(QDebug dbg, const Camera3D & transform);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_TYPEINFO(Qtk::Camera3D, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
#endif // QTK_CAMERA3D_H
|
#endif // QTK_CAMERA3D_H
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <input.h>
|
#include <input.h>
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Static Helper Structs
|
* Static Helper Structs
|
||||||
|
|
16
src/input.h
16
src/input.h
|
@ -12,11 +12,13 @@
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
#include <Qt>
|
#include <Qt>
|
||||||
|
|
||||||
|
#include <qtkapi.h>
|
||||||
|
#include <qtkwidget.h>
|
||||||
|
|
||||||
class Input {
|
namespace Qtk {
|
||||||
friend class MainWidget;
|
class QTKAPI Input {
|
||||||
public:
|
friend class Qtk::QtkWidget;
|
||||||
|
public:
|
||||||
// Possible key states
|
// Possible key states
|
||||||
enum InputState
|
enum InputState
|
||||||
{
|
{
|
||||||
|
@ -49,8 +51,7 @@ public:
|
||||||
static QPoint mousePosition();
|
static QPoint mousePosition();
|
||||||
static QPoint mouseDelta();
|
static QPoint mouseDelta();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// State updating
|
// State updating
|
||||||
static void update();
|
static void update();
|
||||||
static void registerKeyPress(int key);
|
static void registerKeyPress(int key);
|
||||||
|
@ -58,6 +59,7 @@ private:
|
||||||
static void registerMousePress(Qt::MouseButton button);
|
static void registerMousePress(Qt::MouseButton button);
|
||||||
static void registerMouseRelease(Qt::MouseButton button);
|
static void registerMouseRelease(Qt::MouseButton button);
|
||||||
static void reset();
|
static void reset();
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif // QTOPENGL_INPUT_H
|
#endif // QTOPENGL_INPUT_H
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*##############################################################################
|
|
||||||
## Author: Shaun Reed ##
|
|
||||||
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
|
||||||
## About: Main window for Qt6 OpenGL widget application ##
|
|
||||||
## ##
|
|
||||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
|
||||||
##############################################################################*/
|
|
||||||
#ifndef QTK_MAINWIDGET_H
|
|
||||||
#define QTK_MAINWIDGET_H
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <QMatrix4x4>
|
|
||||||
#include <QOpenGLDebugLogger>
|
|
||||||
#include <QOpenGLFunctions>
|
|
||||||
#include <QOpenGLWidget>
|
|
||||||
|
|
||||||
#define QTK_DEBUG
|
|
||||||
|
|
||||||
class MeshRenderer;
|
|
||||||
class Model;
|
|
||||||
class Object;
|
|
||||||
class Scene;
|
|
||||||
class Skybox;
|
|
||||||
class Texture;
|
|
||||||
|
|
||||||
class MainWidget : public QOpenGLWidget,
|
|
||||||
protected QOpenGLFunctions {
|
|
||||||
Q_OBJECT;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
MainWidget();
|
|
||||||
explicit MainWidget(QWidget *parent);
|
|
||||||
explicit MainWidget(const QSurfaceFormat &format);
|
|
||||||
~MainWidget() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void teardownGL();
|
|
||||||
void initObjects();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Inherited virtual Members
|
|
||||||
void paintGL() override;
|
|
||||||
void initializeGL() override;
|
|
||||||
void resizeGL(int width, int height) override;
|
|
||||||
|
|
||||||
protected slots:
|
|
||||||
void update();
|
|
||||||
void messageLogged(const QOpenGLDebugMessage &msg);
|
|
||||||
|
|
||||||
// Protected Helpers
|
|
||||||
protected:
|
|
||||||
void keyPressEvent(QKeyEvent *event);
|
|
||||||
void keyReleaseEvent(QKeyEvent *event);
|
|
||||||
void mousePressEvent(QMouseEvent *event);
|
|
||||||
void mouseReleaseEvent(QMouseEvent *event);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Private helpers
|
|
||||||
void initializeWidget();
|
|
||||||
void printContextInformation();
|
|
||||||
void updateCameraInput();
|
|
||||||
|
|
||||||
Scene * mScene;
|
|
||||||
Object * mObject;
|
|
||||||
|
|
||||||
QOpenGLDebugLogger * mDebugLogger;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // QTK_MAINWIDGET_H
|
|
|
@ -1,15 +0,0 @@
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "ui_mainwindow.h"
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) :
|
|
||||||
QMainWindow(parent),
|
|
||||||
ui(new Ui::MainWindow)
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
|
||||||
setWindowIcon(QIcon("../resources/icon.png"));
|
|
||||||
}
|
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <mesh.h>
|
#include <mesh.h>
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
Cube::Cube(DrawMode mode)
|
Cube::Cube(DrawMode mode)
|
||||||
{
|
{
|
||||||
|
|
56
src/mesh.h
56
src/mesh.h
|
@ -12,25 +12,27 @@
|
||||||
#include <QVector2D>
|
#include <QVector2D>
|
||||||
#include <QVector3D>
|
#include <QVector3D>
|
||||||
|
|
||||||
|
#include <qtkapi.h>
|
||||||
#include <transform3D.h>
|
#include <transform3D.h>
|
||||||
|
|
||||||
class MeshRenderer;
|
namespace Qtk {
|
||||||
class Object;
|
class MeshRenderer;
|
||||||
|
class Object;
|
||||||
|
|
||||||
// Define vertices for drawing a cube using two faces (8 vertex points)
|
// Define vertices for drawing a cube using two faces (8 vertex points)
|
||||||
// Front Vertices
|
// Front Vertices
|
||||||
#define VERTEX_FTR QVector3D( 0.5f, 0.5f, 0.5f) // 1
|
#define VERTEX_FTR QVector3D( 0.5f, 0.5f, 0.5f) // 1
|
||||||
#define VERTEX_FTL QVector3D(-0.5f, 0.5f, 0.5f) // 2
|
#define VERTEX_FTL QVector3D(-0.5f, 0.5f, 0.5f) // 2
|
||||||
#define VERTEX_FBL QVector3D(-0.5f, -0.5f, 0.5f) // 3
|
#define VERTEX_FBL QVector3D(-0.5f, -0.5f, 0.5f) // 3
|
||||||
#define VERTEX_FBR QVector3D( 0.5f, -0.5f, 0.5f) // 4
|
#define VERTEX_FBR QVector3D( 0.5f, -0.5f, 0.5f) // 4
|
||||||
|
|
||||||
// Back Vertices
|
// Back Vertices
|
||||||
#define VERTEX_BTR QVector3D( 0.5f, 0.5f, -0.5f) // 5
|
#define VERTEX_BTR QVector3D( 0.5f, 0.5f, -0.5f) // 5
|
||||||
#define VERTEX_BTL QVector3D(-0.5f, 0.5f, -0.5f) // 6
|
#define VERTEX_BTL QVector3D(-0.5f, 0.5f, -0.5f) // 6
|
||||||
#define VERTEX_BBL QVector3D(-0.5f, -0.5f, -0.5f) // 7
|
#define VERTEX_BBL QVector3D(-0.5f, -0.5f, -0.5f) // 7
|
||||||
#define VERTEX_BBR QVector3D( 0.5f, -0.5f, -0.5f) // 8
|
#define VERTEX_BBR QVector3D( 0.5f, -0.5f, -0.5f) // 8
|
||||||
|
|
||||||
// Direction vectors
|
// Direction vectors
|
||||||
#define VECTOR_UP QVector3D(0.0f, 1.0f, 0.0f)
|
#define VECTOR_UP QVector3D(0.0f, 1.0f, 0.0f)
|
||||||
#define VECTOR_DOWN QVector3D(0.0f, -1.0f, 0.0f)
|
#define VECTOR_DOWN QVector3D(0.0f, -1.0f, 0.0f)
|
||||||
#define VECTOR_LEFT QVector3D(-1.0f, 0.0f, 0.0f)
|
#define VECTOR_LEFT QVector3D(-1.0f, 0.0f, 0.0f)
|
||||||
|
@ -38,11 +40,11 @@ class Object;
|
||||||
#define VECTOR_FORWARD QVector3D(0.0f, 0.0f, 1.0f)
|
#define VECTOR_FORWARD QVector3D(0.0f, 0.0f, 1.0f)
|
||||||
#define VECTOR_BACK QVector3D(0.0f, 0.0f, -1.0f)
|
#define VECTOR_BACK QVector3D(0.0f, 0.0f, -1.0f)
|
||||||
|
|
||||||
// Identity and zero vectors
|
// Identity and zero vectors
|
||||||
#define VECTOR_ONE QVector3D(1.0f, 1.0f, 1.0f)
|
#define VECTOR_ONE QVector3D(1.0f, 1.0f, 1.0f)
|
||||||
#define VECTOR_ZERO QVector3D(0.0f, 0.0f, 0.0f)
|
#define VECTOR_ZERO QVector3D(0.0f, 0.0f, 0.0f)
|
||||||
|
|
||||||
// A series of direction vectors to represent cube face normal
|
// A series of direction vectors to represent cube face normal
|
||||||
#define FACE_TOP VECTOR_UP, VECTOR_UP, VECTOR_UP, \
|
#define FACE_TOP VECTOR_UP, VECTOR_UP, VECTOR_UP, \
|
||||||
VECTOR_UP, VECTOR_UP, VECTOR_UP
|
VECTOR_UP, VECTOR_UP, VECTOR_UP
|
||||||
#define FACE_BOTTOM VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN, \
|
#define FACE_BOTTOM VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN, \
|
||||||
|
@ -56,7 +58,7 @@ class Object;
|
||||||
#define FACE_BACK VECTOR_BACK, VECTOR_BACK, VECTOR_BACK, \
|
#define FACE_BACK VECTOR_BACK, VECTOR_BACK, VECTOR_BACK, \
|
||||||
VECTOR_BACK, VECTOR_BACK, VECTOR_BACK
|
VECTOR_BACK, VECTOR_BACK, VECTOR_BACK
|
||||||
|
|
||||||
// Colors using QVector3Ds as RGB values
|
// Colors using QVector3Ds as RGB values
|
||||||
#define WHITE VECTOR_ONE
|
#define WHITE VECTOR_ONE
|
||||||
#define BLACK VECTOR_ZERO
|
#define BLACK VECTOR_ZERO
|
||||||
#define RED QVector3D(1.0f, 0.0f, 0.0f)
|
#define RED QVector3D(1.0f, 0.0f, 0.0f)
|
||||||
|
@ -71,16 +73,15 @@ class Object;
|
||||||
#define UV_RIGHT QVector2D(0.0f, 1.0f)
|
#define UV_RIGHT QVector2D(0.0f, 1.0f)
|
||||||
#define UV_CORNER QVector2D(1.0f, 1.0f)
|
#define UV_CORNER QVector2D(1.0f, 1.0f)
|
||||||
|
|
||||||
|
typedef std::vector<QVector3D> Vertices;
|
||||||
|
typedef std::vector<QVector3D> Colors;
|
||||||
|
typedef std::vector<GLuint> Indices;
|
||||||
|
typedef std::vector<QVector2D> TexCoords;
|
||||||
|
typedef std::vector<QVector3D> Normals;
|
||||||
|
|
||||||
typedef std::vector<QVector3D> Vertices;
|
enum DrawMode { QTK_DRAW_ARRAYS, QTK_DRAW_ELEMENTS, QTK_DRAW_ELEMENTS_NORMALS };
|
||||||
typedef std::vector<QVector3D> Colors;
|
|
||||||
typedef std::vector<GLuint> Indices;
|
|
||||||
typedef std::vector<QVector2D> TexCoords;
|
|
||||||
typedef std::vector<QVector3D> Normals;
|
|
||||||
|
|
||||||
enum DrawMode { QTK_DRAW_ARRAYS, QTK_DRAW_ELEMENTS, QTK_DRAW_ELEMENTS_NORMALS };
|
struct QTKAPI ShapeBase {
|
||||||
|
|
||||||
struct ShapeBase {
|
|
||||||
ShapeBase(DrawMode mode=QTK_DRAW_ARRAYS, Vertices v={},Indices i={}, Colors c={},
|
ShapeBase(DrawMode mode=QTK_DRAW_ARRAYS, Vertices v={},Indices i={}, Colors c={},
|
||||||
TexCoords t={}, Normals n={})
|
TexCoords t={}, Normals n={})
|
||||||
: mVertices(v), mColors(c), mIndices(i), mTexCoords(t), mNormals(n)
|
: mVertices(v), mColors(c), mIndices(i), mTexCoords(t), mNormals(n)
|
||||||
|
@ -92,7 +93,7 @@ struct ShapeBase {
|
||||||
inline const TexCoords & texCoords() const { return mTexCoords;}
|
inline const TexCoords & texCoords() const { return mTexCoords;}
|
||||||
inline const Normals & normals() const { return mNormals;}
|
inline const Normals & normals() const { return mNormals;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DrawMode mDrawMode;
|
DrawMode mDrawMode;
|
||||||
|
|
||||||
Vertices mVertices;
|
Vertices mVertices;
|
||||||
|
@ -100,9 +101,9 @@ protected:
|
||||||
Indices mIndices;
|
Indices mIndices;
|
||||||
TexCoords mTexCoords;
|
TexCoords mTexCoords;
|
||||||
Normals mNormals;
|
Normals mNormals;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Shape : public ShapeBase {
|
struct Shape : public ShapeBase {
|
||||||
friend MeshRenderer;
|
friend MeshRenderer;
|
||||||
friend Object;
|
friend Object;
|
||||||
Shape () {}
|
Shape () {}
|
||||||
|
@ -114,19 +115,20 @@ struct Shape : public ShapeBase {
|
||||||
virtual inline void setTexCoords(const TexCoords & value) {mTexCoords = value;}
|
virtual inline void setTexCoords(const TexCoords & value) {mTexCoords = value;}
|
||||||
virtual inline void setNormals(const Normals & value) {mNormals = value;}
|
virtual inline void setNormals(const Normals & value) {mNormals = value;}
|
||||||
virtual inline void setShape(const Shape & value) { *this = value;}
|
virtual inline void setShape(const Shape & value) { *this = value;}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Primitives inherit from ShapeBase, does not allow setting of shape values
|
// Primitives inherit from ShapeBase, does not allow setting of shape values
|
||||||
class Mesh {
|
class QTKAPI Mesh {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Cube : public ShapeBase {
|
struct QTKAPI Cube : public ShapeBase {
|
||||||
Cube(DrawMode mode=QTK_DRAW_ARRAYS);
|
Cube(DrawMode mode=QTK_DRAW_ARRAYS);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Triangle : public ShapeBase {
|
struct QTKAPI Triangle : public ShapeBase {
|
||||||
Triangle(DrawMode mode=QTK_DRAW_ARRAYS);
|
Triangle(DrawMode mode=QTK_DRAW_ARRAYS);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif // QTK_MESH_H
|
#endif // QTK_MESH_H
|
||||||
|
|
|
@ -8,14 +8,14 @@
|
||||||
|
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
|
|
||||||
#include <scene.h>
|
#include <abstractscene.h>
|
||||||
|
#include <meshrenderer.h>
|
||||||
#include <texture.h>
|
#include <texture.h>
|
||||||
|
|
||||||
#include <meshrenderer.h>
|
using namespace Qtk;
|
||||||
|
|
||||||
|
|
||||||
// Static QHash that holds all MeshRenderer instances using their mName as keys
|
// Static QHash that holds all MeshRenderer instances using their mName as keys
|
||||||
MeshRenderer::MeshManager MeshRenderer::sInstances;
|
Qtk::MeshRenderer::MeshManager Qtk::MeshRenderer::sInstances;
|
||||||
|
|
||||||
MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape)
|
MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape)
|
||||||
: Object(name, shape), mVertexShader(":/multi-color.vert"),
|
: Object(name, shape), mVertexShader(":/multi-color.vert"),
|
||||||
|
|
|
@ -10,10 +10,12 @@
|
||||||
|
|
||||||
#include <mesh.h>
|
#include <mesh.h>
|
||||||
#include <object.h>
|
#include <object.h>
|
||||||
|
#include <qtkapi.h>
|
||||||
|
|
||||||
|
|
||||||
class MeshRenderer : public Object {
|
namespace Qtk {
|
||||||
public:
|
class QTKAPI MeshRenderer : public Object {
|
||||||
|
public:
|
||||||
// Delegate constructors
|
// Delegate constructors
|
||||||
MeshRenderer(const char * name, Vertices vertices, Indices indices,
|
MeshRenderer(const char * name, Vertices vertices, Indices indices,
|
||||||
DrawMode mode=QTK_DRAW_ARRAYS)
|
DrawMode mode=QTK_DRAW_ARRAYS)
|
||||||
|
@ -66,12 +68,13 @@ public:
|
||||||
|
|
||||||
// Static QHash of all mesh objects within the scene
|
// Static QHash of all mesh objects within the scene
|
||||||
typedef QHash<QString, MeshRenderer *> MeshManager;
|
typedef QHash<QString, MeshRenderer *> MeshManager;
|
||||||
private:
|
private:
|
||||||
static MeshManager sInstances;
|
static MeshManager sInstances;
|
||||||
|
|
||||||
int mDrawType;
|
int mDrawType;
|
||||||
bool mHasTexture;
|
bool mHasTexture;
|
||||||
std::string mVertexShader, mFragmentShader;
|
std::string mVertexShader, mFragmentShader;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif // QTK_MESHRENDERER_H
|
#endif // QTK_MESHRENDERER_H
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
#include <scene.h>
|
#include <abstractscene.h>
|
||||||
#include <texture.h>
|
|
||||||
#include <resourcemanager.h>
|
|
||||||
|
|
||||||
#include <model.h>
|
#include <model.h>
|
||||||
|
#include <resourcemanager.h>
|
||||||
|
#include <texture.h>
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
Model::ModelManager Model::mManager;
|
Model::ModelManager Model::mManager;
|
||||||
|
|
||||||
|
|
35
src/model.h
35
src/model.h
|
@ -16,7 +16,6 @@
|
||||||
#include <QOpenGLShaderProgram>
|
#include <QOpenGLShaderProgram>
|
||||||
#include <QOpenGLTexture>
|
#include <QOpenGLTexture>
|
||||||
#include <QOpenGLVertexArrayObject>
|
#include <QOpenGLVertexArrayObject>
|
||||||
#include <QOpenGLFunctions>
|
|
||||||
|
|
||||||
// Assimp
|
// Assimp
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
|
@ -24,28 +23,29 @@
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
// QTK
|
// QTK
|
||||||
|
#include <qtkapi.h>
|
||||||
#include <transform3D.h>
|
#include <transform3D.h>
|
||||||
|
|
||||||
|
namespace Qtk {
|
||||||
struct ModelVertex {
|
struct QTKAPI ModelVertex {
|
||||||
QVector3D mPosition;
|
QVector3D mPosition;
|
||||||
QVector3D mNormal;
|
QVector3D mNormal;
|
||||||
QVector3D mTangent;
|
QVector3D mTangent;
|
||||||
QVector3D mBitangent;
|
QVector3D mBitangent;
|
||||||
QVector2D mTextureCoord;
|
QVector2D mTextureCoord;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModelTexture {
|
struct QTKAPI ModelTexture {
|
||||||
GLuint mID;
|
GLuint mID;
|
||||||
QOpenGLTexture * mTexture;
|
QOpenGLTexture * mTexture;
|
||||||
std::string mType;
|
std::string mType;
|
||||||
std::string mPath;
|
std::string mPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Model;
|
class Model;
|
||||||
|
|
||||||
class ModelMesh : protected QOpenGLFunctions {
|
class QTKAPI ModelMesh : protected QOpenGLFunctions {
|
||||||
public:
|
public:
|
||||||
friend Model;
|
friend Model;
|
||||||
typedef std::vector<ModelVertex> Vertices;
|
typedef std::vector<ModelVertex> Vertices;
|
||||||
typedef std::vector<GLuint> Indices;
|
typedef std::vector<GLuint> Indices;
|
||||||
|
@ -65,7 +65,7 @@ public:
|
||||||
{ initMesh(vertexShader, fragmentShader);}
|
{ initMesh(vertexShader, fragmentShader);}
|
||||||
~ModelMesh() {}
|
~ModelMesh() {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initMesh(const char * vert, const char * frag);
|
void initMesh(const char * vert, const char * frag);
|
||||||
|
|
||||||
// ModelMesh Private Members
|
// ModelMesh Private Members
|
||||||
|
@ -73,7 +73,7 @@ private:
|
||||||
QOpenGLVertexArrayObject * mVAO;
|
QOpenGLVertexArrayObject * mVAO;
|
||||||
QOpenGLShaderProgram * mProgram;
|
QOpenGLShaderProgram * mProgram;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline void draw() { draw(*mProgram);}
|
inline void draw() { draw(*mProgram);}
|
||||||
void draw(QOpenGLShaderProgram & shader);
|
void draw(QOpenGLShaderProgram & shader);
|
||||||
|
|
||||||
|
@ -82,13 +82,13 @@ public:
|
||||||
Indices mIndices;
|
Indices mIndices;
|
||||||
Textures mTextures;
|
Textures mTextures;
|
||||||
Transform3D mTransform;
|
Transform3D mTransform;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Model : public QObject {
|
class QTKAPI Model : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline Model(const char * name, const char * path,
|
inline Model(const char * name, const char * path,
|
||||||
const char * vertexShader=":/model-basic.vert",
|
const char * vertexShader=":/model-basic.vert",
|
||||||
const char * fragmentShader=":/model-basic.frag")
|
const char * fragmentShader=":/model-basic.frag")
|
||||||
|
@ -120,7 +120,7 @@ public:
|
||||||
static Model * getInstance(const char * name);
|
static Model * getInstance(const char * name);
|
||||||
|
|
||||||
typedef QHash<QString, Model *> ModelManager;
|
typedef QHash<QString, Model *> ModelManager;
|
||||||
private:
|
private:
|
||||||
static ModelManager mManager;
|
static ModelManager mManager;
|
||||||
void loadModel(const std::string & path);
|
void loadModel(const std::string & path);
|
||||||
void processNode(aiNode * node, const aiScene * scene);
|
void processNode(aiNode * node, const aiScene * scene);
|
||||||
|
@ -135,6 +135,7 @@ private:
|
||||||
std::vector<ModelMesh> mMeshes;
|
std::vector<ModelMesh> mMeshes;
|
||||||
std::string mDirectory;
|
std::string mDirectory;
|
||||||
const char * mVertexShader, * mFragmentShader, * mName;
|
const char * mVertexShader, * mFragmentShader, * mName;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif // QTK_MODEL_H
|
#endif // QTK_MODEL_H
|
||||||
|
|
|
@ -7,3 +7,5 @@
|
||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
#include <object.h>
|
#include <object.h>
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
14
src/object.h
14
src/object.h
|
@ -14,12 +14,13 @@
|
||||||
#include <QOpenGLVertexArrayObject>
|
#include <QOpenGLVertexArrayObject>
|
||||||
|
|
||||||
#include <mesh.h>
|
#include <mesh.h>
|
||||||
|
#include <qtkapi.h>
|
||||||
|
|
||||||
|
namespace Qtk {
|
||||||
|
class QTKAPI Object : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
class Object : public QObject {
|
public:
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
friend MeshRenderer;
|
friend MeshRenderer;
|
||||||
// Initialize an object with no shape data assigned
|
// Initialize an object with no shape data assigned
|
||||||
Object(const char * name)
|
Object(const char * name)
|
||||||
|
@ -54,8 +55,9 @@ public:
|
||||||
Shape mShape;
|
Shape mShape;
|
||||||
|
|
||||||
const char * mName;
|
const char * mName;
|
||||||
private:
|
private:
|
||||||
QOpenGLTexture * mTexture;
|
QOpenGLTexture * mTexture;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif // QTK_OBJECT_H
|
#endif // QTK_OBJECT_H
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
/*##############################################################################
|
/*##############################################################################
|
||||||
## Author: Shaun Reed ##
|
## Author: Shaun Reed ##
|
||||||
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
||||||
## About: Manage files and resources used by qtk ##
|
## About: Main window for Qt6 OpenGL widget application ##
|
||||||
## ##
|
## ##
|
||||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
#ifndef QTK_QTKAPI_H
|
||||||
|
#define QTK_QTKAPI_H
|
||||||
|
|
||||||
#include "resourcemanager.h"
|
#include <QtCore/QtGlobal>
|
||||||
#include <algorithm>
|
|
||||||
#include <string>
|
|
||||||
#include <QtGlobal>
|
|
||||||
|
|
||||||
static std::string nixPath(std::string path)
|
#ifdef QTK_SHARED
|
||||||
{
|
# if defined(QTK_EXPORT)
|
||||||
#ifdef Q_OS_WINDOWS
|
# define QTKAPI Q_DECL_EXPORT
|
||||||
std::replace(path.begin(), path.end(), '\\', '/');
|
# else
|
||||||
|
# define QTKAPI Q_DECL_IMPORT
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define QTKAPI
|
||||||
#endif
|
#endif
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string RM::resourcesDir =
|
#endif //QTK_QTKAPI_H
|
||||||
std::string(__FILE__).substr(0, nixPath(__FILE__).find("src/"))
|
|
||||||
+ "resources/";
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
#define QTK_RESOURCES "@QTK_RESOURCES@"
|
|
@ -9,36 +9,36 @@
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
|
||||||
#include <input.h>
|
#include <input.h>
|
||||||
|
#include <qtkwidget.h>
|
||||||
#include <mesh.h>
|
#include <mesh.h>
|
||||||
#include <object.h>
|
#include <abstractscene.h>
|
||||||
#include <scene.h>
|
|
||||||
|
|
||||||
#include <mainwidget.h>
|
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Constructors, Destructors
|
* Constructors, Destructors
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
MainWidget::MainWidget() : 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), mDebugLogger(Q_NULLPTR)
|
QtkWidget::QtkWidget(QWidget *parent) : QOpenGLWidget(parent),
|
||||||
|
mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
|
||||||
{
|
{
|
||||||
initializeWidget();
|
initializeWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWidget::MainWidget(const QSurfaceFormat &format)
|
QtkWidget::QtkWidget(const QSurfaceFormat &format)
|
||||||
: 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,80 +49,26 @@ MainWidget::~MainWidget()
|
||||||
* Private Member Functions
|
* Private Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void MainWidget::teardownGL()
|
void QtkWidget::teardownGL()
|
||||||
{
|
{
|
||||||
// Nothing to teardown yet...
|
// Nothing to teardown yet...
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::initObjects()
|
|
||||||
{
|
|
||||||
mScene = new Scene;
|
|
||||||
|
|
||||||
// Drawing a primitive object using Qt and OpenGL
|
|
||||||
// The Object class only stores basic QOpenGL* members and shape data
|
|
||||||
// + Within mainwidget, mObject serves as a basic QOpenGL example
|
|
||||||
mObject = new Object("testObject");
|
|
||||||
mObject->setVertices(Cube(QTK_DRAW_ELEMENTS).vertices());
|
|
||||||
mObject->setIndices(Cube(QTK_DRAW_ELEMENTS).indices());
|
|
||||||
mObject->mProgram.create();
|
|
||||||
mObject->mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,
|
|
||||||
":/solid-ambient.vert");
|
|
||||||
mObject->mProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,
|
|
||||||
":/solid-ambient.frag");
|
|
||||||
mObject->mProgram.link();
|
|
||||||
mObject->mProgram.bind();
|
|
||||||
|
|
||||||
mObject->mVAO.create();
|
|
||||||
mObject->mVAO.bind();
|
|
||||||
|
|
||||||
mObject->mVBO.create();
|
|
||||||
mObject->mVBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
|
|
||||||
mObject->mVBO.bind();
|
|
||||||
|
|
||||||
mObject->mVBO.allocate(mObject->vertices().data(),
|
|
||||||
mObject->vertices().size()
|
|
||||||
* sizeof(mObject->vertices()[0]));
|
|
||||||
|
|
||||||
mObject->mProgram.enableAttributeArray(0);
|
|
||||||
mObject->mProgram.setAttributeBuffer(0, GL_FLOAT, 0,
|
|
||||||
3, sizeof(mObject->vertices()[0]));
|
|
||||||
mObject->mProgram.setUniformValue("uColor", QVector3D(1.0f, 0.0f, 0.0f));
|
|
||||||
mObject->mProgram.setUniformValue("uLightColor", WHITE);
|
|
||||||
mObject->mProgram.setUniformValue("uAmbientStrength", 0.75f);
|
|
||||||
|
|
||||||
mObject->mVBO.release();
|
|
||||||
mObject->mVAO.release();
|
|
||||||
mObject->mProgram.release();
|
|
||||||
|
|
||||||
mObject->mTransform.setTranslation(13.0f, 0.0f, -2.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* 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);
|
||||||
|
|
||||||
// Draw the scene first, since it handles drawing our skybox
|
// Draw the scene first, since it handles drawing our skybox
|
||||||
mScene->draw();
|
if (mScene != Q_NULLPTR) mScene->draw();
|
||||||
|
|
||||||
// Draw any additional objects within mainwidget manually
|
|
||||||
mObject->mProgram.bind();
|
|
||||||
mObject->mVAO.bind();
|
|
||||||
mObject->mProgram.setUniformValue("uModel", mObject->mTransform.toMatrix());
|
|
||||||
mObject->mProgram.setUniformValue("uView", Scene::Camera().toMatrix());
|
|
||||||
mObject->mProgram.setUniformValue("uProjection", Scene::Projection());
|
|
||||||
glDrawElements(GL_TRIANGLES, mObject->indices().size(),
|
|
||||||
GL_UNSIGNED_INT, mObject->indices().data());
|
|
||||||
mObject->mVAO.release();
|
|
||||||
mObject->mProgram.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
@ -150,12 +96,9 @@ void MainWidget::initializeGL()
|
||||||
glClearDepth(1.0f);
|
glClearDepth(1.0f);
|
||||||
glClearColor(0.0f, 0.25f, 0.0f, 0.0f);
|
glClearColor(0.0f, 0.25f, 0.0f, 0.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
// Initialize default objects within the scene
|
|
||||||
initObjects();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
@ -168,16 +111,16 @@ void MainWidget::resizeGL(int width, int height)
|
||||||
* Protected Slots
|
* Protected Slots
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void MainWidget::update()
|
void QtkWidget::update()
|
||||||
{
|
{
|
||||||
updateCameraInput();
|
updateCameraInput();
|
||||||
|
|
||||||
mScene->update();
|
if (mScene != Q_NULLPTR) mScene->update();
|
||||||
|
|
||||||
QWidget::update();
|
QWidget::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::messageLogged(const QOpenGLDebugMessage &msg)
|
void QtkWidget::messageLogged(const QOpenGLDebugMessage &msg)
|
||||||
{
|
{
|
||||||
QString error;
|
QString error;
|
||||||
|
|
||||||
|
@ -242,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
|
||||||
|
@ -252,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();
|
||||||
|
@ -261,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());
|
||||||
}
|
}
|
||||||
|
@ -276,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);
|
||||||
|
@ -294,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;
|
||||||
|
@ -330,7 +273,7 @@ void MainWidget::printContextInformation()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::updateCameraInput()
|
void QtkWidget::updateCameraInput()
|
||||||
{
|
{
|
||||||
Input::update();
|
Input::update();
|
||||||
// Camera Transformation
|
// Camera Transformation
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*##############################################################################
|
||||||
|
## Author: Shaun Reed ##
|
||||||
|
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
||||||
|
## About: Main window for Qt6 OpenGL widget application ##
|
||||||
|
## ##
|
||||||
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
|
##############################################################################*/
|
||||||
|
#ifndef QTK_QTKWIDGET_H
|
||||||
|
#define QTK_QTKWIDGET_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <QMatrix4x4>
|
||||||
|
#include <QOpenGLDebugLogger>
|
||||||
|
#include <QOpenGLFunctions>
|
||||||
|
#include <QOpenGLWidget>
|
||||||
|
|
||||||
|
#include <qtkapi.h>
|
||||||
|
#include <abstractscene.h>
|
||||||
|
|
||||||
|
namespace Qtk {
|
||||||
|
class QTKAPI QtkWidget : public QOpenGLWidget,
|
||||||
|
protected QOpenGLFunctions {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
QtkWidget();
|
||||||
|
explicit QtkWidget(QWidget *parent);
|
||||||
|
explicit QtkWidget(const QSurfaceFormat &format);
|
||||||
|
~QtkWidget() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void teardownGL();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Inherited virtual Members
|
||||||
|
void paintGL() override;
|
||||||
|
void initializeGL() override;
|
||||||
|
void resizeGL(int width, int height) override;
|
||||||
|
|
||||||
|
inline Qtk::Scene * getScene() {return mScene;}
|
||||||
|
inline void setScene(Qtk::Scene * scene) {
|
||||||
|
if (mScene != Q_NULLPTR) delete mScene;
|
||||||
|
mScene = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void update();
|
||||||
|
#ifdef QTK_DEBUG
|
||||||
|
void messageLogged(const QOpenGLDebugMessage &msg);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Protected Helpers
|
||||||
|
protected:
|
||||||
|
void keyPressEvent(QKeyEvent *event);
|
||||||
|
void keyReleaseEvent(QKeyEvent *event);
|
||||||
|
void mousePressEvent(QMouseEvent *event);
|
||||||
|
void mouseReleaseEvent(QMouseEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Private helpers
|
||||||
|
void initializeWidget();
|
||||||
|
void updateCameraInput();
|
||||||
|
|
||||||
|
Qtk::Scene * mScene;
|
||||||
|
#ifdef QTK_DEBUG
|
||||||
|
void printContextInformation();
|
||||||
|
QOpenGLDebugLogger * mDebugLogger;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QTK_QTKWIDGET_H
|
|
@ -6,23 +6,25 @@
|
||||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
#include <scene.h>
|
#include <abstractscene.h>
|
||||||
|
#include <skybox.h>
|
||||||
#include <texture.h>
|
#include <texture.h>
|
||||||
|
|
||||||
#include <skybox.h>
|
using namespace Qtk;
|
||||||
|
|
||||||
|
|
||||||
Skybox::Skybox(std::string right, std::string top, std::string front,
|
Skybox::Skybox(std::string right, std::string top, std::string front,
|
||||||
std::string left, std::string bottom, std::string back,
|
std::string left, std::string bottom, std::string back,
|
||||||
const std::string & name)
|
const std::string & name)
|
||||||
: mCubeMap(Texture::initCubeMap(
|
: mVBO(QOpenGLBuffer::VertexBuffer),
|
||||||
QImage(right.c_str()).mirrored(), QImage(top.c_str()),
|
|
||||||
QImage(front.c_str()), QImage(left.c_str()),
|
|
||||||
QImage(bottom.c_str()), QImage(back.c_str()))),
|
|
||||||
mVBO(QOpenGLBuffer::VertexBuffer),
|
|
||||||
mVertices(Cube(QTK_DRAW_ELEMENTS).vertices()),
|
mVertices(Cube(QTK_DRAW_ELEMENTS).vertices()),
|
||||||
mIndices(Cube(QTK_DRAW_ELEMENTS).indices())
|
mIndices(Cube(QTK_DRAW_ELEMENTS).indices())
|
||||||
{ init();}
|
{
|
||||||
|
init();
|
||||||
|
mCubeMap = Texture::initCubeMap(
|
||||||
|
QImage(right.c_str()).mirrored(), QImage(top.c_str()),
|
||||||
|
QImage(front.c_str()), QImage(left.c_str()),
|
||||||
|
QImage(bottom.c_str()), QImage(back.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
Skybox::Skybox(std::string name)
|
Skybox::Skybox(std::string name)
|
||||||
: Skybox(":/right.png", ":/top.png", ":/front.png",
|
: Skybox(":/right.png", ":/top.png", ":/front.png",
|
||||||
|
@ -87,13 +89,11 @@ void Skybox::init()
|
||||||
mVBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
|
mVBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
|
||||||
mVBO.bind();
|
mVBO.bind();
|
||||||
// Allocate vertex positions into VBO
|
// Allocate vertex positions into VBO
|
||||||
mVBO.allocate(mVertices.data(),
|
mVBO.allocate(mVertices.data(), mVertices.size() * sizeof(mVertices[0]));
|
||||||
mVertices.size() * sizeof(mVertices[0]));
|
|
||||||
|
|
||||||
// Enable attribute array for vertex positions
|
// Enable attribute array for vertex positions
|
||||||
mProgram.enableAttributeArray(0);
|
mProgram.enableAttributeArray(0);
|
||||||
mProgram.setAttributeBuffer(0, GL_FLOAT, 0,
|
mProgram.setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(QVector3D));
|
||||||
3, sizeof(QVector3D));
|
|
||||||
// Set shader texture unit to 0
|
// Set shader texture unit to 0
|
||||||
mProgram.setUniformValue("uTexture", 0);
|
mProgram.setUniformValue("uTexture", 0);
|
||||||
|
|
||||||
|
|
13
src/skybox.h
13
src/skybox.h
|
@ -10,17 +10,19 @@
|
||||||
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QOpenGLBuffer>
|
#include <QOpenGLBuffer>
|
||||||
|
#include <QOpenGLFunctions>
|
||||||
#include <QOpenGLShaderProgram>
|
#include <QOpenGLShaderProgram>
|
||||||
#include <QOpenGLTexture>
|
#include <QOpenGLTexture>
|
||||||
#include <QOpenGLVertexArrayObject>
|
#include <QOpenGLVertexArrayObject>
|
||||||
#include <QOpenGLFunctions>
|
|
||||||
|
|
||||||
#include <camera3d.h>
|
#include <camera3d.h>
|
||||||
#include <mesh.h>
|
#include <mesh.h>
|
||||||
|
#include <qtkapi.h>
|
||||||
|
|
||||||
|
|
||||||
class Skybox : protected QOpenGLFunctions {
|
namespace Qtk {
|
||||||
public:
|
class QTKAPI Skybox : protected QOpenGLFunctions {
|
||||||
|
public:
|
||||||
// Delegate this constructor to use default skybox images
|
// Delegate this constructor to use default skybox images
|
||||||
// + This allows creating a skybox with no arguments ( auto s = new Skybox; )
|
// + This allows creating a skybox with no arguments ( auto s = new Skybox; )
|
||||||
explicit Skybox(std::string name="Skybox");
|
explicit Skybox(std::string name="Skybox");
|
||||||
|
@ -33,7 +35,7 @@ public:
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
Vertices mVertices;
|
Vertices mVertices;
|
||||||
|
@ -43,6 +45,7 @@ private:
|
||||||
QOpenGLVertexArrayObject mVAO;
|
QOpenGLVertexArrayObject mVAO;
|
||||||
QOpenGLBuffer mVBO;
|
QOpenGLBuffer mVBO;
|
||||||
QOpenGLTexture * mCubeMap;
|
QOpenGLTexture * mCubeMap;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif // QTK_SKYBOX_H
|
#endif // QTK_SKYBOX_H
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <texture.h>
|
#include <texture.h>
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
QImage * Texture::initImage(const char * image, bool flipX, bool flipY)
|
QImage * Texture::initImage(const char * image, bool flipX, bool flipY)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,9 +11,11 @@
|
||||||
|
|
||||||
#include <QOpenGLTexture>
|
#include <QOpenGLTexture>
|
||||||
|
|
||||||
|
#include <qtkapi.h>
|
||||||
|
|
||||||
class Texture {
|
namespace Qtk {
|
||||||
public:
|
class QTKAPI Texture {
|
||||||
|
public:
|
||||||
~Texture() {}
|
~Texture() {}
|
||||||
|
|
||||||
// QImage
|
// QImage
|
||||||
|
@ -34,9 +36,10 @@ public:
|
||||||
const char * front, const char * left,
|
const char * front, const char * left,
|
||||||
const char * bottom, const char * back);
|
const char * bottom, const char * back);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Private ctor to prevent creating instances of this class
|
// Private ctor to prevent creating instances of this class
|
||||||
Texture() {}
|
Texture() {}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif // QTOPENGL_TEXTURE_H
|
#endif // QTOPENGL_TEXTURE_H
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <transform3D.h>
|
#include <transform3D.h>
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
const QVector3D Transform3D::LocalForward(0.0f, 0.0f, 1.0f);
|
const QVector3D Transform3D::LocalForward(0.0f, 0.0f, 1.0f);
|
||||||
const QVector3D Transform3D::LocalUp(0.0f, 1.0f, 0.0f);
|
const QVector3D Transform3D::LocalUp(0.0f, 1.0f, 0.0f);
|
||||||
|
@ -110,8 +111,10 @@ QVector3D Transform3D::right() const
|
||||||
* QT Streams
|
* QT Streams
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const Transform3D & transform)
|
namespace Qtk {
|
||||||
{
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
QDebug operator<<(QDebug dbg, const Transform3D & transform)
|
||||||
|
{
|
||||||
dbg << "Transform3D\n{\n";
|
dbg << "Transform3D\n{\n";
|
||||||
dbg << "Position: <" << transform.translation().x() << ", "
|
dbg << "Position: <" << transform.translation().x() << ", "
|
||||||
<< transform.translation().y() << ", "
|
<< transform.translation().y() << ", "
|
||||||
|
@ -125,20 +128,24 @@ QDebug operator<<(QDebug dbg, const Transform3D & transform)
|
||||||
transform.rotation().scalar() << ">\n}";
|
transform.rotation().scalar() << ">\n}";
|
||||||
return dbg;
|
return dbg;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QDataStream & operator<<(QDataStream & out, const Transform3D & transform)
|
#ifndef QT_NO_DATASTREAM
|
||||||
{
|
QDataStream & operator<<(QDataStream & out, const Transform3D & transform)
|
||||||
|
{
|
||||||
out << transform.mTranslation;
|
out << transform.mTranslation;
|
||||||
out << transform.mScale;
|
out << transform.mScale;
|
||||||
out << transform.mRotation;
|
out << transform.mRotation;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream & operator>>(QDataStream & in, Transform3D & transform)
|
QDataStream & operator>>(QDataStream & in, Transform3D & transform)
|
||||||
{
|
{
|
||||||
in >> transform.mTranslation;
|
in >> transform.mTranslation;
|
||||||
in >> transform.mScale;
|
in >> transform.mScale;
|
||||||
in >> transform.mRotation;
|
in >> transform.mRotation;
|
||||||
transform.m_dirty = true;
|
transform.m_dirty = true;
|
||||||
return in;
|
return in;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,20 @@
|
||||||
#ifndef QTK_TRANSFORM3D_H
|
#ifndef QTK_TRANSFORM3D_H
|
||||||
#define QTK_TRANSFORM3D_H
|
#define QTK_TRANSFORM3D_H
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QMatrix4x4>
|
#include <QMatrix4x4>
|
||||||
#include <QQuaternion>
|
#include <QQuaternion>
|
||||||
#include <QVector3D>
|
#include <QVector3D>
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
#include <QDebug>
|
||||||
|
#endif
|
||||||
|
|
||||||
class Transform3D
|
#include <qtkapi.h>
|
||||||
{
|
|
||||||
public:
|
namespace Qtk {
|
||||||
|
class QTKAPI Transform3D
|
||||||
|
{
|
||||||
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
inline Transform3D() : m_dirty(true),
|
inline Transform3D() : m_dirty(true),
|
||||||
mScale(1.0f, 1.0f, 1.0f),
|
mScale(1.0f, 1.0f, 1.0f),
|
||||||
|
@ -88,7 +93,7 @@ public:
|
||||||
|
|
||||||
static const QVector3D LocalForward, LocalUp, LocalRight;
|
static const QVector3D LocalForward, LocalUp, LocalRight;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector3D mTranslation;
|
QVector3D mTranslation;
|
||||||
QQuaternion mRotation;
|
QQuaternion mRotation;
|
||||||
QVector3D mScale;
|
QVector3D mScale;
|
||||||
|
@ -96,22 +101,25 @@ private:
|
||||||
|
|
||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
|
|
||||||
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
#ifndef QT_NO_DATASTREAM
|
||||||
friend QDataStream &operator<<(QDataStream & out, const Transform3D & transform);
|
friend QDataStream &operator<<(QDataStream & out, const Transform3D & transform);
|
||||||
friend QDataStream &operator>>(QDataStream & in, Transform3D & transform);
|
friend QDataStream &operator>>(QDataStream & in, Transform3D & transform);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_TYPEINFO(Transform3D, Q_MOVABLE_TYPE);
|
|
||||||
|
|
||||||
// Qt Streams
|
// Qt Streams
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
QDebug operator<<(QDebug dbg, const Transform3D & transform);
|
QDebug operator<<(QDebug dbg, const Transform3D & transform);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
#ifndef QT_NO_DATASTREAM
|
||||||
QDataStream &operator<<(QDataStream & out, const Transform3D & transform);
|
QDataStream &operator<<(QDataStream & out, const Transform3D & transform);
|
||||||
QDataStream &operator>>(QDataStream & in, Transform3D & transform);
|
QDataStream &operator>>(QDataStream & in, Transform3D & transform);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_TYPEINFO(Qtk::Transform3D, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
#endif // QTK_TRANSFORM3D_H
|
#endif // QTK_TRANSFORM3D_H
|
||||||
|
|
Loading…
Reference in New Issue