Compare commits
5 Commits
0dcb6d337b
...
logging
| Author | SHA1 | Date | |
|---|---|---|---|
| 64c7b3d2eb | |||
| 2087b306b9 | |||
|
|
d0c8316f79 | ||
| ad59d9149e | |||
| e889785b65 |
282
.github/workflows/all-builds.yml
vendored
282
.github/workflows/all-builds.yml
vendored
@@ -5,21 +5,27 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
QT_VERSION: 6.6.0
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Build-Qtk:
|
Qtk:
|
||||||
env:
|
env:
|
||||||
CONFIG: -DQTK_UPDATE_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_ENABLE_CCACHE=OFF -DQTK_INSTALL_GUI=ON -DQTK_INSTALL_LIB=ON -DQTK_INSTALL_PLUGINS=OFF
|
CONFIG: -DQTK_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_CCACHE=OFF -DQTK_GUI=ON -DQTK_PLUGINS=OFF -DQTK_EXAMPLE=ON
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/6.5.0/gcc_64/ $CONFIG
|
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG
|
||||||
|
flags: -j $(nproc)
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/6.5.0/mingw81_64/ $CONFIG
|
cmake: -DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/$QT_VERSION/mingw81_64/ $CONFIG
|
||||||
|
flags: ''
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/6.5.0/gcc_64/ $CONFIG
|
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG
|
||||||
|
flags: -j $(nproc)
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
@@ -28,7 +34,7 @@ jobs:
|
|||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v2
|
||||||
with:
|
with:
|
||||||
version: '6.5.0'
|
version: ${{ env.QT_VERSION }}
|
||||||
|
|
||||||
# Windows
|
# Windows
|
||||||
|
|
||||||
@@ -38,43 +44,85 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
args: install pkgconfiglite --checksum e87b5ea3c9142256af60f2d5b917aa63b571e6a0 --checksum-type sha1
|
args: install pkgconfiglite --checksum e87b5ea3c9142256af60f2d5b917aa63b571e6a0 --checksum-type sha1
|
||||||
|
|
||||||
- name: Configure Qtk Application (Windows)
|
- name: Install Debian packaging dependencies
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
sudo apt update -y
|
||||||
|
sudo apt install libxcb-cursor0 -y
|
||||||
|
|
||||||
|
- name: Configure Qtk Application
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake -B build/ ${{ matrix.cmake }}
|
run: cmake -B build/ ${{ matrix.cmake }}
|
||||||
|
|
||||||
- name: Build Qtk Application (Windows)
|
- name: Build Qtk Application
|
||||||
if: matrix.os == 'windows-latest'
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake --build build/ --config Release
|
run: cmake --build build/ --config Release --target qtk_gui ${{ matrix.flags }}
|
||||||
|
|
||||||
# OSX / Linux
|
- name: Build Qtk Example
|
||||||
|
|
||||||
- name: Configure Qtk Application (OSX / Linux)
|
|
||||||
if: matrix.os != 'windows-latest'
|
if: matrix.os != 'windows-latest'
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake -B build/ ${{ matrix.cmake }}
|
run: cmake --build build/ --config Release --target qtk_example ${{ matrix.flags }}
|
||||||
|
|
||||||
- name: Build Qtk Application (OSX / Linux)
|
|
||||||
if: matrix.os != 'windows-latest'
|
|
||||||
shell: bash
|
|
||||||
run: cmake --build build/ --config Release --target qtk_main -- -j $(nproc)
|
|
||||||
|
|
||||||
# Packaging
|
# Packaging
|
||||||
|
|
||||||
- name: Install Qtk Application
|
- name: Install Qtk Application
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake --install build/ --config Release --prefix=$(pwd)/install --component qtk_main
|
run: cmake --install build/ --config Release --component qtk_gui
|
||||||
|
|
||||||
- name: Package Qtk Application
|
- name: Package Qtk Application
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake --build build/ --target package --config Release
|
run: cmake --build build/ --target package --config Release
|
||||||
|
|
||||||
# - uses: actions/upload-artifact@v3
|
- name: Package Qtk (DEB)
|
||||||
# if: always()
|
if: matrix.os == 'ubuntu-latest'
|
||||||
# with:
|
shell: bash
|
||||||
# name: qtk-${{ matrix.os }}-install
|
run: |
|
||||||
# path: install/*
|
cd build
|
||||||
|
cpack -C Release -G DEB
|
||||||
|
|
||||||
|
- name: Upload package artifacts (DEB)
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: qtk-gui-${{ matrix.os }}
|
||||||
|
path: |
|
||||||
|
build/packages/*.deb
|
||||||
|
|
||||||
|
- name: Package Qtk (WIN)
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
cpack -C Release -G NSIS
|
||||||
|
|
||||||
|
- name: Upload package artifacts (WIN)
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: qtk-gui-${{ matrix.os }}
|
||||||
|
path: |
|
||||||
|
build/packages/*.exe
|
||||||
|
|
||||||
|
- name: Package Qtk (OSX)
|
||||||
|
if: matrix.os == 'macos-latest'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
cpack -C Release -G TGZ
|
||||||
|
|
||||||
|
- name: Upload package artifacts (OSX)
|
||||||
|
if: matrix.os == 'macos-latest'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: qtk-gui-${{ matrix.os }}
|
||||||
|
path: |
|
||||||
|
build/packages/*.tar.gz
|
||||||
|
|
||||||
|
- name: Upload Qtk install directory
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: qtk-gui-${{ matrix.os }}-install
|
||||||
|
path: install/*
|
||||||
|
|
||||||
# TODO: Enable after trimming resources.
|
# TODO: Enable after trimming resources.
|
||||||
# - name: Package Qtk Application Sources
|
# - name: Package Qtk Application Sources
|
||||||
@@ -82,38 +130,32 @@ jobs:
|
|||||||
# shell: bash
|
# shell: bash
|
||||||
# run: |
|
# run: |
|
||||||
# cmake --build build/ --target package_source
|
# cmake --build build/ --target package_source
|
||||||
|
#
|
||||||
# - name: Upload package artifacts
|
# - name: Upload package artifacts
|
||||||
# uses: actions/upload-artifact@v3
|
# uses: actions/upload-artifact@v3
|
||||||
# if: always()
|
|
||||||
# with:
|
# with:
|
||||||
# name: qtk-packages-${{ matrix.os }}
|
# name: qtk-${{ matrix.os }}-packages
|
||||||
# path: |
|
# path: |
|
||||||
# build/packages/
|
# build/packages/*
|
||||||
# !build/packages/_CPack_Packages/*
|
# !build/packages/_CPack_Packages/*
|
||||||
|
|
||||||
- name: Upload logs on failure
|
Qtk-Library:
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
if: ${{ failure() && matrix.os == 'windows-latest' }}
|
|
||||||
with:
|
|
||||||
name: qtk-failed-packages-${{ matrix.os }}
|
|
||||||
path: |
|
|
||||||
build/_CPack_Packages/win64/NSIS/NSISOutput.log
|
|
||||||
|
|
||||||
Build-Qtk-Library:
|
|
||||||
env:
|
env:
|
||||||
CONFIG: -DQTK_UPDATE_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_ENABLE_CCACHE=OFF -DQTK_INSTALL_GUI=OFF -DQTK_INSTALL_LIB=ON -DQTK_INSTALL_PLUGINS=OFF
|
CONFIG: -DQTK_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_CCACHE=OFF -DQTK_GUI=OFF -DQTK_PLUGINS=OFF -DQTK_EXAMPLE=OFF
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/6.5.0/gcc_64/ $CONFIG
|
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG
|
||||||
|
flags: -j $(nproc)
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/6.5.0/mingw81_64/ $CONFIG
|
cmake: -DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/$QT_VERSION/mingw81_64/ $CONFIG
|
||||||
|
flags: ''
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/6.5.0/gcc_64/ $CONFIG
|
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG
|
||||||
|
flags: -j $(nproc)
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
@@ -122,7 +164,7 @@ jobs:
|
|||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v2
|
||||||
with:
|
with:
|
||||||
version: '6.5.0'
|
version: ${{ env.QT_VERSION }}
|
||||||
|
|
||||||
# Windows
|
# Windows
|
||||||
|
|
||||||
@@ -132,27 +174,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
args: install pkgconfiglite --checksum e87b5ea3c9142256af60f2d5b917aa63b571e6a0 --checksum-type sha1
|
args: install pkgconfiglite --checksum e87b5ea3c9142256af60f2d5b917aa63b571e6a0 --checksum-type sha1
|
||||||
|
|
||||||
- name: Configure Qtk Library (Windows)
|
- name: Configure Qtk Library
|
||||||
if: matrix.os == 'windows-latest'
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake -B build/ ${{ matrix.cmake }}
|
run: cmake -B build/ ${{ matrix.cmake }}
|
||||||
|
|
||||||
- name: Build Qtk Library (Windows)
|
- name: Build Qtk Library
|
||||||
if: matrix.os == 'windows-latest'
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake --build build/ --config Release
|
run: cmake --build build/ --config Release --target qtk_library -- ${{ matrix.flags }}
|
||||||
|
|
||||||
# OSX / Linux
|
|
||||||
|
|
||||||
- name: Configure Qtk Library (OSX / Linux)
|
|
||||||
if: matrix.os != 'windows-latest'
|
|
||||||
shell: bash
|
|
||||||
run: cmake -B build/ ${{ matrix.cmake }}
|
|
||||||
|
|
||||||
- name: Build Qtk Library (OSX / Linux)
|
|
||||||
if: matrix.os != 'windows-latest'
|
|
||||||
shell: bash
|
|
||||||
run: cmake --build build/ --config Release --target qtk_library -- -j $(nproc)
|
|
||||||
|
|
||||||
# Packaging
|
# Packaging
|
||||||
|
|
||||||
@@ -164,43 +192,75 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: cmake --build build/ --target package --config Release
|
run: cmake --build build/ --target package --config Release
|
||||||
|
|
||||||
# - uses: actions/upload-artifact@v3
|
- name: Package Qtk Library (DEB)
|
||||||
# if: always()
|
if: matrix.os == 'ubuntu-latest'
|
||||||
# with:
|
shell: bash
|
||||||
# name: libqtk-${{ matrix.os }}-install
|
run: |
|
||||||
# path: install/*
|
cd build
|
||||||
|
cpack -C Release -G DEB
|
||||||
|
|
||||||
# - name: Upload package artifacts
|
- name: Upload package artifacts (DEB)
|
||||||
# uses: actions/upload-artifact@v3
|
if: matrix.os == 'ubuntu-latest'
|
||||||
# if: always()
|
|
||||||
# with:
|
|
||||||
# name: libqtk-packages-${{ matrix.os }}
|
|
||||||
# path: |
|
|
||||||
# build/packages/
|
|
||||||
# !build/packages/_CPack_Packages/*
|
|
||||||
|
|
||||||
- name: Upload logs on failure
|
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
if: ${{ failure() && matrix.os == 'windows-latest' }}
|
|
||||||
with:
|
with:
|
||||||
name: libqtk-failed-packages-${{ matrix.os }}
|
name: libqtk-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
build/_CPack_Packages/win64/NSIS/NSISOutput.log
|
build/packages/*.deb
|
||||||
|
|
||||||
Build-Qtk-Plugins:
|
- name: Package Qtk Library (WIN)
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
cpack -C Release -G NSIS
|
||||||
|
|
||||||
|
- name: Upload package artifacts (WIN)
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: qtk-${{ matrix.os }}
|
||||||
|
path: |
|
||||||
|
build/packages/*.exe
|
||||||
|
|
||||||
|
- name: Package Qtk Library (OSX)
|
||||||
|
if: matrix.os == 'macos-latest'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
cpack -C Release -G TGZ
|
||||||
|
|
||||||
|
- name: Upload package artifacts (OSX)
|
||||||
|
if: matrix.os == 'macos-latest'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: qtk-${{ matrix.os }}
|
||||||
|
path: |
|
||||||
|
build/packages/*.tar.gz
|
||||||
|
|
||||||
|
- name: Upload libqtk install
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: libqtk-${{ matrix.os }}-install
|
||||||
|
path: install/*
|
||||||
|
|
||||||
|
Qtk-Plugins:
|
||||||
env:
|
env:
|
||||||
CONFIG: -DQTK_UPDATE_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_ENABLE_CCACHE=OFF -DQTK_INSTALL_GUI=OFF -DQTK_INSTALL_LIB=OFF -DQTK_INSTALL_PLUGINS=ON
|
CONFIG: -DQTK_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_CCACHE=OFF -DQTK_GUI=OFF -DQTK_PLUGINS=ON -DQTK_EXAMPLE=OFF
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/6.5.0/gcc_64/ $CONFIG
|
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG
|
||||||
|
flags: -j $(nproc)
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/6.5.0/mingw81_64/ $CONFIG
|
cmake: -DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/$QT_VERSION/mingw81_64/ $CONFIG
|
||||||
|
flags: ''
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/6.5.0/gcc_64/ $CONFIG
|
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG
|
||||||
|
flags: -j $(nproc)
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
@@ -209,9 +269,7 @@ jobs:
|
|||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v2
|
||||||
with:
|
with:
|
||||||
version: '6.5.0'
|
version: ${{ env.QT_VERSION }}
|
||||||
|
|
||||||
# Windows
|
|
||||||
|
|
||||||
- name: Chocolatey Action
|
- name: Chocolatey Action
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
@@ -219,44 +277,30 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
args: install pkgconfiglite --checksum e87b5ea3c9142256af60f2d5b917aa63b571e6a0 --checksum-type sha1
|
args: install pkgconfiglite --checksum e87b5ea3c9142256af60f2d5b917aa63b571e6a0 --checksum-type sha1
|
||||||
|
|
||||||
- name: Configure Qtk Plugins (Windows)
|
- name: Configure Qtk Plugins
|
||||||
if: matrix.os == 'windows-latest'
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake -B build/ ${{ matrix.cmake }}
|
run: cmake -B build/ ${{ matrix.cmake }}
|
||||||
|
|
||||||
- name: Build Qtk Plugins (Windows)
|
- name: Build Qtk Plugins
|
||||||
if: matrix.os == 'windows-latest'
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake --build build/ --config Release
|
run: cmake --build build/ --config Release --target qtk_plugins -- ${{ matrix.flags }}
|
||||||
|
|
||||||
# OSX / Linux
|
|
||||||
|
|
||||||
- name: Configure Qtk Plugins (OSX / Linux)
|
|
||||||
if: matrix.os != 'windows-latest'
|
|
||||||
shell: bash
|
|
||||||
run: cmake -B build/ ${{ matrix.cmake }}
|
|
||||||
|
|
||||||
- name: Build Qtk Plugins (OSX / Linux)
|
|
||||||
if: matrix.os != 'windows-latest'
|
|
||||||
shell: bash
|
|
||||||
run: cmake --build build/ --config Release --target qtk_collection -- -j $(nproc)
|
|
||||||
|
|
||||||
# Packaging
|
# Packaging
|
||||||
|
|
||||||
- name: Install Qtk Plugins
|
- name: Install Qtk Plugins
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake --install build/ --config Release --prefix=$(pwd)/install --component qtk_collection
|
run: cmake --install build/ --config Release --component qtk_plugins
|
||||||
|
|
||||||
Build-Qtk-Assimp-Targets:
|
Qtk-Assimp-Targets:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest]
|
os: [ubuntu-latest, macos-latest]
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/6.5.0/gcc_64/
|
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/6.5.0/gcc_64/ -DASSIMP_NEW_INTERFACE=ON
|
cmake: -DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
@@ -265,7 +309,7 @@ jobs:
|
|||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v2
|
||||||
with:
|
with:
|
||||||
version: '6.5.0'
|
version: ${{ env.QT_VERSION }}
|
||||||
|
|
||||||
- name: Install Assimp MacOS
|
- name: Install Assimp MacOS
|
||||||
if: matrix.os == 'macos-latest'
|
if: matrix.os == 'macos-latest'
|
||||||
@@ -279,24 +323,10 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
sudo apt install libassimp-dev
|
sudo apt install libassimp-dev
|
||||||
|
|
||||||
- name: Build Qtk
|
- name: Configure Qtk
|
||||||
if: matrix.os == 'windows-latest'
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: cmake -B build/ ${{ matrix.cmake }} -DQTK_CCACHE=OFF -DQTK_ASSIMP_NEW_INTERFACE=ON
|
||||||
cmake -B build/ ${{ matrix.cmake }} -DQTK_DEBUG=OFF -DQTK_ENABLE_CCACHE=OFF
|
|
||||||
cmake --build build/ --config Release
|
|
||||||
|
|
||||||
- name: Build Qtk
|
- name: Build Qtk
|
||||||
if: matrix.os != 'windows-latest'
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: cmake --build build/ --config Release
|
||||||
cmake -B build/ ${{ matrix.cmake }} -DQTK_DEBUG=OFF -DQTK_ENABLE_CCACHE=OFF
|
|
||||||
cmake --build build/ --config Release -- -j $(nproc)
|
|
||||||
|
|
||||||
# TODO: Enable with tag only when done testing
|
|
||||||
# Release-Qtk:
|
|
||||||
# needs: Build-Qtk
|
|
||||||
# strategy:
|
|
||||||
# fail-fast: false
|
|
||||||
# matrix:
|
|
||||||
# os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
|
|||||||
4
.github/workflows/linting.yml
vendored
4
.github/workflows/linting.yml
vendored
@@ -21,8 +21,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Build Qtk
|
- name: Build Qtk
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -DQTK_UPDATE_SUBMODULES=OFF -DQTK_ENABLE_CCACHE=OFF
|
cmake -B build -DQTK_SUBMODULES=OFF -DQTK_CCACHE=OFF -DQTK_PLUGINS=OFF -DQTK_GUI=ON
|
||||||
cmake --build build
|
cmake --build build --target qtk_gui -- -j $(nproc)
|
||||||
|
|
||||||
- uses: cpp-linter/cpp-linter-action@v2
|
- uses: cpp-linter/cpp-linter-action@v2
|
||||||
id: linter
|
id: linter
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,6 +1,9 @@
|
|||||||
# CLion
|
# CLion
|
||||||
**/.idea/**
|
**/.idea/**
|
||||||
|
|
||||||
|
# VS Code
|
||||||
|
**/.vscode/**
|
||||||
|
|
||||||
# CMake build files
|
# CMake build files
|
||||||
**/cmake-build-debug/**
|
**/cmake-build-debug/**
|
||||||
**/build/**
|
**/build/**
|
||||||
|
|||||||
104
CMakeLists.txt
104
CMakeLists.txt
@@ -23,6 +23,7 @@ if(WIN32)
|
|||||||
set(CMAKE_COMPILE_WARNING_AS_ERROR OFF)
|
set(CMAKE_COMPILE_WARNING_AS_ERROR OFF)
|
||||||
add_compile_options(/wd4131 /wd4127)
|
add_compile_options(/wd4131 /wd4127)
|
||||||
endif()
|
endif()
|
||||||
|
add_compile_options(-fPIC)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Project
|
# Project
|
||||||
@@ -45,14 +46,13 @@ include(GNUInstallDirs)
|
|||||||
# Options
|
# Options
|
||||||
################################################################################
|
################################################################################
|
||||||
option(QTK_DEBUG "Enable debugger" OFF)
|
option(QTK_DEBUG "Enable debugger" OFF)
|
||||||
option(QTK_UPDATE_SUBMODULES "Update external project (assimp) submodule" OFF)
|
option(QTK_SUBMODULES "Update external project (assimp) submodule" OFF)
|
||||||
option(QTK_INSTALL_GUI "Build the Qtk desktop application" ON)
|
option(QTK_GUI "Build the Qtk desktop application" ON)
|
||||||
option(QTK_INSTALL_LIB "Install libqtk to CMAKE_INSTALL_PREFIX path." ON)
|
option(QTK_PLUGINS "Install Qtk plugins to Qt Creator path." OFF)
|
||||||
option(QTK_INSTALL_PLUGINS "Install Qtk plugin collection to Qt Creator." OFF)
|
option(QTK_EXAMPLE "Build the Qtk example desktop application" ON)
|
||||||
option(QTK_BUILD_EXAMPLE "Build the Qtk example desktop application" ON)
|
option(QTK_CCACHE "Enable ccache" ON)
|
||||||
option(QTK_ENABLE_CCACHE "Enable ccache" ON)
|
|
||||||
|
|
||||||
if (QTK_ENABLE_CCACHE)
|
if (QTK_CCACHE)
|
||||||
set(CMAKE_CXX_COMPILER_LAUNCHER ccache)
|
set(CMAKE_CXX_COMPILER_LAUNCHER ccache)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -60,26 +60,33 @@ endif()
|
|||||||
option(QTK_PREFIX_QTCREATOR "Install Qtk to Qt Creator. Untested." OFF)
|
option(QTK_PREFIX_QTCREATOR "Install Qtk to Qt Creator. Untested." OFF)
|
||||||
|
|
||||||
# Option for bringing your own assimp installation; Otherwise not needed
|
# Option for bringing your own assimp installation; Otherwise not needed
|
||||||
# + If assimp is available system-wide we can just set QTK_UPDATE_SUBMODULES OFF
|
# + If assimp is available system-wide we can just set QTK_SUBMODULES OFF
|
||||||
option(
|
option(
|
||||||
QTK_ASSIMP_NEW_INTERFACE
|
QTK_ASSIMP_NEW_INTERFACE
|
||||||
"Use the assimp::assimp interface (WIN / OSX)"
|
"Use the assimp::assimp interface (WIN / OSX)"
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT QTK_DEBUG)
|
if(QTK_DEBUG OR CMAKE_BUILD_TYPE MATCHES "^[Dd][Ee][Bb][Uu][Gg]$")
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
set(QTK_DEBUG ON)
|
||||||
else()
|
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
|
else()
|
||||||
|
set(QTK_DEBUG OFF)
|
||||||
|
set(CMAKE_BUILD_TYPE Release)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# This should be set to your Qt6 installation directory.
|
# This should be set to your Qt6 installation directory.
|
||||||
set(QT_INSTALL_DIR "$ENV{HOME}/Qt/6.5.0/gcc_64" CACHE PATH "Path to Qt6 install.")
|
set(QT_INSTALL_DIR "$ENV{HOME}/Qt/6.5.0/gcc_64/lib/cmake" CACHE PATH "Path to Qt6 install.")
|
||||||
|
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||||
|
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(QTK_RESOURCES "${CMAKE_SOURCE_DIR}/resources")
|
||||||
|
set(QTK_OSX_ICONS ${CMAKE_SOURCE_DIR}/resources/icons/osx/kilroy.icns)
|
||||||
|
|
||||||
# Point CMAKE_PREFIX_PATH to Qt6 install directory
|
# Point CMAKE_PREFIX_PATH to Qt6 install directory
|
||||||
# If Qtk is built within Qt Creator this is not required.
|
# If Qtk is built within Qt Creator this is not required.
|
||||||
list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}")
|
list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}")
|
||||||
# TODO: Remove if not using sdlibdeps.
|
|
||||||
#set(CMAKE_INSTALL_RPATH "${QT_INSTALL_DIR}/lib")
|
|
||||||
if (QTK_PREFIX_QTCREATOR)
|
if (QTK_PREFIX_QTCREATOR)
|
||||||
# TODO: This might be a bit strange and needs more testing.
|
# TODO: This might be a bit strange and needs more testing.
|
||||||
set(CMAKE_INSTALL_PREFIX "${QT_INSTALL_DIR}")
|
set(CMAKE_INSTALL_PREFIX "${QT_INSTALL_DIR}")
|
||||||
@@ -90,31 +97,13 @@ set(
|
|||||||
"${QT_INSTALL_DIR}/../../Tools/QtCreator"
|
"${QT_INSTALL_DIR}/../../Tools/QtCreator"
|
||||||
CACHE PATH "Qt Creator path used to install Qtk plugins for Qt Designer."
|
CACHE PATH "Qt Creator path used to install Qtk plugins for Qt Designer."
|
||||||
)
|
)
|
||||||
# Qt Designer will look in different locations if WIN / Unix.
|
|
||||||
# These paths are for using Qt Designer integrated within Qt Creator.
|
|
||||||
# Standalone Qt Designer may use different paths.
|
|
||||||
if (WIN32)
|
|
||||||
# These paths may be different on windows. I have not tested this.
|
|
||||||
set(QT_PLUGIN_INSTALL_DIR "${QT_CREATOR_DIR}/bin/plugins/designer")
|
|
||||||
set(QT_PLUGIN_LIBRARY_DIR "${QT_CREATOR_DIR}/lib/Qt/lib")
|
|
||||||
else()
|
|
||||||
set(QT_PLUGIN_INSTALL_DIR "${QT_CREATOR_DIR}/lib/Qt/plugins/designer")
|
|
||||||
set(QT_PLUGIN_LIBRARY_DIR "${QT_CREATOR_DIR}/lib/Qt/lib")
|
|
||||||
endif()
|
|
||||||
set(QTK_PLUGIN_LIBRARY_DIR "${QT_PLUGIN_LIBRARY_DIR}")
|
|
||||||
set(QTK_PLUGIN_INSTALL_DIR "${QT_PLUGIN_INSTALL_DIR}")
|
|
||||||
|
|
||||||
message(STATUS "[Qtk] CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}")
|
# Print all QTK options and their values at the end of configuration.
|
||||||
set(QTK_RESOURCES "${CMAKE_SOURCE_DIR}/resources")
|
# We initialize this list here so that we can append to it as needed.
|
||||||
set(QTK_OSX_ICONS ${CMAKE_SOURCE_DIR}/resources/icons/osx/kilroy.icns)
|
# All variables in this list will be printed at the end of configuration.
|
||||||
|
|
||||||
# Print all QTK options and their values.
|
|
||||||
get_cmake_property(VAR_NAMES VARIABLES)
|
get_cmake_property(VAR_NAMES VARIABLES)
|
||||||
list(FILTER VAR_NAMES INCLUDE REGEX "^Q[tT][kK]_.*$")
|
list(FILTER VAR_NAMES INCLUDE REGEX "^[qQ][tT][kK]_.*$")
|
||||||
list(SORT VAR_NAMES)
|
list(SORT VAR_NAMES)
|
||||||
foreach(VAR_NAME ${VAR_NAMES})
|
|
||||||
message(STATUS "[Qtk] ${VAR_NAME}=${${VAR_NAME}}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# External Dependencies
|
# External Dependencies
|
||||||
@@ -134,8 +123,33 @@ if(NOT Qt6_FOUND)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
#
|
||||||
|
# To use custom plugins, set QT_PLUGIN_PATH environment variable before running designer
|
||||||
|
# Or, we can install plugins to the designer for use across all projects.
|
||||||
|
# Qt Creator on linux will look here for widget plugins in the integrated designer
|
||||||
|
# /home/shaun/Qt/Tools/QtCreator/lib/Qt/lib
|
||||||
|
# Qt Designer will use the following path on linux
|
||||||
|
# /home/shaun/Qt/6.5.0/gcc_64/plugins/designer/
|
||||||
|
# We can use this path after find_package(Qt6) to install our plugins on all systems
|
||||||
|
# ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_PLUGINS}/designer
|
||||||
|
# And run designer at ${QT6_INSTALL_PREFIX}/bin/designer
|
||||||
|
# Use cmake -DQTK_PLUGIN_INSTALL_DIR=/some/path to override this install path
|
||||||
|
set(
|
||||||
|
QTK_PLUGIN_INSTALL_DIR
|
||||||
|
"${QT6_INSTALL_PREFIX}/${QT6_INSTALL_PLUGINS}/designer" CACHE PATH
|
||||||
|
"Path to install Qtk plugin collection."
|
||||||
|
)
|
||||||
|
# See cmake configure output for values of these variables on your system
|
||||||
|
set(
|
||||||
|
VAR_PATHS
|
||||||
|
CMAKE_PREFIX_PATH CMAKE_INSTALL_PREFIX QTK_PLUGIN_INSTALL_DIR QT6_INSTALL_PREFIX
|
||||||
|
QT_INSTALL_DIR
|
||||||
|
)
|
||||||
|
# Add QT6_INSTALL_PLUGINS to VAR_NAMES so it is printed at end of configuration.
|
||||||
|
list(APPEND VAR_NAMES QT6_INSTALL_PLUGINS)
|
||||||
|
|
||||||
# Find Assimp.
|
# Find Assimp.
|
||||||
if(QTK_UPDATE_SUBMODULES)
|
if(QTK_SUBMODULES)
|
||||||
# Required to statically link.
|
# Required to statically link.
|
||||||
add_compile_options(-fPIC)
|
add_compile_options(-fPIC)
|
||||||
set(BUILD_SHARED_LIBS OFF CACHE STRING "Build static assimp libs" FORCE)
|
set(BUILD_SHARED_LIBS OFF CACHE STRING "Build static assimp libs" FORCE)
|
||||||
@@ -167,8 +181,20 @@ endif()
|
|||||||
################################################################################
|
################################################################################
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
if(QTK_BUILD_EXAMPLE)
|
if(QTK_EXAMPLE)
|
||||||
# Create a namespaced alias for linking with qtk_library in the example.
|
# Create a namespaced alias for linking with qtk_library in the example.
|
||||||
add_library(${PROJECT_NAME}::qtk_library ALIAS qtk_library)
|
add_library(${PROJECT_NAME}::qtk_library ALIAS qtk_library)
|
||||||
add_subdirectory(example-app)
|
add_subdirectory(example-app EXCLUDE_FROM_ALL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Print all QTK options and their values at the end of configuration. This also
|
||||||
|
# prints any additional variables that we have added to VAR_NAMES and VAR_PATHS.
|
||||||
|
foreach(VAR_NAME IN LISTS VAR_NAMES VAR_PATHS)
|
||||||
|
if(VAR_NAME IN_LIST VAR_PATHS)
|
||||||
|
# Print absolute if variable is path
|
||||||
|
get_filename_component(VAR_REALPATH "${${VAR_NAME}}" REALPATH)
|
||||||
|
message(STATUS "[Qtk] ${VAR_NAME}=${VAR_REALPATH}")
|
||||||
|
else()
|
||||||
|
message(STATUS "[Qtk] ${VAR_NAME}=${${VAR_NAME}}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|||||||
211
README.md
211
README.md
@@ -1,4 +1,5 @@
|
|||||||
# Qtk
|
# Qtk
|
||||||
|
|
||||||
[](https://github.com/shaunrd0/qtk/actions/workflows/all-builds.yml)
|
[](https://github.com/shaunrd0/qtk/actions/workflows/all-builds.yml)
|
||||||
[](https://github.com/shaunrd0/qtk/actions/workflows/linting.yml)
|
[](https://github.com/shaunrd0/qtk/actions/workflows/linting.yml)
|
||||||
|
|
||||||
@@ -11,72 +12,100 @@ practice shader coding or graphics programming techniques. In doing this I hope
|
|||||||
to also learn more about the Qt UI framework, and the CMake build system.
|
to also learn more about the Qt UI framework, and the CMake build system.
|
||||||
|
|
||||||
Key features that are planned:
|
Key features that are planned:
|
||||||
* Runtime loading of `.obj` or similar 3D models.
|
|
||||||
* Drag-and-drop interaction for adding objects to the scene.
|
|
||||||
* Runtime reloading of modified GLSL shaders attached to objects within scenes.
|
|
||||||
* Multiple views of a scene at one time.
|
|
||||||
* Camera control modes such as panning, orbiting, or following objects.
|
|
||||||
* Save / load for scene data. The current inheritance model is temporary.
|
|
||||||
* Basic text editor for quickly modifying shaders attached to objects.
|
|
||||||
* Shader / object properties panel to modify related settings.
|
|
||||||
* Reduce size of application resources and git references.
|
|
||||||
|
|
||||||
The Qtk desktop application provides a model loader using [Assimp](https://assimp.org/) within a Qt widget application.
|
* Runtime loading of `.obj` or similar 3D models.
|
||||||
|
* Drag-and-drop interaction for adding objects to the scene.
|
||||||
|
* Runtime reloading of modified GLSL shaders attached to objects within scenes.
|
||||||
|
* Multiple views of a scene at one time.
|
||||||
|
* Camera control modes such as panning, orbiting, or following objects.
|
||||||
|
* Save / load for scene data. The current inheritance model is temporary.
|
||||||
|
* Basic text editor for quickly modifying shaders attached to objects.
|
||||||
|
* Shader / object properties panel to modify related settings.
|
||||||
|
* Reduce size of application resources and git references.
|
||||||
|
|
||||||
|
The Qtk desktop application provides a model loader
|
||||||
|
using [Assimp](https://assimp.org/) within a Qt widget application.
|
||||||
|
|
||||||
For examples of using the Qtk API, see the `example-app` project in the root of
|
For examples of using the Qtk API, see the `example-app` project in the root of
|
||||||
this repository.
|
this repository.
|
||||||
|
|
||||||
To get textures loading on models look into [material files](http://www.paulbourke.net/dataformats/mtl/)
|
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.
|
and see some examples in the `resources/models/` directory.
|
||||||
|
|
||||||
### Source Builds
|
### Source Builds
|
||||||
|
|
||||||
Qtk was developed and tested using CLion and [Qt Creator](https://github.com/qt-creator/qt-creator).
|
Qtk was developed and tested using CLion
|
||||||
Simply open the root `CMakeLists.txt` with either of these editors and configurations will be loaded.
|
and [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 **Qt 6.5.0**, which is not yet available in Ubuntu apt repositories.
|
This project has been ported to **Qt 6.6.0**, which is not yet available in
|
||||||
To run this project, you will *need* to install [Qt6 Open Source Binaries](https://www.qt.io/download-qt-installer) for your system, **version 6.5.0** or later.
|
Ubuntu apt repositories.
|
||||||
Be sure to take note of the Qt6 installation directory, as we will need it to correctly set our `CMAKE_PREFIX_PATH` in the next steps.
|
To run this project, you will *need* to
|
||||||
|
install [Qt6 Open Source Binaries](https://www.qt.io/download-qt-installer) for
|
||||||
|
your system, **version 6.6.0** or later.
|
||||||
|
Be sure to take note of the Qt6 installation directory, as we will need it to
|
||||||
|
correctly set our `CMAKE_PREFIX_PATH` in the next steps.
|
||||||
|
|
||||||
|
If you are building on **Windows / Mac**, consider setting
|
||||||
|
the `-DQTK_ASSIMP_NEW_INTERFACE` cmake build option.
|
||||||
|
|
||||||
|
If the build is configured with all options enabled, we can subsequently install
|
||||||
|
individual components as needed with cmake.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update -y && sudo apt install libassimp-dev cmake build-essential git ccache libgl1-mesa-dev libglvnd-dev zlib1g-dev -y
|
||||||
|
git clone https://github.com/shaunrd0/qtk
|
||||||
|
cd qtk
|
||||||
|
# Configure the build with all components enabled
|
||||||
|
cmake -B build-all -DQTK_GUI=ON -DQTK_PLUGINS=ON -DQTK_EXAMPLE=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.6.0/gcc_64
|
||||||
|
# Build all targets
|
||||||
|
cmake --build build-all/
|
||||||
|
````
|
||||||
|
|
||||||
|
By default, the build will not initialize Assimp as a git submodule and build
|
||||||
|
from source.
|
||||||
|
We can turn this on by setting the `-DQTK_SUBMODULES=ON` flag when running
|
||||||
|
CMake.
|
||||||
|
Building using this option will fetch and build Assimp for us, but builds will
|
||||||
|
take longer as a result.
|
||||||
|
Using `-DQTK_SUBMODULES=ON` supports providing assimp on cross-platform builds (
|
||||||
|
Windows / Mac / Linux) and may be easier
|
||||||
|
to configure.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake -B build-all -DQTK_GUI=ON -DQTK_PLUGINS=ON -DQTK_EXAMPLE=ON -DQTK_SUBMODULES=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.6.0/gcc_64
|
||||||
|
```
|
||||||
|
|
||||||
#### Qtk GUI
|
#### Qtk GUI
|
||||||
|
|
||||||
Once Qt6 is installed, to build and run `qtk` on Ubuntu -
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt update -y && sudo apt install libassimp-dev cmake build-essential git ccache
|
cmake --build build-all/ --target qtk_gui -- -j $(nproc)
|
||||||
git clone https://github.com/shaunrd0/qtk
|
# Install Qtk desktop application (output removed)
|
||||||
cmake -S qtk/ -B qtk/build/ -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64
|
# Installation prefix path must be absolute, since Qtk uses Qt deploy tools.
|
||||||
cmake --build qtk/build/ -j $(nproc --ignore=2)
|
cmake --install build-all/ --component qtk_gui --prefix=$(pwd)/install
|
||||||
./qtk/build/bin/qtk-main
|
./install/bin/qtk_gui
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, the build will not initialize Assimp as a git submodule and build from source.
|
If any errors are encountered loading plugins, we can debug plugin loading by
|
||||||
We can turn this on by setting the `-DQTK_UPDATE_SUBMODULES=ON` flag when running CMake.
|
setting the following environment variable -
|
||||||
Building using this option will fetch and build Assimp for us, but builds will take longer as a result.
|
|
||||||
Using `-DQTK_UPDATE_SUBMODULES=ON` supports providing assimp on cross-platform builds (Windows / Mac / Linux) and may be easier to configure.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cmake -S qtk/ -B qtk/build/ -DQTK_UPDATE_SUBMODULES=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64
|
QT_DEBUG_PLUGINS=1 ./install/bin/qtk_gui
|
||||||
cmake --build qtk/build/ -j $(nproc --ignore=2)
|
|
||||||
./qtk/build/bin/qtk-main
|
|
||||||
```
|
|
||||||
|
|
||||||
If any errors are encountered loading plugins, we can debug plugin loading by setting the following environment variable -
|
|
||||||
|
|
||||||
```bash
|
|
||||||
QT_DEBUG_PLUGINS=1 ./qtk-main
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Qtk Library
|
#### Qtk Library
|
||||||
|
|
||||||
Qtk provides a simple library for working with QOpenGL.
|
Qtk provides a simple library for working with QOpenGL.
|
||||||
We can install this library on a system path or a custom path and then set `CMAKE_PREFIX_PATH` to point to this location when building an application using libqtk.
|
We can install this library on a system path or a custom path and then
|
||||||
|
set `CMAKE_PREFIX_PATH` to point to this location when building an application
|
||||||
Below is an example of installing on a system path.
|
using libqtk.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cmake -S qtk/ -B qtk/build/ -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64 -DQTK_INSTALL_GUI=OFF -DQTK_INSTALL_PLUGINS=OFF
|
# Install libqtk only
|
||||||
cmake --build qtk/build/ -j $(nproc --ignore=2)
|
cmake --build build-all/ --target qtk_library -- -j $(nproc)
|
||||||
sudo cmake --install . --prefix=/usr/local
|
cmake --install build-all/ --component qtk_library --prefix=/usr/local
|
||||||
-- Install configuration: "Release"
|
-- Install configuration: "Release"
|
||||||
-- Installing: /usr/local/lib/cmake/Qtk/QtkConfig.cmake
|
-- Installing: /usr/local/lib/cmake/Qtk/QtkConfig.cmake
|
||||||
-- Installing: /usr/local/lib/cmake/Qtk/QtkConfigVersion.cmake
|
-- Installing: /usr/local/lib/cmake/Qtk/QtkConfigVersion.cmake
|
||||||
@@ -103,32 +132,51 @@ sudo cmake --install . --prefix=/usr/local
|
|||||||
|
|
||||||
This project defines a collection of widget plugins for use with Qt Designer.
|
This project defines a collection of widget plugins for use with Qt Designer.
|
||||||
These plugins were used to build the interface for the Qtk desktop application.
|
These plugins were used to build the interface for the Qtk desktop application.
|
||||||
Qt Designer will list Qtk widgets in the side panel when editing a UI file within the designer.
|
Qt Designer will list Qtk widgets in the side panel when editing a UI file
|
||||||
Qtk widgets will also render and behave correctly within the UI preview in designer.
|
within the designer.
|
||||||
The widgets in the Qtk collection were created by implementing the [QDesignerCustomWidgetInterface](https://doc.qt.io/qt-6/qdesignercustomwidgetinterface.html#details) and [QDesignerCustomWidgetCollectionInterface](https://doc.qt.io/qt-6/qdesignercustomwidgetcollectioninterface.html) interfaces.
|
Qtk widgets will also render and behave correctly within the UI preview in
|
||||||
|
designer.
|
||||||
|
The widgets in the Qtk collection were created by implementing
|
||||||
|
the [QDesignerCustomWidgetInterface](https://doc.qt.io/qt-6/qdesignercustomwidgetinterface.html#details)
|
||||||
|
and [QDesignerCustomWidgetCollectionInterface](https://doc.qt.io/qt-6/qdesignercustomwidgetcollectioninterface.html)
|
||||||
|
interfaces.
|
||||||
|
|
||||||
To build and install the Qtk plugin collection -
|
To build and install the Qtk plugin collection -
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cmake -S /path/to/qtk -B /path/to/qtk/build -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64 -DQTK_INSTALL_PLUGINS=ON -DQTK_INSTALL_GUI=OFF -DQTK_INSTALL_LIB=OFF
|
cmake --build build-all/ --target qtk_plugins -- -j $(nproc)
|
||||||
cmake --build /path/to/qtk/build
|
# Install Qtk widget collection to use Qt Designer
|
||||||
cmake --install /path/to/qtk/build
|
# The path here should be initialized during build configuration, so no need for --prefix
|
||||||
|
cmake --install build-all/ --component qtk_plugins
|
||||||
|
-- Install configuration: "Release"
|
||||||
|
-- Up-to-date: /home/shaun/Qt/6.6.0/gcc_64/../../Tools/QtCreator/lib/Qt/lib/libqtk_library.a
|
||||||
|
-- Up-to-date: /home/shaun/Qt/6.6.0/gcc_64/../../Tools/QtCreator/lib/Qt/lib/libqtk_plugin_library.a
|
||||||
|
-- Up-to-date: /home/shaun/Qt/6.6.0/gcc_64/../../Tools/QtCreator/lib/Qt/plugins/designer/libqtk_collection.so
|
||||||
```
|
```
|
||||||
|
|
||||||
To uninstall after a previous installation, we can run the following command from the root of the repository.
|
To uninstall after a previous installation, we can run the following command
|
||||||
|
from the root of the repository.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
xargs rm < build/install_manifest.txt
|
xargs rm < build/install_manifest.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Qtk Example
|
||||||
|
|
||||||
#### Windows / MacOS
|
There is a simple example of using libqtk in the [example-app/](example-app)
|
||||||
|
directory. The example can be built standalone using `find_package` or as a
|
||||||
|
target within any qtk build.
|
||||||
|
|
||||||
If you are building on **Windows / Mac**, consider setting the `-DASSIMP_NEW_INTERFACE` build flag.
|
|
||||||
```bash
|
```bash
|
||||||
cmake -S qtk/ -B qtk/build/ -DASSIMP_NEW_INTERFACE=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64;/path/to/assimp/
|
# Build the example from a configured qtk build tree
|
||||||
cmake --build qtk/build/ -j $(nproc --ignore=2)
|
cmake --build build-all/ --target qtk_example -- -j $(nproc)
|
||||||
|
cmake --install build-all/ --component qtk_example --prefix=install
|
||||||
|
./install/bin/qtk_example
|
||||||
```
|
```
|
||||||
|
|
||||||
|
See the README in the [example-app/](example-app) subdirectory for instructions
|
||||||
|
on standalone builds.
|
||||||
|
|
||||||
### Controls
|
### Controls
|
||||||
|
|
||||||
You can fly around the scene if you hold the right mouse button and use WASD.
|
You can fly around the scene if you hold the right mouse button and use WASD.
|
||||||
@@ -166,7 +214,9 @@ cmake --build build -j $(nproc --ignore=2)
|
|||||||
sudo cmake --build build -j $(nproc --ignore=2) --target install
|
sudo cmake --build build -j $(nproc --ignore=2) --target install
|
||||||
```
|
```
|
||||||
|
|
||||||
If the `clang-format` version is any earlier than `15.0.0`, running `clang-format` will fail because this project uses configuration options made available since `15.0.0`.
|
If the `clang-format` version is any earlier than `15.0.0`,
|
||||||
|
running `clang-format` will fail because this project uses configuration options
|
||||||
|
made available since `15.0.0`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
clang-format --version
|
clang-format --version
|
||||||
@@ -174,7 +224,8 @@ clang-format version 15.0.5 (git@github.com:llvm/llvm-project.git 154e88af7ec97d
|
|||||||
```
|
```
|
||||||
|
|
||||||
CLion has integration for IDE code reformatting actions with `clang-format`.
|
CLion has integration for IDE code reformatting actions with `clang-format`.
|
||||||
If you're using CLion, the `.clang-format` configuration will be picked up by CLion automatically.
|
If you're using CLion, the `.clang-format` configuration will be picked up by
|
||||||
|
CLion automatically.
|
||||||
|
|
||||||
`clang-tidy` can be run with the following commands.
|
`clang-tidy` can be run with the following commands.
|
||||||
|
|
||||||
@@ -182,7 +233,7 @@ If you're using CLion, the `.clang-format` configuration will be picked up by CL
|
|||||||
# Move to the root of the repo
|
# Move to the root of the repo
|
||||||
cd qtk
|
cd qtk
|
||||||
# Build
|
# Build
|
||||||
cmake -B build && cmake --build build
|
cmake -B build && cmake --build build -- -j $(nproc)
|
||||||
clang-tidy -p build/ --fix --config-file=.clang-tidy src/*.cpp src/*.h app/*.cpp app/*.h
|
clang-tidy -p build/ --fix --config-file=.clang-tidy src/*.cpp src/*.h app/*.cpp app/*.h
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -190,7 +241,7 @@ Last we need to run `clang-format`, this can be done with the command directly.
|
|||||||
This will reformat all the code in the repository.
|
This will reformat all the code in the repository.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
clang-format -i --style=file:.clang-format src/*.cpp src/*.h app/*.cpp app/*.h
|
clang-format -i --style=file:.clang-format src/app/*.cpp src/app/*.h src/qtk/*.cpp src/qtk/*.h example-app/*.cpp example-app/*.h
|
||||||
```
|
```
|
||||||
|
|
||||||
`clang-format` can be run with git integration (or CLion if you prefer).
|
`clang-format` can be run with git integration (or CLion if you prefer).
|
||||||
@@ -214,8 +265,10 @@ changed files:
|
|||||||
##### Packaging
|
##### Packaging
|
||||||
|
|
||||||
Packaging for Qtk is in early development.
|
Packaging for Qtk is in early development.
|
||||||
This section documents how to package Qtk, but only source builds have been verified on Windows / Mac / Linux.
|
This section documents how to package Qtk, but only source builds have been
|
||||||
For this reason, it is recommended to install Qtk by strictly building from source at this time.
|
verified on Windows / Mac / Linux.
|
||||||
|
For this reason, it is recommended to install Qtk by strictly building from
|
||||||
|
source at this time.
|
||||||
|
|
||||||
Below are the steps to package a Qtk release.
|
Below are the steps to package a Qtk release.
|
||||||
|
|
||||||
@@ -228,6 +281,7 @@ cmake --build build --target package_source
|
|||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, we can use `cpack` directly -
|
Alternatively, we can use `cpack` directly -
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /path/to/qtk && cmake -B build
|
cd /path/to/qtk && cmake -B build
|
||||||
# Generate all install packages
|
# Generate all install packages
|
||||||
@@ -242,13 +296,15 @@ cpack -C Release -G DEB
|
|||||||
cpack -C Release -G NSIS
|
cpack -C Release -G NSIS
|
||||||
```
|
```
|
||||||
|
|
||||||
Any of the above options can be appended with `--trace-expand` to debug package generation issues.
|
Any of the above options can be appended with `--trace-expand` to debug package
|
||||||
|
generation issues.
|
||||||
The contents of all packages will depend on how the build was configured.
|
The contents of all packages will depend on how the build was configured.
|
||||||
|
|
||||||
If we are generating packages for *only* libqtk, we set `-DQTK_INSTALL_LIB=ON` during the cmake configuration step.
|
To generate packages for Qtk desktop application, we should
|
||||||
To generate packages for Qtk desktop application, we should set `-DQTK_INSTALL_GUI=ON`, and optionally `-DQTK_INSTALL_LIB=ON` if we would like to bundle libqtk with the desktop application.
|
set `-DQTK_GUI=ON`. If this option is not set we will only package libqtk.
|
||||||
|
|
||||||
The NSIS installer will allow component-specific path modification for all of these installation components through a GUI install application.
|
The NSIS installer will allow component-specific path modification for all of
|
||||||
|
these installation components through a GUI install application.
|
||||||
|
|
||||||
##### Resources
|
##### Resources
|
||||||
|
|
||||||
@@ -258,19 +314,34 @@ Some useful links and resources that I have found while working on this project.
|
|||||||
|
|
||||||
[QtPlugin Import / Export plugins](https://doc.qt.io/qt-6/qtplugin.html)
|
[QtPlugin Import / Export plugins](https://doc.qt.io/qt-6/qtplugin.html)
|
||||||
|
|
||||||
|
[KDAB](https://www.kdab.com/)
|
||||||
|
|
||||||
## Model Artists
|
## 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/).
|
||||||
|
|
||||||
"Scythe World Of Warcraft" (https://skfb.ly/6UooG) by Warcraft-3D-Models is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
|
"Scythe World Of Warcraft" (https://skfb.ly/6UooG) by Warcraft-3D-Models is
|
||||||
|
licensed under Creative Commons
|
||||||
|
Attribution (http://creativecommons.org/licenses/by/4.0/).
|
||||||
|
|
||||||
"Spartan Armour MKV - Halo Reach" (https://skfb.ly/6QVvM) by McCarthy3D is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
|
"Spartan Armour MKV - Halo Reach" (https://skfb.ly/6QVvM) by McCarthy3D is
|
||||||
|
licensed under Creative Commons
|
||||||
|
Attribution (http://creativecommons.org/licenses/by/4.0/).
|
||||||
|
|
||||||
"Survival Guitar Backpack (Low Poly)" (https://skfb.ly/6RnCB) by Berk Gedik is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
|
"Survival Guitar Backpack (Low Poly)" (https://skfb.ly/6RnCB) by Berk Gedik is
|
||||||
Model by Berk Gedik, from: https://sketchfab.com/3d-models/survival-guitar-backpack-low-poly-799f8c4511f84fab8c3f12887f7e6b36
|
licensed under Creative Commons
|
||||||
Modified (learnopengl.com) material assignment (Joey de Vries) for easier load in OpenGL model loading chapter, and renamed albedo to diffuse and metallic to specular to match non-PBR lighting setup.
|
Attribution (http://creativecommons.org/licenses/by/4.0/).
|
||||||
|
Model by Berk Gedik,
|
||||||
|
from: https://sketchfab.com/3d-models/survival-guitar-backpack-low-poly-799f8c4511f84fab8c3f12887f7e6b36
|
||||||
|
Modified (learnopengl.com) material assignment (Joey de Vries) for easier load
|
||||||
|
in OpenGL model loading chapter, and renamed albedo to diffuse and metallic to
|
||||||
|
specular to match non-PBR lighting setup.
|
||||||
|
|
||||||
"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/).
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ find_package(Git)
|
|||||||
# _PATH: Path to git submodule location that we want to update
|
# _PATH: Path to git submodule location that we want to update
|
||||||
# + submodule_update(extern/assimp)
|
# + submodule_update(extern/assimp)
|
||||||
function(submodule_update _PATH)
|
function(submodule_update _PATH)
|
||||||
if (NOT QTK_UPDATE_SUBMODULES)
|
if (NOT QTK_SUBMODULES)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,12 @@
|
|||||||
|
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/QtkTargets.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/QtkTargets.cmake")
|
||||||
|
|
||||||
set_and_check(QTK_EXECUTABLE "${PACKAGE_PREFIX_DIR}/bin/qtk_main")
|
set_and_check(QTK_EXECUTABLE "${PACKAGE_PREFIX_DIR}/bin/qtk_gui")
|
||||||
set_and_check(QTK_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")
|
set_and_check(QTK_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")
|
||||||
set_and_check(QTK_LIBRARIES "${PACKAGE_PREFIX_DIR}/lib")
|
set_and_check(QTK_LIBRARIES "${PACKAGE_PREFIX_DIR}/lib")
|
||||||
|
|
||||||
|
set_and_check(Qtk_EXECUTABLE "${PACKAGE_PREFIX_DIR}/bin/qtk_gui")
|
||||||
|
set_and_check(Qtk_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")
|
||||||
|
set_and_check(Qtk_LIBRARIES "${PACKAGE_PREFIX_DIR}/lib")
|
||||||
|
|
||||||
check_required_components(Qtk)
|
check_required_components(Qtk)
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# If you did not install Qtk on a system path, point cmake to installation.
|
# If you did not install Qtk on a system path, point cmake to installation.
|
||||||
set(QTK_PATH /usr/local CACHE PATH "Path to installation of Qtk")
|
set(
|
||||||
|
QTK_PATH ../build/install/lib/cmake/Qtk
|
||||||
|
CACHE PATH "Path to installation of Qtk"
|
||||||
|
FORCE
|
||||||
|
)
|
||||||
|
|
||||||
# If you did not install Qt6 on a system path, point cmake to installation.
|
# If you did not install Qt6 on a system path, point cmake to installation.
|
||||||
set(QT_INSTALL_DIR "$ENV{HOME}/Qt/6.5.0/gcc_64/" CACHE PATH "Path to Qt6")
|
set(QT_INSTALL_DIR "$ENV{HOME}/Qt/6.5.0/gcc_64/" CACHE PATH "Path to Qt6")
|
||||||
@@ -40,12 +44,6 @@ project(
|
|||||||
list(APPEND CMAKE_PREFIX_PATH "${QTK_PATH}")
|
list(APPEND CMAKE_PREFIX_PATH "${QTK_PATH}")
|
||||||
list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}")
|
list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}")
|
||||||
|
|
||||||
# Allow add_subdirectory on this project to use target ALIAS if available.
|
|
||||||
# If this example project is opened standalone we will use find_package.
|
|
||||||
if(NOT TARGET Qtk::qtk_library)
|
|
||||||
find_package(Qtk 0.2 REQUIRED)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Print all QTK variables
|
# Print all QTK variables
|
||||||
if (NOT Qtk_IS_TOP_LEVEL)
|
if (NOT Qtk_IS_TOP_LEVEL)
|
||||||
get_cmake_property(VAR_NAMES VARIABLES)
|
get_cmake_property(VAR_NAMES VARIABLES)
|
||||||
@@ -56,6 +54,12 @@ if (NOT Qtk_IS_TOP_LEVEL)
|
|||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Allow add_subdirectory on this project to use target ALIAS if available.
|
||||||
|
# If this example project is opened standalone we will use find_package.
|
||||||
|
if(NOT TARGET Qtk::qtk_library)
|
||||||
|
find_package(Qtk 0.2 REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(Qt6 COMPONENTS Core Widgets OpenGLWidgets REQUIRED)
|
find_package(Qt6 COMPONENTS Core Widgets OpenGLWidgets REQUIRED)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
@@ -65,6 +69,28 @@ set(
|
|||||||
examplewidget.cpp examplewidget.h
|
examplewidget.cpp examplewidget.h
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(example ${EXAMPLE_SOURCES})
|
configure_file(
|
||||||
target_link_libraries(example PUBLIC Qt6::Widgets Qt6::OpenGLWidgets Qt6::Core)
|
#[[INPUT]] "${CMAKE_CURRENT_SOURCE_DIR}/resources.h.in"
|
||||||
target_link_libraries(example PUBLIC Qtk::qtk_library)
|
#[[OUTPUT]] "${CMAKE_CURRENT_BINARY_DIR}/resources.h"
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_add_executable(qtk_example ${EXAMPLE_SOURCES})
|
||||||
|
target_link_libraries(qtk_example PUBLIC Qt6::Widgets Qt6::OpenGLWidgets Qt6::Core)
|
||||||
|
target_link_libraries(qtk_example PUBLIC Qtk::qtk_library)
|
||||||
|
target_include_directories(qtk_example PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS qtk_example
|
||||||
|
COMPONENT qtk_example
|
||||||
|
BUNDLE DESTINATION .
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
ARCHIVE DESTINATION lib/static
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
)
|
||||||
|
qt_generate_deploy_app_script(
|
||||||
|
TARGET qtk_example
|
||||||
|
OUTPUT_SCRIPT QTK_EXAMPLE_DEPLOY_SCRIPT
|
||||||
|
NO_UNSUPPORTED_PLATFORM_ERROR
|
||||||
|
)
|
||||||
|
install(SCRIPT ${QTK_EXAMPLE_DEPLOY_SCRIPT} COMPONENT qtk_example)
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
|
|
||||||
This is an example application that is using the Qtk API to create custom Qt
|
This is an example application that is using the Qtk API to create custom Qt
|
||||||
OpenGL widgets. This is very similar to `QtkWidget` in the Qtk desktop
|
OpenGL widgets. This is very similar to `QtkWidget` in the Qtk desktop
|
||||||
application, but could be modified for different uses if needed.
|
application source code, but could be modified for different uses if needed.
|
||||||
|
|
||||||
|
There are no camera controls supported in this example. The camera is fixed.
|
||||||
|
If these controls are desired, they can be implemented by the client.
|
||||||
|
|
||||||
You can import your own models within `examplescene.cpp`, inside the
|
You can import your own models within `examplescene.cpp`, inside the
|
||||||
`ExampleScene::init()` function. Rotations and translations
|
`ExampleScene::init()` function. Rotations and translations
|
||||||
are applied in `ExampleScene::update()`.
|
are applied in `ExampleScene::update()`.
|
||||||
|
|
||||||
The syntax for adding shapes and models is seen in the example below.
|
The syntax for adding shapes and models is seen in the example below.
|
||||||
This would result in a scene with a red cube and a miniature spartan model placed on top.
|
This would result in a scene with a red cube and a miniature spartan model
|
||||||
|
placed on top.
|
||||||
|
|
||||||
```C++
|
```C++
|
||||||
void ExampleScene::init() {
|
void ExampleScene::init() {
|
||||||
@@ -41,7 +44,6 @@ void ExampleScene::update() {
|
|||||||
|
|
||||||
Other examples can be found in the source files for this example project.
|
Other examples can be found in the source files for this example project.
|
||||||
|
|
||||||
|
|
||||||
## Build Instructions
|
## Build Instructions
|
||||||
|
|
||||||
Currently, this application requires manual build and installation of Qtk.
|
Currently, this application requires manual build and installation of Qtk.
|
||||||
@@ -55,14 +57,17 @@ cmake -S /path/to/qtk/example-app/ -B /path/to/qtk/example-app/build
|
|||||||
cmake --build /path/to/qtk/example-app/build
|
cmake --build /path/to/qtk/example-app/build
|
||||||
```
|
```
|
||||||
|
|
||||||
If Qtk was not installed system-wide, we can set `QTK_PATH` to point to the custom installation directory.
|
If Qtk was not installed system-wide, we can set `QTK_PATH` to point to the
|
||||||
|
custom installation directory.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cmake -S /path/to/qtk/example-app/ -B /path/to/qtk/example-app/build -DQTK_PATH=/path/to/qtk/install/
|
cmake -S /path/to/qtk/example-app/ -B /path/to/qtk/example-app/build -DQTK_PATH=/path/to/qtk/install/
|
||||||
cmake --build /path/to/qtk/example-app/build
|
cmake --build /path/to/qtk/example-app/build --target qtk_example -- -j $(nproc)
|
||||||
|
cmake --install build/ --component qtk_example
|
||||||
```
|
```
|
||||||
|
|
||||||
After this, we can run the example application -
|
After this, we can run the example application -
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./path/to/qtk/example-app/build/bin/example
|
./path/to/qtk/example-app/build/install/bin/example
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -7,13 +7,14 @@
|
|||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
#include "examplescene.h"
|
#include "examplescene.h"
|
||||||
|
#include <resources.h>
|
||||||
|
|
||||||
using namespace Qtk;
|
using namespace Qtk;
|
||||||
|
|
||||||
ExampleScene::ExampleScene() {
|
ExampleScene::ExampleScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) {
|
||||||
setSceneName("Example Scene");
|
setSceneName("Example Scene");
|
||||||
getCamera().getTransform().setTranslation(-8.0f, 0.0f, 10.0f);
|
getCamera().setTranslation({-8.0f, 0.0f, 10.0f});
|
||||||
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
getCamera().setRotation(0.0f, 1.0f, 0.0f, -5.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExampleScene::~ExampleScene() {}
|
ExampleScene::~ExampleScene() {}
|
||||||
@@ -22,9 +23,11 @@ void ExampleScene::init() {
|
|||||||
auto skybox = new Qtk::Skybox("Skybox");
|
auto skybox = new Qtk::Skybox("Skybox");
|
||||||
setSkybox(skybox);
|
setSkybox(skybox);
|
||||||
|
|
||||||
auto spartan = new Model(
|
std::string spartanPath = QTK_EXAMPLE_SOURCE_DIR;
|
||||||
"spartan", "/home/kapper/Code/qtk/resources/models/spartan/spartan.obj");
|
spartanPath += "/resources/models/spartan/spartan.obj";
|
||||||
|
auto spartan = new Model("spartan", spartanPath.c_str());
|
||||||
addObject(spartan);
|
addObject(spartan);
|
||||||
|
spartan->getTransform().setTranslation(-4.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
auto mesh = addObject(
|
auto mesh = addObject(
|
||||||
new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ARRAYS)));
|
new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ARRAYS)));
|
||||||
@@ -61,10 +64,10 @@ void ExampleScene::update() {
|
|||||||
// Pitch forward and roll sideways
|
// Pitch forward and roll sideways
|
||||||
MeshRenderer::getInstance("leftTriangle")
|
MeshRenderer::getInstance("leftTriangle")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 1.0f, 0.0f, 0.0f);
|
.rotate(1.0f, 0.0f, 0.0f, 0.75f);
|
||||||
MeshRenderer::getInstance("rightTriangle")
|
MeshRenderer::getInstance("rightTriangle")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 0.0f, 0.0f, 1.0f);
|
.rotate(0.0f, 0.0f, 1.0f, 0.75f);
|
||||||
|
|
||||||
static float translateX = 0.025f;
|
static float translateX = 0.025f;
|
||||||
float limit = -9.0f; // Origin position.x - 2.0f
|
float limit = -9.0f; // Origin position.x - 2.0f
|
||||||
@@ -83,12 +86,12 @@ void ExampleScene::update() {
|
|||||||
.translate(-translateX, 0.0f, 0.0f);
|
.translate(-translateX, 0.0f, 0.0f);
|
||||||
MeshRenderer::getInstance("topTriangle")
|
MeshRenderer::getInstance("topTriangle")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 0.2f, 0.0f, 0.4f);
|
.rotate(0.2f, 0.0f, 0.4f, 0.75f);
|
||||||
MeshRenderer::getInstance("bottomTriangle")
|
MeshRenderer::getInstance("bottomTriangle")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 0.0f, 0.2f, 0.4f);
|
.rotate(0.0f, 0.2f, 0.4f, 0.75f);
|
||||||
|
|
||||||
MeshRenderer::getInstance("centerCube")
|
MeshRenderer::getInstance("centerCube")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 0.2f, 0.4f, 0.6f);
|
.rotate(0.2f, 0.4f, 0.6f, 0.75f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
|
|
||||||
#include <qtk/scene.h>
|
#include <qtk/scene.h>
|
||||||
|
|
||||||
class ExampleScene : public Qtk::Scene {
|
class ExampleScene : public Qtk::SceneInterface {
|
||||||
public:
|
public:
|
||||||
ExampleScene();
|
ExampleScene(Qtk::Scene * scene);
|
||||||
|
|
||||||
~ExampleScene();
|
~ExampleScene();
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,12 @@
|
|||||||
#include "examplewidget.h"
|
#include "examplewidget.h"
|
||||||
|
|
||||||
ExampleWidget::ExampleWidget(QWidget * parent) :
|
ExampleWidget::ExampleWidget(QWidget * parent) :
|
||||||
QOpenGLWidget(parent), mScene(new ExampleScene) {
|
QOpenGLWidget(parent), mScene(new ExampleScene(new Qtk::SceneEmpty)) {
|
||||||
|
// NOTE: The decorator pattern is used to save / load scenes in Qtk currently.
|
||||||
|
// The initializer above sets mScene to the concrete decorator ExampleScene.
|
||||||
|
// Qtk::SceneEmpty provides an empty scene as the concrete component.
|
||||||
|
// ExampleScene is defined in client source, deriving Qtk::SceneInterface.
|
||||||
|
|
||||||
QSurfaceFormat format;
|
QSurfaceFormat format;
|
||||||
format.setRenderableType(QSurfaceFormat::OpenGL);
|
format.setRenderableType(QSurfaceFormat::OpenGL);
|
||||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class ExampleWidget : public QOpenGLWidget, protected QOpenGLFunctions {
|
|||||||
void update();
|
void update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ExampleScene * mScene;
|
Qtk::Scene * mScene;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QTKCLIENT_EXAMPLEWIDGET_H
|
#endif // QTKCLIENT_EXAMPLEWIDGET_H
|
||||||
|
|||||||
6
example-app/resources.h.in
Normal file
6
example-app/resources.h.in
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef QTK_RESOURCES_H_IN_H
|
||||||
|
#define QTK_RESOURCES_H_IN_H
|
||||||
|
|
||||||
|
#define QTK_EXAMPLE_SOURCE_DIR "@CMAKE_SOURCE_DIR@"
|
||||||
|
|
||||||
|
#endif // QTK_RESOURCES_H_IN_H
|
||||||
2
extern/assimp/assimp
vendored
2
extern/assimp/assimp
vendored
Submodule extern/assimp/assimp updated: eb328ce69d...5d5496f1ad
BIN
resources/images/plaster.png
Normal file
BIN
resources/images/plaster.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 MiB |
@@ -1,5 +1,6 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/textures">
|
<qresource prefix="/textures">
|
||||||
|
<file alias="plaster.png">images/plaster.png</file>
|
||||||
<file alias="crate.png">images/crate.png</file>
|
<file alias="crate.png">images/crate.png</file>
|
||||||
<file alias="stone.png">images/stone.png</file>
|
<file alias="stone.png">images/stone.png</file>
|
||||||
<file alias="wood.png">images/wood.png</file>
|
<file alias="wood.png">images/wood.png</file>
|
||||||
|
|||||||
@@ -6,46 +6,67 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# Qtk Library
|
# Qtk Library
|
||||||
|
|
||||||
|
# We always build libqtk since the plugins and GUI both depend on it.
|
||||||
add_subdirectory(qtk)
|
add_subdirectory(qtk)
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
||||||
|
COMPONENT qtk_library
|
||||||
|
DESTINATION lib/cmake/${PROJECT_NAME}
|
||||||
|
)
|
||||||
|
install(
|
||||||
|
EXPORT qtk_export
|
||||||
|
FILE ${PROJECT_NAME}Targets.cmake
|
||||||
|
NAMESPACE ${PROJECT_NAME}::
|
||||||
|
COMPONENT qtk_library
|
||||||
|
DESTINATION lib/cmake/${PROJECT_NAME}
|
||||||
|
)
|
||||||
|
# System install for qtk_library
|
||||||
|
install(
|
||||||
|
TARGETS qtk_library
|
||||||
|
# Associate qtk_library target with qtk-export
|
||||||
|
EXPORT qtk_export
|
||||||
|
COMPONENT qtk_library
|
||||||
|
FILE_SET HEADERS DESTINATION include
|
||||||
|
INCLUDES DESTINATION include
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
ARCHIVE DESTINATION lib
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
)
|
||||||
|
|
||||||
# Qtk Application
|
# Qtk Application
|
||||||
if (QTK_INSTALL_GUI OR QTK_INSTALL_PLUGINS)
|
if(QTK_GUI OR QTK_PLUGINS)
|
||||||
add_subdirectory(app)
|
add_subdirectory(app)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Install custom Qtk plugins for Qt Designer.
|
if(QTK_PLUGINS)
|
||||||
if(QTK_INSTALL_PLUGINS)
|
|
||||||
install(
|
install(
|
||||||
TARGETS qtk_library qtk_plugin_library
|
TARGETS qtk_plugins qtk_library qtk_plugin_library
|
||||||
COMPONENT qtk_collection
|
COMPONENT qtk_plugins
|
||||||
LIBRARY DESTINATION "${QTK_PLUGIN_LIBRARY_DIR}"
|
|
||||||
ARCHIVE DESTINATION "${QTK_PLUGIN_LIBRARY_DIR}"
|
|
||||||
RUNTIME DESTINATION "${QTK_PLUGIN_LIBRARY_DIR}"
|
|
||||||
)
|
|
||||||
install(
|
|
||||||
TARGETS qtk_collection
|
|
||||||
COMPONENT qtk_collection
|
|
||||||
LIBRARY DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
|
LIBRARY DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
|
||||||
ARCHIVE DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
|
ARCHIVE DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
|
||||||
RUNTIME DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
|
RUNTIME DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(QTK_INSTALL_GUI)
|
if(QTK_GUI)
|
||||||
install(
|
install(
|
||||||
TARGETS qtk_main qtk_library
|
TARGETS qtk_gui
|
||||||
COMPONENT qtk
|
COMPONENT qtk_gui
|
||||||
BUNDLE DESTINATION .
|
BUNDLE DESTINATION .
|
||||||
LIBRARY DESTINATION lib
|
LIBRARY DESTINATION lib
|
||||||
ARCHIVE DESTINATION lib/static
|
ARCHIVE DESTINATION lib
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION bin
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_generate_deploy_app_script(
|
qt_generate_deploy_app_script(
|
||||||
TARGET qtk_main
|
TARGET qtk_gui
|
||||||
OUTPUT_SCRIPT QTK_DEPLOY_SCRIPT
|
OUTPUT_SCRIPT QTK_DEPLOY_SCRIPT
|
||||||
NO_UNSUPPORTED_PLATFORM_ERROR
|
NO_UNSUPPORTED_PLATFORM_ERROR
|
||||||
)
|
)
|
||||||
install(SCRIPT ${QTK_DEPLOY_SCRIPT} COMPONENT qtk)
|
install(SCRIPT ${QTK_DEPLOY_SCRIPT} COMPONENT qtk_gui)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
if(MSVC AND TARGET Qt6::qmake)
|
if(MSVC AND TARGET Qt6::qmake)
|
||||||
@@ -58,7 +79,7 @@ if (QTK_INSTALL_GUI OR QTK_INSTALL_PLUGINS)
|
|||||||
)
|
)
|
||||||
file(TO_NATIVE_PATH "${QT6_INSTALL_PREFIX}/bin" QT6_INSTALL_PREFIX)
|
file(TO_NATIVE_PATH "${QT6_INSTALL_PREFIX}/bin" QT6_INSTALL_PREFIX)
|
||||||
|
|
||||||
set(VSUSER_FILE "${CMAKE_CURRENT_BINARY_DIR}/qtk_main.vcxproj.user")
|
set(VSUSER_FILE "${CMAKE_CURRENT_BINARY_DIR}/qtk_gui.vcxproj.user")
|
||||||
file(WRITE ${VSUSER_FILE} "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
file(WRITE ${VSUSER_FILE} "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
||||||
file(APPEND ${VSUSER_FILE} "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n")
|
file(APPEND ${VSUSER_FILE} "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n")
|
||||||
file(APPEND ${VSUSER_FILE} " <PropertyGroup>\n")
|
file(APPEND ${VSUSER_FILE} " <PropertyGroup>\n")
|
||||||
@@ -69,7 +90,6 @@ if (QTK_INSTALL_GUI OR QTK_INSTALL_PLUGINS)
|
|||||||
file(APPEND ${VSUSER_FILE} "</Project>\n")
|
file(APPEND ${VSUSER_FILE} "</Project>\n")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
write_basic_package_version_file(
|
write_basic_package_version_file(
|
||||||
@@ -82,35 +102,6 @@ configure_package_config_file(
|
|||||||
INSTALL_DESTINATION lib/cmake/${PROJECT_NAME}
|
INSTALL_DESTINATION lib/cmake/${PROJECT_NAME}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (QTK_INSTALL_LIB)
|
|
||||||
install(
|
|
||||||
FILES
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
|
||||||
COMPONENT libqtk
|
|
||||||
DESTINATION lib/cmake/${PROJECT_NAME}
|
|
||||||
)
|
|
||||||
install(
|
|
||||||
EXPORT qtk_export
|
|
||||||
FILE ${PROJECT_NAME}Targets.cmake
|
|
||||||
NAMESPACE ${PROJECT_NAME}::
|
|
||||||
COMPONENT libqtk
|
|
||||||
DESTINATION lib/cmake/${PROJECT_NAME}
|
|
||||||
)
|
|
||||||
# System install for qtk_library
|
|
||||||
install(
|
|
||||||
TARGETS qtk_library
|
|
||||||
# Associate qtk_library target with qtk-export
|
|
||||||
EXPORT qtk_export
|
|
||||||
COMPONENT libqtk
|
|
||||||
FILE_SET HEADERS DESTINATION include
|
|
||||||
INCLUDES DESTINATION include
|
|
||||||
LIBRARY DESTINATION lib
|
|
||||||
ARCHIVE DESTINATION lib/static
|
|
||||||
RUNTIME DESTINATION bin
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
||||||
@@ -125,7 +116,7 @@ set(CPACK_THREADS 0)
|
|||||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Qtk")
|
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Qtk")
|
||||||
|
|
||||||
# Remove any assimp components if defined by submodule.
|
# Remove any assimp components if defined by submodule.
|
||||||
if (QTK_UPDATE_SUBMODULES)
|
if (QTK_SUBMODULES)
|
||||||
get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
|
get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
|
||||||
list(FILTER CPACK_COMPONENTS_ALL EXCLUDE REGEX .*assimp.*)
|
list(FILTER CPACK_COMPONENTS_ALL EXCLUDE REGEX .*assimp.*)
|
||||||
list(REMOVE_ITEM CPACK_COMPONENTS_ALL Unspecified)
|
list(REMOVE_ITEM CPACK_COMPONENTS_ALL Unspecified)
|
||||||
@@ -137,26 +128,23 @@ set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
|
|||||||
# https://nsis.sourceforge.io/Reference/CreateShortCut
|
# https://nsis.sourceforge.io/Reference/CreateShortCut
|
||||||
set(
|
set(
|
||||||
CPACK_NSIS_CREATE_ICONS_EXTRA
|
CPACK_NSIS_CREATE_ICONS_EXTRA
|
||||||
"CreateShortCut '$SMPROGRAMS\\$STARTMENU_FOLDER\\Qtk.lnk' '$INSTDIR\\bin\\qtk_main.exe'"
|
"CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Qtk.lnk' '$INSTDIR\\\\bin\\\\qtk_gui.exe'"
|
||||||
)
|
)
|
||||||
set(
|
set(
|
||||||
CPACK_NSIS_DELETE_ICONS_EXTRA
|
CPACK_NSIS_DELETE_ICONS_EXTRA
|
||||||
"Delete '$SMPROGRAMS\\$START_MENU\\Qtk.lnk'"
|
"Delete '$SMPROGRAMS\\\\$START_MENU\\\\Qtk.lnk'"
|
||||||
)
|
)
|
||||||
# TODO: Icons for NSIS installer.
|
# TODO: Icons for NSIS installer.
|
||||||
#set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/resources/icon.png")
|
#set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/resources/icon.png")
|
||||||
#set(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/resources/icon.png")
|
#set(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/resources/icon.png")
|
||||||
|
|
||||||
# Debian
|
# Debian
|
||||||
# TODO: Fix output sharedlib path.
|
|
||||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE ${CPACK_PACKAGE_HOMEPAGE_URL})
|
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE ${CPACK_PACKAGE_HOMEPAGE_URL})
|
||||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||||
#set(CPACK_PACKAGING_INSTALL_PREFIX /usr/local/)
|
|
||||||
|
|
||||||
# OSX
|
# OSX
|
||||||
# TODO: Fix OSX appbundle error.
|
|
||||||
set(CPACK_BUNDLE_NAME ${PROJECT_NAME})
|
set(CPACK_BUNDLE_NAME ${PROJECT_NAME})
|
||||||
set(CPACK_BUNDLE_PLIST $<TARGET_BUNDLE_CONTENT_DIR:qtk_main>/Info.plist)
|
set(CPACK_BUNDLE_PLIST $<TARGET_BUNDLE_CONTENT_DIR:qtk_gui>/Info.plist)
|
||||||
set(CPACK_BUNDLE_ICON ${QTK_OSX_ICONS})
|
set(CPACK_BUNDLE_ICON ${QTK_OSX_ICONS})
|
||||||
|
|
||||||
# Platform defaults for source bundles.
|
# Platform defaults for source bundles.
|
||||||
|
|||||||
@@ -33,39 +33,32 @@ target_sources(
|
|||||||
target_link_libraries(qtk_plugin_library PUBLIC Qt6::UiPlugin qtk_library)
|
target_link_libraries(qtk_plugin_library PUBLIC Qt6::UiPlugin qtk_library)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Qtk Widget Collection Plugin
|
# Qtk Widget Plugins
|
||||||
################################################################################
|
################################################################################
|
||||||
# Create a Qt Designer plugin for a collection of widgets from our library.
|
# Create a Qt Designer plugin for a collection of widgets from our library.
|
||||||
qt_add_plugin(qtk_collection SHARED EXCLUDE_FROM_ALL)
|
qt_add_plugin(qtk_plugins SHARED)
|
||||||
target_sources(
|
target_sources(
|
||||||
qtk_collection PRIVATE
|
qtk_plugins PRIVATE
|
||||||
widgetplugincollection.cpp widgetplugincollection.h
|
widgetplugincollection.cpp widgetplugincollection.h
|
||||||
widgetplugin.cpp widgetplugin.h
|
widgetplugin.cpp widgetplugin.h
|
||||||
)
|
)
|
||||||
target_link_libraries(qtk_collection PUBLIC qtk_plugin_library)
|
target_link_libraries(qtk_plugins PUBLIC qtk_plugin_library)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Final Qtk Application
|
# Final Qtk Application
|
||||||
################################################################################
|
################################################################################
|
||||||
|
# Source files for the main window and core application
|
||||||
set(
|
set(
|
||||||
QTK_APP_SOURCES
|
QTK_GUI_SOURCES
|
||||||
examplescene.cpp examplescene.h
|
qtkscene.cpp qtkscene.h
|
||||||
|
# logger.cpp logger.h
|
||||||
main.cpp
|
main.cpp
|
||||||
)
|
)
|
||||||
|
qt_add_executable(qtk_gui ${QTK_GUI_SOURCES})
|
||||||
qt6_add_big_resources(QTK_APP_SOURCES "${QTK_RESOURCES}/resources.qrc")
|
target_link_libraries(qtk_gui PRIVATE qtk_plugin_library)
|
||||||
configure_file(
|
|
||||||
resources.h.in
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/resources.h"
|
|
||||||
@ONLY
|
|
||||||
)
|
|
||||||
|
|
||||||
qt_add_executable(qtk_main ${QTK_APP_SOURCES})
|
|
||||||
target_link_libraries(qtk_main PRIVATE qtk_plugin_library)
|
|
||||||
|
|
||||||
set_target_properties(
|
set_target_properties(
|
||||||
qtk_main PROPERTIES
|
qtk_gui PROPERTIES
|
||||||
WIN32_EXECUTABLE TRUE
|
WIN32_EXECUTABLE TRUE
|
||||||
MACOSX_BUNDLE TRUE
|
MACOSX_BUNDLE TRUE
|
||||||
MACOSX_BUNDLE_BUNDLE_NAME Qtk
|
MACOSX_BUNDLE_BUNDLE_NAME Qtk
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ DebugConsole::DebugConsole(
|
|||||||
|
|
||||||
auto qtkWidget = dynamic_cast<QtkWidget *>(owner);
|
auto qtkWidget = dynamic_cast<QtkWidget *>(owner);
|
||||||
if(qtkWidget) {
|
if(qtkWidget) {
|
||||||
connect(qtkWidget, &QtkWidget::sendLog, this, &DebugConsole::sendLog);
|
connect(
|
||||||
|
qtkWidget->getLogger(), &Logger::sendLog, this, &DebugConsole::sendLog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ namespace Qtk {
|
|||||||
* @param context The DebugContext to use for the message.
|
* @param context The DebugContext to use for the message.
|
||||||
* Default value is Status.
|
* Default value is Status.
|
||||||
*/
|
*/
|
||||||
inline void sendLog(QString message, DebugContext context = Status) {
|
inline void sendLog(QString message, Qtk::DebugContext context = Status) {
|
||||||
|
// qDebug() << "[LOGGER]: " << qPrintable(message) << "; LOGGER";
|
||||||
mConsole->setTextColor(logColor(context));
|
mConsole->setTextColor(logColor(context));
|
||||||
mConsole->append(logPrefix(message, context));
|
mConsole->append(logPrefix(message, context));
|
||||||
}
|
}
|
||||||
|
|||||||
107
src/app/logger.cpp
Normal file
107
src/app/logger.cpp
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*##############################################################################
|
||||||
|
## Author: Shaun Reed ##
|
||||||
|
## Legal: All Content (c) 2023 Shaun Reed, all rights reserved ##
|
||||||
|
## About: Logger for Qtk ##
|
||||||
|
## ##
|
||||||
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
|
##############################################################################*/
|
||||||
|
|
||||||
|
#include "logger.h"
|
||||||
|
#include "qtkwidget.h"
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
|
Logger::Logger(Qtk::QtkWidget * parent) : QObject(parent) {
|
||||||
|
// connect(
|
||||||
|
// this, SIGNAL(sendLog(QString, Qtk::DebugContext)), this,
|
||||||
|
// SLOT(log(QString, Qtk::DebugContext)));
|
||||||
|
if(parent != Q_NULLPTR) {
|
||||||
|
connect(
|
||||||
|
parent, SIGNAL(sendLog(QString, Qtk::DebugContext)), this,
|
||||||
|
SLOT(log(QString, Qtk::DebugContext)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QString, DebugContext> Logger::log(const QOpenGLDebugMessage & msg) {
|
||||||
|
QString error_msg;
|
||||||
|
DebugContext context;
|
||||||
|
|
||||||
|
// Format based on severity
|
||||||
|
switch(msg.severity()) {
|
||||||
|
case QOpenGLDebugMessage::NotificationSeverity:
|
||||||
|
error_msg += "--";
|
||||||
|
context = Status;
|
||||||
|
break;
|
||||||
|
case QOpenGLDebugMessage::HighSeverity:
|
||||||
|
error_msg += "!!";
|
||||||
|
context = Fatal;
|
||||||
|
break;
|
||||||
|
case QOpenGLDebugMessage::MediumSeverity:
|
||||||
|
error_msg += "!~";
|
||||||
|
context = Error;
|
||||||
|
break;
|
||||||
|
case QOpenGLDebugMessage::LowSeverity:
|
||||||
|
error_msg += "~~";
|
||||||
|
context = Warn;
|
||||||
|
break;
|
||||||
|
case QOpenGLDebugMessage::InvalidSeverity:
|
||||||
|
error_msg += "??";
|
||||||
|
context = Invalid;
|
||||||
|
break;
|
||||||
|
case QOpenGLDebugMessage::AnySeverity:
|
||||||
|
error_msg += "**";
|
||||||
|
context = Any;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_msg += " (";
|
||||||
|
|
||||||
|
// Format based on source
|
||||||
|
#define CASE(c) \
|
||||||
|
case QOpenGLDebugMessage::c: \
|
||||||
|
error_msg += #c; \
|
||||||
|
break
|
||||||
|
switch(msg.source()) {
|
||||||
|
CASE(APISource);
|
||||||
|
CASE(WindowSystemSource);
|
||||||
|
CASE(ShaderCompilerSource);
|
||||||
|
CASE(ThirdPartySource);
|
||||||
|
CASE(ApplicationSource);
|
||||||
|
CASE(OtherSource);
|
||||||
|
CASE(InvalidSource);
|
||||||
|
CASE(AnySource);
|
||||||
|
}
|
||||||
|
#undef CASE
|
||||||
|
|
||||||
|
error_msg += " : ";
|
||||||
|
|
||||||
|
// Format based on type
|
||||||
|
#define CASE(c) \
|
||||||
|
case QOpenGLDebugMessage::c: \
|
||||||
|
error_msg += #c; \
|
||||||
|
break
|
||||||
|
switch(msg.type()) {
|
||||||
|
CASE(InvalidType);
|
||||||
|
CASE(ErrorType);
|
||||||
|
CASE(DeprecatedBehaviorType);
|
||||||
|
CASE(UndefinedBehaviorType);
|
||||||
|
CASE(PortabilityType);
|
||||||
|
CASE(PerformanceType);
|
||||||
|
CASE(OtherType);
|
||||||
|
CASE(MarkerType);
|
||||||
|
CASE(GroupPushType);
|
||||||
|
CASE(GroupPopType);
|
||||||
|
CASE(AnyType);
|
||||||
|
}
|
||||||
|
#undef CASE
|
||||||
|
|
||||||
|
error_msg += ")\n" + msg.message();
|
||||||
|
log(error_msg, context);
|
||||||
|
return {error_msg, context};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::log(const QString & message, DebugContext context) {
|
||||||
|
const QString log_msg = "[LOGGER]: " + message + "; LOGGER";
|
||||||
|
qDebug() << qPrintable(log_msg);
|
||||||
|
emit sendLog(log_msg, context);
|
||||||
|
}
|
||||||
37
src/app/logger.h
Normal file
37
src/app/logger.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*##############################################################################
|
||||||
|
## Author: Shaun Reed ##
|
||||||
|
## Legal: All Content (c) 2023 Shaun Reed, all rights reserved ##
|
||||||
|
## About: Logger for Qtk ##
|
||||||
|
## ##
|
||||||
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
|
##############################################################################*/
|
||||||
|
|
||||||
|
#ifndef QTK_LOGGER_H
|
||||||
|
#define QTK_LOGGER_H
|
||||||
|
|
||||||
|
#include <QOpenGLDebugMessage>
|
||||||
|
#include <QString>
|
||||||
|
#include "qtk/qtkapi.h"
|
||||||
|
namespace Qtk {
|
||||||
|
class QtkWidget;
|
||||||
|
|
||||||
|
class Logger : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Logger(Qtk::QtkWidget * parent = nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
std::pair<QString, DebugContext> log(
|
||||||
|
const QOpenGLDebugMessage & msg);
|
||||||
|
|
||||||
|
void log(
|
||||||
|
const QString & message,
|
||||||
|
Qtk::DebugContext context = Qtk::DebugContext::Status);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sendLog(const QString & message, Qtk::DebugContext context);
|
||||||
|
};
|
||||||
|
} // namespace Qtk
|
||||||
|
|
||||||
|
#endif // QTK_LOGGER_H
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
#include "qtkmainwindow.h"
|
#include "qtkmainwindow.h"
|
||||||
|
#include "qtkscene.h"
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
Q_INIT_RESOURCE(resources);
|
Q_INIT_RESOURCE(resources);
|
||||||
@@ -16,7 +17,12 @@ int main(int argc, char * argv[]) {
|
|||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
auto window = MainWindow::getMainWindow();
|
auto window = MainWindow::getMainWindow();
|
||||||
window->show();
|
|
||||||
|
|
||||||
|
// Qtk currently uses the decorator pattern to save / load scenes.
|
||||||
|
// This is a temporary solution and will be improved in the future.
|
||||||
|
auto emptyScene = new Qtk::SceneEmpty;
|
||||||
|
window->getQtkWidget()->setScene(new QtkScene(emptyScene));
|
||||||
|
|
||||||
|
window->show();
|
||||||
return QApplication::exec();
|
return QApplication::exec();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
#include "qtkmainwindow.h"
|
#include "qtkmainwindow.h"
|
||||||
#include "examplescene.h"
|
#include "qtkscene.h"
|
||||||
#include "ui_qtkmainwindow.h"
|
#include "ui_qtkmainwindow.h"
|
||||||
|
|
||||||
MainWindow * MainWindow::mainWindow_ = Q_NULLPTR;
|
MainWindow * MainWindow::mainWindow_ = Q_NULLPTR;
|
||||||
@@ -27,19 +27,32 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) {
|
|||||||
// Initialize static container for all active QtkWidgets
|
// Initialize static container for all active QtkWidgets
|
||||||
auto qtkWidgets = findChildren<Qtk::QtkWidget *>();
|
auto qtkWidgets = findChildren<Qtk::QtkWidget *>();
|
||||||
for(auto & qtkWidget : qtkWidgets) {
|
for(auto & qtkWidget : qtkWidgets) {
|
||||||
qtkWidget->setScene(new ExampleScene);
|
qtkWidget->setScene(new Qtk::SceneEmpty);
|
||||||
views_.emplace(qtkWidget->getScene()->getSceneName(), qtkWidget);
|
views_.emplace(qtkWidget->getScene()->getSceneName(), qtkWidget);
|
||||||
|
|
||||||
|
// Add GUI 'view' toolbar option to show debug console.
|
||||||
ui_->menuView->addAction(qtkWidget->getActionToggleConsole());
|
ui_->menuView->addAction(qtkWidget->getActionToggleConsole());
|
||||||
|
// Refresh GUI widgets when scene or objects are updated.
|
||||||
connect(
|
connect(
|
||||||
qtkWidget->getScene(), &Qtk::Scene::sceneUpdated, this,
|
qtkWidget->getScene(), &Qtk::Scene::sceneUpdated, this,
|
||||||
&MainWindow::refreshScene);
|
&MainWindow::refreshScene);
|
||||||
|
connect(
|
||||||
|
qtkWidget, &Qtk::QtkWidget::objectFocusChanged, ui_->qtk__ToolBox,
|
||||||
|
&Qtk::ToolBox::updateFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto docks = findChildren<QDockWidget *>();
|
// TODO: Fix / use MainWindow in Qt Designer to add these dock widgets.
|
||||||
for(auto & dock : docks) {
|
// For now we will add them manually, but we should be able to do this in the
|
||||||
addDockWidget(Qt::RightDockWidgetArea, dock);
|
// designer. At the moment if you edit the UI in designer the dock widget
|
||||||
ui_->menuView->addAction(dock->toggleViewAction());
|
// areas below will override the designer settings.
|
||||||
}
|
|
||||||
|
// Dock the toolbox widget to the main window.
|
||||||
|
addDockWidget(Qt::LeftDockWidgetArea, ui_->qtk__ToolBox);
|
||||||
|
// Add an option to toggle active widgets in the GUI's toolbar 'view' menu.
|
||||||
|
ui_->menuView->addAction(ui_->qtk__ToolBox->toggleViewAction());
|
||||||
|
|
||||||
|
addDockWidget(Qt::RightDockWidgetArea, ui_->qtk__TreeView);
|
||||||
|
ui_->menuView->addAction(ui_->qtk__TreeView->toggleViewAction());
|
||||||
|
|
||||||
// Set the window icon used for Qtk.
|
// Set the window icon used for Qtk.
|
||||||
setWindowIcon(Qtk::getIcon());
|
setWindowIcon(Qtk::getIcon());
|
||||||
@@ -60,6 +73,13 @@ MainWindow * MainWindow::getMainWindow() {
|
|||||||
return mainWindow_;
|
return mainWindow_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qtk::QtkWidget * MainWindow::getQtkWidget(int64_t index) {
|
||||||
|
if(views_.size() <= index) {
|
||||||
|
return Q_NULLPTR;
|
||||||
|
}
|
||||||
|
return views_.begin(index)->second;
|
||||||
|
}
|
||||||
|
|
||||||
Qtk::QtkWidget * MainWindow::getQtkWidget(const QString & name) {
|
Qtk::QtkWidget * MainWindow::getQtkWidget(const QString & name) {
|
||||||
if(!views_.count(name)) {
|
if(!views_.count(name)) {
|
||||||
return Q_NULLPTR;
|
return Q_NULLPTR;
|
||||||
@@ -67,7 +87,7 @@ Qtk::QtkWidget * MainWindow::getQtkWidget(const QString & name) {
|
|||||||
return views_[name];
|
return views_[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refreshScene(QString sceneName) {
|
void MainWindow::refreshScene(const QString & sceneName) {
|
||||||
// TODO: Select TreeView using sceneName>
|
// TODO: Select TreeView using sceneName
|
||||||
ui_->qtk__TreeView->updateView(getQtkWidget(sceneName)->getScene());
|
ui_->qtk__TreeView->updateView(getQtkWidget()->getScene());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ class MainWindow : public QMainWindow {
|
|||||||
*/
|
*/
|
||||||
static MainWindow * getMainWindow();
|
static MainWindow * getMainWindow();
|
||||||
|
|
||||||
|
Qtk::QtkWidget * getQtkWidget(int64_t index = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accessor for retrieving a QtkWidget by it's objectName.
|
* Accessor for retrieving a QtkWidget by it's objectName.
|
||||||
* This function will not construct a new QtkWidget if none is found.
|
* This function will not construct a new QtkWidget if none is found.
|
||||||
@@ -67,7 +69,7 @@ class MainWindow : public QMainWindow {
|
|||||||
* Trigger a refresh for widgets related to a scene that has been updated.
|
* Trigger a refresh for widgets related to a scene that has been updated.
|
||||||
* @param sceneName The name of the scene that has been modified.
|
* @param sceneName The name of the scene that has been modified.
|
||||||
*/
|
*/
|
||||||
void refreshScene(QString sceneName);
|
void refreshScene(const QString & sceneName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>824</width>
|
<width>1034</width>
|
||||||
<height>601</height>
|
<height>601</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@@ -28,11 +28,27 @@
|
|||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="Qtk::ToolBox" name="qtk::ToolBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Object details and configuration panel.</string>
|
||||||
|
</property>
|
||||||
|
<property name="whatsThis">
|
||||||
|
<string>When an object is double-clicked in the TreeView for a scene, this panel will display relevant details and options.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>3</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
@@ -50,10 +66,10 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="Qtk::QtkWidget" name="qtk::QtkWidget">
|
<widget class="Qtk::QtkWidget" name="qtk::QtkWidget">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>A custom widget tool tip.</string>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="whatsThis">
|
<property name="whatsThis">
|
||||||
<string>Custom widget what's this?</string>
|
<string>Qtk scene view rendered using OpenGL.</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -66,30 +82,22 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="Qtk::TreeView" name="qtk::TreeView">
|
<widget class="Qtk::TreeView" name="qtk::TreeView">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>A custom widget tool tip.</string>
|
<string>TreeView of objects within the current scene.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="whatsThis">
|
<property name="whatsThis">
|
||||||
<string>Custom widget what's this?</string>
|
<string>TreeView of objects within the current scene. Double-click to select an object and snap to it's position.</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="Qtk::ToolBox" name="qtk::ToolBox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>A custom widget tool tip.</string>
|
|
||||||
</property>
|
|
||||||
<property name="whatsThis">
|
|
||||||
<string>Custom widget what's this?</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenuBar" name="menubar">
|
<widget class="QMenuBar" name="menubar">
|
||||||
@@ -97,7 +105,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>824</width>
|
<width>1034</width>
|
||||||
<height>22</height>
|
<height>22</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@@ -179,7 +187,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<action name="actionOpen">
|
<action name="actionOpen">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../resources/resources.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</iconset>
|
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -188,7 +196,7 @@
|
|||||||
</action>
|
</action>
|
||||||
<action name="actionSave">
|
<action name="actionSave">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../resources/resources.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</iconset>
|
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -215,7 +223,7 @@
|
|||||||
</action>
|
</action>
|
||||||
<action name="actionLoad_Model">
|
<action name="actionLoad_Model">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../resources/resources.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</iconset>
|
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -227,7 +235,7 @@
|
|||||||
</action>
|
</action>
|
||||||
<action name="actionDelete_Object">
|
<action name="actionDelete_Object">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../resources/resources.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</iconset>
|
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -318,9 +326,7 @@
|
|||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources/>
|
||||||
<include location="../../resources/resources.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>actionExit</sender>
|
<sender>actionExit</sender>
|
||||||
|
|||||||
@@ -6,8 +6,7 @@
|
|||||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
#include "examplescene.h"
|
#include "qtkscene.h"
|
||||||
#include "resources.h"
|
|
||||||
|
|
||||||
using namespace Qtk;
|
using namespace Qtk;
|
||||||
|
|
||||||
@@ -15,13 +14,14 @@ using namespace Qtk;
|
|||||||
* Constructors, Destructors
|
* Constructors, Destructors
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
ExampleScene::ExampleScene() {
|
QtkScene::QtkScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) {
|
||||||
setSceneName("Example Scene");
|
setSceneName("Qtk Scene");
|
||||||
getCamera().getTransform().setTranslation(0.0f, 0.0f, 20.0f);
|
getCamera().setTranslation({0.0f, 0.0f, 20.0f});
|
||||||
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
getCamera().setRotation(
|
||||||
|
QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -5.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
ExampleScene::~ExampleScene() {
|
QtkScene::~QtkScene() {
|
||||||
delete mTestPhong;
|
delete mTestPhong;
|
||||||
delete mTestSpecular;
|
delete mTestSpecular;
|
||||||
delete mTestDiffuse;
|
delete mTestDiffuse;
|
||||||
@@ -32,18 +32,19 @@ ExampleScene::~ExampleScene() {
|
|||||||
* Public Member Functions
|
* Public Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void ExampleScene::init() {
|
void QtkScene::init() {
|
||||||
// Add a skybox to the scene using default cube map images and settings.
|
// Add a skybox to the scene using default cube map images and settings.
|
||||||
setSkybox(new Qtk::Skybox("Skybox"));
|
setSkybox(new Qtk::Skybox("Skybox"));
|
||||||
|
|
||||||
/* Create a red cube with a mini master chief on top. */
|
/* Create a red cube with a mini master chief on top. */
|
||||||
auto myCube = new MeshRenderer("My cube", Cube(Qtk::QTK_DRAW_ELEMENTS));
|
auto myCube = new MeshRenderer("My cube", Cube(Qtk::QTK_DRAW_ELEMENTS));
|
||||||
myCube->setColor(RED);
|
myCube->setColor(RED);
|
||||||
|
myCube->getTransform().setTranslation(5.0f, 0.0f, 0.0f);
|
||||||
addObject(myCube);
|
addObject(myCube);
|
||||||
|
|
||||||
auto mySpartan =
|
auto mySpartan =
|
||||||
new Model("My spartan", ":/models/models/spartan/spartan.obj");
|
new Model("My spartan", ":/models/models/spartan/spartan.obj");
|
||||||
mySpartan->getTransform().setTranslation(0.0f, 0.5f, 0.0f);
|
mySpartan->getTransform().setTranslation(5.0f, 0.5f, 0.0f);
|
||||||
mySpartan->getTransform().setScale(0.5f);
|
mySpartan->getTransform().setScale(0.5f);
|
||||||
addObject(mySpartan);
|
addObject(mySpartan);
|
||||||
|
|
||||||
@@ -89,18 +90,18 @@ void ExampleScene::init() {
|
|||||||
model->getTransform().setTranslation(2.0f, 2.0f, -10.0f);
|
model->getTransform().setTranslation(2.0f, 2.0f, -10.0f);
|
||||||
// Sometimes the models are very large
|
// Sometimes the models are very large
|
||||||
model->getTransform().scale(0.0025f);
|
model->getTransform().scale(0.0025f);
|
||||||
model->getTransform().rotate(-110.0f, 0.0f, 1.0f, 0.0f);
|
model->getTransform().rotate(0.0f, 1.0f, 0.0f, -110.0f);
|
||||||
|
|
||||||
model = addObject(
|
model = addObject(
|
||||||
new Qtk::Model("alien", ":/models/models/alien-hominid/alien.obj"));
|
new Qtk::Model("alien", ":/models/models/alien-hominid/alien.obj"));
|
||||||
model->getTransform().setTranslation(2.0f, -1.0f, -5.0f);
|
model->getTransform().setTranslation(2.0f, -1.0f, -5.0f);
|
||||||
model->getTransform().scale(0.15f);
|
model->getTransform().scale(0.15f);
|
||||||
|
|
||||||
model =
|
model = addObject(
|
||||||
addObject(new Qtk::Model("scythe", ":/models/models/scythe/scythe.obj"));
|
new Qtk::Model("My scythe", ":/models/models/scythe/scythe.obj"));
|
||||||
model->getTransform().setTranslation(-6.0f, 0.0f, -10.0f);
|
model->getTransform().setTranslation(-6.0f, 0.0f, -10.0f);
|
||||||
model->getTransform().rotate(-90.0f, 1.0f, 0.0f, 0.0f);
|
model->getTransform().rotate(1.0f, 0.0f, 0.0f, -90.0f);
|
||||||
model->getTransform().rotate(90.0f, 0.0f, 1.0f, 0.0f);
|
model->getTransform().rotate(0.0f, 1.0f, 0.0f, 90.0f);
|
||||||
|
|
||||||
model = addObject(
|
model = addObject(
|
||||||
new Qtk::Model("masterChief", ":/models/models/spartan/spartan.obj"));
|
new Qtk::Model("masterChief", ":/models/models/spartan/spartan.obj"));
|
||||||
@@ -331,14 +332,14 @@ void ExampleScene::init() {
|
|||||||
mesh->reallocateNormals(mesh->getNormals());
|
mesh->reallocateNormals(mesh->getNormals());
|
||||||
mesh->reallocateTexCoords(mesh->getTexCoords(), 3);
|
mesh->reallocateTexCoords(mesh->getTexCoords(), 3);
|
||||||
mesh->releaseShaders();
|
mesh->releaseShaders();
|
||||||
mesh->getTransform().rotate(45.0f, 0.0f, 1.0f, 0.0f);
|
mesh->getTransform().rotate(0.0f, 1.0f, 0.0f, 45.0f);
|
||||||
|
|
||||||
// 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
|
||||||
mesh =
|
mesh =
|
||||||
addObject(new Qtk::MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS)));
|
addObject(new Qtk::MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS)));
|
||||||
mesh->getTransform().setTranslation(-3.0f, 1.0f, -2.0f);
|
mesh->getTransform().setTranslation(-3.0f, 1.0f, -2.0f);
|
||||||
mesh->getTransform().setRotation(45.0f, 0.0f, 1.0f, 0.0f);
|
mesh->getTransform().setRotation(0.0f, 1.0f, 0.0f, 45.0f);
|
||||||
mesh->setShaders(
|
mesh->setShaders(
|
||||||
":/shaders/texture-cubemap.vert", ":/shaders/texture-cubemap.frag");
|
":/shaders/texture-cubemap.vert", ":/shaders/texture-cubemap.frag");
|
||||||
mesh->setCubeMap(":/textures/crate.png");
|
mesh->setCubeMap(":/textures/crate.png");
|
||||||
@@ -387,19 +388,11 @@ void ExampleScene::init() {
|
|||||||
mesh->reallocateTexCoords(mesh->getTexCoords());
|
mesh->reallocateTexCoords(mesh->getTexCoords());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExampleScene::draw() {
|
void QtkScene::draw() {
|
||||||
// WARNING: We must call the base class draw() function first.
|
// WARNING: We must call the base class draw() function first.
|
||||||
// + This will handle rendering core scene components like the Skybox.
|
// + This will handle rendering core scene components like the Skybox.
|
||||||
Scene::draw();
|
Scene::draw();
|
||||||
|
|
||||||
for(const auto & model : getModels()) {
|
|
||||||
model->draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(const auto & mesh : getMeshes()) {
|
|
||||||
mesh->draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
mTestPhong->bindShaders();
|
mTestPhong->bindShaders();
|
||||||
mTestPhong->setUniform(
|
mTestPhong->setUniform(
|
||||||
"uModelInverseTransposed",
|
"uModelInverseTransposed",
|
||||||
@@ -408,15 +401,13 @@ void ExampleScene::draw() {
|
|||||||
"uLightPosition",
|
"uLightPosition",
|
||||||
MeshRenderer::getInstance("phongLight")->getTransform().getTranslation());
|
MeshRenderer::getInstance("phongLight")->getTransform().getTranslation());
|
||||||
mTestPhong->setUniform(
|
mTestPhong->setUniform(
|
||||||
"uCameraPosition",
|
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
||||||
ExampleScene::getCamera().getTransform().getTranslation());
|
|
||||||
mTestPhong->releaseShaders();
|
mTestPhong->releaseShaders();
|
||||||
mTestPhong->draw();
|
mTestPhong->draw();
|
||||||
|
|
||||||
mTestAmbient->bindShaders();
|
mTestAmbient->bindShaders();
|
||||||
mTestAmbient->setUniform(
|
mTestAmbient->setUniform(
|
||||||
"uCameraPosition",
|
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
||||||
ExampleScene::getCamera().getTransform().getTranslation());
|
|
||||||
mTestAmbient->releaseShaders();
|
mTestAmbient->releaseShaders();
|
||||||
mTestAmbient->draw();
|
mTestAmbient->draw();
|
||||||
|
|
||||||
@@ -429,8 +420,7 @@ void ExampleScene::draw() {
|
|||||||
->getTransform()
|
->getTransform()
|
||||||
.getTranslation());
|
.getTranslation());
|
||||||
mTestDiffuse->setUniform(
|
mTestDiffuse->setUniform(
|
||||||
"uCameraPosition",
|
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
||||||
ExampleScene::getCamera().getTransform().getTranslation());
|
|
||||||
mTestDiffuse->releaseShaders();
|
mTestDiffuse->releaseShaders();
|
||||||
mTestDiffuse->draw();
|
mTestDiffuse->draw();
|
||||||
|
|
||||||
@@ -443,18 +433,17 @@ void ExampleScene::draw() {
|
|||||||
->getTransform()
|
->getTransform()
|
||||||
.getTranslation());
|
.getTranslation());
|
||||||
mTestSpecular->setUniform(
|
mTestSpecular->setUniform(
|
||||||
"uCameraPosition",
|
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
||||||
ExampleScene::getCamera().getTransform().getTranslation());
|
|
||||||
mTestSpecular->releaseShaders();
|
mTestSpecular->releaseShaders();
|
||||||
mTestSpecular->draw();
|
mTestSpecular->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExampleScene::update() {
|
void QtkScene::update() {
|
||||||
auto mySpartan = Model::getInstance("My spartan");
|
auto mySpartan = Model::getInstance("My spartan");
|
||||||
mySpartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
mySpartan->getTransform().rotate(0.0f, 1.0f, 0.0f, 0.75f);
|
||||||
|
|
||||||
auto myCube = MeshRenderer::getInstance("My cube");
|
auto myCube = MeshRenderer::getInstance("My cube");
|
||||||
myCube->getTransform().rotate(-0.75f, 0.0f, 1.0f, 0.0f);
|
myCube->getTransform().rotate(-0.0f, 1.0f, 0.0f, 0.75f);
|
||||||
|
|
||||||
auto position = MeshRenderer::getInstance("alienTestLight")
|
auto position = MeshRenderer::getInstance("alienTestLight")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
@@ -462,14 +451,13 @@ void ExampleScene::update() {
|
|||||||
auto alien = Model::getInstance("alienTest");
|
auto alien = Model::getInstance("alienTest");
|
||||||
alien->setUniform("uLight.position", position);
|
alien->setUniform("uLight.position", position);
|
||||||
alien->setUniform(
|
alien->setUniform(
|
||||||
"uCameraPosition",
|
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
||||||
ExampleScene::getCamera().getTransform().getTranslation());
|
|
||||||
auto posMatrix = alien->getTransform().toMatrix();
|
auto posMatrix = alien->getTransform().toMatrix();
|
||||||
alien->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
alien->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||||
alien->setUniform("uMVP.model", posMatrix);
|
alien->setUniform("uMVP.model", posMatrix);
|
||||||
alien->setUniform("uMVP.view", ExampleScene::getCamera().toMatrix());
|
alien->setUniform("uMVP.view", QtkScene::getCamera().toMatrix());
|
||||||
alien->setUniform("uMVP.projection", ExampleScene::getProjectionMatrix());
|
alien->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
|
||||||
alien->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
alien->getTransform().rotate(0.0f, 1.0f, 0.0f, 0.75f);
|
||||||
|
|
||||||
position = MeshRenderer::getInstance("spartanTestLight")
|
position = MeshRenderer::getInstance("spartanTestLight")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
@@ -477,53 +465,51 @@ void ExampleScene::update() {
|
|||||||
auto spartan = Model::getInstance("spartanTest");
|
auto spartan = Model::getInstance("spartanTest");
|
||||||
spartan->setUniform("uLight.position", position);
|
spartan->setUniform("uLight.position", position);
|
||||||
spartan->setUniform(
|
spartan->setUniform(
|
||||||
"uCameraPosition",
|
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
||||||
ExampleScene::getCamera().getTransform().getTranslation());
|
|
||||||
posMatrix = spartan->getTransform().toMatrix();
|
posMatrix = spartan->getTransform().toMatrix();
|
||||||
spartan->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
spartan->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||||
spartan->setUniform("uMVP.model", posMatrix);
|
spartan->setUniform("uMVP.model", posMatrix);
|
||||||
spartan->setUniform("uMVP.view", ExampleScene::getCamera().toMatrix());
|
spartan->setUniform("uMVP.view", QtkScene::getCamera().toMatrix());
|
||||||
spartan->setUniform("uMVP.projection", ExampleScene::getProjectionMatrix());
|
spartan->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
|
||||||
spartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
spartan->getTransform().rotate(0.0f, 1.0f, 0.0f, 0.75f);
|
||||||
|
|
||||||
auto phong = MeshRenderer::getInstance("testPhong");
|
auto phong = MeshRenderer::getInstance("testPhong");
|
||||||
phong->getTransform().rotate(0.75f, 1.0f, 0.5f, 0.0f);
|
phong->getTransform().rotate(1.0f, 0.5f, 0.0f, 0.75f);
|
||||||
phong->bindShaders();
|
phong->bindShaders();
|
||||||
position =
|
position =
|
||||||
MeshRenderer::getInstance("testLight")->getTransform().getTranslation();
|
MeshRenderer::getInstance("testLight")->getTransform().getTranslation();
|
||||||
phong->setUniform("uLight.position", position);
|
phong->setUniform("uLight.position", position);
|
||||||
phong->setUniform(
|
phong->setUniform(
|
||||||
"uCameraPosition",
|
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
||||||
ExampleScene::getCamera().getTransform().getTranslation());
|
|
||||||
posMatrix = phong->getTransform().toMatrix();
|
posMatrix = phong->getTransform().toMatrix();
|
||||||
phong->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
phong->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||||
phong->setUniform("uMVP.model", posMatrix);
|
phong->setUniform("uMVP.model", posMatrix);
|
||||||
phong->setUniform("uMVP.view", ExampleScene::getCamera().toMatrix());
|
phong->setUniform("uMVP.view", QtkScene::getCamera().toMatrix());
|
||||||
phong->setUniform("uMVP.projection", ExampleScene::getProjectionMatrix());
|
phong->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
|
||||||
phong->releaseShaders();
|
phong->releaseShaders();
|
||||||
|
|
||||||
// Rotate lighting example cubes
|
// Rotate lighting example cubes
|
||||||
mTestPhong->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
|
mTestPhong->getTransform().rotate(0.5f, 0.3f, 0.2f, 0.75f);
|
||||||
MeshRenderer::getInstance("noLight")->getTransform().rotate(
|
MeshRenderer::getInstance("noLight")->getTransform().rotate(
|
||||||
0.75f, 0.5f, 0.3f, 0.2f);
|
0.5f, 0.3f, 0.2f, 0.75f);
|
||||||
mTestAmbient->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
|
mTestAmbient->getTransform().rotate(0.5f, 0.3f, 0.2f, 0.75f);
|
||||||
mTestDiffuse->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
|
mTestDiffuse->getTransform().rotate(0.5f, 0.3f, 0.2f, 0.75f);
|
||||||
mTestSpecular->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
|
mTestSpecular->getTransform().rotate(0.5f, 0.3f, 0.2f, 0.75f);
|
||||||
|
|
||||||
// Examples of various translations and rotations
|
// Examples of various translations and rotations
|
||||||
|
|
||||||
// Rotate in multiple directions simultaneously
|
// Rotate in multiple directions simultaneously
|
||||||
MeshRenderer::getInstance("rgbNormalsCube")
|
MeshRenderer::getInstance("rgbNormalsCube")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 0.2f, 0.4f, 0.6f);
|
.rotate(0.2f, 0.4f, 0.6f, 0.75f);
|
||||||
|
|
||||||
// Pitch forward and roll sideways
|
// Pitch forward and roll sideways
|
||||||
MeshRenderer::getInstance("leftTriangle")
|
MeshRenderer::getInstance("leftTriangle")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 1.0f, 0.0f, 0.0f);
|
.rotate(1.0f, 0.0f, 0.0f, 0.75f);
|
||||||
MeshRenderer::getInstance("rightTriangle")
|
MeshRenderer::getInstance("rightTriangle")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 0.0f, 0.0f, 1.0f);
|
.rotate(0.0f, 0.0f, 1.0f, 0.75f);
|
||||||
|
|
||||||
// Move between two positions over time
|
// Move between two positions over time
|
||||||
static float translateX = 0.025f;
|
static float translateX = 0.025f;
|
||||||
@@ -544,15 +530,15 @@ void ExampleScene::update() {
|
|||||||
// And lets rotate the triangles in two directions at once
|
// And lets rotate the triangles in two directions at once
|
||||||
MeshRenderer::getInstance("topTriangle")
|
MeshRenderer::getInstance("topTriangle")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 0.2f, 0.0f, 0.4f);
|
.rotate(0.2f, 0.0f, 0.4f, 0.75f);
|
||||||
MeshRenderer::getInstance("bottomTriangle")
|
MeshRenderer::getInstance("bottomTriangle")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 0.0f, 0.2f, 0.4f);
|
.rotate(0.0f, 0.2f, 0.4f, 0.75f);
|
||||||
// And make the bottom triangle green, instead of RGB
|
// And make the bottom triangle green, instead of RGB
|
||||||
|
|
||||||
// Rotate center cube in several directions simultaneously
|
// Rotate center cube in several directions simultaneously
|
||||||
// + Not subject to gimbal lock since we are using quaternions :)
|
// + Not subject to gimbal lock since we are using quaternions :)
|
||||||
MeshRenderer::getInstance("centerCube")
|
MeshRenderer::getInstance("centerCube")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 0.2f, 0.4f, 0.6f);
|
.rotate(0.2f, 0.4f, 0.6f, 0.75f);
|
||||||
}
|
}
|
||||||
@@ -29,15 +29,15 @@
|
|||||||
*
|
*
|
||||||
* To create your own Scene from scratch see Qtk::Scene.
|
* To create your own Scene from scratch see Qtk::Scene.
|
||||||
*/
|
*/
|
||||||
class ExampleScene : public Qtk::Scene {
|
class QtkScene : public Qtk::SceneInterface {
|
||||||
public:
|
public:
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Contructors / Destructors
|
* Contructors / Destructors
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
ExampleScene();
|
QtkScene(Qtk::Scene * scene);
|
||||||
|
|
||||||
~ExampleScene();
|
~QtkScene();
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Inherited Public Overrides
|
* Inherited Public Overrides
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
#include <QMimeData>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#include <qtk/input.h>
|
#include <qtk/input.h>
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
#include <qtk/shape.h>
|
#include <qtk/shape.h>
|
||||||
|
|
||||||
#include "debugconsole.h"
|
#include "debugconsole.h"
|
||||||
|
#include "qtk/qtkmessagelogger.h"
|
||||||
#include "qtkmainwindow.h"
|
#include "qtkmainwindow.h"
|
||||||
#include "qtkwidget.h"
|
#include "qtkwidget.h"
|
||||||
|
|
||||||
@@ -29,8 +31,10 @@ QtkWidget::QtkWidget(QWidget * parent, const QString & name) :
|
|||||||
QtkWidget(parent, name, Q_NULLPTR) {}
|
QtkWidget(parent, name, Q_NULLPTR) {}
|
||||||
|
|
||||||
QtkWidget::QtkWidget(QWidget * parent, const QString & name, Scene * scene) :
|
QtkWidget::QtkWidget(QWidget * parent, const QString & name, Scene * scene) :
|
||||||
QOpenGLWidget(parent), mDebugLogger(Q_NULLPTR),
|
QOpenGLWidget(parent), mDebugLogger(new QOpenGLDebugLogger(this)),
|
||||||
mConsole(new DebugConsole(this, name)), mScene(Q_NULLPTR) {
|
mConsole(new DebugConsole(this, name)), mScene(Q_NULLPTR),
|
||||||
|
mLogger(new Qtk::Logger(this)) {
|
||||||
|
setAcceptDrops(true);
|
||||||
setScene(scene);
|
setScene(scene);
|
||||||
setObjectName(name);
|
setObjectName(name);
|
||||||
QSurfaceFormat format;
|
QSurfaceFormat format;
|
||||||
@@ -70,14 +74,22 @@ void QtkWidget::initializeGL() {
|
|||||||
// Connect the frameSwapped signal to call the update() function
|
// Connect the frameSwapped signal to call the update() function
|
||||||
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
||||||
|
|
||||||
|
toggleConsole();
|
||||||
// Initialize OpenGL debug context
|
// Initialize OpenGL debug context
|
||||||
mDebugLogger = new QOpenGLDebugLogger(this);
|
|
||||||
if(mDebugLogger->initialize()) {
|
if(mDebugLogger->initialize()) {
|
||||||
qDebug() << "GL_DEBUG Debug Logger" << mDebugLogger << "\n";
|
|
||||||
connect(
|
connect(
|
||||||
mDebugLogger, SIGNAL(messageLogged(QOpenGLDebugMessage)), this,
|
mDebugLogger, SIGNAL(messageLogged(QOpenGLDebugMessage)), mLogger,
|
||||||
SLOT(messageLogged(QOpenGLDebugMessage)));
|
SLOT(log(QOpenGLDebugMessage)));
|
||||||
|
// connect(
|
||||||
|
// Qtk::QtkMessageLogger::get(),
|
||||||
|
// &Qtk::QtkMessageLogger::messageLogged, mLogger,
|
||||||
|
// &Qtk::Logger::parseError);
|
||||||
mDebugLogger->startLogging();
|
mDebugLogger->startLogging();
|
||||||
|
QString msg;
|
||||||
|
QTextStream stream(&msg);
|
||||||
|
stream << "Logging started on GL_DEBUG Debug Logger: " << mDebugLogger;
|
||||||
|
mDebugLogger->logMessage(QOpenGLDebugMessage::createApplicationMessage(
|
||||||
|
stream.string()->toStdString().c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
printContextInformation();
|
printContextInformation();
|
||||||
@@ -107,8 +119,14 @@ void QtkWidget::paintGL() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::setScene(Qtk::Scene * scene) {
|
void QtkWidget::setScene(Scene * scene) {
|
||||||
|
if(mScene != Q_NULLPTR) {
|
||||||
delete mScene;
|
delete mScene;
|
||||||
|
connect(
|
||||||
|
scene, &Scene::sceneUpdated, MainWindow::getMainWindow(),
|
||||||
|
&MainWindow::refreshScene);
|
||||||
|
}
|
||||||
|
|
||||||
mScene = scene;
|
mScene = scene;
|
||||||
if(mScene != Q_NULLPTR) {
|
if(mScene != Q_NULLPTR) {
|
||||||
mConsole->setTitle(mScene->getSceneName());
|
mConsole->setTitle(mScene->getSceneName());
|
||||||
@@ -123,8 +141,7 @@ void QtkWidget::toggleConsole() {
|
|||||||
mConsoleActive = false;
|
mConsoleActive = false;
|
||||||
} else {
|
} else {
|
||||||
MainWindow::getMainWindow()->addDockWidget(
|
MainWindow::getMainWindow()->addDockWidget(
|
||||||
Qt::DockWidgetArea::BottomDockWidgetArea,
|
Qt::DockWidgetArea::BottomDockWidgetArea, mConsole);
|
||||||
dynamic_cast<QDockWidget *>(mConsole));
|
|
||||||
mConsole->setHidden(false);
|
mConsole->setHidden(false);
|
||||||
mConsoleActive = true;
|
mConsoleActive = true;
|
||||||
}
|
}
|
||||||
@@ -134,6 +151,34 @@ void QtkWidget::toggleConsole() {
|
|||||||
* Protected Methods
|
* Protected Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
void QtkWidget::dragEnterEvent(QDragEnterEvent * event) {
|
||||||
|
if(event->mimeData()->hasFormat("text/plain")) {
|
||||||
|
event->acceptProposedAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtkWidget::dropEvent(QDropEvent * event) {
|
||||||
|
mConsole->sendLog(event->mimeData()->text());
|
||||||
|
auto urls = event->mimeData()->urls();
|
||||||
|
if(!urls.isEmpty()) {
|
||||||
|
if(urls.size() > 1) {
|
||||||
|
qDebug() << "Cannot accept drop of multiple files.";
|
||||||
|
event->ignore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Support other object types.
|
||||||
|
auto url = urls.front();
|
||||||
|
if(url.fileName().endsWith(".obj")) {
|
||||||
|
mScene->loadModel(url);
|
||||||
|
event->acceptProposedAction();
|
||||||
|
} else {
|
||||||
|
qDebug() << "Unsupported file type: " + url.fileName() + "\n";
|
||||||
|
event->ignore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QtkWidget::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
|
||||||
@@ -169,74 +214,6 @@ void QtkWidget::update() {
|
|||||||
QWidget::update();
|
QWidget::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::messageLogged(const QOpenGLDebugMessage & msg) {
|
|
||||||
QString error;
|
|
||||||
|
|
||||||
DebugContext context;
|
|
||||||
// Format based on severity
|
|
||||||
switch(msg.severity()) {
|
|
||||||
case QOpenGLDebugMessage::NotificationSeverity:
|
|
||||||
error += "--";
|
|
||||||
context = Status;
|
|
||||||
break;
|
|
||||||
case QOpenGLDebugMessage::HighSeverity:
|
|
||||||
error += "!!";
|
|
||||||
context = Fatal;
|
|
||||||
break;
|
|
||||||
case QOpenGLDebugMessage::MediumSeverity:
|
|
||||||
error += "!~";
|
|
||||||
context = Error;
|
|
||||||
break;
|
|
||||||
case QOpenGLDebugMessage::LowSeverity:
|
|
||||||
error += "~~";
|
|
||||||
context = Warn;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
error += " (";
|
|
||||||
|
|
||||||
// Format based on source
|
|
||||||
#define CASE(c) \
|
|
||||||
case QOpenGLDebugMessage::c: \
|
|
||||||
error += #c; \
|
|
||||||
break
|
|
||||||
switch(msg.source()) {
|
|
||||||
CASE(APISource);
|
|
||||||
CASE(WindowSystemSource);
|
|
||||||
CASE(ShaderCompilerSource);
|
|
||||||
CASE(ThirdPartySource);
|
|
||||||
CASE(ApplicationSource);
|
|
||||||
CASE(OtherSource);
|
|
||||||
CASE(InvalidSource);
|
|
||||||
}
|
|
||||||
#undef CASE
|
|
||||||
|
|
||||||
error += " : ";
|
|
||||||
|
|
||||||
// Format based on type
|
|
||||||
#define CASE(c) \
|
|
||||||
case QOpenGLDebugMessage::c: \
|
|
||||||
error += #c; \
|
|
||||||
break
|
|
||||||
switch(msg.type()) {
|
|
||||||
CASE(InvalidType);
|
|
||||||
CASE(ErrorType);
|
|
||||||
CASE(DeprecatedBehaviorType);
|
|
||||||
CASE(UndefinedBehaviorType);
|
|
||||||
CASE(PortabilityType);
|
|
||||||
CASE(PerformanceType);
|
|
||||||
CASE(OtherType);
|
|
||||||
CASE(MarkerType);
|
|
||||||
CASE(GroupPushType);
|
|
||||||
CASE(GroupPopType);
|
|
||||||
}
|
|
||||||
#undef CASE
|
|
||||||
|
|
||||||
error += ")\n" + msg.message() + "\n";
|
|
||||||
qDebug() << qPrintable(error);
|
|
||||||
sendLog("(OpenGL) " + error.replace("\n", "\n(OpenGL) "), context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Private Methods
|
* Private Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@@ -247,15 +224,16 @@ void QtkWidget::teardownGL() { /* Nothing to teardown yet... */
|
|||||||
void QtkWidget::updateCameraInput() {
|
void QtkWidget::updateCameraInput() {
|
||||||
Input::update();
|
Input::update();
|
||||||
// Camera Transformation
|
// Camera Transformation
|
||||||
if(Input::buttonPressed(Qt::RightButton)) {
|
if(Input::buttonPressed(Qt::LeftButton)
|
||||||
|
|| Input::buttonPressed(Qt::RightButton)) {
|
||||||
static const float transSpeed = 0.1f;
|
static const float transSpeed = 0.1f;
|
||||||
static const float rotSpeed = 0.5f;
|
static const float rotSpeed = 0.5f;
|
||||||
|
|
||||||
// Handle rotations
|
// Handle rotations
|
||||||
Scene::getCamera().getTransform().rotate(
|
Scene::getCamera().rotate(QQuaternion::fromAxisAndAngle(
|
||||||
-rotSpeed * Input::mouseDelta().x(), Camera3D::LocalUp);
|
Camera3D::LocalUp, -rotSpeed * Input::mouseDelta().x()));
|
||||||
Scene::getCamera().getTransform().rotate(
|
Scene::getCamera().rotate(QQuaternion::fromAxisAndAngle(
|
||||||
-rotSpeed * Input::mouseDelta().y(), Scene::getCamera().getRight());
|
Scene::getCamera().getRight(), -rotSpeed * Input::mouseDelta().y()));
|
||||||
|
|
||||||
// Handle translations
|
// Handle translations
|
||||||
QVector3D translation;
|
QVector3D translation;
|
||||||
@@ -277,7 +255,7 @@ void QtkWidget::updateCameraInput() {
|
|||||||
if(Input::keyPressed(Qt::Key_E)) {
|
if(Input::keyPressed(Qt::Key_E)) {
|
||||||
translation += Scene::getCamera().getUp() / 2.0f;
|
translation += Scene::getCamera().getUp() / 2.0f;
|
||||||
}
|
}
|
||||||
Scene::getCamera().getTransform().translate(transSpeed * translation);
|
Scene::getCamera().translate(transSpeed * translation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,6 +288,5 @@ void QtkWidget::printContextInformation() {
|
|||||||
auto message = QString(glType) + glVersion + "(" + glProfile + ")"
|
auto message = QString(glType) + glVersion + "(" + glProfile + ")"
|
||||||
+ "\nOpenGL Vendor: " + glVendor
|
+ "\nOpenGL Vendor: " + glVendor
|
||||||
+ "\nRendering Device: " + glRenderer;
|
+ "\nRendering Device: " + glRenderer;
|
||||||
qDebug() << qPrintable(message);
|
emit sendLog("(OpenGL) " + message.replace("\n", "\n(OpenGL) "), Status);
|
||||||
sendLog("(OpenGL) " + message.replace("\n", "\n(OpenGL) "), Status);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <qtk/qtkapi.h>
|
#include <qtk/qtkapi.h>
|
||||||
#include <qtk/scene.h>
|
#include <qtk/scene.h>
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk {
|
||||||
class DebugConsole;
|
class DebugConsole;
|
||||||
@@ -100,6 +101,15 @@ namespace Qtk {
|
|||||||
*/
|
*/
|
||||||
inline Qtk::Scene * getScene() { return mScene; }
|
inline Qtk::Scene * getScene() { return mScene; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Pointer to the QOpenGLDebugLogger attached to this widget.
|
||||||
|
*/
|
||||||
|
inline QOpenGLDebugLogger * getOpenGLDebugLogger() {
|
||||||
|
return mDebugLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Logger * getLogger() { return mLogger; }
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Setters
|
* Setters
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
@@ -122,13 +132,21 @@ namespace Qtk {
|
|||||||
* @param message The message to log.
|
* @param message The message to log.
|
||||||
* @param context The context of the log message.
|
* @param context The context of the log message.
|
||||||
*/
|
*/
|
||||||
void sendLog(const QString & message, DebugContext context = Status);
|
void sendLog(const QString & message, Qtk::DebugContext context = Status);
|
||||||
|
|
||||||
|
// TODO: Use this signal in treeview and toolbox to update object
|
||||||
|
// properties
|
||||||
|
void objectFocusChanged(const QString objectName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Protected Methods
|
* Protected Methods
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
void dragEnterEvent(QDragEnterEvent * event) override;
|
||||||
|
|
||||||
|
void dropEvent(QDropEvent * event) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param event Key press event to update camera input manager.
|
* @param event Key press event to update camera input manager.
|
||||||
*/
|
*/
|
||||||
@@ -159,10 +177,11 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* Called when the `messageLogged` signal is caught.
|
* Called when the `messageLogged` signal is caught.
|
||||||
* See definition of initializeGL()
|
* See definition of initializeGL()
|
||||||
|
* https://doc.qt.io/qt-6/qopengldebuglogger.html#signals
|
||||||
*
|
*
|
||||||
* @param msg The message logged.
|
* @param msg The message logged.
|
||||||
*/
|
*/
|
||||||
void messageLogged(const QOpenGLDebugMessage & msg);
|
// void messageLogged(const QOpenGLDebugMessage & msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -188,6 +207,7 @@ namespace Qtk {
|
|||||||
* Private Members
|
* Private Members
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
Qtk::Logger * mLogger;
|
||||||
QOpenGLDebugLogger * mDebugLogger;
|
QOpenGLDebugLogger * mDebugLogger;
|
||||||
Qtk::Scene * mScene;
|
Qtk::Scene * mScene;
|
||||||
Qtk::DebugConsole * mConsole;
|
Qtk::DebugConsole * mConsole;
|
||||||
|
|||||||
@@ -8,13 +8,142 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "toolbox.h"
|
#include "toolbox.h"
|
||||||
|
#include "qtkmainwindow.h"
|
||||||
#include "ui_toolbox.h"
|
#include "ui_toolbox.h"
|
||||||
|
|
||||||
Qtk::ToolBox::ToolBox(QWidget * parent) :
|
#include <QFormLayout>
|
||||||
QDockWidget(parent), ui(new Ui::ToolBox) {
|
#include <QLabel>
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
|
ToolBox::ToolBox(QWidget * parent) : QDockWidget(parent), ui(new Ui::ToolBox) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
setMinimumWidth(350);
|
||||||
}
|
}
|
||||||
|
|
||||||
Qtk::ToolBox::~ToolBox() {
|
void ToolBox::updateFocus(const QString & name) {
|
||||||
|
auto object =
|
||||||
|
MainWindow::getMainWindow()->getQtkWidget()->getScene()->getObject(name);
|
||||||
|
if(object != Q_NULLPTR) {
|
||||||
|
removePages();
|
||||||
|
createPageProperties(object);
|
||||||
|
createPageShader(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolBox::~ToolBox() {
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ToolBox::removePages() {
|
||||||
|
// Remove all existing pages.
|
||||||
|
for(size_t i = 0; i < ui->toolBox->count(); i++) {
|
||||||
|
delete ui->toolBox->widget(i);
|
||||||
|
ui->toolBox->removeItem(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBox::createPageProperties(const Object * object) {
|
||||||
|
auto transform = object->getTransform();
|
||||||
|
auto type = object->getType();
|
||||||
|
auto * widget = new QWidget;
|
||||||
|
ui->toolBox->addItem(widget, "Properties");
|
||||||
|
ui->toolBox->setCurrentWidget(widget);
|
||||||
|
|
||||||
|
auto * layout = new QFormLayout;
|
||||||
|
layout->addRow(
|
||||||
|
new QLabel(tr("Name:")), new QLabel(object->getName().c_str()));
|
||||||
|
|
||||||
|
layout->addRow(
|
||||||
|
new QLabel(tr("Type:")),
|
||||||
|
new QLabel(type == Object::Type::QTK_MESH ? "Mesh" : "Model"));
|
||||||
|
|
||||||
|
auto rowLayout = new QHBoxLayout;
|
||||||
|
rowLayout->addWidget(new QLabel(tr("Translation:")));
|
||||||
|
int minWidth = 75;
|
||||||
|
for(size_t i = 0; i < 3; i++) {
|
||||||
|
auto spinBox = new QDoubleSpinBox;
|
||||||
|
spinBox->setMinimum(std::numeric_limits<double>::lowest());
|
||||||
|
spinBox->setSingleStep(0.1);
|
||||||
|
spinBox->setValue(transform.getTranslation()[i]);
|
||||||
|
spinBox->setFixedWidth(minWidth);
|
||||||
|
rowLayout->addWidget(spinBox);
|
||||||
|
|
||||||
|
if(i == 0) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object,
|
||||||
|
&Object::setTranslationX);
|
||||||
|
} else if(i == 1) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object,
|
||||||
|
&Object::setTranslationY);
|
||||||
|
} else if(i == 2) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object,
|
||||||
|
&Object::setTranslationZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layout->addRow(rowLayout);
|
||||||
|
|
||||||
|
rowLayout = new QHBoxLayout;
|
||||||
|
rowLayout->addWidget(new QLabel(tr("Scale:")));
|
||||||
|
for(size_t i = 0; i < 3; i++) {
|
||||||
|
auto spinBox = new QDoubleSpinBox;
|
||||||
|
spinBox->setMinimum(std::numeric_limits<double>::lowest());
|
||||||
|
spinBox->setSingleStep(0.1);
|
||||||
|
spinBox->setValue(transform.getScale()[i]);
|
||||||
|
spinBox->setFixedWidth(minWidth);
|
||||||
|
rowLayout->addWidget(spinBox);
|
||||||
|
|
||||||
|
if(i == 0) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object, &Object::setScaleX);
|
||||||
|
} else if(i == 1) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object, &Object::setScaleY);
|
||||||
|
} else if(i == 2) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object, &Object::setScaleZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layout->addRow(rowLayout);
|
||||||
|
widget->setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBox::createPageShader(const Object * object) {
|
||||||
|
// Shaders page.
|
||||||
|
auto widget = new QWidget;
|
||||||
|
ui->toolBox->addItem(widget, "Shaders");
|
||||||
|
auto mainLayout = new QFormLayout;
|
||||||
|
auto rowLayout = new QHBoxLayout;
|
||||||
|
rowLayout->addWidget(new QLabel("Vertex Shader:"));
|
||||||
|
rowLayout->addWidget(new QLabel(object->getVertexShader().c_str()));
|
||||||
|
mainLayout->addRow(rowLayout);
|
||||||
|
|
||||||
|
auto shaderView = new QTextEdit;
|
||||||
|
shaderView->setReadOnly(true);
|
||||||
|
auto vertexFile = QFile(object->getVertexShader().c_str());
|
||||||
|
if(vertexFile.exists()) {
|
||||||
|
vertexFile.open(QIODeviceBase::ReadOnly);
|
||||||
|
shaderView->setText(vertexFile.readAll());
|
||||||
|
vertexFile.close();
|
||||||
|
mainLayout->addRow(shaderView);
|
||||||
|
}
|
||||||
|
|
||||||
|
rowLayout = new QHBoxLayout;
|
||||||
|
rowLayout->addWidget(new QLabel("Fragment Shader:"));
|
||||||
|
rowLayout->addWidget(new QLabel(object->getFragmentShader().c_str()));
|
||||||
|
mainLayout->addRow(rowLayout);
|
||||||
|
|
||||||
|
shaderView = new QTextEdit;
|
||||||
|
shaderView->setReadOnly(true);
|
||||||
|
auto fragmentfile = QFile(object->getFragmentShader().c_str());
|
||||||
|
if(fragmentfile.exists()) {
|
||||||
|
fragmentfile.open(QIODeviceBase::ReadOnly);
|
||||||
|
shaderView->setText(fragmentfile.readAll());
|
||||||
|
fragmentfile.close();
|
||||||
|
mainLayout->addRow(shaderView);
|
||||||
|
}
|
||||||
|
|
||||||
|
widget->setLayout(mainLayout);
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,11 @@
|
|||||||
|
|
||||||
#include <QDesignerExportWidget>
|
#include <QDesignerExportWidget>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QGroupBox>
|
||||||
|
|
||||||
|
|
||||||
|
#include "qtk/scene.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ToolBox;
|
class ToolBox;
|
||||||
@@ -30,6 +35,15 @@ namespace Qtk {
|
|||||||
|
|
||||||
~ToolBox();
|
~ToolBox();
|
||||||
|
|
||||||
|
void removePages();
|
||||||
|
|
||||||
|
void createPageProperties(const Object * object);
|
||||||
|
|
||||||
|
void createPageShader(const Object * object);
|
||||||
|
|
||||||
|
void updateFocus(const QString & name);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Private Members
|
* Private Members
|
||||||
|
|||||||
@@ -10,17 +10,57 @@
|
|||||||
<height>300</height>
|
<height>300</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>86</width>
|
||||||
|
<height>167</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Object Details</string>
|
<string>Object Details</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="dockWidgetContents">
|
<widget class="QWidget" name="dockWidgetContents">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolBox" name="toolBox">
|
<widget class="QToolBox" name="toolBox">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page">
|
<widget class="QWidget" name="page_properties">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>382</width>
|
||||||
|
<height>201</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<attribute name="label">
|
||||||
|
<string>Properties</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="page_shaders">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
@@ -33,19 +73,6 @@
|
|||||||
<string>Shaders</string>
|
<string>Shaders</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="page_2">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>382</width>
|
|
||||||
<height>201</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<attribute name="label">
|
|
||||||
<string>Properties</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
@@ -37,23 +37,33 @@ void Qtk::TreeView::updateView(const Qtk::Scene * scene) {
|
|||||||
mSceneName = scene->getSceneName();
|
mSceneName = scene->getSceneName();
|
||||||
auto objects = scene->getObjects();
|
auto objects = scene->getObjects();
|
||||||
for(const auto & object : objects) {
|
for(const auto & object : objects) {
|
||||||
auto item = new QTreeWidgetItem(QStringList(QString(object->getName())));
|
auto item =
|
||||||
|
new QTreeWidgetItem(QStringList(QString(object->getName().c_str())));
|
||||||
ui->treeWidget->insertTopLevelItem(0, item);
|
ui->treeWidget->insertTopLevelItem(0, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column) {
|
void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column) {
|
||||||
QString name = item->text(column);
|
QString name = item->text(column);
|
||||||
auto scene =
|
auto scene = MainWindow::getMainWindow()->getQtkWidget()->getScene();
|
||||||
MainWindow::getMainWindow()->getQtkWidget(mSceneName)->getScene();
|
|
||||||
auto & transform = scene->getCamera().getTransform();
|
|
||||||
auto object = scene->getObject(name);
|
auto object = scene->getObject(name);
|
||||||
Transform3D * objectTransform;
|
Transform3D * objectTransform;
|
||||||
if(object->getType() == Object::QTK_MESH) {
|
// If the object is a mesh or model, focus the camera on it.
|
||||||
|
if(object == Q_NULLPTR) {
|
||||||
|
qDebug() << "Attempt to get non-existing object with name '" << name
|
||||||
|
<< "'\n";
|
||||||
|
} else if(object->getType() == Object::QTK_MESH) {
|
||||||
objectTransform = &dynamic_cast<MeshRenderer *>(object)->getTransform();
|
objectTransform = &dynamic_cast<MeshRenderer *>(object)->getTransform();
|
||||||
} else if(object->getType() == Object::QTK_MODEL) {
|
} else if(object->getType() == Object::QTK_MODEL) {
|
||||||
objectTransform = &dynamic_cast<Model *>(object)->getTransform();
|
objectTransform = &dynamic_cast<Model *>(object)->getTransform();
|
||||||
}
|
}
|
||||||
transform.setTranslation(objectTransform->getTranslation());
|
auto focusScale = objectTransform->getScale();
|
||||||
transform.translate(0.0f, 0.0f, 3.0f);
|
float height = focusScale.y() / 2.0f;
|
||||||
|
QVector3D pos = objectTransform->getTranslation();
|
||||||
|
pos.setY(pos.y() + height);
|
||||||
|
Qtk::Scene::getCamera().setTranslation(pos);
|
||||||
|
Qtk::Scene::getCamera().translate({0.0f, 0.0f, 3.0f});
|
||||||
|
|
||||||
|
// Emit signal from qtk widget for new object focus. Triggers GUI updates.
|
||||||
|
emit MainWindow::getMainWindow()->getQtkWidget()->objectFocusChanged(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ set(
|
|||||||
skybox.h
|
skybox.h
|
||||||
texture.h
|
texture.h
|
||||||
transform3D.h
|
transform3D.h
|
||||||
|
qtkmessagelogger.h
|
||||||
|
../app/logger.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
@@ -41,6 +43,8 @@ set(
|
|||||||
skybox.cpp
|
skybox.cpp
|
||||||
texture.cpp
|
texture.cpp
|
||||||
transform3D.cpp
|
transform3D.cpp
|
||||||
|
qtkmessagelogger.cpp
|
||||||
|
../app/logger.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
qt6_add_big_resources(QTK_LIBRARY_SOURCES "${QTK_RESOURCES}/resources.qrc")
|
qt6_add_big_resources(QTK_LIBRARY_SOURCES "${QTK_RESOURCES}/resources.qrc")
|
||||||
@@ -68,15 +72,12 @@ target_link_libraries(
|
|||||||
Qt6::Core Qt6::OpenGLWidgets Qt6::Widgets
|
Qt6::Core Qt6::OpenGLWidgets Qt6::Widgets
|
||||||
)
|
)
|
||||||
|
|
||||||
if(QTK_UPDATE_SUBMODULES OR NOT ASSIMP_NEW_INTERFACE)
|
if(QTK_SUBMODULES OR NOT QTK_ASSIMP_NEW_INTERFACE)
|
||||||
target_link_libraries(qtk_library PUBLIC assimp)
|
target_link_libraries(qtk_library PUBLIC assimp)
|
||||||
elseif(ASSIMP_NEW_INTERFACE)
|
elseif(QTK_ASSIMP_NEW_INTERFACE)
|
||||||
target_link_libraries(qtk_library PUBLIC assimp::assimp)
|
target_link_libraries(qtk_library PUBLIC assimp::assimp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(qtk_library PUBLIC OpenGL::GL)
|
target_link_libraries(qtk_library PUBLIC OpenGL::GL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#install(SCRIPT ${LIBQTK_DEPLOY_SCRIPT} COMPONENT libqtk)
|
|
||||||
## Install qtk_library to Qt Designer to support widget plugins.
|
|
||||||
|
|||||||
@@ -29,28 +29,3 @@ const QMatrix4x4 & Camera3D::toMatrix() {
|
|||||||
mWorld.translate(-mTransform.getTranslation());
|
mWorld.translate(-mTransform.getTranslation());
|
||||||
return mWorld;
|
return mWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Qt Streams
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
QDataStream & operator<<(QDataStream & out, Camera3D & transform) {
|
|
||||||
out << transform.getTransform();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDataStream & operator>>(QDataStream & in, Camera3D & transform) {
|
|
||||||
in >> transform.getTransform();
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const Camera3D & transform) {
|
|
||||||
dbg << "Camera3D\n{\n";
|
|
||||||
dbg << "Position: <" << transform.getTranslation().x() << ", "
|
|
||||||
<< transform.getTranslation().y() << ", "
|
|
||||||
<< transform.getTranslation().z() << ">\n";
|
|
||||||
dbg << "Rotation: <" << transform.getRotation().x() << ", "
|
|
||||||
<< transform.getRotation().y() << ", " << transform.getRotation().z()
|
|
||||||
<< " | " << transform.getRotation().scalar() << ">\n}";
|
|
||||||
return dbg;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return Transform3D associated with this camera.
|
* @return Transform3D associated with this camera.
|
||||||
*/
|
*/
|
||||||
inline Transform3D & getTransform() { return mTransform; }
|
[[nodiscard]] inline const Transform3D & getTransform() const {
|
||||||
|
return mTransform;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current translation of the camera as a QVector3D.
|
* @return Current translation of the camera as a QVector3D.
|
||||||
@@ -78,33 +80,85 @@ namespace Qtk {
|
|||||||
*/
|
*/
|
||||||
const QMatrix4x4 & toMatrix();
|
const QMatrix4x4 & toMatrix();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the translation for this camera.
|
||||||
|
* TODO: Replace these methods by inheriting from a base class.
|
||||||
|
*
|
||||||
|
* @param translation QVector3D for the new translation.
|
||||||
|
*/
|
||||||
|
inline void setTranslation(const QVector3D & translation) {
|
||||||
|
mTransform.setTranslation(translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the rotation for this camera.
|
||||||
|
*
|
||||||
|
* @param rotation QQuaternion for the new rotation.
|
||||||
|
*/
|
||||||
|
inline void setRotation(const QQuaternion & rotation) {
|
||||||
|
mTransform.setRotation(rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a rotation upon an axis represented by the 3D vector (x, y, z)
|
||||||
|
*
|
||||||
|
* @param ax X axis to set angle for.
|
||||||
|
* @param ay Y axis to set angle for.
|
||||||
|
* @param az Z axis to set angle for.
|
||||||
|
* @param angle Angle to set rotation.
|
||||||
|
*/
|
||||||
|
inline void setRotation(float ax, float ay, float az, float angle) {
|
||||||
|
mTransform.setRotation(ax, ay, az, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the camera by the given position.
|
||||||
|
*
|
||||||
|
* @param position QVector3D for the position to translate by.
|
||||||
|
*/
|
||||||
|
inline void translate(const QVector3D & position) {
|
||||||
|
mTransform.translate(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate the camera by the given rotation.
|
||||||
|
*
|
||||||
|
* @param rotation QQaternion for the rotation to apply.
|
||||||
|
*/
|
||||||
|
inline void rotate(const QQuaternion & rotation) {
|
||||||
|
mTransform.rotate(rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a rotation upon an axis represented by the 3D vector (x, y, z)
|
||||||
|
*
|
||||||
|
* @param ax X axis to set angle for.
|
||||||
|
* @param ay Y axis to set angle for.
|
||||||
|
* @param az Z axis to set angle for.
|
||||||
|
* @param angle Angle to set rotation.
|
||||||
|
*/
|
||||||
|
inline void rotate(float ax, float ay, float az, float angle) {
|
||||||
|
mTransform.rotate(ax, ay, az, angle);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*************************************************************************
|
|
||||||
* Private Methods
|
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
|
||||||
friend QDataStream & operator<<(QDataStream & out, Camera3D & transform);
|
|
||||||
friend QDataStream & operator>>(QDataStream & in, Camera3D & transform);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Private Members
|
* Private Members
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
Transform3D mTransform;
|
Transform3D mTransform;
|
||||||
QMatrix4x4 mWorld;
|
QMatrix4x4 mWorld;
|
||||||
};
|
|
||||||
|
|
||||||
// Qt Streams
|
/*************************************************************************
|
||||||
|
* Qt Streams
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
#ifndef QT_NO_DATASTREAM
|
||||||
QDataStream & operator<<(QDataStream & out, const Camera3D & transform);
|
friend QDataStream & operator<<(
|
||||||
QDataStream & operator>>(QDataStream & in, Camera3D & transform);
|
QDataStream & out, const Camera3D & camera);
|
||||||
#endif
|
friend QDataStream & operator>>(QDataStream & in, Camera3D & camera);
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
|
||||||
QDebug operator<<(QDebug dbg, const Camera3D & transform);
|
|
||||||
#endif
|
#endif
|
||||||
|
};
|
||||||
} // namespace Qtk
|
} // namespace Qtk
|
||||||
|
|
||||||
Q_DECLARE_TYPEINFO(Qtk::Camera3D, Q_MOVABLE_TYPE);
|
Q_DECLARE_TYPEINFO(Qtk::Camera3D, Q_MOVABLE_TYPE);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
MeshRenderer::~MeshRenderer() {
|
MeshRenderer::~MeshRenderer() {
|
||||||
sInstances.remove(mName);
|
sInstances.remove(mName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|||||||
@@ -211,6 +211,14 @@ namespace Qtk {
|
|||||||
*/
|
*/
|
||||||
inline Transform3D & getTransform() { return mTransform; }
|
inline Transform3D & getTransform() { return mTransform; }
|
||||||
|
|
||||||
|
inline std::string getVertexShader() const override {
|
||||||
|
return mVertexShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string getFragmentShader() const override {
|
||||||
|
return mFragmentShader;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Private Members
|
* Private Members
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ void Model::flipTexture(const std::string & fileName, bool flipX, bool flipY) {
|
|||||||
texture.mTexture->destroy();
|
texture.mTexture->destroy();
|
||||||
texture.mTexture->create();
|
texture.mTexture->create();
|
||||||
texture.mTexture->setData(
|
texture.mTexture->setData(
|
||||||
*OpenGLTextureFactory::initImage(fullPath.c_str(), flipX, flipY));
|
OpenGLTextureFactory::initImage(fullPath.c_str(), flipX, flipY));
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ void Model::loadModel(const std::string & path) {
|
|||||||
sortModelMeshes();
|
sortModelMeshes();
|
||||||
|
|
||||||
// Object finished loading, insert it into ModelManager
|
// Object finished loading, insert it into ModelManager
|
||||||
mManager.insert(getName(), this);
|
mManager.insert(getName().c_str(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::processNode(aiNode * node, const aiScene * scene) {
|
void Model::processNode(aiNode * node, const aiScene * scene) {
|
||||||
@@ -200,7 +200,9 @@ ModelMesh Model::processMesh(aiMesh * mesh, const aiScene * scene) {
|
|||||||
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
|
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
return {vertices, indices, textures, mVertexShader, mFragmentShader};
|
return {
|
||||||
|
vertices, indices, textures, mVertexShader.c_str(),
|
||||||
|
mFragmentShader.c_str()};
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelMesh::Textures Model::loadMaterialTextures(
|
ModelMesh::Textures Model::loadMaterialTextures(
|
||||||
@@ -236,7 +238,7 @@ ModelMesh::Textures Model::loadMaterialTextures(
|
|||||||
// Add the texture to the textures container
|
// Add the texture to the textures container
|
||||||
textures.push_back(texture);
|
textures.push_back(texture);
|
||||||
// Add the texture to the loaded textures to avoid loading it twice
|
// Add the texture to the loaded textures to avoid loading it twice
|
||||||
mTexturesLoaded.push_back(texture);
|
mTexturesLoaded.push_back(textures.back());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
|
|
||||||
// Qtk
|
// Qtk
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
|
||||||
#include "modelmesh.h"
|
#include "modelmesh.h"
|
||||||
#include "qtkapi.h"
|
#include "qtkapi.h"
|
||||||
|
|
||||||
@@ -58,7 +61,7 @@ namespace Qtk {
|
|||||||
loadModel(mModelPath);
|
loadModel(mModelPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ~Model() override { mManager.remove(getName()); }
|
inline ~Model() override { mManager.remove(getName().c_str()); }
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Public Methods
|
* Public Methods
|
||||||
@@ -124,6 +127,14 @@ namespace Qtk {
|
|||||||
*/
|
*/
|
||||||
inline Transform3D & getTransform() { return mTransform; }
|
inline Transform3D & getTransform() { return mTransform; }
|
||||||
|
|
||||||
|
inline std::string getVertexShader() const override {
|
||||||
|
return mVertexShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string getFragmentShader() const override {
|
||||||
|
return mFragmentShader;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Private Methods
|
* Private Methods
|
||||||
@@ -197,7 +208,7 @@ namespace Qtk {
|
|||||||
/** The directory this model and it's textures are stored. */
|
/** The directory this model and it's textures are stored. */
|
||||||
std::string mDirectory {};
|
std::string mDirectory {};
|
||||||
/** File names for shaders and 3D model on disk. */
|
/** File names for shaders and 3D model on disk. */
|
||||||
const char *mVertexShader, *mFragmentShader, *mModelPath;
|
std::string mVertexShader, mFragmentShader, mModelPath;
|
||||||
};
|
};
|
||||||
} // namespace Qtk
|
} // namespace Qtk
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,10 @@ void ModelMesh::draw(QOpenGLShaderProgram & shader) {
|
|||||||
shader.setUniformValue((name + number).c_str(), i);
|
shader.setUniformValue((name + number).c_str(), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always reset active texture to GL_TEXTURE0 before we draw.
|
||||||
|
// This is important for models with no textures.
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
// Draw the mesh
|
// Draw the mesh
|
||||||
glDrawElements(
|
glDrawElements(
|
||||||
GL_TRIANGLES, mIndices.size(), GL_UNSIGNED_INT, mIndices.data());
|
GL_TRIANGLES, mIndices.size(), GL_UNSIGNED_INT, mIndices.data());
|
||||||
@@ -62,7 +66,6 @@ void ModelMesh::draw(QOpenGLShaderProgram & shader) {
|
|||||||
}
|
}
|
||||||
shader.release();
|
shader.release();
|
||||||
mVAO->release();
|
mVAO->release();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -73,7 +76,7 @@ void ModelMesh::initMesh(const char * vert, const char * frag) {
|
|||||||
initializeOpenGLFunctions();
|
initializeOpenGLFunctions();
|
||||||
|
|
||||||
// Create VAO, VBO, EBO
|
// Create VAO, VBO, EBO
|
||||||
mVAO->create();
|
bool status = mVAO->create();
|
||||||
mVBO->create();
|
mVBO->create();
|
||||||
mEBO->create();
|
mEBO->create();
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,21 @@ namespace Qtk {
|
|||||||
* Struct to store model textures. 3D Models may have multiple.
|
* Struct to store model textures. 3D Models may have multiple.
|
||||||
*/
|
*/
|
||||||
struct QTKAPI ModelTexture {
|
struct QTKAPI ModelTexture {
|
||||||
|
ModelTexture() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a ModelTexture.
|
||||||
|
*
|
||||||
|
* @param id Texture ID for this texture.
|
||||||
|
* @param type Type of texture in string format.
|
||||||
|
* @param path Path to the texture on disk.
|
||||||
|
*/
|
||||||
|
ModelTexture(const std::string & type, const std::string & path) :
|
||||||
|
mType(type), mPath(path) {
|
||||||
|
mTexture = OpenGLTextureFactory::initTexture(path.c_str());
|
||||||
|
mID = mTexture->textureId();
|
||||||
|
}
|
||||||
|
|
||||||
/** Texture ID for for this texture. */
|
/** Texture ID for for this texture. */
|
||||||
GLuint mID {};
|
GLuint mID {};
|
||||||
QOpenGLTexture * mTexture {};
|
QOpenGLTexture * mTexture {};
|
||||||
|
|||||||
@@ -92,14 +92,28 @@ namespace Qtk {
|
|||||||
return mShape.mVertices;
|
return mShape.mVertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline const char * getName() const { return mName; }
|
[[nodiscard]] inline std::string getName() const { return mName; }
|
||||||
|
|
||||||
[[nodiscard]] inline const Type & getType() const { return mType; }
|
[[nodiscard]] inline const Type & getType() const { return mType; }
|
||||||
|
|
||||||
|
[[nodiscard]] inline virtual const Transform3D & getTransform() const {
|
||||||
|
return mTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline virtual std::string getVertexShader() const {
|
||||||
|
return "Base Object has no vertex shader.";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual inline std::string getFragmentShader() const {
|
||||||
|
return "Base Object has no fragment shader.";
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Setters
|
* Setters
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
virtual inline void setName(const std::string & name) { mName = name; }
|
||||||
|
|
||||||
virtual inline void setColors(const Colors & value) {
|
virtual inline void setColors(const Colors & value) {
|
||||||
mShape.mColors = value;
|
mShape.mColors = value;
|
||||||
}
|
}
|
||||||
@@ -135,6 +149,39 @@ namespace Qtk {
|
|||||||
mShape.mVertices = value;
|
mShape.mVertices = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void setScaleX(double x) {
|
||||||
|
mTransform.setScale(
|
||||||
|
x, mTransform.getScale().y(), mTransform.getScale().z());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setScaleY(double y) {
|
||||||
|
mTransform.setScale(
|
||||||
|
mTransform.getScale().x(), y, mTransform.getScale().z());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setScaleZ(double z) {
|
||||||
|
mTransform.setScale(
|
||||||
|
mTransform.getScale().x(), mTransform.getScale().y(), z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setTranslationX(double x) {
|
||||||
|
mTransform.setTranslation(
|
||||||
|
x, mTransform.getTranslation().y(),
|
||||||
|
mTransform.getTranslation().z());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setTranslationY(double y) {
|
||||||
|
mTransform.setTranslation(
|
||||||
|
mTransform.getTranslation().x(), y,
|
||||||
|
mTransform.getTranslation().z());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setTranslationZ(double z) {
|
||||||
|
mTransform.setTranslation(
|
||||||
|
mTransform.getTranslation().x(), mTransform.getTranslation().y(),
|
||||||
|
z);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Public Methods
|
* Public Methods
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
@@ -160,7 +207,7 @@ namespace Qtk {
|
|||||||
Transform3D mTransform;
|
Transform3D mTransform;
|
||||||
Shape mShape;
|
Shape mShape;
|
||||||
Texture mTexture;
|
Texture mTexture;
|
||||||
const char * mName;
|
std::string mName;
|
||||||
bool mBound;
|
bool mBound;
|
||||||
Type mType = QTK_OBJECT;
|
Type mType = QTK_OBJECT;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#define QTKAPI
|
#define QTKAPI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "qtk/qtkmessagelogger.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize Qt resources required by the Qtk library.
|
* Initialize Qt resources required by the Qtk library.
|
||||||
* This cannot be defined within any namespace, but can be called by ctors.
|
* This cannot be defined within any namespace, but can be called by ctors.
|
||||||
@@ -35,7 +37,7 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* Flag to set context for debug messages.
|
* Flag to set context for debug messages.
|
||||||
*/
|
*/
|
||||||
enum DebugContext { Status, Debug, Warn, Error, Fatal };
|
enum DebugContext { Status, Debug, Warn, Error, Fatal, Invalid, Any };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find top level parent for a widget.
|
* Find top level parent for a widget.
|
||||||
|
|||||||
@@ -17,17 +17,23 @@ using namespace Qtk;
|
|||||||
QtkIOStream::QtkIOStream(const char * pFile, const char * pMode) :
|
QtkIOStream::QtkIOStream(const char * pFile, const char * pMode) :
|
||||||
mFile(pFile) {
|
mFile(pFile) {
|
||||||
QString mode(pMode);
|
QString mode(pMode);
|
||||||
bool read = mode.contains('r');
|
bool open = false;
|
||||||
bool write = mode.contains('w');
|
if(mode == "w" || mode == "wb") {
|
||||||
if(read && write) {
|
open = mFile.open(QIODeviceBase::WriteOnly);
|
||||||
mFile.open(QIODevice::ReadWrite);
|
} else if(mode == "r" || mode == "rb") {
|
||||||
} else if(read) {
|
open = mFile.open(QIODeviceBase::ReadOnly);
|
||||||
mFile.open(QIODevice::ReadOnly);
|
} else if(mode == "wt") {
|
||||||
} else if(write) {
|
open = mFile.open(QIODeviceBase::WriteOnly | QIODeviceBase::Text);
|
||||||
mFile.open(QIODevice::WriteOnly);
|
} else if(mode == "rt") {
|
||||||
|
open = mFile.open(QIODeviceBase::ReadOnly | QIODeviceBase::Text);
|
||||||
} else {
|
} else {
|
||||||
|
open = false;
|
||||||
qDebug() << "[Qtk::QtkIOStream] Invalid file open mode: " << mode << "\n";
|
qDebug() << "[Qtk::QtkIOStream] Invalid file open mode: " << mode << "\n";
|
||||||
}
|
}
|
||||||
|
if(!open) {
|
||||||
|
qDebug() << "[Qtk::QtkIOStream] Could not open file: " << QString(pFile)
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -35,34 +41,24 @@ QtkIOStream::QtkIOStream(const char * pFile, const char * pMode) :
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
size_t QtkIOStream::Read(void * pvBuffer, size_t pSize, size_t pCount) {
|
size_t QtkIOStream::Read(void * pvBuffer, size_t pSize, size_t pCount) {
|
||||||
size_t read = 0;
|
qint64 readSize = mFile.read((char *)pvBuffer, pSize * pCount);
|
||||||
do {
|
|
||||||
auto readSize = mFile.read((char *)pvBuffer + read, pSize);
|
|
||||||
if(readSize < 0) {
|
if(readSize < 0) {
|
||||||
qDebug() << "[Qtk::QtkIOStream] Failed to read (" << pSize
|
qDebug() << "[Qtk::QtkIOStream] Failed to read (" << pSize
|
||||||
<< ") bytes from file at: " << mFile.filesystemFileName().c_str()
|
<< ") bytes from file at: " << mFile.filesystemFileName().c_str()
|
||||||
<< "\n";
|
<< "\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
read += readSize;
|
return readSize;
|
||||||
} while(pCount--);
|
|
||||||
return read;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t QtkIOStream::Write(const void * pvBuffer, size_t pSize, size_t pCount) {
|
size_t QtkIOStream::Write(const void * pvBuffer, size_t pSize, size_t pCount) {
|
||||||
size_t wrote = 0;
|
qint64 writeSize = mFile.write((char *)pvBuffer, pSize * pCount);
|
||||||
do {
|
|
||||||
auto writeSize = mFile.write((char *)pvBuffer + wrote, pSize);
|
|
||||||
if(writeSize < 0) {
|
if(writeSize < 0) {
|
||||||
qDebug() << "[Qtk::QtkIOStream] Failed to write buffer with size ("
|
qDebug() << "[Qtk::QtkIOStream] Failed to write buffer with size (" << pSize
|
||||||
<< pSize
|
<< ") to file at: " << mFile.filesystemFileName().c_str() << "\n";
|
||||||
<< ") to file at: " << mFile.filesystemFileName().c_str()
|
|
||||||
<< "\n";
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wrote += writeSize;
|
return writeSize;
|
||||||
} while(pCount--);
|
|
||||||
return wrote;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aiReturn QtkIOStream::Seek(size_t pOffset, aiOrigin pOrigin) {
|
aiReturn QtkIOStream::Seek(size_t pOffset, aiOrigin pOrigin) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
#include "qtkiosystem.h"
|
#include "qtkiosystem.h"
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
using namespace Qtk;
|
using namespace Qtk;
|
||||||
|
|
||||||
@@ -19,15 +20,11 @@ bool QtkIOSystem::Exists(const char * pFile) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char QtkIOSystem::getOsSeparator() const {
|
char QtkIOSystem::getOsSeparator() const {
|
||||||
#ifndef _WIN32
|
return QDir::separator().toLatin1();
|
||||||
return '/';
|
|
||||||
#else
|
|
||||||
return '\\';
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Assimp::IOStream * QtkIOSystem::Open(const char * pFile, const char * pMode) {
|
Assimp::IOStream * QtkIOSystem::Open(const char * pFile, const char * pMode) {
|
||||||
if(!QFileInfo::exists(pFile)) {
|
if(!Exists(pFile)) {
|
||||||
qDebug() << "[Qtk::QtkIOSystem] failed to open file: " << pFile << "\n";
|
qDebug() << "[Qtk::QtkIOSystem] failed to open file: " << pFile << "\n";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
61
src/qtk/qtkmessagelogger.cpp
Normal file
61
src/qtk/qtkmessagelogger.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
#include "qtkmessagelogger.h"
|
||||||
|
#include "camera3d.h"
|
||||||
|
#include "transform3D.h"
|
||||||
|
|
||||||
|
|
||||||
|
Qtk::QtkDebug Qtk::QtkDebug::operator<<(const Qtk::Transform3D & transform) {}
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
QDebug Qtk::operator<<(QDebug dbg, const Qtk::Transform3D & transform) {
|
||||||
|
dbg << "Transform3D\n{\n";
|
||||||
|
dbg << "Position: <" << transform.getTranslation().x() << ", "
|
||||||
|
<< transform.getTranslation().y() << ", "
|
||||||
|
<< transform.getTranslation().z() << ">\n";
|
||||||
|
dbg << "Scale: <" << transform.getScale().x() << ", "
|
||||||
|
<< transform.getScale().y() << ", " << transform.getScale().z() << ">\n";
|
||||||
|
dbg << "Rotation: <" << transform.getRotation().x() << ", "
|
||||||
|
<< transform.getRotation().y() << ", " << transform.getRotation().z()
|
||||||
|
<< " | " << transform.getRotation().scalar() << ">\n}";
|
||||||
|
return dbg;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug Qtk::operator<<(QDebug dbg, const Qtk::Camera3D & transform) {
|
||||||
|
dbg << "Camera3D\n{\n";
|
||||||
|
dbg << "Position: <" << transform.getTranslation().x() << ", "
|
||||||
|
<< transform.getTranslation().y() << ", "
|
||||||
|
<< transform.getTranslation().z() << ">\n";
|
||||||
|
dbg << "Rotation: <" << transform.getRotation().x() << ", "
|
||||||
|
<< transform.getRotation().y() << ", " << transform.getRotation().z()
|
||||||
|
<< " | " << transform.getRotation().scalar() << ">\n}";
|
||||||
|
return dbg;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef QT_NO_DATASTREAM
|
||||||
|
QDataStream & Qtk::operator<<(
|
||||||
|
QDataStream & out, const Qtk::Transform3D & transform) {
|
||||||
|
out << transform.mTranslation;
|
||||||
|
out << transform.mScale;
|
||||||
|
out << transform.mRotation;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream & Qtk::operator>>(QDataStream & in, Qtk::Transform3D & transform) {
|
||||||
|
in >> transform.mTranslation;
|
||||||
|
in >> transform.mScale;
|
||||||
|
in >> transform.mRotation;
|
||||||
|
transform.m_dirty = true;
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream & Qtk::operator<<(QDataStream & out, const Qtk::Camera3D & camera) {
|
||||||
|
out << camera.getTransform();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream & Qtk::operator>>(QDataStream & in, Qtk::Camera3D & camera) {
|
||||||
|
in >> camera.mTransform;
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
96
src/qtk/qtkmessagelogger.h
Normal file
96
src/qtk/qtkmessagelogger.h
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
|
||||||
|
#ifndef QTK_QTKMESSAGELOGGER_H
|
||||||
|
#define QTK_QTKMESSAGELOGGER_H
|
||||||
|
|
||||||
|
#include "qtkapi.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QMessageLogger>
|
||||||
|
#include <Qt>
|
||||||
|
|
||||||
|
// #define qtkDebug Qtk::QtkMessageLogger::get().debug
|
||||||
|
// #define qtkInfo Qtk::QtkMessageLogger::get().info
|
||||||
|
// #define qtkWarning Qtk::QtkMessageLogger::get().warning
|
||||||
|
// #define qtkCritical Qtk::QtkMessageLogger::get().critical
|
||||||
|
// #define qtkFatal Qtk::QtkMessageLogger::get().fatal
|
||||||
|
|
||||||
|
#define qtkDebug \
|
||||||
|
Qtk::QtkMessageLogger( \
|
||||||
|
QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC) \
|
||||||
|
.logger() \
|
||||||
|
.debug
|
||||||
|
#define qtkInfo \
|
||||||
|
Qtk::QtkMessageLogger( \
|
||||||
|
QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC) \
|
||||||
|
.logger() \
|
||||||
|
.info
|
||||||
|
#define qtkWarning \
|
||||||
|
Qtk::QtkMessageLogger( \
|
||||||
|
QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC) \
|
||||||
|
.logger() \
|
||||||
|
.warning
|
||||||
|
#define qtkCritical \
|
||||||
|
Qtk::QtkMessageLogger( \
|
||||||
|
QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC) \
|
||||||
|
.logger() \
|
||||||
|
.critical
|
||||||
|
#define qtkFatal \
|
||||||
|
Qtk::QtkMessageLogger( \
|
||||||
|
QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC) \
|
||||||
|
.logger() \
|
||||||
|
.fatal
|
||||||
|
|
||||||
|
namespace Qtk {
|
||||||
|
class Transform3D;
|
||||||
|
class Camera3D;
|
||||||
|
|
||||||
|
class QTKAPI QtkDebug : public QDebug {
|
||||||
|
public:
|
||||||
|
QtkDebug operator<<(const Transform3D & transform);
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
QDebug operator<<(QDebug dbg, const Transform3D & transform);
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug dbg, const Camera3D & camera);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef QT_NO_DATASTREAM
|
||||||
|
QDataStream & operator<<(QDataStream & out, const Transform3D & transform);
|
||||||
|
QDataStream & operator>>(QDataStream & in, Transform3D & transform);
|
||||||
|
|
||||||
|
QDataStream & operator<<(QDataStream & out, const Camera3D & camera);
|
||||||
|
QDataStream & operator>>(QDataStream & in, Camera3D & camera);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class QTKAPI QtkMessageLogger {
|
||||||
|
public:
|
||||||
|
QtkMessageLogger(const char * file, int line, const char * function) :
|
||||||
|
mQMessageLogger(file, line, function) {
|
||||||
|
qDebug();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static QtkMessageLogger * get() {
|
||||||
|
// if(mQtkMessageLogger == Q_NULLPTR) {
|
||||||
|
// mQtkMessageLogger = new QtkMessageLogger();
|
||||||
|
// }
|
||||||
|
// return mQtkMessageLogger;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// QtkDebug debug() const {}
|
||||||
|
|
||||||
|
[[nodiscard]] inline const QMessageLogger & logger() const {
|
||||||
|
return mQMessageLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QtkDebug debug() const { return {}; };
|
||||||
|
|
||||||
|
|
||||||
|
static QtkMessageLogger * mQtkMessageLogger;
|
||||||
|
QMessageLogger mQMessageLogger;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Qtk
|
||||||
|
|
||||||
|
#endif // QTK_QTKMESSAGELOGGER_H
|
||||||
@@ -19,8 +19,8 @@ QMatrix4x4 Scene::mProjection;
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
Scene::Scene() : mSceneName("Default Scene") {
|
Scene::Scene() : mSceneName("Default Scene") {
|
||||||
mCamera.getTransform().setTranslation(0.0f, 0.0f, 20.0f);
|
mCamera.setTranslation({0.0f, 0.0f, 20.0f});
|
||||||
mCamera.getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
mCamera.setRotation({-5.0f, 0.0f, 1.0f, 0.0f});
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene() {
|
Scene::~Scene() {
|
||||||
@@ -37,11 +37,54 @@ Scene::~Scene() {
|
|||||||
* Public Methods
|
* Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
template <> MeshRenderer * Scene::addObject(MeshRenderer * object) {
|
||||||
|
initSceneObjectName(object);
|
||||||
|
mMeshes.push_back(object);
|
||||||
|
sceneUpdated(mSceneName);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> Model * Scene::addObject(Model * object) {
|
||||||
|
initSceneObjectName(object);
|
||||||
|
mModels.push_back(object);
|
||||||
|
sceneUpdated(mSceneName);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::draw() {
|
||||||
|
if(!mInit) {
|
||||||
|
initializeOpenGLFunctions();
|
||||||
|
init();
|
||||||
|
mInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(!mModelLoadQueue.empty()) {
|
||||||
|
auto modelSpec = mModelLoadQueue.front();
|
||||||
|
// Load the model and add it to the scene.
|
||||||
|
addObject(new Model(modelSpec.first.c_str(), modelSpec.second.c_str()));
|
||||||
|
mModelLoadQueue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mPause) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mSkybox != Q_NULLPTR) {
|
||||||
|
mSkybox->draw();
|
||||||
|
}
|
||||||
|
for(const auto & model : mModels) {
|
||||||
|
model->draw();
|
||||||
|
}
|
||||||
|
for(const auto & mesh : mMeshes) {
|
||||||
|
mesh->draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Object *> Scene::getObjects() const {
|
std::vector<Object *> Scene::getObjects() const {
|
||||||
// All scene objects must inherit from Qtk::Object.
|
// All scene objects must inherit from Qtk::Object.
|
||||||
std::vector<Object *> objects(mMeshes.begin(), mMeshes.end());
|
std::vector<Object *> objects(mMeshes.begin(), mMeshes.end());
|
||||||
for(auto model : mModels) {
|
for(const auto & model : mModels) {
|
||||||
objects.push_back(dynamic_cast<Object *>(model));
|
objects.push_back(model);
|
||||||
if(objects.back() == nullptr) {
|
if(objects.back() == nullptr) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -49,9 +92,9 @@ std::vector<Object *> Scene::getObjects() const {
|
|||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object * Scene::getObject(const QString & name) {
|
Object * Scene::getObject(const QString & name) const {
|
||||||
for(auto object : getObjects()) {
|
for(const auto & object : getObjects()) {
|
||||||
if(object->getName() == name) {
|
if(object->getName() == name.toStdString()) {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,35 +106,14 @@ void Scene::setSkybox(Skybox * skybox) {
|
|||||||
mSkybox = skybox;
|
mSkybox = skybox;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> MeshRenderer * Scene::addObject(MeshRenderer * object) {
|
void Scene::initSceneObjectName(Object * object) {
|
||||||
mMeshes.push_back(object);
|
if(!mObjectCount.count(object->getName())) {
|
||||||
sceneUpdated(mSceneName);
|
mObjectCount[object->getName()] = 1;
|
||||||
return object;
|
} else {
|
||||||
}
|
mObjectCount[object->getName()]++;
|
||||||
|
|
||||||
template <> Model * Scene::addObject(Model * object) {
|
|
||||||
mModels.push_back(object);
|
|
||||||
sceneUpdated(mSceneName);
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Private Methods
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
void Scene::privateDraw() {
|
|
||||||
if(!mInit) {
|
|
||||||
initializeOpenGLFunctions();
|
|
||||||
init();
|
|
||||||
mInit = true;
|
|
||||||
}
|
}
|
||||||
if(mSkybox != Q_NULLPTR) {
|
auto count = mObjectCount[object->getName()];
|
||||||
mSkybox->draw();
|
if(count > 1) {
|
||||||
}
|
object->setName(object->getName() + " (" + std::to_string(count) + ")");
|
||||||
for(auto & model : mModels) {
|
|
||||||
model->draw();
|
|
||||||
}
|
|
||||||
for(const auto & mesh : mMeshes) {
|
|
||||||
mesh->draw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
#define QTK_SCENE_H
|
#define QTK_SCENE_H
|
||||||
|
|
||||||
#include <QMatrix4x4>
|
#include <QMatrix4x4>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "camera3d.h"
|
#include "camera3d.h"
|
||||||
@@ -65,7 +69,7 @@ namespace Qtk {
|
|||||||
*
|
*
|
||||||
* This function is only called when the widget is redrawn.
|
* This function is only called when the widget is redrawn.
|
||||||
*/
|
*/
|
||||||
virtual void draw() { privateDraw(); };
|
virtual void draw();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called to update the QOpenGLWidget. Does not trigger a redraw.
|
* Function called to update the QOpenGLWidget. Does not trigger a redraw.
|
||||||
@@ -74,6 +78,18 @@ namespace Qtk {
|
|||||||
*/
|
*/
|
||||||
virtual void update() {}
|
virtual void update() {}
|
||||||
|
|
||||||
|
void loadModel(const QUrl & url) {
|
||||||
|
auto fileName = url.fileName().replace(".obj", "").toStdString();
|
||||||
|
auto filePath = url.toLocalFile().toStdString();
|
||||||
|
loadModel(fileName, filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadModel(const std::string & name, const std::string & path) {
|
||||||
|
// Add the dropped model to the load queue.
|
||||||
|
// This is consumed during rendering of the scene if not empty.
|
||||||
|
mModelLoadQueue.emplace(name, path);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Accessors
|
* Accessors
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
@@ -90,7 +106,16 @@ namespace Qtk {
|
|||||||
* @param name The objectName to look for within this scene.
|
* @param name The objectName to look for within this scene.
|
||||||
* @return The found object or Q_NULLPTR if none found.
|
* @return The found object or Q_NULLPTR if none found.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] Object * getObject(const QString & name);
|
[[nodiscard]] Object * getObject(const QString & name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The number of objects within the scene with the given name.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] uint64_t getObjectCount(const QString & name) {
|
||||||
|
return mObjectCount.count(name.toStdString())
|
||||||
|
? mObjectCount[name.toStdString()]
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Camera attached to this scene.
|
* @return Camera attached to this scene.
|
||||||
@@ -165,6 +190,8 @@ namespace Qtk {
|
|||||||
*/
|
*/
|
||||||
inline void setSceneName(QString name) { mSceneName = std::move(name); }
|
inline void setSceneName(QString name) { mSceneName = std::move(name); }
|
||||||
|
|
||||||
|
inline void setPause(bool pause) { mPause = pause; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* Signal thrown when the scene is modified by adding or removing objects.
|
* Signal thrown when the scene is modified by adding or removing objects.
|
||||||
@@ -174,16 +201,25 @@ namespace Qtk {
|
|||||||
*/
|
*/
|
||||||
void sceneUpdated(QString sceneName);
|
void sceneUpdated(QString sceneName);
|
||||||
|
|
||||||
private:
|
|
||||||
/*************************************************************************
|
|
||||||
* Private Methods
|
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Public Members
|
||||||
|
************************************************************************/
|
||||||
|
public:
|
||||||
|
/* Models used for storing 3D models in the scene. */
|
||||||
|
std::vector<Model *> mModels {};
|
||||||
|
|
||||||
|
/* Queue of models requested to load at runtime. */
|
||||||
|
std::queue<std::pair<std::string, std::string>> mModelLoadQueue;
|
||||||
|
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
* Handles drawing members encapsulated by this base class.
|
* Initialize an object name relative to other objects already loaded.
|
||||||
* Child classes do not need to draw these objects manually.
|
* Protects against having two objects with the same name.
|
||||||
|
*
|
||||||
|
* @param object Qtk Object to name within this scene.
|
||||||
*/
|
*/
|
||||||
void privateDraw();
|
void initSceneObjectName(Qtk::Object * object);
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Private Members
|
* Private Members
|
||||||
@@ -192,15 +228,41 @@ namespace Qtk {
|
|||||||
static Camera3D mCamera;
|
static Camera3D mCamera;
|
||||||
static QMatrix4x4 mProjection;
|
static QMatrix4x4 mProjection;
|
||||||
bool mInit = false;
|
bool mInit = false;
|
||||||
|
/* Pause rendering of the scene. */
|
||||||
|
bool mPause = false;
|
||||||
|
|
||||||
QString mSceneName;
|
QString mSceneName;
|
||||||
/* The skybox for this scene. */
|
/* The skybox for this scene. */
|
||||||
Skybox * mSkybox {};
|
Skybox * mSkybox {};
|
||||||
/* MeshRenderers used simple geometry. */
|
/* MeshRenderers used simple geometry. */
|
||||||
std::vector<MeshRenderer *> mMeshes {};
|
std::vector<MeshRenderer *> mMeshes {};
|
||||||
/* Models used for storing 3D models in the scene. */
|
/* Track count of objects with same initial name. */
|
||||||
std::vector<Model *> mModels {};
|
std::unordered_map<std::string, uint64_t> mObjectCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SceneEmpty : public Scene {
|
||||||
|
public:
|
||||||
|
void init() override { setSceneName("Empty Scene"); }
|
||||||
|
|
||||||
|
void draw() override { Scene::draw(); }
|
||||||
|
|
||||||
|
void update() override { Scene::update(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class SceneInterface : public Scene {
|
||||||
|
public:
|
||||||
|
explicit SceneInterface(Scene * scene) : mScene(scene) {}
|
||||||
|
|
||||||
|
void init() override { mScene->init(); }
|
||||||
|
|
||||||
|
void draw() override { mScene->draw(); }
|
||||||
|
|
||||||
|
void update() override { mScene->update(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Scene * mScene;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Qtk
|
} // namespace Qtk
|
||||||
|
|
||||||
#endif // QTK_SCENE_H
|
#endif // QTK_SCENE_H
|
||||||
|
|||||||
@@ -9,19 +9,18 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
|
|
||||||
|
#include "app/qtkmainwindow.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
using namespace Qtk;
|
using namespace Qtk;
|
||||||
|
|
||||||
QImage * OpenGLTextureFactory::initImage(
|
QImage OpenGLTextureFactory::initImage(
|
||||||
const char * image, bool flipX, bool flipY) {
|
const char * image, bool flipX, bool flipY) {
|
||||||
// Qt6 limits loaded images to 256MB by default
|
// Qt6 limits loaded images to 256MB by default
|
||||||
QImageReader::setAllocationLimit(512);
|
QImageReader::setAllocationLimit(1024);
|
||||||
auto loadedImage = new QImage(QImage(image).mirrored(flipX, flipY));
|
auto loadedImage = QImage(image).mirrored(flipX, flipY);
|
||||||
if(loadedImage->isNull()) {
|
if(loadedImage.isNull()) {
|
||||||
qDebug() << "[Qtk::OpenGLTextureFactory] Error loading image: " << image
|
return defaultTexture();
|
||||||
<< "\nSupported types: " << QImageReader::supportedImageFormats();
|
|
||||||
return Q_NULLPTR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return loadedImage;
|
return loadedImage;
|
||||||
@@ -29,13 +28,12 @@ QImage * OpenGLTextureFactory::initImage(
|
|||||||
|
|
||||||
QOpenGLTexture * OpenGLTextureFactory::initTexture(
|
QOpenGLTexture * OpenGLTextureFactory::initTexture(
|
||||||
const char * texture, bool flipX, bool flipY) {
|
const char * texture, bool flipX, bool flipY) {
|
||||||
QImage * image = initImage(texture, flipX, flipY);
|
QImage image = initImage(texture, flipX, flipY);
|
||||||
auto newTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
auto newTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
||||||
newTexture->setData(*image);
|
newTexture->setData(image);
|
||||||
newTexture->setWrapMode(QOpenGLTexture::Repeat);
|
newTexture->setWrapMode(QOpenGLTexture::Repeat);
|
||||||
newTexture->setMinMagFilters(
|
newTexture->setMinMagFilters(
|
||||||
QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
|
QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
|
||||||
delete image;
|
|
||||||
return newTexture;
|
return newTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +69,7 @@ QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
|
|||||||
QImage faceImage(faceTextures[i]);
|
QImage faceImage(faceTextures[i]);
|
||||||
if(faceImage.isNull()) {
|
if(faceImage.isNull()) {
|
||||||
qDebug() << "Error loading cube map image\n";
|
qDebug() << "Error loading cube map image\n";
|
||||||
|
faceImage = defaultTexture();
|
||||||
}
|
}
|
||||||
faceImage = faceImage.convertToFormat(QImage::Format_RGBA8888);
|
faceImage = faceImage.convertToFormat(QImage::Format_RGBA8888);
|
||||||
|
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ namespace Qtk {
|
|||||||
* Can be absolute or Qt resource path.
|
* Can be absolute or Qt resource path.
|
||||||
* @param flipX If true the image will be flipped on X axis.
|
* @param flipX If true the image will be flipped on X axis.
|
||||||
* @param flipY If true the image will be flipped on Y axis.
|
* @param flipY If true the image will be flipped on Y axis.
|
||||||
* @return Pointer to an initialized QImage object.
|
* @return QImage object.
|
||||||
*/
|
*/
|
||||||
static QImage * initImage(
|
static QImage initImage(
|
||||||
const char * image, bool flipX = false, bool flipY = false);
|
const char * image, bool flipX = false, bool flipY = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,6 +132,14 @@ namespace Qtk {
|
|||||||
const char * right, const char * top, const char * front,
|
const char * right, const char * top, const char * front,
|
||||||
const char * left, const char * bottom, const char * back);
|
const char * left, const char * bottom, const char * back);
|
||||||
|
|
||||||
|
/// The texture used in place of a missing texture.
|
||||||
|
static QImage defaultTexture() {
|
||||||
|
// Use plaster for default texture if image fails to load.
|
||||||
|
// This prevents segfaults when loading a texture that doesn't exist.
|
||||||
|
// TODO: Replace with a '?' texture to indicate missing texture.
|
||||||
|
return QImage(":/textures/plaster.png");
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Private ctor to prevent creating instances of this class
|
// Private ctor to prevent creating instances of this class
|
||||||
OpenGLTextureFactory() = default;
|
OpenGLTextureFactory() = default;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ void Transform3D::rotate(const QQuaternion & dr) {
|
|||||||
|
|
||||||
void Transform3D::setTranslation(const QVector3D & t) {
|
void Transform3D::setTranslation(const QVector3D & t) {
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
qtkDebug() << "Setting translation to " << t;
|
||||||
mTranslation = t;
|
mTranslation = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,45 +78,3 @@ QVector3D Transform3D::getUp() const {
|
|||||||
QVector3D Transform3D::getRight() const {
|
QVector3D Transform3D::getRight() const {
|
||||||
return mRotation.rotatedVector(LocalRight);
|
return mRotation.rotatedVector(LocalRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Private Methods
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
namespace Qtk {
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
|
||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const Transform3D & transform) {
|
|
||||||
dbg << "Transform3D\n{\n";
|
|
||||||
dbg << "Position: <" << transform.getTranslation().x() << ", "
|
|
||||||
<< transform.getTranslation().y() << ", "
|
|
||||||
<< transform.getTranslation().z() << ">\n";
|
|
||||||
dbg << "Scale: <" << transform.getScale().x() << ", "
|
|
||||||
<< transform.getScale().y() << ", " << transform.getScale().z()
|
|
||||||
<< ">\n";
|
|
||||||
dbg << "Rotation: <" << transform.getRotation().x() << ", "
|
|
||||||
<< transform.getRotation().y() << ", " << transform.getRotation().z()
|
|
||||||
<< " | " << transform.getRotation().scalar() << ">\n}";
|
|
||||||
return dbg;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
|
||||||
QDataStream & operator<<(QDataStream & out, const Transform3D & transform) {
|
|
||||||
out << transform.mTranslation;
|
|
||||||
out << transform.mScale;
|
|
||||||
out << transform.mRotation;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDataStream & operator>>(QDataStream & in, Transform3D & transform) {
|
|
||||||
in >> transform.mTranslation;
|
|
||||||
in >> transform.mScale;
|
|
||||||
in >> transform.mRotation;
|
|
||||||
transform.m_dirty = true;
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
} // namespace Qtk
|
|
||||||
|
|||||||
@@ -116,12 +116,12 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* Apply rotation upon an axis represented by the 3D vector (x, y, z)
|
* Apply rotation upon an axis represented by the 3D vector (x, y, z)
|
||||||
*
|
*
|
||||||
* @param angle Angle to rotate.
|
|
||||||
* @param ax X axis to apply the rotation on.
|
* @param ax X axis to apply the rotation on.
|
||||||
* @param ay Y axis to apply the rotation on.
|
* @param ay Y axis to apply the rotation on.
|
||||||
* @param az Z axis to apply the rotation on.
|
* @param az Z axis to apply the rotation on.
|
||||||
|
* @param angle Angle to rotate.
|
||||||
*/
|
*/
|
||||||
inline void rotate(float angle, float ax, float ay, float az) {
|
inline void rotate(float ax, float ay, float az, float angle) {
|
||||||
rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));
|
rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,12 +178,12 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* Sets a rotation upon an axis represented by the 3D vector (x, y, z)
|
* Sets a rotation upon an axis represented by the 3D vector (x, y, z)
|
||||||
*
|
*
|
||||||
* @param angle Angle to set rotation.
|
|
||||||
* @param ax X axis to set angle for.
|
* @param ax X axis to set angle for.
|
||||||
* @param ay Y axis to set angle for.
|
* @param ay Y axis to set angle for.
|
||||||
* @param az Z axis to set angle for.
|
* @param az Z axis to set angle for.
|
||||||
|
* @param angle Angle to set rotation.
|
||||||
*/
|
*/
|
||||||
inline void setRotation(float angle, float ax, float ay, float az) {
|
inline void setRotation(float ax, float ay, float az, float angle) {
|
||||||
setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));
|
setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +249,10 @@ namespace Qtk {
|
|||||||
|
|
||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Qt Streams
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
#ifndef QT_NO_DATASTREAM
|
||||||
friend QDataStream & operator<<(
|
friend QDataStream & operator<<(
|
||||||
QDataStream & out, const Transform3D & transform);
|
QDataStream & out, const Transform3D & transform);
|
||||||
@@ -256,15 +260,6 @@ namespace Qtk {
|
|||||||
QDataStream & in, Transform3D & transform);
|
QDataStream & in, Transform3D & transform);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
|
||||||
QDebug operator<<(QDebug dbg, const Transform3D & transform);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
|
||||||
QDataStream & operator<<(QDataStream & out, const Transform3D & transform);
|
|
||||||
QDataStream & operator>>(QDataStream & in, Transform3D & transform);
|
|
||||||
#endif
|
|
||||||
} // namespace Qtk
|
} // namespace Qtk
|
||||||
|
|
||||||
Q_DECLARE_TYPEINFO(Qtk::Transform3D, Q_MOVABLE_TYPE);
|
Q_DECLARE_TYPEINFO(Qtk::Transform3D, Q_MOVABLE_TYPE);
|
||||||
|
|||||||
Reference in New Issue
Block a user