Work on separating widget from main application

+ Thanks @OgreTransporter for help in #4!
+ Closes #4
This commit is contained in:
Shaun Reed 2022-08-07 13:12:12 -04:00
parent 432bf9919c
commit 249a2b4446
31 changed files with 913 additions and 718 deletions

View File

@ -3,7 +3,7 @@
## ## ## ##
## Project for working with OpenGL and Qt6 widgets ## ## Project for working with OpenGL and Qt6 widgets ##
################################################################################ ################################################################################
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.2)
project( project(
#[[NAME]] Qtk #[[NAME]] Qtk
@ -16,72 +16,177 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
option(QTK_DEBUG "Enable debugger" ON)
option(BUILD_SHARED_LIBS "Build shared library" ON)
option(ASSIMP_NEW_INTERFACE "Use assimp::assimp as target instead of assimp" OFF)
################################################################################
# External Libraries
################################################################################
# For CLion builds, point CMAKE_PREFIX_PATH to Qt6 install directory # For CLion builds, point CMAKE_PREFIX_PATH to Qt6 install directory
list(APPEND CMAKE_PREFIX_PATH $ENV{HOME}/Code/Clones/Qt/6.3.1/gcc_64/) list(APPEND CMAKE_PREFIX_PATH $ENV{HOME}/Code/Clones/Qt/6.3.1/gcc_64/)
# Find Qt
find_package(Qt6 COMPONENTS OpenGLWidgets) find_package(Qt6 COMPONENTS OpenGLWidgets)
if (NOT Qt6_FOUND) if (NOT Qt6_FOUND)
message(SEND_ERROR "Unable to find Qt6 at CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}") message(SEND_ERROR "Unable to find Qt6 at CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
message(FATAL_ERROR "Specify path to Qt6 with `cmake -DCMAKE_PREFIX_PATH=/path/to/Qt/6.x.x/gcc_64 -S /path/to/qtk -B /path/to/qtk/build && cmake --build /path/to/qtk/build -j $(nprocs)`") message(FATAL_ERROR "Specify path to Qt6 with `cmake -DCMAKE_PREFIX_PATH=/path/to/Qt/6.x.x/gcc_64 -S /path/to/qtk -B /path/to/qtk/build && cmake --build /path/to/qtk/build -j $(nprocs)`")
endif() endif()
################################################################################ # Find Assimp
# External Libraries
################################################################################
# https://github.com/assimp/assimp/commit/6ac8279977c3a54118551e549d77329497116f66 # https://github.com/assimp/assimp/commit/6ac8279977c3a54118551e549d77329497116f66
find_package(assimp REQUIRED) find_package(assimp REQUIRED)
option(ASSIMP_NEW_INTERFACE "Use assimp::assimp as target instead of assimp" OFF)
include(GenerateExportHeader) include(GenerateExportHeader)
################################################################################
# Qtk
################################################################################
set(PUBLIC_HEADERS
src/mainwidget.h
src/abstractscene.h
src/camera3d.h
src/mesh.h
src/meshrenderer.h
src/model.h
src/object.h
src/skybox.h
src/texture.h
src/transform3D.h
)
set(SOURCE_FILES
src/mainwidget.cpp
src/abstractscene.cpp
src/camera3d.cpp
src/input.cpp
src/input.h
src/mesh.cpp
src/meshrenderer.cpp
src/model.cpp
src/object.cpp
src/qtkapi.h
src/skybox.cpp
src/texture.cpp
src/transform3D.cpp
)
qt_add_library(qtk-widget STATIC ${PUBLIC_HEADERS} ${SOURCE_FILES})
target_include_directories(qtk-widget PRIVATE src/ app/)
generate_export_header(qtk-widget)
set_target_properties(qtk-widget PROPERTIES
PUBLIC_HEADER "${PUBLIC_HEADERS}"
VERSION ${PROJECT_VERSION}
)
target_include_directories(qtk-widget PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
if(BUILD_SHARED_LIBS)
target_compile_definitions(qtk-widget PRIVATE QTK_EXPORT PUBLIC QTK_SHARED)
target_link_libraries(qtk-widget PRIVATE Qt6::OpenGLWidgets)
if(ASSIMP_NEW_INTERFACE)
target_link_libraries(qtk-widget PUBLIC assimp::assimp)
else()
target_link_libraries(qtk-widget PUBLIC assimp)
endif()
else()
target_compile_definitions(qtk-widget PUBLIC QTK_STATIC)
target_link_libraries(qtk-widget PUBLIC Qt6::OpenGLWidgets)
if(ASSIMP_NEW_INTERFACE)
target_link_libraries(qtk-widget PUBLIC assimp::assimp)
else()
target_link_libraries(qtk-widget PUBLIC assimp)
endif()
endif()
if(QTK_DEBUG)
target_compile_definitions(qtk-widget PUBLIC QTK_DEBUG)
endif()
if(WIN32)
find_package(OpenGL REQUIRED)
target_link_libraries(qtk-widget PUBLIC OpenGL::GL)
endif()
# Install files
install(TARGETS qtk-widget
# Associate qtk-widget target with qtk-export
EXPORT qtk-export
# <prefix>/bin on DLL systems and <prefix>/lib on non-dll systems
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static
RUNTIME DESTINATION bin
PUBLIC_HEADER DESTINATION include
)
# Install export
# qtkTargets.cmake will only be installed when one of the CONFIGURATIONS is installed
# + The generated import will only reference that qtk configuration
install(EXPORT qtk-export
FILE qtkTargets.cmake
CONFIGURATIONS Debug|Release
DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake
)
################################################################################ ################################################################################
# Final Application # Final Application
################################################################################ ################################################################################
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/resources.h "#ifndef QTK_RESOURCES_H\n#define QTK_RESOURCES_H\n#define QTK_RESOURCES_DIR \"${CMAKE_SOURCE_DIR}/resources\"\n#endif\n")
# Add our Qt resources.qrc file to our application # Add our Qt resources.qrc file to our application
set(SOURCES app/main.cpp) set(QTK_APP_SOURCES app/main.cpp
qt6_add_big_resources(SOURCES resources.qrc) app/mainwindow.cpp app/mainwindow.h app/mainwindow.ui
qt_add_executable(qtk ${SOURCES}) app/scene.cpp app/scene.h
app/resourcemanager.cpp app/resourcemanager.h
set(SOURCES ${CMAKE_CURRENT_BINARY_DIR}/resources.h
src/mainwidget.cpp src/mainwidget.h
src/mainwindow.cpp src/mainwindow.h src/mainwindow.ui
src/input.cpp src/input.h
src/mesh.cpp src/mesh.h
src/texture.cpp src/texture.h
src/object.cpp src/object.h
src/meshrenderer.cpp src/meshrenderer.h
src/camera3d.cpp src/camera3d.h
src/skybox.cpp src/skybox.h
src/transform3D.cpp src/transform3D.h
src/model.cpp src/model.h
src/scene.cpp src/scene.h
src/resourcemanager.cpp src/resourcemanager.h
) )
qt_add_library(main-widget STATIC ${SOURCES}) qt6_add_big_resources(QTK_APP_SOURCES resources.qrc)
target_include_directories(main-widget PUBLIC src/) qt_add_executable(qtk-app ${QTK_APP_SOURCES})
if(ASSIMP_NEW_INTERFACE) target_include_directories(qtk-app PRIVATE src/ app/)
target_link_libraries(main-widget PRIVATE assimp::assimp)
else()
target_link_libraries(main-widget PRIVATE assimp)
endif()
target_link_libraries(main-widget PUBLIC Qt6::OpenGLWidgets)
if(WIN32)
find_package(OpenGL REQUIRED)
target_link_libraries(main-widget PUBLIC OpenGL::GL)
endif()
target_link_libraries(qtk PUBLIC main-widget) # Link qtk-app executable to main qtk-widget library
target_link_libraries(qtk-app PRIVATE Qt6::OpenGLWidgets qtk-widget)
# Link qtk executable to main main-widget library set_target_properties(qtk-app PROPERTIES
set_target_properties(qtk PROPERTIES
WIN32_EXECUTABLE TRUE WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
) )
install(TARGETS qtk-app
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
generate_export_header(main-widget) if(WIN32)
get_target_property(_qt6_qmake_location Qt6::qmake IMPORTED_LOCATION)
execute_process(COMMAND "${_qt6_qmake_location}" -query QT_INSTALL_PREFIX RESULT_VARIABLE return_code OUTPUT_VARIABLE qt6_install_prefix OUTPUT_STRIP_TRAILING_WHITESPACE)
file(TO_NATIVE_PATH "${qt6_install_prefix}/bin" qt6_install_prefix)
if(TARGET Qt6::windeployqt)
add_custom_command(TARGET qtk-app
POST_BUILD
COMMAND set PATH=%PATH%$<SEMICOLON>${qt6_install_prefix}
COMMAND Qt6::windeployqt --dir "${CMAKE_BINARY_DIR}/windeployqt" "$<TARGET_FILE_DIR:qtk-app>/$<TARGET_FILE_NAME:qtk-app>"
)
install(DIRECTORY "${CMAKE_BINARY_DIR}/windeployqt/" DESTINATION bin)
endif()
if(MSVC AND TARGET Qt6::qmake)
set(VSUSER_FILE ${CMAKE_CURRENT_BINARY_DIR}/qtk-app.vcxproj.user)
file(TO_NATIVE_PATH "${assimp_DIR}/bin" assimp_bin)
file(WRITE ${VSUSER_FILE} "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
file(APPEND ${VSUSER_FILE} "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n")
file(APPEND ${VSUSER_FILE} " <PropertyGroup>\n")
file(APPEND ${VSUSER_FILE} " <LocalDebuggerEnvironment>Path=$(SolutionDir)\\lib\\$(Configuration);${qt6_install_prefix};${assimp_bin};$(Path)\n")
file(APPEND ${VSUSER_FILE} "$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>\n")
file(APPEND ${VSUSER_FILE} " <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\n")
file(APPEND ${VSUSER_FILE} " </PropertyGroup>\n")
file(APPEND ${VSUSER_FILE} "</Project>\n")
endif()
endif()

View File

@ -1,11 +1,13 @@
#include "mainwindow.h" #include <mainwindow.h>
#include "ui_mainwindow.h" #include <ui_mainwindow.h>
MainWindow::MainWindow(QWidget *parent) : MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::MainWindow) ui(new Ui::MainWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
mScene = new ExampleScene();
ui->openGLWidget->setScene(mScene);
setWindowIcon(QIcon("../resources/icon.png")); setWindowIcon(QIcon("../resources/icon.png"));
} }

View File

@ -3,13 +3,15 @@
#include <QMainWindow> #include <QMainWindow>
#include "main-widget_export.h" #include <qtk-widget_export.h>
#include <scene.h>
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
} }
class MAIN_WIDGET_EXPORT MainWindow : public QMainWindow class QTK_WIDGET_EXPORT MainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
@ -19,6 +21,7 @@ public:
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
Qtk::Scene * mScene;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -14,7 +14,7 @@
<string>Qtk - MainWindow</string> <string>Qtk - MainWindow</string>
</property> </property>
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<widget class="MainWidget" name="openGLWidget"> <widget class="Qtk::MainWidget" name="openGLWidget">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>10</x> <x>10</x>

View File

@ -6,19 +6,4 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## ## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/ ##############################################################################*/
#include "resourcemanager.h" #include <resourcemanager.h>
#include <algorithm>
#include <string>
#include <QtGlobal>
static std::string nixPath(std::string path)
{
#ifdef Q_OS_WINDOWS
std::replace(path.begin(), path.end(), '\\', '/');
#endif
return path;
}
std::string RM::resourcesDir =
std::string(__FILE__).substr(0, nixPath(__FILE__).find("src/"))
+ "resources/";

View File

@ -8,6 +8,8 @@
#include <string> #include <string>
#include <resources.h>
#ifndef QTK_RESOURCEMANAGER_H #ifndef QTK_RESOURCEMANAGER_H
#define QTK_RESOURCEMANAGER_H #define QTK_RESOURCEMANAGER_H
@ -26,10 +28,8 @@ public:
*/ */
static std::string getPath(const std::string & path) { static std::string getPath(const std::string & path) {
// Only construct qtk resource path if in qrc format; else return it as-is // Only construct qtk resource path if in qrc format; else return it as-is
return path[0] == ':' ? resourcesDir + path.substr(2) : path; return path[0] == ':' ? QTK_RESOURCES_DIR + path.substr(1) : path;
} }
static std::string resourcesDir;
} RM; } RM;
#endif //QTK_RESOURCEMANAGER_H #endif //QTK_RESOURCEMANAGER_H

View File

@ -6,32 +6,27 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## ## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/ ##############################################################################*/
#include <abstractscene.h>
#include <camera3d.h> #include <camera3d.h>
#include <texture.h>
#include <meshrenderer.h> #include <meshrenderer.h>
#include <model.h> #include <model.h>
#include <resourcemanager.h> #include <resourcemanager.h>
#include <scene.h> #include <scene.h>
#include <texture.h>
using namespace Qtk;
Camera3D Scene::mCamera;
QMatrix4x4 Scene::mProjection;
/******************************************************************************* /*******************************************************************************
* Constructors, Destructors * Constructors, Destructors
******************************************************************************/ ******************************************************************************/
Scene::Scene() ExampleScene::ExampleScene()
{ {
mCamera.transform().setTranslation(0.0f, 0.0f, 20.0f); Camera().transform().setTranslation(0.0f, 0.0f, 20.0f);
mCamera.transform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f); Camera().transform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
init();
} }
Scene::~Scene() ExampleScene::~ExampleScene()
{ {
delete mTestPhong; delete mTestPhong;
delete mTestSpecular; delete mTestSpecular;
@ -39,6 +34,7 @@ Scene::~Scene()
delete mTestAmbient; delete mTestAmbient;
for (auto & mesh : mMeshes) delete mesh; for (auto & mesh : mMeshes) delete mesh;
for (auto & model : mModels) delete model; for (auto & model : mModels) delete model;
delete mSkybox;
} }
@ -46,10 +42,13 @@ Scene::~Scene()
* Public Member Functions * Public Member Functions
******************************************************************************/ ******************************************************************************/
void Scene::init() void ExampleScene::init()
{ {
Qtk::Skybox * sb = new Qtk::Skybox("Skybox");
setSkybox(sb);
// Initialize Phong example cube // Initialize Phong example cube
mTestPhong = new MeshRenderer("phong", Cube()); mTestPhong = new Qtk::MeshRenderer("phong", Qtk::Cube());
mTestPhong->mTransform.setTranslation(3.0f, 0.0f, -2.0f); mTestPhong->mTransform.setTranslation(3.0f, 0.0f, -2.0f);
mTestPhong->setShaders(":/solid-phong.vert", ":/solid-phong.frag"); mTestPhong->setShaders(":/solid-phong.vert", ":/solid-phong.frag");
mTestPhong->init(); mTestPhong->init();
@ -76,7 +75,7 @@ void Scene::init()
// Initialize Ambient example cube // Initialize Ambient example cube
mTestAmbient = new MeshRenderer("ambient", Cube()); mTestAmbient = new Qtk::MeshRenderer("ambient", Cube());
mTestAmbient->mTransform.setTranslation(7.0f, 0.0f, -2.0f); mTestAmbient->mTransform.setTranslation(7.0f, 0.0f, -2.0f);
mTestAmbient->setShaders(":/solid-ambient.vert", ":/solid-ambient.frag"); mTestAmbient->setShaders(":/solid-ambient.vert", ":/solid-ambient.frag");
mTestAmbient->init(); mTestAmbient->init();
@ -100,7 +99,7 @@ void Scene::init()
mTestAmbient->mProgram.release(); mTestAmbient->mProgram.release();
// Initialize Diffuse example cube // Initialize Diffuse example cube
mTestDiffuse = new MeshRenderer("diffuse", Cube()); mTestDiffuse = new Qtk::MeshRenderer("diffuse", Cube());
mTestDiffuse->mTransform.setTranslation(9.0f, 0.0f, -2.0f); mTestDiffuse->mTransform.setTranslation(9.0f, 0.0f, -2.0f);
mTestDiffuse->setShaders(":/solid-diffuse.vert", ":/solid-diffuse.frag"); mTestDiffuse->setShaders(":/solid-diffuse.vert", ":/solid-diffuse.frag");
mTestDiffuse->init(); mTestDiffuse->init();
@ -124,7 +123,7 @@ void Scene::init()
mTestDiffuse->mProgram.release(); mTestDiffuse->mProgram.release();
// Initialize Specular example cube // Initialize Specular example cube
mTestSpecular = new MeshRenderer("specular", Cube()); mTestSpecular = new Qtk::MeshRenderer("specular", Cube());
mTestSpecular->mTransform.setTranslation(11.0f, 0.0f, -2.0f); mTestSpecular->mTransform.setTranslation(11.0f, 0.0f, -2.0f);
mTestSpecular->setShaders(":/solid-specular.vert", ":/solid-specular.frag"); mTestSpecular->setShaders(":/solid-specular.vert", ":/solid-specular.frag");
mTestSpecular->init(); mTestSpecular->init();
@ -152,31 +151,31 @@ void Scene::init()
// //
// Model loading // Model loading
mModels.push_back(new Model("backpack", ":/models/backpack/backpack.obj")); mModels.push_back(new Qtk::Model("backpack", ":/models/backpack/backpack.obj"));
// Sometimes model textures need flipped in certain directions // Sometimes model textures need flipped in certain directions
mModels.back()->flipTexture("diffuse.jpg", false, true); mModels.back()->flipTexture("diffuse.jpg", false, true);
mModels.back()->mTransform.setTranslation(0.0f, 0.0f, -10.0f); mModels.back()->mTransform.setTranslation(0.0f, 0.0f, -10.0f);
mModels.push_back(new Model("bird", ":/models/bird/bird.obj")); mModels.push_back(new Qtk::Model("bird", ":/models/bird/bird.obj"));
mModels.back()->mTransform.setTranslation(2.0f, 2.0f, -10.0f); mModels.back()->mTransform.setTranslation(2.0f, 2.0f, -10.0f);
// Sometimes the models are very large // Sometimes the models are very large
mModels.back()->mTransform.scale(0.0025f); mModels.back()->mTransform.scale(0.0025f);
mModels.back()->mTransform.rotate(-110.0f, 0.0f, 1.0f, 0.0f); mModels.back()->mTransform.rotate(-110.0f, 0.0f, 1.0f, 0.0f);
mModels.push_back(new Model("lion", ":/models/lion/lion.obj")); mModels.push_back(new Qtk::Model("lion", ":/models/lion/lion.obj"));
mModels.back()->mTransform.setTranslation(-3.0f, -1.0f, -10.0f); mModels.back()->mTransform.setTranslation(-3.0f, -1.0f, -10.0f);
mModels.back()->mTransform.scale(0.15f); mModels.back()->mTransform.scale(0.15f);
mModels.push_back(new Model("alien", ":/models/alien-hominid/alien.obj")); mModels.push_back(new Qtk::Model("alien", ":/models/alien-hominid/alien.obj"));
mModels.back()->mTransform.setTranslation(2.0f, -1.0f, -5.0f); mModels.back()->mTransform.setTranslation(2.0f, -1.0f, -5.0f);
mModels.back()->mTransform.scale(0.15f); mModels.back()->mTransform.scale(0.15f);
mModels.push_back(new Model("scythe", ":/models/scythe/scythe.obj")); mModels.push_back(new Qtk::Model("scythe", ":/models/scythe/scythe.obj"));
mModels.back()->mTransform.setTranslation(-6.0f, 0.0f, -10.0f); mModels.back()->mTransform.setTranslation(-6.0f, 0.0f, -10.0f);
mModels.back()->mTransform.rotate(-90.0f, 1.0f, 0.0f, 0.0f); mModels.back()->mTransform.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
mModels.back()->mTransform.rotate(90.0f, 0.0f, 1.0f, 0.0f); mModels.back()->mTransform.rotate(90.0f, 0.0f, 1.0f, 0.0f);
mModels.push_back(new Model("masterChief", ":/models/spartan/spartan.obj")); mModels.push_back(new Qtk::Model("masterChief", ":/models/spartan/spartan.obj"));
mModels.back()->mTransform.setTranslation(-1.5f, 0.5f, -2.0f); mModels.back()->mTransform.setTranslation(-1.5f, 0.5f, -2.0f);
@ -186,7 +185,7 @@ void Scene::init()
// Render an alien with specular // Render an alien with specular
// Test alien Model with phong lighting and specular mapping // Test alien Model with phong lighting and specular mapping
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("alienTestLight", Triangle(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("alienTestLight", Triangle(Qtk::QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(4.0f, 1.5f, 10.0f); mMeshes.back()->mTransform.setTranslation(4.0f, 1.5f, 10.0f);
mMeshes.back()->mTransform.scale(0.25f); mMeshes.back()->mTransform.scale(0.25f);
// This function changes values we have allocated in a buffer, so init() after // This function changes values we have allocated in a buffer, so init() after
@ -194,7 +193,7 @@ void Scene::init()
mMeshes.back()->init(); mMeshes.back()->init();
mModels.push_back( mModels.push_back(
new Model("alienTest", ":/models/alien-hominid/alien.obj", new Qtk::Model("alienTest", ":/models/alien-hominid/alien.obj",
":/model-specular.vert", ":/model-specular.frag") ":/model-specular.vert", ":/model-specular.frag")
); );
mModels.back()->mTransform.setTranslation(3.0f, -1.0f, 10.0f); mModels.back()->mTransform.setTranslation(3.0f, -1.0f, 10.0f);
@ -214,7 +213,7 @@ void Scene::init()
// Test spartan Model with phong lighting, specular and normal mapping // Test spartan Model with phong lighting, specular and normal mapping
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("spartanTestLight", Triangle(QTK_DRAW_ELEMENTS)) new Qtk::MeshRenderer("spartanTestLight", Triangle(QTK_DRAW_ELEMENTS))
); );
mMeshes.back()->mTransform.setTranslation(1.0f, 1.5f, 10.0f); mMeshes.back()->mTransform.setTranslation(1.0f, 1.5f, 10.0f);
mMeshes.back()->mTransform.scale(0.25f); mMeshes.back()->mTransform.scale(0.25f);
@ -223,7 +222,7 @@ void Scene::init()
mMeshes.back()->init(); mMeshes.back()->init();
mModels.push_back( mModels.push_back(
new Model("spartanTest", ":/models/spartan/spartan.obj", new Qtk::Model("spartanTest", ":/models/spartan/spartan.obj",
":/model-normals.vert", ":/model-normals.frag") ":/model-normals.vert", ":/model-normals.frag")
); );
mModels.back()->mTransform.setTranslation(0.0f, -1.0f, 10.0f); mModels.back()->mTransform.setTranslation(0.0f, -1.0f, 10.0f);
@ -242,7 +241,7 @@ void Scene::init()
// Test basic cube with phong.vert and phong.frag shaders // Test basic cube with phong.vert and phong.frag shaders
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("testLight", Triangle(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("testLight", Triangle(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(5.0f, 1.25f, 10.0f); mMeshes.back()->mTransform.setTranslation(5.0f, 1.25f, 10.0f);
mMeshes.back()->mTransform.scale(0.25f); mMeshes.back()->mTransform.scale(0.25f);
mMeshes.back()->setDrawType(GL_LINE_LOOP); mMeshes.back()->setDrawType(GL_LINE_LOOP);
@ -251,7 +250,7 @@ void Scene::init()
mMeshes.back()->init(); mMeshes.back()->init();
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("testPhong", Cube(QTK_DRAW_ARRAYS))); new Qtk::MeshRenderer("testPhong", Cube(QTK_DRAW_ARRAYS)));
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 10.0f); mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 10.0f);
mMeshes.back()->setShaders(":/phong.vert", ":/phong.frag"); mMeshes.back()->setShaders(":/phong.vert", ":/phong.frag");
mMeshes.back()->setColor(QVector3D(0.0f, 0.25f, 0.0f)); mMeshes.back()->setColor(QVector3D(0.0f, 0.25f, 0.0f));
@ -291,25 +290,25 @@ void Scene::init()
// Create simple shapes using MeshRenderer class and data in mesh.h // Create simple shapes using MeshRenderer class and data in mesh.h
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(-5.0f, 0.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(-5.0f, 0.0f, -2.0f);
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("centerCube", Cube(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("centerCube", Cube(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(-7.0f, 0.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(-7.0f, 0.0f, -2.0f);
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("leftTriangle", Triangle(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("leftTriangle", Triangle(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(-9.0f, 0.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(-9.0f, 0.0f, -2.0f);
mMeshes.back()->setDrawType(GL_LINE_LOOP); mMeshes.back()->setDrawType(GL_LINE_LOOP);
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("topTriangle", Triangle(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("topTriangle", Triangle(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(-7.0f, 2.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(-7.0f, 2.0f, -2.0f);
mMeshes.back()->mTransform.scale(0.25f); mMeshes.back()->mTransform.scale(0.25f);
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("bottomTriangle", Triangle(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("bottomTriangle", Triangle(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(-7.0f, -2.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(-7.0f, -2.0f, -2.0f);
mMeshes.back()->mTransform.scale(0.25f); mMeshes.back()->mTransform.scale(0.25f);
mMeshes.back()->setDrawType(GL_LINE_LOOP); mMeshes.back()->setDrawType(GL_LINE_LOOP);
@ -322,7 +321,7 @@ void Scene::init()
// RGB Normals cube to show normals are correct with QTK_DRAW_ARRAYS // RGB Normals cube to show normals are correct with QTK_DRAW_ARRAYS
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("rgbNormalsCubeArraysTest", Cube(QTK_DRAW_ARRAYS))); new Qtk::MeshRenderer("rgbNormalsCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 4.0f); mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 4.0f);
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag"); mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
mMeshes.back()->init(); mMeshes.back()->init();
@ -344,7 +343,7 @@ void Scene::init()
// RGB Normals cube to show normals are correct with QTK_DRAW_ELEMENTS_NORMALS // RGB Normals cube to show normals are correct with QTK_DRAW_ELEMENTS_NORMALS
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("rgbNormalsCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS))); new Qtk::MeshRenderer("rgbNormalsCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 2.0f); mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 2.0f);
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag"); mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
mMeshes.back()->init(); mMeshes.back()->init();
@ -369,7 +368,7 @@ void Scene::init()
// + UVs required duplicating element position data from QTK_DRAW_ELEMENTS // + UVs required duplicating element position data from QTK_DRAW_ELEMENTS
// + This is because the same position must use different UV coordinates // + This is because the same position must use different UV coordinates
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("uvCubeArraysTest", Cube(QTK_DRAW_ARRAYS))); new Qtk::MeshRenderer("uvCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
mMeshes.back()->mTransform.setTranslation(-3.0f, 0.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(-3.0f, 0.0f, -2.0f);
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag"); mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
mMeshes.back()->init(); mMeshes.back()->init();
@ -397,7 +396,7 @@ void Scene::init()
// Test drawing a cube with texture coordinates using glDrawElements // Test drawing a cube with texture coordinates using glDrawElements
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("uvCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS))); new Qtk::MeshRenderer("uvCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
mMeshes.back()->mTransform.setTranslation(-1.7f, 0.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(-1.7f, 0.0f, -2.0f);
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag"); mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
mMeshes.back()->init(); mMeshes.back()->init();
@ -423,7 +422,7 @@ void Scene::init()
// Texturing a cube using a cube map // Texturing a cube using a cube map
// + Cube map texturing works with both QTK_DRAW_ARRAYS and QTK_DRAW_ELEMENTS // + Cube map texturing works with both QTK_DRAW_ARRAYS and QTK_DRAW_ELEMENTS
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(-3.0f, 1.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(-3.0f, 1.0f, -2.0f);
mMeshes.back()->mTransform.setRotation(45.0f, 0.0f, 1.0f, 0.0f); mMeshes.back()->mTransform.setRotation(45.0f, 0.0f, 1.0f, 0.0f);
mMeshes.back()->setShaders(":/texture-cubemap.vert", ":/texture-cubemap.frag"); mMeshes.back()->setShaders(":/texture-cubemap.vert", ":/texture-cubemap.frag");
@ -450,7 +449,7 @@ void Scene::init()
// Create a cube with custom shaders // Create a cube with custom shaders
// + Apply RGB normals shader and spin the cube for a neat effect // + Apply RGB normals shader and spin the cube for a neat effect
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("rgbNormalsCube", Cube(QTK_DRAW_ARRAYS))); new Qtk::MeshRenderer("rgbNormalsCube", Cube(QTK_DRAW_ARRAYS)));
mMeshes.back()->mTransform.setTranslation(5.0f, 2.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(5.0f, 2.0f, -2.0f);
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag"); mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
mMeshes.back()->init(); mMeshes.back()->init();
@ -472,7 +471,7 @@ void Scene::init()
// RGB Normals triangle to show normals are correct with QTK_DRAW_ARRAYS // RGB Normals triangle to show normals are correct with QTK_DRAW_ARRAYS
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("rgbTriangleArraysTest", Triangle(QTK_DRAW_ARRAYS))); new Qtk::MeshRenderer("rgbTriangleArraysTest", Triangle(QTK_DRAW_ARRAYS)));
mMeshes.back()->mTransform.setTranslation(7.0f, 0.0f, 2.0f); mMeshes.back()->mTransform.setTranslation(7.0f, 0.0f, 2.0f);
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag"); mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
mMeshes.back()->init(); mMeshes.back()->init();
@ -493,7 +492,7 @@ void Scene::init()
// RGB Normals triangle to show normals are correct with QTK_DRAW_ELEMENTS // RGB Normals triangle to show normals are correct with QTK_DRAW_ELEMENTS
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("rgbTriangleElementsTest", new Qtk::MeshRenderer("rgbTriangleElementsTest",
Triangle(QTK_DRAW_ELEMENTS_NORMALS))); Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
mMeshes.back()->mTransform.setTranslation(7.0f, 0.0f, 4.0f); mMeshes.back()->mTransform.setTranslation(7.0f, 0.0f, 4.0f);
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag"); mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
@ -515,7 +514,7 @@ void Scene::init()
// Test drawing triangle with glDrawArrays with texture coordinates // Test drawing triangle with glDrawArrays with texture coordinates
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("testTriangleArraysUV", Triangle(QTK_DRAW_ARRAYS))); new Qtk::MeshRenderer("testTriangleArraysUV", Triangle(QTK_DRAW_ARRAYS)));
mMeshes.back()->mTransform.setTranslation(-3.0f, 2.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(-3.0f, 2.0f, -2.0f);
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag"); mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
mMeshes.back()->init(); mMeshes.back()->init();
@ -543,7 +542,7 @@ void Scene::init()
// Test drawing triangle with glDrawElements with texture coordinates // Test drawing triangle with glDrawElements with texture coordinates
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("testTriangleElementsUV", new Qtk::MeshRenderer("testTriangleElementsUV",
Triangle(QTK_DRAW_ELEMENTS_NORMALS))); Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
mMeshes.back()->mTransform.setTranslation(-2.5f, 0.0f, -1.0f); mMeshes.back()->mTransform.setTranslation(-2.5f, 0.0f, -1.0f);
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag"); mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
@ -575,7 +574,7 @@ void Scene::init()
// Example of a cube with no lighting applied // Example of a cube with no lighting applied
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("noLight", Cube(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("noLight", Cube(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, -2.0f);
mMeshes.back()->setShaders(":/solid-perspective.vert", mMeshes.back()->setShaders(":/solid-perspective.vert",
":/solid-perspective.frag"); ":/solid-perspective.frag");
@ -586,24 +585,24 @@ void Scene::init()
// Create objects that represent light sources for lighting examples // Create objects that represent light sources for lighting examples
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("phongLight", Triangle(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("phongLight", Triangle(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(3.0f, 2.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(3.0f, 2.0f, -2.0f);
mMeshes.back()->mTransform.scale(0.25f); mMeshes.back()->mTransform.scale(0.25f);
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("diffuseLight", Triangle(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("diffuseLight", Triangle(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(9.0f, 2.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(9.0f, 2.0f, -2.0f);
mMeshes.back()->mTransform.scale(0.25f); mMeshes.back()->mTransform.scale(0.25f);
mMeshes.push_back( mMeshes.push_back(
new MeshRenderer("specularLight", Triangle(QTK_DRAW_ELEMENTS))); new Qtk::MeshRenderer("specularLight", Triangle(QTK_DRAW_ELEMENTS)));
mMeshes.back()->mTransform.setTranslation(11.0f, 2.0f, -2.0f); mMeshes.back()->mTransform.setTranslation(11.0f, 2.0f, -2.0f);
mMeshes.back()->mTransform.scale(0.25f); mMeshes.back()->mTransform.scale(0.25f);
} }
void Scene::draw() void ExampleScene::draw()
{ {
mSkybox.draw(); mSkybox->draw();
for (auto & model : mModels) model->draw(); for (auto & model : mModels) model->draw();
@ -616,13 +615,13 @@ void Scene::draw()
"uLightPosition", "uLightPosition",
MeshRenderer::getInstance("phongLight")->mTransform.translation()); MeshRenderer::getInstance("phongLight")->mTransform.translation());
mTestPhong->setUniform("uCameraPosition", mTestPhong->setUniform("uCameraPosition",
Scene::Camera().transform().translation()); ExampleScene::Camera().transform().translation());
mTestPhong->mProgram.release(); mTestPhong->mProgram.release();
mTestPhong->draw(); mTestPhong->draw();
mTestAmbient->mProgram.bind(); mTestAmbient->mProgram.bind();
mTestAmbient->setUniform("uCameraPosition", mTestAmbient->setUniform("uCameraPosition",
Scene::Camera().transform().translation()); ExampleScene::Camera().transform().translation());
mTestAmbient->mProgram.release(); mTestAmbient->mProgram.release();
mTestAmbient->draw(); mTestAmbient->draw();
@ -632,7 +631,7 @@ void Scene::draw()
mTestDiffuse->setUniform( mTestDiffuse->setUniform(
"uLightPosition", "uLightPosition",
MeshRenderer::getInstance("diffuseLight")->mTransform.translation()); MeshRenderer::getInstance("diffuseLight")->mTransform.translation());
mTestDiffuse->setUniform("uCameraPosition", Scene::Camera().transform().translation()); mTestDiffuse->setUniform("uCameraPosition", ExampleScene::Camera().transform().translation());
mTestDiffuse->mProgram.release(); mTestDiffuse->mProgram.release();
mTestDiffuse->draw(); mTestDiffuse->draw();
@ -643,43 +642,43 @@ void Scene::draw()
mTestSpecular->setUniform( mTestSpecular->setUniform(
"uLightPosition", "uLightPosition",
MeshRenderer::getInstance("specularLight")->mTransform.translation()); MeshRenderer::getInstance("specularLight")->mTransform.translation());
mTestSpecular->setUniform("uCameraPosition", Scene::Camera().transform().translation()); mTestSpecular->setUniform("uCameraPosition", ExampleScene::Camera().transform().translation());
mTestSpecular->mProgram.release(); mTestSpecular->mProgram.release();
mTestSpecular->draw(); mTestSpecular->draw();
} }
void Scene::update() void ExampleScene::update()
{ {
auto position = MeshRenderer::getInstance("alienTestLight")->mTransform.translation(); auto position = MeshRenderer::getInstance("alienTestLight")->mTransform.translation();
Model::getInstance("alienTest")->setUniform( Model::getInstance("alienTest")->setUniform(
"uLight.position", position); "uLight.position", position);
Model::getInstance("alienTest")->setUniform( Model::getInstance("alienTest")->setUniform(
"uCameraPosition", Scene::Camera().transform().translation()); "uCameraPosition", ExampleScene::Camera().transform().translation());
auto posMatrix = Model::getInstance("alienTest")->mTransform.toMatrix(); auto posMatrix = Model::getInstance("alienTest")->mTransform.toMatrix();
Model::getInstance("alienTest")->setUniform( Model::getInstance("alienTest")->setUniform(
"uMVP.normalMatrix", posMatrix.normalMatrix()); "uMVP.normalMatrix", posMatrix.normalMatrix());
Model::getInstance("alienTest")->setUniform( Model::getInstance("alienTest")->setUniform(
"uMVP.model", posMatrix); "uMVP.model", posMatrix);
Model::getInstance("alienTest")->setUniform( Model::getInstance("alienTest")->setUniform(
"uMVP.view", Scene::Camera().toMatrix()); "uMVP.view", ExampleScene::Camera().toMatrix());
Model::getInstance("alienTest")->setUniform( Model::getInstance("alienTest")->setUniform(
"uMVP.projection", Scene::Projection()); "uMVP.projection", ExampleScene::Projection());
Model::getInstance("alienTest")->mTransform.rotate(0.75f, 0.0f, 1.0f, 0.0f); Model::getInstance("alienTest")->mTransform.rotate(0.75f, 0.0f, 1.0f, 0.0f);
position = MeshRenderer::getInstance("spartanTestLight")->mTransform.translation(); position = MeshRenderer::getInstance("spartanTestLight")->mTransform.translation();
Model::getInstance("spartanTest")->setUniform( Model::getInstance("spartanTest")->setUniform(
"uLight.position", position); "uLight.position", position);
Model::getInstance("spartanTest")->setUniform( Model::getInstance("spartanTest")->setUniform(
"uCameraPosition", Scene::Camera().transform().translation()); "uCameraPosition", ExampleScene::Camera().transform().translation());
posMatrix = Model::getInstance("spartanTest")->mTransform.toMatrix(); posMatrix = Model::getInstance("spartanTest")->mTransform.toMatrix();
Model::getInstance("spartanTest")->setUniform( Model::getInstance("spartanTest")->setUniform(
"uMVP.normalMatrix", posMatrix.normalMatrix()); "uMVP.normalMatrix", posMatrix.normalMatrix());
Model::getInstance("spartanTest")->setUniform( Model::getInstance("spartanTest")->setUniform(
"uMVP.model", posMatrix); "uMVP.model", posMatrix);
Model::getInstance("spartanTest")->setUniform( Model::getInstance("spartanTest")->setUniform(
"uMVP.view", Scene::Camera().toMatrix()); "uMVP.view", ExampleScene::Camera().toMatrix());
Model::getInstance("spartanTest")->setUniform( Model::getInstance("spartanTest")->setUniform(
"uMVP.projection", Scene::Projection()); "uMVP.projection", ExampleScene::Projection());
Model::getInstance("spartanTest")->mTransform.rotate(0.75f, 0.0f, 1.0f, 0.0f); Model::getInstance("spartanTest")->mTransform.rotate(0.75f, 0.0f, 1.0f, 0.0f);
@ -691,16 +690,16 @@ void Scene::update()
MeshRenderer::getInstance("testPhong")->setUniform( MeshRenderer::getInstance("testPhong")->setUniform(
"uLight.position", position); "uLight.position", position);
MeshRenderer::getInstance("testPhong")->setUniform( MeshRenderer::getInstance("testPhong")->setUniform(
"uCameraPosition", Scene::Camera().transform().translation()); "uCameraPosition", ExampleScene::Camera().transform().translation());
posMatrix = MeshRenderer::getInstance("testPhong")->mTransform.toMatrix(); posMatrix = MeshRenderer::getInstance("testPhong")->mTransform.toMatrix();
MeshRenderer::getInstance("testPhong")->setUniform( MeshRenderer::getInstance("testPhong")->setUniform(
"uMVP.normalMatrix", posMatrix.normalMatrix()); "uMVP.normalMatrix", posMatrix.normalMatrix());
MeshRenderer::getInstance("testPhong")->setUniform( MeshRenderer::getInstance("testPhong")->setUniform(
"uMVP.model", posMatrix); "uMVP.model", posMatrix);
MeshRenderer::getInstance("testPhong")->setUniform( MeshRenderer::getInstance("testPhong")->setUniform(
"uMVP.view", Scene::Camera().toMatrix()); "uMVP.view", ExampleScene::Camera().toMatrix());
MeshRenderer::getInstance("testPhong")->setUniform( MeshRenderer::getInstance("testPhong")->setUniform(
"uMVP.projection", Scene::Projection()); "uMVP.projection", ExampleScene::Projection());
MeshRenderer::getInstance("testPhong")->mProgram.release(); MeshRenderer::getInstance("testPhong")->mProgram.release();
// Rotate lighting example cubes // Rotate lighting example cubes

View File

@ -6,40 +6,31 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## ## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/ ##############################################################################*/
#ifndef QTK_SCENE_H #ifndef QTK_EXAMPLE_SCENE_H
#define QTK_SCENE_H #define QTK_EXAMPLE_SCENE_H
#include <abstractscene.h>
#include <camera3d.h> #include <camera3d.h>
#include <skybox.h> #include <skybox.h>
#include <QMatrix4x4> #include <QMatrix4x4>
class MeshRenderer;
class Model;
class Scene { class ExampleScene : public Qtk::Scene {
public: public:
Scene(); ExampleScene();
~Scene(); ~ExampleScene();
void init(); virtual void init();
void draw(); virtual void draw();
void update(); virtual void update();
static Camera3D & Camera() { return mCamera;}
static QMatrix4x4 View() { return mCamera.toMatrix();}
static QMatrix4x4 & Projection() { return mProjection;}
private: private:
static Camera3D mCamera;
static QMatrix4x4 mProjection;
Skybox mSkybox; Qtk::MeshRenderer * mTestPhong;
MeshRenderer * mTestPhong; Qtk::MeshRenderer * mTestSpecular;
MeshRenderer * mTestSpecular; Qtk::MeshRenderer * mTestDiffuse;
MeshRenderer * mTestDiffuse; Qtk::MeshRenderer * mTestAmbient;
MeshRenderer * mTestAmbient;
std::vector<MeshRenderer *> mMeshes;
std::vector<Model *> mModels;
}; };
#endif // QTK_SCENE_H #endif // QTK_EXAMPLE_SCENE_H

48
src/abstractscene.cpp Normal file
View File

@ -0,0 +1,48 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Classes for managing objects and data within a scene ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <abstractscene.h>
#include <camera3d.h>
#include <resourcemanager.h>
#include <texture.h>
using namespace Qtk;
Camera3D Scene::mCamera;
QMatrix4x4 Scene::mProjection;
/*******************************************************************************
* Constructors, Destructors
******************************************************************************/
Scene::Scene()
{
mCamera.transform().setTranslation(0.0f, 0.0f, 20.0f);
mCamera.transform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
}
Scene::~Scene()
{
for (auto & mesh : mMeshes) delete mesh;
for (auto & model : mModels) delete model;
if (mSkybox != Q_NULLPTR) delete mSkybox;
}
void Scene::privDraw()
{
if (!mInit) {
initializeOpenGLFunctions();
init();
mInit = true;
}
if (mSkybox != Q_NULLPTR) mSkybox->draw();
for (auto & model : mModels) model->draw();
for (const auto & mesh : mMeshes) mesh->draw();
}

54
src/abstractscene.h Normal file
View File

@ -0,0 +1,54 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Classes for managing objects and data within a scene ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#ifndef QTK_SCENE_H
#define QTK_SCENE_H
#include <camera3d.h>
#include <meshrenderer.h>
#include <model.h>
#include <skybox.h>
#include <QMatrix4x4>
namespace Qtk {
class Scene : protected QOpenGLFunctions {
friend class MainWidget;
public:
Scene();
~Scene();
virtual void init() = 0;
virtual void draw() = 0;
virtual void update() = 0;
static Camera3D & Camera() { return mCamera;}
static QMatrix4x4 View() { return mCamera.toMatrix();}
static QMatrix4x4 & Projection() { return mProjection;}
inline Skybox * getSkybox() {return mSkybox;}
inline void setSkybox(Skybox * skybox) {
mSkybox = skybox;
}
private:
static Camera3D mCamera;
static QMatrix4x4 mProjection;
bool mInit = false;
void privDraw();
protected:
Skybox * mSkybox;
std::vector<MeshRenderer *> mMeshes;
std::vector<Model *> mModels;
};
}
#endif // QTK_SCENE_H

View File

@ -8,6 +8,7 @@
#include <camera3d.h> #include <camera3d.h>
using namespace Qtk;
const QVector3D Camera3D::LocalForward(0.0f, 0.0f, -1.0f); const QVector3D Camera3D::LocalForward(0.0f, 0.0f, -1.0f);
const QVector3D Camera3D::LocalUp(0.0f, 1.0f, 0.0f); const QVector3D Camera3D::LocalUp(0.0f, 1.0f, 0.0f);

View File

@ -12,51 +12,53 @@
#include <QDebug> #include <QDebug>
#include <transform3D.h> #include <transform3D.h>
#include <qtkapi.h>
namespace Qtk {
class QTKAPI Camera3D {
public:
// Constants
static const QVector3D LocalForward;
static const QVector3D LocalUp;
static const QVector3D LocalRight;
class Camera3D { // Accessors
public: inline Transform3D & transform() { return mTransform;}
// Constants inline const QVector3D & translation() const
static const QVector3D LocalForward; { return mTransform.translation();}
static const QVector3D LocalUp; inline const QQuaternion & rotation() const
static const QVector3D LocalRight; { return mTransform.rotation();}
const QMatrix4x4 & toMatrix();
// Accessors // Queries
inline Transform3D & transform() { return mTransform;} inline QVector3D forward() const
inline const QVector3D & translation() const { return mTransform.rotation().rotatedVector(LocalForward);}
{ return mTransform.translation();} inline QVector3D right() const
inline const QQuaternion & rotation() const { return mTransform.rotation().rotatedVector(LocalRight);}
{ return mTransform.rotation();} inline QVector3D up() const
const QMatrix4x4 & toMatrix(); { return mTransform.rotation().rotatedVector(LocalUp);}
// Queries private:
inline QVector3D forward() const Transform3D mTransform;
{ return mTransform.rotation().rotatedVector(LocalForward);} QMatrix4x4 mWorld;
inline QVector3D right() const
{ return mTransform.rotation().rotatedVector(LocalRight);}
inline QVector3D up() const
{ return mTransform.rotation().rotatedVector(LocalUp);}
private:
Transform3D mTransform;
QMatrix4x4 mWorld;
#ifndef QT_NO_DATASTREAM #ifndef QT_NO_DATASTREAM
friend QDataStream & operator<<(QDataStream & out, Camera3D & transform); friend QDataStream & operator<<(QDataStream & out, Camera3D & transform);
friend QDataStream & operator>>(QDataStream & in, Camera3D & transform); friend QDataStream & operator>>(QDataStream & in, Camera3D & transform);
#endif #endif
}; };
Q_DECLARE_TYPEINFO(Camera3D, Q_MOVABLE_TYPE);
// Qt Streams // Qt Streams
#ifndef QT_NO_DATASTREAM #ifndef QT_NO_DATASTREAM
QDataStream & operator<<(QDataStream & out, const Camera3D & transform); QDataStream & operator<<(QDataStream & out, const Camera3D & transform);
QDataStream & operator>>(QDataStream & in, Camera3D & transform); QDataStream & operator>>(QDataStream & in, Camera3D & transform);
#endif #endif
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const Camera3D & transform); QDebug operator<<(QDebug dbg, const Camera3D & transform);
#endif #endif
}
Q_DECLARE_TYPEINFO(Qtk::Camera3D, Q_MOVABLE_TYPE);
#endif // QTK_CAMERA3D_H #endif // QTK_CAMERA3D_H

View File

@ -13,6 +13,7 @@
#include <input.h> #include <input.h>
using namespace Qtk;
/******************************************************************************* /*******************************************************************************
* Static Helper Structs * Static Helper Structs

View File

@ -12,52 +12,53 @@
#include <QPoint> #include <QPoint>
#include <Qt> #include <Qt>
#include <qtkapi.h>
class Input { namespace Qtk {
friend class MainWidget; class QTKAPI Input {
public: friend class MainWidget;
public:
// Possible key states
enum InputState
{
InputInvalid,
InputRegistered,
InputUnregistered,
InputTriggered,
InputPressed,
InputReleased
};
// Possible key states // State checking
enum InputState inline static bool keyTriggered(Qt::Key key)
{ { return keyState(key) == InputTriggered;}
InputInvalid, inline static bool keyPressed(Qt::Key key)
InputRegistered, { return keyState(key) == InputPressed;}
InputUnregistered, inline static bool keyReleased(Qt::Key key)
InputTriggered, { return keyState(key) == InputReleased;}
InputPressed, inline static bool buttonTriggered(Qt::MouseButton button)
InputReleased { return buttonState(button) == InputTriggered;}
inline static bool buttonPressed(Qt::MouseButton button)
{ return buttonState(button) == InputPressed;}
inline static bool buttonReleased(Qt::MouseButton button)
{ return buttonState(button) == InputReleased;}
// Implementation
static InputState keyState(Qt::Key key);
static InputState buttonState(Qt::MouseButton button);
static QPoint mousePosition();
static QPoint mouseDelta();
private:
// State updating
static void update();
static void registerKeyPress(int key);
static void registerKeyRelease(int key);
static void registerMousePress(Qt::MouseButton button);
static void registerMouseRelease(Qt::MouseButton button);
static void reset();
}; };
}
// State checking
inline static bool keyTriggered(Qt::Key key)
{ return keyState(key) == InputTriggered;}
inline static bool keyPressed(Qt::Key key)
{ return keyState(key) == InputPressed;}
inline static bool keyReleased(Qt::Key key)
{ return keyState(key) == InputReleased;}
inline static bool buttonTriggered(Qt::MouseButton button)
{ return buttonState(button) == InputTriggered;}
inline static bool buttonPressed(Qt::MouseButton button)
{ return buttonState(button) == InputPressed;}
inline static bool buttonReleased(Qt::MouseButton button)
{ return buttonState(button) == InputReleased;}
// Implementation
static InputState keyState(Qt::Key key);
static InputState buttonState(Qt::MouseButton button);
static QPoint mousePosition();
static QPoint mouseDelta();
private:
// State updating
static void update();
static void registerKeyPress(int key);
static void registerKeyRelease(int key);
static void registerMousePress(Qt::MouseButton button);
static void registerMouseRelease(Qt::MouseButton button);
static void reset();
};
#endif // QTOPENGL_INPUT_H #endif // QTOPENGL_INPUT_H

View File

@ -9,30 +9,30 @@
#include <QKeyEvent> #include <QKeyEvent>
#include <input.h> #include <input.h>
#include <mesh.h>
#include <object.h>
#include <scene.h>
#include <mainwidget.h> #include <mainwidget.h>
#include <mesh.h>
#include <abstractscene.h>
using namespace Qtk;
/******************************************************************************* /*******************************************************************************
* Constructors, Destructors * Constructors, Destructors
******************************************************************************/ ******************************************************************************/
MainWidget::MainWidget() : mDebugLogger(Q_NULLPTR) MainWidget::MainWidget() : mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
{ {
initializeWidget(); initializeWidget();
} }
// Constructor for using this widget in QtDesigner // Constructor for using this widget in QtDesigner
MainWidget::MainWidget(QWidget *parent) : QOpenGLWidget(parent), mDebugLogger(Q_NULLPTR) MainWidget::MainWidget(QWidget *parent) : QOpenGLWidget(parent),
mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
{ {
initializeWidget(); initializeWidget();
} }
MainWidget::MainWidget(const QSurfaceFormat &format) MainWidget::MainWidget(const QSurfaceFormat &format)
: mDebugLogger(Q_NULLPTR) : mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
{ {
setFormat(format); setFormat(format);
setFocusPolicy(Qt::ClickFocus); setFocusPolicy(Qt::ClickFocus);
@ -54,49 +54,6 @@ void MainWidget::teardownGL()
// Nothing to teardown yet... // Nothing to teardown yet...
} }
void MainWidget::initObjects()
{
mScene = new Scene;
// Drawing a primitive object using Qt and OpenGL
// The Object class only stores basic QOpenGL* members and shape data
// + Within mainwidget, mObject serves as a basic QOpenGL example
mObject = new Object("testObject");
mObject->setVertices(Cube(QTK_DRAW_ELEMENTS).vertices());
mObject->setIndices(Cube(QTK_DRAW_ELEMENTS).indices());
mObject->mProgram.create();
mObject->mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,
":/solid-ambient.vert");
mObject->mProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,
":/solid-ambient.frag");
mObject->mProgram.link();
mObject->mProgram.bind();
mObject->mVAO.create();
mObject->mVAO.bind();
mObject->mVBO.create();
mObject->mVBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
mObject->mVBO.bind();
mObject->mVBO.allocate(mObject->vertices().data(),
mObject->vertices().size()
* sizeof(mObject->vertices()[0]));
mObject->mProgram.enableAttributeArray(0);
mObject->mProgram.setAttributeBuffer(0, GL_FLOAT, 0,
3, sizeof(mObject->vertices()[0]));
mObject->mProgram.setUniformValue("uColor", QVector3D(1.0f, 0.0f, 0.0f));
mObject->mProgram.setUniformValue("uLightColor", WHITE);
mObject->mProgram.setUniformValue("uAmbientStrength", 0.75f);
mObject->mVBO.release();
mObject->mVAO.release();
mObject->mProgram.release();
mObject->mTransform.setTranslation(13.0f, 0.0f, -2.0f);
}
/******************************************************************************* /*******************************************************************************
* Inherited Virtual Member Functions * Inherited Virtual Member Functions
@ -108,18 +65,7 @@ void MainWidget::paintGL()
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
// Draw the scene first, since it handles drawing our skybox // Draw the scene first, since it handles drawing our skybox
mScene->draw(); if (mScene != Q_NULLPTR) mScene->privDraw();
// Draw any additional objects within mainwidget manually
mObject->mProgram.bind();
mObject->mVAO.bind();
mObject->mProgram.setUniformValue("uModel", mObject->mTransform.toMatrix());
mObject->mProgram.setUniformValue("uView", Scene::Camera().toMatrix());
mObject->mProgram.setUniformValue("uProjection", Scene::Projection());
glDrawElements(GL_TRIANGLES, mObject->indices().size(),
GL_UNSIGNED_INT, mObject->indices().data());
mObject->mVAO.release();
mObject->mProgram.release();
} }
void MainWidget::initializeGL() void MainWidget::initializeGL()
@ -150,9 +96,6 @@ void MainWidget::initializeGL()
glClearDepth(1.0f); glClearDepth(1.0f);
glClearColor(0.0f, 0.25f, 0.0f, 0.0f); glClearColor(0.0f, 0.25f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Initialize default objects within the scene
initObjects();
} }
void MainWidget::resizeGL(int width, int height) void MainWidget::resizeGL(int width, int height)
@ -172,7 +115,7 @@ void MainWidget::update()
{ {
updateCameraInput(); updateCameraInput();
mScene->update(); if (mScene != Q_NULLPTR) mScene->update();
QWidget::update(); QWidget::update();
} }

View File

@ -15,57 +15,61 @@
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
#include <QOpenGLWidget> #include <QOpenGLWidget>
#define QTK_DEBUG #include <qtkapi.h>
#include <abstractscene.h>
class MeshRenderer;
class Model;
class Object;
class Scene;
class Skybox;
class Texture;
class MainWidget : public QOpenGLWidget, namespace Qtk {
protected QOpenGLFunctions { class QTKAPI MainWidget : public QOpenGLWidget,
Q_OBJECT; protected QOpenGLFunctions {
Q_OBJECT;
public: public:
// Constructors // Constructors
MainWidget(); MainWidget();
explicit MainWidget(QWidget *parent); explicit MainWidget(QWidget *parent);
explicit MainWidget(const QSurfaceFormat &format); explicit MainWidget(const QSurfaceFormat &format);
~MainWidget() override; ~MainWidget() override;
private: private:
void teardownGL(); void teardownGL();
void initObjects();
public: public:
// Inherited virtual Members // Inherited virtual Members
void paintGL() override; void paintGL() override;
void initializeGL() override; void initializeGL() override;
void resizeGL(int width, int height) override; void resizeGL(int width, int height) override;
protected slots: inline Scene * getScene() {return mScene;}
void update(); inline void setScene(Scene * scene) {
void messageLogged(const QOpenGLDebugMessage &msg); if (mScene != Q_NULLPTR) delete mScene;
mScene = scene;
}
// Protected Helpers protected slots:
protected: void update();
void keyPressEvent(QKeyEvent *event); #ifdef QTK_DEBUG
void keyReleaseEvent(QKeyEvent *event); void messageLogged(const QOpenGLDebugMessage &msg);
void mousePressEvent(QMouseEvent *event); #endif
void mouseReleaseEvent(QMouseEvent *event);
private: // Protected Helpers
// Private helpers protected:
void initializeWidget(); void keyPressEvent(QKeyEvent *event);
void printContextInformation(); void keyReleaseEvent(QKeyEvent *event);
void updateCameraInput(); void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
Scene * mScene; private:
Object * mObject; // Private helpers
void initializeWidget();
void updateCameraInput();
QOpenGLDebugLogger * mDebugLogger; Scene * mScene;
}; #ifdef QTK_DEBUG
void printContextInformation();
QOpenGLDebugLogger * mDebugLogger;
#endif
};
}
#endif // QTK_MAINWIDGET_H #endif // QTK_MAINWIDGET_H

View File

@ -8,6 +8,7 @@
#include <mesh.h> #include <mesh.h>
using namespace Qtk;
Cube::Cube(DrawMode mode) Cube::Cube(DrawMode mode)
{ {

View File

@ -12,25 +12,27 @@
#include <QVector2D> #include <QVector2D>
#include <QVector3D> #include <QVector3D>
#include <qtkapi.h>
#include <transform3D.h> #include <transform3D.h>
class MeshRenderer; namespace Qtk {
class Object; class MeshRenderer;
class Object;
// Define vertices for drawing a cube using two faces (8 vertex points) // Define vertices for drawing a cube using two faces (8 vertex points)
// Front Vertices // Front Vertices
#define VERTEX_FTR QVector3D( 0.5f, 0.5f, 0.5f) // 1 #define VERTEX_FTR QVector3D( 0.5f, 0.5f, 0.5f) // 1
#define VERTEX_FTL QVector3D(-0.5f, 0.5f, 0.5f) // 2 #define VERTEX_FTL QVector3D(-0.5f, 0.5f, 0.5f) // 2
#define VERTEX_FBL QVector3D(-0.5f, -0.5f, 0.5f) // 3 #define VERTEX_FBL QVector3D(-0.5f, -0.5f, 0.5f) // 3
#define VERTEX_FBR QVector3D( 0.5f, -0.5f, 0.5f) // 4 #define VERTEX_FBR QVector3D( 0.5f, -0.5f, 0.5f) // 4
// Back Vertices // Back Vertices
#define VERTEX_BTR QVector3D( 0.5f, 0.5f, -0.5f) // 5 #define VERTEX_BTR QVector3D( 0.5f, 0.5f, -0.5f) // 5
#define VERTEX_BTL QVector3D(-0.5f, 0.5f, -0.5f) // 6 #define VERTEX_BTL QVector3D(-0.5f, 0.5f, -0.5f) // 6
#define VERTEX_BBL QVector3D(-0.5f, -0.5f, -0.5f) // 7 #define VERTEX_BBL QVector3D(-0.5f, -0.5f, -0.5f) // 7
#define VERTEX_BBR QVector3D( 0.5f, -0.5f, -0.5f) // 8 #define VERTEX_BBR QVector3D( 0.5f, -0.5f, -0.5f) // 8
// Direction vectors // Direction vectors
#define VECTOR_UP QVector3D(0.0f, 1.0f, 0.0f) #define VECTOR_UP QVector3D(0.0f, 1.0f, 0.0f)
#define VECTOR_DOWN QVector3D(0.0f, -1.0f, 0.0f) #define VECTOR_DOWN QVector3D(0.0f, -1.0f, 0.0f)
#define VECTOR_LEFT QVector3D(-1.0f, 0.0f, 0.0f) #define VECTOR_LEFT QVector3D(-1.0f, 0.0f, 0.0f)
@ -38,25 +40,25 @@ class Object;
#define VECTOR_FORWARD QVector3D(0.0f, 0.0f, 1.0f) #define VECTOR_FORWARD QVector3D(0.0f, 0.0f, 1.0f)
#define VECTOR_BACK QVector3D(0.0f, 0.0f, -1.0f) #define VECTOR_BACK QVector3D(0.0f, 0.0f, -1.0f)
// Identity and zero vectors // Identity and zero vectors
#define VECTOR_ONE QVector3D(1.0f, 1.0f, 1.0f) #define VECTOR_ONE QVector3D(1.0f, 1.0f, 1.0f)
#define VECTOR_ZERO QVector3D(0.0f, 0.0f, 0.0f) #define VECTOR_ZERO QVector3D(0.0f, 0.0f, 0.0f)
// A series of direction vectors to represent cube face normal // A series of direction vectors to represent cube face normal
#define FACE_TOP VECTOR_UP, VECTOR_UP, VECTOR_UP, \ #define FACE_TOP VECTOR_UP, VECTOR_UP, VECTOR_UP, \
VECTOR_UP, VECTOR_UP, VECTOR_UP VECTOR_UP, VECTOR_UP, VECTOR_UP
#define FACE_BOTTOM VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN, \ #define FACE_BOTTOM VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN, \
VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN
#define FACE_LEFT VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT, \ #define FACE_LEFT VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT, \
VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT
#define FACE_RIGHT VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT, \ #define FACE_RIGHT VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT, \
VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT
#define FACE_FRONT VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD, \ #define FACE_FRONT VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD, \
VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD
#define FACE_BACK VECTOR_BACK, VECTOR_BACK, VECTOR_BACK, \ #define FACE_BACK VECTOR_BACK, VECTOR_BACK, VECTOR_BACK, \
VECTOR_BACK, VECTOR_BACK, VECTOR_BACK VECTOR_BACK, VECTOR_BACK, VECTOR_BACK
// Colors using QVector3Ds as RGB values // Colors using QVector3Ds as RGB values
#define WHITE VECTOR_ONE #define WHITE VECTOR_ONE
#define BLACK VECTOR_ZERO #define BLACK VECTOR_ZERO
#define RED QVector3D(1.0f, 0.0f, 0.0f) #define RED QVector3D(1.0f, 0.0f, 0.0f)
@ -71,62 +73,62 @@ class Object;
#define UV_RIGHT QVector2D(0.0f, 1.0f) #define UV_RIGHT QVector2D(0.0f, 1.0f)
#define UV_CORNER QVector2D(1.0f, 1.0f) #define UV_CORNER QVector2D(1.0f, 1.0f)
typedef std::vector<QVector3D> Vertices;
typedef std::vector<QVector3D> Colors;
typedef std::vector<GLuint> Indices;
typedef std::vector<QVector2D> TexCoords;
typedef std::vector<QVector3D> Normals;
typedef std::vector<QVector3D> Vertices; enum DrawMode { QTK_DRAW_ARRAYS, QTK_DRAW_ELEMENTS, QTK_DRAW_ELEMENTS_NORMALS };
typedef std::vector<QVector3D> Colors;
typedef std::vector<GLuint> Indices;
typedef std::vector<QVector2D> TexCoords;
typedef std::vector<QVector3D> Normals;
enum DrawMode { QTK_DRAW_ARRAYS, QTK_DRAW_ELEMENTS, QTK_DRAW_ELEMENTS_NORMALS }; struct QTKAPI ShapeBase {
ShapeBase(DrawMode mode=QTK_DRAW_ARRAYS, Vertices v={},Indices i={}, Colors c={},
TexCoords t={}, Normals n={})
: mVertices(v), mColors(c), mIndices(i), mTexCoords(t), mNormals(n)
{}
struct ShapeBase { inline const Vertices & vertices() const { return mVertices;}
ShapeBase(DrawMode mode=QTK_DRAW_ARRAYS, Vertices v={},Indices i={}, Colors c={}, inline const Indices & indices() const { return mIndices;}
TexCoords t={}, Normals n={}) inline const Colors & colors() const { return mColors;}
: mVertices(v), mColors(c), mIndices(i), mTexCoords(t), mNormals(n) inline const TexCoords & texCoords() const { return mTexCoords;}
{} inline const Normals & normals() const { return mNormals;}
inline const Vertices & vertices() const { return mVertices;} protected:
inline const Indices & indices() const { return mIndices;} DrawMode mDrawMode;
inline const Colors & colors() const { return mColors;}
inline const TexCoords & texCoords() const { return mTexCoords;}
inline const Normals & normals() const { return mNormals;}
protected: Vertices mVertices;
DrawMode mDrawMode; Colors mColors;
Indices mIndices;
TexCoords mTexCoords;
Normals mNormals;
};
Vertices mVertices; struct Shape : public ShapeBase {
Colors mColors; friend MeshRenderer;
Indices mIndices; friend Object;
TexCoords mTexCoords; Shape () {}
Normals mNormals; Shape(const ShapeBase & rhs) : ShapeBase(rhs) {}
};
struct Shape : public ShapeBase { virtual inline void setVertices(const Vertices & value) {mVertices = value;}
friend MeshRenderer; virtual inline void setIndices(const Indices & value) {mIndices = value;}
friend Object; virtual inline void setColors(const Colors & value) {mColors = value;}
Shape () {} virtual inline void setTexCoords(const TexCoords & value) {mTexCoords = value;}
Shape(const ShapeBase & rhs) : ShapeBase(rhs) {} virtual inline void setNormals(const Normals & value) {mNormals = value;}
virtual inline void setShape(const Shape & value) { *this = value;}
virtual inline void setVertices(const Vertices & value) {mVertices = value;} };
virtual inline void setIndices(const Indices & value) {mIndices = value;}
virtual inline void setColors(const Colors & value) {mColors = value;}
virtual inline void setTexCoords(const TexCoords & value) {mTexCoords = value;}
virtual inline void setNormals(const Normals & value) {mNormals = value;}
virtual inline void setShape(const Shape & value) { *this = value;}
};
// Primitives inherit from ShapeBase, does not allow setting of shape values // Primitives inherit from ShapeBase, does not allow setting of shape values
class Mesh { class QTKAPI Mesh {
}; };
struct Cube : public ShapeBase { struct QTKAPI Cube : public ShapeBase {
Cube(DrawMode mode=QTK_DRAW_ARRAYS); Cube(DrawMode mode=QTK_DRAW_ARRAYS);
}; };
struct Triangle : public ShapeBase { struct QTKAPI Triangle : public ShapeBase {
Triangle(DrawMode mode=QTK_DRAW_ARRAYS); Triangle(DrawMode mode=QTK_DRAW_ARRAYS);
}; };
}
#endif // QTK_MESH_H #endif // QTK_MESH_H

View File

@ -8,14 +8,14 @@
#include <QImageReader> #include <QImageReader>
#include <scene.h> #include <abstractscene.h>
#include <meshrenderer.h>
#include <texture.h> #include <texture.h>
#include <meshrenderer.h> using namespace Qtk;
// Static QHash that holds all MeshRenderer instances using their mName as keys // Static QHash that holds all MeshRenderer instances using their mName as keys
MeshRenderer::MeshManager MeshRenderer::sInstances; Qtk::MeshRenderer::MeshManager Qtk::MeshRenderer::sInstances;
MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape) MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape)
: Object(name, shape), mVertexShader(":/multi-color.vert"), : Object(name, shape), mVertexShader(":/multi-color.vert"),

View File

@ -10,68 +10,71 @@
#include <mesh.h> #include <mesh.h>
#include <object.h> #include <object.h>
#include <qtkapi.h>
class MeshRenderer : public Object { namespace Qtk {
public: class QTKAPI MeshRenderer : public Object {
// Delegate constructors public:
MeshRenderer(const char * name, Vertices vertices, Indices indices, // Delegate constructors
DrawMode mode=QTK_DRAW_ARRAYS) MeshRenderer(const char * name, Vertices vertices, Indices indices,
: MeshRenderer(name, ShapeBase(mode, vertices, indices)) DrawMode mode=QTK_DRAW_ARRAYS)
{} : MeshRenderer(name, ShapeBase(mode, vertices, indices))
MeshRenderer(const char * name) {}
: MeshRenderer(name, Cube(QTK_DRAW_ELEMENTS)) MeshRenderer(const char * name)
{} : MeshRenderer(name, Cube(QTK_DRAW_ELEMENTS))
// Constructor {}
MeshRenderer(const char * name, const ShapeBase &shape); // Constructor
~MeshRenderer(); MeshRenderer(const char * name, const ShapeBase &shape);
~MeshRenderer();
// Retrieve a mesh by name stored within a static QHash // Retrieve a mesh by name stored within a static QHash
static MeshRenderer * getInstance(const QString & name); static MeshRenderer * getInstance(const QString & name);
void init(); void init();
void draw(); void draw();
// Draw types like GL_TRIANGLES, GL_POINTS, GL_LINES, etc // Draw types like GL_TRIANGLES, GL_POINTS, GL_LINES, etc
void setDrawType(int drawType) { mDrawType = drawType;} void setDrawType(int drawType) { mDrawType = drawType;}
// Shader settings // Shader settings
inline void setShaderVertex(const std::string & vert) { mVertexShader = vert;} inline void setShaderVertex(const std::string & vert) { mVertexShader = vert;}
inline void setShaderFragment(const std::string & frag) inline void setShaderFragment(const std::string & frag)
{ mFragmentShader = frag;} { mFragmentShader = frag;}
void setShaders(const std::string & vert, const std::string & frag); void setShaders(const std::string & vert, const std::string & frag);
template <typename T> template <typename T>
inline void setUniform(int location, T value) inline void setUniform(int location, T value)
{ mProgram.setUniformValue(location, value);} { mProgram.setUniformValue(location, value);}
template <typename T> template <typename T>
inline void setUniform(const char * location, T value) inline void setUniform(const char * location, T value)
{ mProgram.setUniformValue(location, value);} { mProgram.setUniformValue(location, value);}
// Set MVP matrix using this Object's transform // Set MVP matrix using this Object's transform
// + View and projection provided by MainWidget static members // + View and projection provided by MainWidget static members
void setUniformMVP(const char * model="uModel", const char * view="uView", void setUniformMVP(const char * model="uModel", const char * view="uView",
const char * projection="uProjection"); const char * projection="uProjection");
// Sets the texture to the image at the given path // Sets the texture to the image at the given path
// + Sets mHasTexture to enable texture binding in draw() // + Sets mHasTexture to enable texture binding in draw()
void setTexture(const char * path); void setTexture(const char * path);
void setTexture(QOpenGLTexture * texture); void setTexture(QOpenGLTexture * texture);
// These functions modify data stored in a VBO // These functions modify data stored in a VBO
// + After calling them, the VBO will need to be reallocated // + After calling them, the VBO will need to be reallocated
void setShape(const Shape & value) override; void setShape(const Shape & value) override;
void setColor(const QVector3D & color); void setColor(const QVector3D & color);
// Static QHash of all mesh objects within the scene // Static QHash of all mesh objects within the scene
typedef QHash<QString, MeshRenderer *> MeshManager; typedef QHash<QString, MeshRenderer *> MeshManager;
private: private:
static MeshManager sInstances; static MeshManager sInstances;
int mDrawType; int mDrawType;
bool mHasTexture; bool mHasTexture;
std::string mVertexShader, mFragmentShader; std::string mVertexShader, mFragmentShader;
}; };
}
#endif // QTK_MESHRENDERER_H #endif // QTK_MESHRENDERER_H

View File

@ -9,12 +9,12 @@
#include <QFileInfo> #include <QFileInfo>
#include <scene.h> #include <abstractscene.h>
#include <texture.h>
#include <resourcemanager.h>
#include <model.h> #include <model.h>
#include <resourcemanager.h>
#include <texture.h>
using namespace Qtk;
Model::ModelManager Model::mManager; Model::ModelManager Model::mManager;

View File

@ -16,7 +16,6 @@
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
#include <QOpenGLFunctions>
// Assimp // Assimp
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
@ -24,117 +23,119 @@
#include <assimp/scene.h> #include <assimp/scene.h>
// QTK // QTK
#include <qtkapi.h>
#include <transform3D.h> #include <transform3D.h>
namespace Qtk {
struct QTKAPI ModelVertex {
QVector3D mPosition;
QVector3D mNormal;
QVector3D mTangent;
QVector3D mBitangent;
QVector2D mTextureCoord;
};
struct ModelVertex { struct QTKAPI ModelTexture {
QVector3D mPosition; GLuint mID;
QVector3D mNormal; QOpenGLTexture * mTexture;
QVector3D mTangent; std::string mType;
QVector3D mBitangent; std::string mPath;
QVector2D mTextureCoord; };
};
struct ModelTexture { class Model;
GLuint mID;
QOpenGLTexture * mTexture;
std::string mType;
std::string mPath;
};
class Model; class QTKAPI ModelMesh : protected QOpenGLFunctions {
public:
friend Model;
typedef std::vector<ModelVertex> Vertices;
typedef std::vector<GLuint> Indices;
typedef std::vector<ModelTexture> Textures;
class ModelMesh : protected QOpenGLFunctions { // Constructors, Destructors
public: ModelMesh(Vertices vertices, Indices indices, Textures textures,
friend Model; const char * vertexShader=":/model-basic.vert",
typedef std::vector<ModelVertex> Vertices; const char * fragmentShader=":/model-basic.frag")
typedef std::vector<GLuint> Indices; : mProgram(new QOpenGLShaderProgram),
typedef std::vector<ModelTexture> Textures;
// Constructors, Destructors
ModelMesh(Vertices vertices, Indices indices, Textures textures,
const char * vertexShader=":/model-basic.vert",
const char * fragmentShader=":/model-basic.frag")
: mProgram(new QOpenGLShaderProgram),
mVAO(new QOpenGLVertexArrayObject), mVAO(new QOpenGLVertexArrayObject),
mVBO(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)), mVBO(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)),
mEBO(new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer)), mEBO(new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer)),
mVertices(std::move(vertices)), mVertices(std::move(vertices)),
mIndices(std::move(indices)), mIndices(std::move(indices)),
mTextures(std::move(textures)) mTextures(std::move(textures))
{ initMesh(vertexShader, fragmentShader);} { initMesh(vertexShader, fragmentShader);}
~ModelMesh() {} ~ModelMesh() {}
private: private:
void initMesh(const char * vert, const char * frag); void initMesh(const char * vert, const char * frag);
// ModelMesh Private Members // ModelMesh Private Members
QOpenGLBuffer * mVBO, * mEBO; QOpenGLBuffer * mVBO, * mEBO;
QOpenGLVertexArrayObject * mVAO; QOpenGLVertexArrayObject * mVAO;
QOpenGLShaderProgram * mProgram; QOpenGLShaderProgram * mProgram;
public: public:
inline void draw() { draw(*mProgram);} inline void draw() { draw(*mProgram);}
void draw(QOpenGLShaderProgram & shader); void draw(QOpenGLShaderProgram & shader);
// ModelMesh Public Members // ModelMesh Public Members
Vertices mVertices; Vertices mVertices;
Indices mIndices; Indices mIndices;
Textures mTextures; Textures mTextures;
Transform3D mTransform; Transform3D mTransform;
}; };
class Model : public QObject { class QTKAPI Model : public QObject {
Q_OBJECT Q_OBJECT
public: public:
inline Model(const char * name, const char * path, inline Model(const char * name, const char * path,
const char * vertexShader=":/model-basic.vert", const char * vertexShader=":/model-basic.vert",
const char * fragmentShader=":/model-basic.frag") const char * fragmentShader=":/model-basic.frag")
: mName(name), mVertexShader(vertexShader), : mName(name), mVertexShader(vertexShader),
mFragmentShader(fragmentShader) mFragmentShader(fragmentShader)
{ loadModel(path);} { loadModel(path);}
inline ~Model() { mManager.remove(mName);} inline ~Model() { mManager.remove(mName);}
void draw(); void draw();
void draw(QOpenGLShaderProgram & shader); void draw(QOpenGLShaderProgram & shader);
void flipTexture(const std::string & fileName, void flipTexture(const std::string & fileName,
bool flipX=false, bool flipY=true); bool flipX=false, bool flipY=true);
template <typename T> template <typename T>
void setUniform(const char * location, T value) void setUniform(const char * location, T value)
{ {
for (auto & mesh : mMeshes) { for (auto & mesh : mMeshes) {
mesh.mProgram->bind(); mesh.mProgram->bind();
mesh.mProgram->setUniformValue(location, value); mesh.mProgram->setUniformValue(location, value);
mesh.mProgram->release(); mesh.mProgram->release();
}
} }
}
Transform3D mTransform; Transform3D mTransform;
static Model * getInstance(const char * name); static Model * getInstance(const char * name);
typedef QHash<QString, Model *> ModelManager; typedef QHash<QString, Model *> ModelManager;
private: private:
static ModelManager mManager; static ModelManager mManager;
void loadModel(const std::string & path); void loadModel(const std::string & path);
void processNode(aiNode * node, const aiScene * scene); void processNode(aiNode * node, const aiScene * scene);
ModelMesh processMesh(aiMesh * mesh, const aiScene * scene); ModelMesh processMesh(aiMesh * mesh, const aiScene * scene);
ModelMesh::Textures loadMaterialTextures(aiMaterial * mat, aiTextureType type, ModelMesh::Textures loadMaterialTextures(aiMaterial * mat, aiTextureType type,
const std::string & typeName); const std::string & typeName);
void sortModels(); void sortModels();
// Model Private Members // Model Private Members
ModelMesh::Textures mTexturesLoaded; ModelMesh::Textures mTexturesLoaded;
std::vector<ModelMesh> mMeshes; std::vector<ModelMesh> mMeshes;
std::string mDirectory; std::string mDirectory;
const char * mVertexShader, * mFragmentShader, * mName; const char * mVertexShader, * mFragmentShader, * mName;
}; };
}
#endif // QTK_MODEL_H #endif // QTK_MODEL_H

View File

@ -7,3 +7,5 @@
##############################################################################*/ ##############################################################################*/
#include <object.h> #include <object.h>
using namespace Qtk;

View File

@ -14,48 +14,50 @@
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
#include <mesh.h> #include <mesh.h>
#include <qtkapi.h>
namespace Qtk {
class QTKAPI Object : public QObject {
Q_OBJECT
class Object : public QObject { public:
Q_OBJECT friend MeshRenderer;
// Initialize an object with no shape data assigned
Object(const char * name)
: mName(name), mVBO(QOpenGLBuffer::VertexBuffer)
{ }
// Initialize an object with shape data assigned
Object(const char * name, const ShapeBase & shape)
: mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mShape(shape)
{ }
public: ~Object() {}
friend MeshRenderer;
// Initialize an object with no shape data assigned
Object(const char * name)
: mName(name), mVBO(QOpenGLBuffer::VertexBuffer)
{ }
// Initialize an object with shape data assigned
Object(const char * name, const ShapeBase & shape)
: mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mShape(shape)
{ }
~Object() {} inline const Vertices & vertices() { return mShape.mVertices;}
inline const Indices & indices() { return mShape.mIndices;}
inline const Colors & colors() { return mShape.mColors;}
inline const TexCoords & texCoords() { return mShape.mTexCoords;}
inline const Normals & normals() { return mShape.mNormals;}
inline QOpenGLTexture & texture() const { return *mTexture;}
inline const Vertices & vertices() { return mShape.mVertices;} virtual inline void setVertices(const Vertices & value) { mShape.mVertices = value;}
inline const Indices & indices() { return mShape.mIndices;} virtual inline void setIndices(const Indices & value) { mShape.mIndices = value;}
inline const Colors & colors() { return mShape.mColors;} virtual inline void setColors(const Colors & value) { mShape.mColors = value;}
inline const TexCoords & texCoords() { return mShape.mTexCoords;} virtual inline void setTexCoords(const TexCoords & value) { mShape.mTexCoords = value;}
inline const Normals & normals() { return mShape.mNormals;} virtual inline void setNormals(const Normals & value) { mShape.mNormals = value;}
inline QOpenGLTexture & texture() const { return *mTexture;} virtual inline void setShape(const Shape & value) { mShape = value;}
virtual inline void setVertices(const Vertices & value) { mShape.mVertices = value;} QOpenGLBuffer mVBO, mNBO;
virtual inline void setIndices(const Indices & value) { mShape.mIndices = value;} QOpenGLVertexArrayObject mVAO;
virtual inline void setColors(const Colors & value) { mShape.mColors = value;} QOpenGLShaderProgram mProgram;
virtual inline void setTexCoords(const TexCoords & value) { mShape.mTexCoords = value;}
virtual inline void setNormals(const Normals & value) { mShape.mNormals = value;}
virtual inline void setShape(const Shape & value) { mShape = value;}
QOpenGLBuffer mVBO, mNBO; Transform3D mTransform;
QOpenGLVertexArrayObject mVAO; Shape mShape;
QOpenGLShaderProgram mProgram;
Transform3D mTransform; const char * mName;
Shape mShape; private:
QOpenGLTexture * mTexture;
const char * mName; };
private: }
QOpenGLTexture * mTexture;
};
#endif // QTK_OBJECT_H #endif // QTK_OBJECT_H

23
src/qtkapi.h Normal file
View File

@ -0,0 +1,23 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Main window for Qt6 OpenGL widget application ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#ifndef QTK_QTKAPI_H
#define QTK_QTKAPI_H
#include <QtCore/QtGlobal>
#ifdef QTK_SHARED
# if defined(QTK_EXPORT)
# define QTKAPI Q_DECL_EXPORT
# else
# define QTKAPI Q_DECL_IMPORT
# endif
#else
# define QTKAPI
#endif
#endif //QTK_QTKAPI_H

View File

@ -6,11 +6,11 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## ## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/ ##############################################################################*/
#include <scene.h> #include <abstractscene.h>
#include <skybox.h>
#include <texture.h> #include <texture.h>
#include <skybox.h> using namespace Qtk;
Skybox::Skybox(std::string right, std::string top, std::string front, Skybox::Skybox(std::string right, std::string top, std::string front,
std::string left, std::string bottom, std::string back, std::string left, std::string bottom, std::string back,

View File

@ -10,39 +10,42 @@
#include <QImage> #include <QImage>
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
#include <QOpenGLFunctions>
#include <camera3d.h> #include <camera3d.h>
#include <mesh.h> #include <mesh.h>
#include <qtkapi.h>
class Skybox : protected QOpenGLFunctions { namespace Qtk {
public: class QTKAPI Skybox : protected QOpenGLFunctions {
// Delegate this constructor to use default skybox images public:
// + This allows creating a skybox with no arguments ( auto s = new Skybox; ) // Delegate this constructor to use default skybox images
explicit Skybox(std::string name="Skybox"); // + This allows creating a skybox with no arguments ( auto s = new Skybox; )
explicit Skybox(QOpenGLTexture * cubeMap, const std::string & name="Skybox"); explicit Skybox(std::string name="Skybox");
// Constructor, Destructor explicit Skybox(QOpenGLTexture * cubeMap, const std::string & name="Skybox");
Skybox(std::string right, std::string top, std::string front, // Constructor, Destructor
std::string left, std::string bottom, std::string back, Skybox(std::string right, std::string top, std::string front,
const std::string & name="Skybox"); std::string left, std::string bottom, std::string back,
~Skybox() {} const std::string & name="Skybox");
~Skybox() {}
void draw(); void draw();
private: private:
void init(); void init();
Vertices mVertices; Vertices mVertices;
Indices mIndices; Indices mIndices;
QOpenGLShaderProgram mProgram; QOpenGLShaderProgram mProgram;
QOpenGLVertexArrayObject mVAO; QOpenGLVertexArrayObject mVAO;
QOpenGLBuffer mVBO; QOpenGLBuffer mVBO;
QOpenGLTexture * mCubeMap; QOpenGLTexture * mCubeMap;
}; };
}
#endif // QTK_SKYBOX_H #endif // QTK_SKYBOX_H

View File

@ -11,6 +11,7 @@
#include <texture.h> #include <texture.h>
using namespace Qtk;
QImage * Texture::initImage(const char * image, bool flipX, bool flipY) QImage * Texture::initImage(const char * image, bool flipX, bool flipY)
{ {

View File

@ -11,32 +11,35 @@
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <qtkapi.h>
class Texture { namespace Qtk {
public: class QTKAPI Texture {
~Texture() {} public:
~Texture() {}
// QImage // QImage
static QImage * initImage(const char * image, static QImage * initImage(const char * image,
bool flipX=false, bool flipY=false); bool flipX=false, bool flipY=false);
// 2D Texture // 2D Texture
static QOpenGLTexture * initTexture2D(const char * texture, static QOpenGLTexture * initTexture2D(const char * texture,
bool flipX=false, bool flipY=false); bool flipX=false, bool flipY=false);
// Cube maps // Cube maps
static QOpenGLTexture * initCubeMap(QImage right, QImage top, static QOpenGLTexture * initCubeMap(QImage right, QImage top,
QImage front, QImage left, QImage front, QImage left,
QImage bottom, QImage back); QImage bottom, QImage back);
// Overloads for cube map initialization // Overloads for cube map initialization
static QOpenGLTexture * initCubeMap(const char * tile); static QOpenGLTexture * initCubeMap(const char * tile);
static QOpenGLTexture * initCubeMap(const char * right, const char * top, static QOpenGLTexture * initCubeMap(const char * right, const char * top,
const char * front, const char * left, const char * front, const char * left,
const char * bottom, const char * back); const char * bottom, const char * back);
private: private:
// Private ctor to prevent creating instances of this class // Private ctor to prevent creating instances of this class
Texture() {} Texture() {}
}; };
}
#endif // QTOPENGL_TEXTURE_H #endif // QTOPENGL_TEXTURE_H

View File

@ -9,6 +9,7 @@
#include <transform3D.h> #include <transform3D.h>
using namespace Qtk;
const QVector3D Transform3D::LocalForward(0.0f, 0.0f, 1.0f); const QVector3D Transform3D::LocalForward(0.0f, 0.0f, 1.0f);
const QVector3D Transform3D::LocalUp(0.0f, 1.0f, 0.0f); const QVector3D Transform3D::LocalUp(0.0f, 1.0f, 0.0f);
@ -110,35 +111,41 @@ QVector3D Transform3D::right() const
* QT Streams * QT Streams
******************************************************************************/ ******************************************************************************/
QDebug operator<<(QDebug dbg, const Transform3D & transform) namespace Qtk {
{ #ifndef QT_NO_DEBUG_STREAM
dbg << "Transform3D\n{\n"; QDebug operator<<(QDebug dbg, const Transform3D & transform)
dbg << "Position: <" << transform.translation().x() << ", " {
<< transform.translation().y() << ", " dbg << "Transform3D\n{\n";
<< transform.translation().z() << ">\n"; dbg << "Position: <" << transform.translation().x() << ", "
dbg << "Scale: <" << transform.scale().x() << ", " << transform.translation().y() << ", "
<< transform.scale().y() << ", " << transform.translation().z() << ">\n";
<< transform.scale().z() << ">\n"; dbg << "Scale: <" << transform.scale().x() << ", "
dbg << "Rotation: <" << transform.rotation().x() << ", " << transform.scale().y() << ", "
<< transform.rotation().y() << ", " << transform.scale().z() << ">\n";
<< transform.rotation().z() << " | " << dbg << "Rotation: <" << transform.rotation().x() << ", "
transform.rotation().scalar() << ">\n}"; << transform.rotation().y() << ", "
return dbg; << transform.rotation().z() << " | " <<
transform.rotation().scalar() << ">\n}";
return dbg;
} }
#endif
QDataStream & operator<<(QDataStream & out, const Transform3D & transform) #ifndef QT_NO_DATASTREAM
{ QDataStream & operator<<(QDataStream & out, const Transform3D & transform)
out << transform.mTranslation; {
out << transform.mScale; out << transform.mTranslation;
out << transform.mRotation; out << transform.mScale;
return out; out << transform.mRotation;
} return out;
}
QDataStream & operator>>(QDataStream & in, Transform3D & transform) QDataStream & operator>>(QDataStream & in, Transform3D & transform)
{ {
in >> transform.mTranslation; in >> transform.mTranslation;
in >> transform.mScale; in >> transform.mScale;
in >> transform.mRotation; in >> transform.mRotation;
transform.m_dirty = true; transform.m_dirty = true;
return in; return in;
}
#endif
} }

View File

@ -10,108 +10,116 @@
#ifndef QTK_TRANSFORM3D_H #ifndef QTK_TRANSFORM3D_H
#define QTK_TRANSFORM3D_H #define QTK_TRANSFORM3D_H
#include <QDebug>
#include <QMatrix4x4> #include <QMatrix4x4>
#include <QQuaternion> #include <QQuaternion>
#include <QVector3D> #include <QVector3D>
#ifndef QT_NO_DEBUG_STREAM
#include <QDebug>
#endif
class Transform3D #include <qtkapi.h>
{
public:
// Constructors
inline Transform3D() : m_dirty(true),
mScale(1.0f, 1.0f, 1.0f),
mTranslation(0.0f, 0.0f, 0.0f) { }
// namespace Qtk {
// Transformations class QTKAPI Transform3D
{
public:
// Constructors
inline Transform3D() : m_dirty(true),
mScale(1.0f, 1.0f, 1.0f),
mTranslation(0.0f, 0.0f, 0.0f) { }
void translate(const QVector3D & dt); //
inline void translate(float dx, float dy, float dz) // Transformations
{ translate(QVector3D(dx, dy, dz));}
// Scale object with multiplication void translate(const QVector3D & dt);
void scale(const QVector3D & ds); inline void translate(float dx, float dy, float dz)
inline void scale(float dx, float dy, float dz) { translate(QVector3D(dx, dy, dz));}
{ scale(QVector3D(dx, dy, dz));}
inline void scale(float factor)
{ scale(QVector3D(factor, factor, factor));}
// Multiplying by a rotation // Scale object with multiplication
void rotate(const QQuaternion & dr); void scale(const QVector3D & ds);
inline void rotate(float angle, const QVector3D & axis) inline void scale(float dx, float dy, float dz)
{ rotate(QQuaternion::fromAxisAndAngle(axis, angle));} { scale(QVector3D(dx, dy, dz));}
inline void rotate(float angle, float ax, float ay, float az) inline void scale(float factor)
{ rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));} { scale(QVector3D(factor, factor, factor));}
// Scale object by addition // Multiplying by a rotation
void grow(const QVector3D & ds); void rotate(const QQuaternion & dr);
inline void grow(float dx, float dy, float dz) inline void rotate(float angle, const QVector3D & axis)
{ grow(QVector3D(dx, dy, dz));} { rotate(QQuaternion::fromAxisAndAngle(axis, angle));}
inline void grow(float factor) inline void rotate(float angle, float ax, float ay, float az)
{ grow(QVector3D(factor, factor, factor));} { rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));}
// // Scale object by addition
// Setters void grow(const QVector3D & ds);
inline void grow(float dx, float dy, float dz)
{ grow(QVector3D(dx, dy, dz));}
inline void grow(float factor)
{ grow(QVector3D(factor, factor, factor));}
// Set object position //
void setTranslation(const QVector3D & t); // Setters
inline void setTranslation(float x, float y, float z)
{ setTranslation(QVector3D(x, y, z));}
// Set object scale // Set object position
void setScale(const QVector3D & s); void setTranslation(const QVector3D & t);
inline void setScale(float x, float y, float z) inline void setTranslation(float x, float y, float z)
{ setScale(QVector3D(x, y, z));} { setTranslation(QVector3D(x, y, z));}
inline void setScale(float k)
{ setScale(QVector3D(k, k, k));}
// Set object rotation // Set object scale
void setRotation(const QQuaternion & r); void setScale(const QVector3D & s);
inline void setRotation(float angle, const QVector3D & axis) inline void setScale(float x, float y, float z)
{ setRotation(QQuaternion::fromAxisAndAngle(axis, angle));} { setScale(QVector3D(x, y, z));}
inline void setRotation(float angle, float ax, float ay, float az) inline void setScale(float k)
{ setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));} { setScale(QVector3D(k, k, k));}
// // Set object rotation
// Accessors void setRotation(const QQuaternion & r);
inline void setRotation(float angle, const QVector3D & axis)
{ setRotation(QQuaternion::fromAxisAndAngle(axis, angle));}
inline void setRotation(float angle, float ax, float ay, float az)
{ setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));}
inline const QVector3D & translation() const { return mTranslation;} //
inline const QVector3D & scale() const { return mScale; } // Accessors
inline const QQuaternion & rotation() const { return mRotation; }
const QMatrix4x4 & toMatrix();
QVector3D forward() const; inline const QVector3D & translation() const { return mTranslation;}
QVector3D up() const; inline const QVector3D & scale() const { return mScale; }
QVector3D right() const; inline const QQuaternion & rotation() const { return mRotation; }
const QMatrix4x4 & toMatrix();
static const QVector3D LocalForward, LocalUp, LocalRight; QVector3D forward() const;
QVector3D up() const;
QVector3D right() const;
private: static const QVector3D LocalForward, LocalUp, LocalRight;
QVector3D mTranslation;
QQuaternion mRotation; private:
QVector3D mScale; QVector3D mTranslation;
QMatrix4x4 mWorld; QQuaternion mRotation;
QVector3D mScale;
QMatrix4x4 mWorld;
bool m_dirty;
bool m_dirty;
#ifndef QT_NO_DATASTREAM #ifndef QT_NO_DATASTREAM
friend QDataStream &operator<<(QDataStream & out, const Transform3D & transform); friend QDataStream &operator<<(QDataStream & out, const Transform3D & transform);
friend QDataStream &operator>>(QDataStream & in, Transform3D & transform); friend QDataStream &operator>>(QDataStream & in, Transform3D & transform);
#endif #endif
}; };
Q_DECLARE_TYPEINFO(Transform3D, Q_MOVABLE_TYPE);
// Qt Streams // Qt Streams
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const Transform3D & transform); QDebug operator<<(QDebug dbg, const Transform3D & transform);
#endif #endif
#ifndef QT_NO_DATASTREAM #ifndef QT_NO_DATASTREAM
QDataStream &operator<<(QDataStream & out, const Transform3D & transform); QDataStream &operator<<(QDataStream & out, const Transform3D & transform);
QDataStream &operator>>(QDataStream & in, Transform3D & transform); QDataStream &operator>>(QDataStream & in, Transform3D & transform);
#endif #endif
}
Q_DECLARE_TYPEINFO(Qtk::Transform3D, Q_MOVABLE_TYPE);
#endif // QTK_TRANSFORM3D_H #endif // QTK_TRANSFORM3D_H