Refactor build system and UI

+ Install configs for Qt Designer plugins and Qtk application
+ Add Qtk plugin collection for Qt Designer
+ QtkWidget plugin
+ TreeView widget plugin
+ DebugConsole widget plugin
+ All widgets are fully integrated with Qt Designer
+ All widgets can be popped out or docked within the window
+ All widgets can be stacked to use tab view for side panels
+ All widgets can be toggled on/off through the view context menu
+ QtkWidget debug console
+ QtkWidget active scene TreeVew
+ QtkWidget dockable tool bar
+ Double-click an object name in the TreeView to focus camera
+ Separate libaray from widgets

There is still a lot to do here, but the major refactoring should be
done after this commit. Some of the new features were put together as
POC for working with the new UI. A few placeholder buttons were added
that have no functionality.
This commit is contained in:
2022-12-18 09:19:04 -05:00
parent c948d9e1a6
commit 194888ed19
53 changed files with 2079 additions and 779 deletions

23
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,23 @@
################################################################################
## Author: Shaun Reed | Contact: shaunrd0@gmail.com | URL: www.shaunreed.com ##
## ##
## Project for working with OpenGL and Qt6 widgets ##
################################################################################
# Qtk Library
add_subdirectory(qtk)
# Qtk Application
if (QTK_BUILD_GUI)
#TODO: Use this to test local builds?
# SET(CMAKE_INSTALL_RPATH "${QTK_INSTALL_PREFIX}/lib")
add_subdirectory(app)
endif()
# Install export
install(EXPORT qtk-export
FILE QtkTargets.cmake
NAMESPACE Qtk::
CONFIGURATIONS Debug|Release
DESTINATION ${QTK_INSTALL_PREFIX}/cmake
)

95
src/app/CMakeLists.txt Normal file
View File

@@ -0,0 +1,95 @@
################################################################################
## Author: Shaun Reed | Contact: shaunrd0@gmail.com | URL: www.shaunreed.com ##
## ##
## Project for working with OpenGL and Qt6 widgets ##
################################################################################
################################################################################
# Qtk Widget Library
################################################################################
# Create a library of widgets used to build Qtk GUI
set(QTK_PLUGIN_LIBRARY_SOURCES
debugconsole.cpp debugconsole.ui
toolbox.cpp toolbox.ui
treeview.cpp treeview.ui
)
set(QTK_PLUGIN_LIBRARY_HEADERS
debugconsole.h
toolbox.h
treeview.h
)
qt_add_library(qtk-plugin-library SHARED)
target_sources(qtk-plugin-library PRIVATE
${QTK_PLUGIN_LIBRARY_SOURCES}
${QTK_PLUGIN_LIBRARY_HEADERS}
)
target_link_libraries(qtk-plugin-library PUBLIC Qt6::UiPlugin qtk-library)
install(TARGETS qtk-plugin-library
EXPORT qtk-export
BUNDLE DESTINATION ${QTK_INSTALL_PREFIX}/lib
LIBRARY DESTINATION ${QTK_INSTALL_PREFIX}/lib
ARCHIVE DESTINATION ${QTK_INSTALL_PREFIX}/lib/static
RUNTIME DESTINATION ${QTK_INSTALL_PREFIX}/bin
)
install(TARGETS qtk-plugin-library
BUNDLE DESTINATION ${QTK_PLUGIN_LIBRARY_DIR}
LIBRARY DESTINATION ${QTK_PLUGIN_LIBRARY_DIR}
RUNTIME DESTINATION ${QTK_PLUGIN_LIBRARY_DIR}
ARCHIVE DESTINATION ${QTK_PLUGIN_LIBRARY_DIR}
)
################################################################################
# Qtk Widget Collection Plugin
################################################################################
# Create a Qt Designer plugin for a collection of widgets from our library.
qt_add_plugin(qtk-collection)
target_sources(qtk-collection PRIVATE
widgetplugincollection.cpp widgetplugincollection.h
widgetplugin.cpp widgetplugin.h
)
target_link_libraries(qtk-collection PUBLIC qtk-plugin-library)
install(TARGETS qtk-collection
RUNTIME DESTINATION ${QTK_PLUGIN_INSTALL_DIR}
BUNDLE DESTINATION ${QTK_PLUGIN_INSTALL_DIR}
LIBRARY DESTINATION ${QTK_PLUGIN_INSTALL_DIR}
)
################################################################################
# Final Qtk Application
################################################################################
set(QTK_APP_SOURCES
qtkwidget.cpp qtkwidget.h
examplescene.cpp examplescene.h
qtkmainwindow.cpp qtkmainwindow.ui
qtkmainwindow.h
main.cpp
)
qt6_add_resources(QTK_APP_SOURCES ${CMAKE_SOURCE_DIR}/resources.qrc)
configure_file(
"resources.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/resources.h"
@ONLY
)
qt_add_executable(qtk-main ${QTK_APP_SOURCES})
# Link qtk-main executable to main qtk-library library
target_link_libraries(qtk-main PRIVATE qtk-plugin-library)
target_include_directories(qtk-main PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
set_target_properties(qtk-main PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
)
# TODO: Fix install for qtk-main unable to find so files
install(TARGETS qtk-main
BUNDLE DESTINATION ${QTK_INSTALL_PREFIX}/bin
RUNTIME DESTINATION ${QTK_INSTALL_PREFIX}/bin
LIBRARY DESTINATION ${QTK_INSTALL_PREFIX}/bin/lib
)

44
src/app/debugconsole.cpp Normal file
View File

@@ -0,0 +1,44 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: MainWindow for creating an example Qt application ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <QMainWindow>
#include <QWindow>
#include "debugconsole.h"
#include "ui_debugconsole.h"
using namespace Qtk;
DebugConsole::DebugConsole(QWidget * owner, const QString & key) :
DebugConsole(owner, key, key + "Debugger") {}
DebugConsole::DebugConsole(
QWidget * owner, const QString & key, const QString & name) {
ui_ = new Ui::DebugConsole;
ui_->setupUi(this);
setObjectName(name);
mConsole = ui_->textEdit;
setWidget(mConsole);
setWindowTitle(name + " Debug Console");
auto qtkWidget = dynamic_cast<QtkWidget *>(owner);
if(qtkWidget) {
connect(qtkWidget, &QtkWidget::sendLog, this, &DebugConsole::sendLog);
sendLog(
"Debug console (" + name + ") attached to QtkWidget: '"
+ qtkWidget->objectName() + "'");
sendLog("Test\nLogging\t\n\tStuff", Status);
sendLog("Test\nLogging\t\n\tStuff", Debug);
sendLog("Test\nLogging\t\n\tStuff", Warn);
sendLog("Test\nLogging\t\n\tStuff", Error);
sendLog(
"Test\nLogging\t\n\tStuff that is really long and will wrap around but "
"it might not you don't know until you try",
Fatal);
}
}

129
src/app/debugconsole.h Normal file
View File

@@ -0,0 +1,129 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Debug console for qtk views ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#ifndef QTK_DEBUGCONSOLE_H
#define QTK_DEBUGCONSOLE_H
#include <QApplication>
#include <QDockWidget>
#include <QPlainTextEdit>
#include <QVBoxLayout>
#include "qtkwidget.h"
namespace Ui {
class DebugConsole;
}
namespace Qtk {
class DebugConsole : public QDockWidget {
Q_OBJECT;
public:
/**
* Construct a new DebugConsole.
* Assigns a default name to the console using `key + "Debugger"`
*
* @param owner Parent widget for this console or nullptr if no parent.
* If this parameter inherits from QMainWindow we will add this dock
* widget to the window.
* @param key The objectName associated with the attached QtkWidget.
*/
DebugConsole(QWidget * owner, const QString & key);
/**
* Construct a new DebugConsole.
*
* @param owner Parent widget for this console or nullptr if no parent.
* If this parameter inherits from QMainWindow we will add this dock
* widget to the window.
* @param key The objectName associated with the attached QtkWidget.
* @param name The objectName to associate with this DebugConsole.
*/
DebugConsole(QWidget * owner, const QString & key, const QString & name);
~DebugConsole() = default;
public slots:
/*************************************************************************
* Public Qt slots
************************************************************************/
/**
* Log a message to the DebugConsole text view.
*
* @param message The message to log.
* @param context The DebugContext to use for the message.
* Default value is Status.
*/
inline void sendLog(QString message, DebugContext context = Status) {
mConsole->setTextColor(logColor(context));
mConsole->append(logPrefix(message, context));
}
/**
* Sets the window title for the DebugConsole. This will appear in the
* widget title bar and within any context menu actions.
*
* @param name Base name for the DebugConsole window.
*/
inline void setTitle(QString name) {
setWindowTitle(name + "Debug Console");
}
private:
[[nodiscard]] QColor logColor(const DebugContext & context) const {
switch(context) {
case Status:
return Qt::GlobalColor::darkGray;
case Debug:
return Qt::GlobalColor::white;
case Warn:
return Qt::GlobalColor::yellow;
case Error:
return Qt::GlobalColor::red;
case Fatal:
return Qt::GlobalColor::magenta;
default:
return Qt::GlobalColor::darkYellow;
}
}
[[nodiscard]] QString logPrefix(
QString & message, const DebugContext & context) {
QString prefix;
switch(context) {
case Status:
prefix = "[Status]: ";
break;
case Debug:
prefix = "[Debug]: ";
break;
case Warn:
prefix = "[Warn]: ";
break;
case Error:
prefix = "[Error]: ";
break;
case Fatal:
prefix = "[Fatal]: ";
break;
default:
prefix = "[No Context]: ";
break;
}
message = prefix + message.replace("\n", "\t\n" + prefix);
return message;
}
QTextEdit * mConsole;
Ui::DebugConsole * ui_;
};
} // namespace Qtk
#endif // QTK_DEBUGCONSOLE_H

33
src/app/debugconsole.ui Normal file
View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DebugConsole</class>
<widget class="QDockWidget" name="DebugConsole">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Debug Console</string>
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTextEdit" name="textEdit">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

560
src/app/examplescene.cpp Normal file
View File

@@ -0,0 +1,560 @@
/*##############################################################################
## 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 <qtk/meshrenderer.h>
#include <qtk/model.h>
#include <qtk/texture.h>
#include "examplescene.h"
#include "resources.h"
using namespace Qtk;
/*******************************************************************************
* Constructors, Destructors
******************************************************************************/
ExampleScene::ExampleScene() {
setSceneName("Example Scene");
getCamera().getTransform().setTranslation(0.0f, 0.0f, 20.0f);
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
}
ExampleScene::~ExampleScene() {
delete mTestPhong;
delete mTestSpecular;
delete mTestDiffuse;
delete mTestAmbient;
}
/*******************************************************************************
* Public Member Functions
******************************************************************************/
void ExampleScene::init() {
// Add a skybox to the scene using default cube map images and settings.
setSkybox(new Qtk::Skybox("Skybox"));
/* Create a red cube with a mini master chief on top. */
auto myCube = new MeshRenderer("My cube", Cube(Qtk::QTK_DRAW_ELEMENTS));
myCube->setColor(RED);
addObject(myCube);
auto mySpartan = new Model("My spartan", PATH("/models/spartan/spartan.obj"));
mySpartan->getTransform().setTranslation(0.0f, 0.5f, 0.0f);
mySpartan->getTransform().setScale(0.5f);
addObject(mySpartan);
//
// Create simple shapes using MeshRenderer class and data in mesh.h
auto mesh = addObject(
new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(-5.0f, 0.0f, -2.0f);
mesh =
addObject(new Qtk::MeshRenderer("centerCube", Cube(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(-7.0f, 0.0f, -2.0f);
mesh = addObject(
new Qtk::MeshRenderer("leftTriangle", Triangle(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(-9.0f, 0.0f, -2.0f);
mesh->setDrawType(GL_LINE_LOOP);
mesh = addObject(
new Qtk::MeshRenderer("topTriangle", Triangle(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(-7.0f, 2.0f, -2.0f);
mesh->getTransform().scale(0.25f);
mesh = addObject(
new Qtk::MeshRenderer("bottomTriangle", Triangle(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(-7.0f, -2.0f, -2.0f);
mesh->getTransform().scale(0.25f);
mesh->setDrawType(GL_LINE_LOOP);
mesh->setColor(GREEN);
//
// 3D Model loading
auto model = addObject(
new Qtk::Model("backpack", PATH("/models/backpack/backpack.obj")));
auto test = PATH("/models/backpack/backpack.obj");
// Sometimes model textures need flipped in certain directions
model->flipTexture("diffuse.jpg", false, true);
model->getTransform().setTranslation(0.0f, 0.0f, -10.0f);
model = addObject(new Qtk::Model("bird", PATH("/models/bird/bird.obj")));
model->getTransform().setTranslation(2.0f, 2.0f, -10.0f);
// Sometimes the models are very large
model->getTransform().scale(0.0025f);
model->getTransform().rotate(-110.0f, 0.0f, 1.0f, 0.0f);
model = addObject(new Qtk::Model("lion", PATH("/models/lion/lion.obj")));
model->getTransform().setTranslation(-3.0f, -1.0f, -10.0f);
model->getTransform().scale(0.15f);
model = addObject(
new Qtk::Model("alien", PATH("/models/alien-hominid/alien.obj")));
model->getTransform().setTranslation(2.0f, -1.0f, -5.0f);
model->getTransform().scale(0.15f);
model =
addObject(new Qtk::Model("scythe", PATH("/models/scythe/scythe.obj")));
model->getTransform().setTranslation(-6.0f, 0.0f, -10.0f);
model->getTransform().rotate(-90.0f, 1.0f, 0.0f, 0.0f);
model->getTransform().rotate(90.0f, 0.0f, 1.0f, 0.0f);
model = addObject(
new Qtk::Model("masterChief", PATH("/models/spartan/spartan.obj")));
model->getTransform().setTranslation(-1.5f, 0.5f, -2.0f);
//
// Simple cube lighting examples.
/* Phong lighting example on a basic cube. */
mTestPhong = new Qtk::MeshRenderer("phong", Qtk::Cube());
mTestPhong->getTransform().setTranslation(3.0f, 0.0f, -2.0f);
// NOTE: You no longer need to manually bind shader program to set uniforms.
// + You can still bind it if you want to for performance reasons.
// + Qtk will only bind / release if the shader program is not already bound.
mTestPhong->setShaders(":/solid-phong.vert", ":/solid-phong.frag");
// For example this would technically not be efficient, because each one of
// these calls will bind, set, release. We could instead bind, set N uniforms,
// and release when we are finished.
// mTestPhong->bindShaders();
mTestPhong->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
mTestPhong->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
mTestPhong->setUniform("uAmbientStrength", 0.2f);
mTestPhong->setUniform("uSpecularStrength", 0.50f);
mTestPhong->setUniform("uSpecularShine", 256);
// mTestPhong->releaseShaders();
mTestPhong->reallocateNormals(mTestPhong->getNormals());
// NOTE: This is only an example and I won't worry about this kind of
// efficiency while initializing the following objects.
// Phong lighting example light source. This is just for visual reference.
// + We refer to the position of this object in draw() to update lighting.
mesh = addObject(
new Qtk::MeshRenderer("phongLight", Triangle(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(3.0f, 2.0f, -2.0f);
mesh->getTransform().scale(0.25f);
/* Example of a cube with no lighting applied */
mesh = addObject(new Qtk::MeshRenderer("noLight", Cube(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(5.0f, 0.0f, -2.0f);
mesh->setShaders(":/solid-perspective.vert", ":/solid-perspective.frag");
mesh->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
// No light source needed for this lighting technique
/* Initialize Ambient example cube */
mTestAmbient = new Qtk::MeshRenderer("ambient", Cube());
mTestAmbient->getTransform().setTranslation(7.0f, 0.0f, -2.0f);
mTestAmbient->setShaders(":/solid-ambient.vert", ":/solid-ambient.frag");
// Changing these uniform values will alter lighting effects.
mTestAmbient->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
mTestAmbient->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
mTestAmbient->setUniform("uAmbientStrength", 0.2f);
mTestAmbient->reallocateNormals(mTestAmbient->getNormals());
// No light source needed for this lighting technique
/* Initialize Diffuse example cube */
mTestDiffuse = new Qtk::MeshRenderer("diffuse", Cube());
mTestDiffuse->getTransform().setTranslation(9.0f, 0.0f, -2.0f);
mTestDiffuse->setShaders(":/solid-diffuse.vert", ":/solid-diffuse.frag");
mTestDiffuse->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
mTestDiffuse->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
mTestDiffuse->setUniform("uAmbientStrength", 0.2f);
mTestDiffuse->reallocateNormals(mTestDiffuse->getNormals());
// Diffuse lighting example light source. This is just for visual reference.
mesh = addObject(
new Qtk::MeshRenderer("diffuseLight", Triangle(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(9.0f, 2.0f, -2.0f);
mesh->getTransform().scale(0.25f);
/* Initialize Specular example cube */
mTestSpecular = new Qtk::MeshRenderer("specular", Cube());
mTestSpecular->getTransform().setTranslation(11.0f, 0.0f, -2.0f);
mTestSpecular->setShaders(":/solid-specular.vert", ":/solid-specular.frag");
mTestSpecular->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
mTestSpecular->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
mTestSpecular->setUniform("uAmbientStrength", 0.2f);
mTestSpecular->setUniform("uSpecularStrength", 0.50f);
mTestSpecular->setUniform("uSpecularShine", 256);
mTestSpecular->reallocateNormals(mTestSpecular->getNormals());
// Specular lighting example light source. This is just for visual reference.
mesh = addObject(
new Qtk::MeshRenderer("specularLight", Triangle(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(11.0f, 2.0f, -2.0f);
mesh->getTransform().scale(0.25f);
/* Test basic cube with phong.vert and phong.frag shaders */
mesh = addObject(new Qtk::MeshRenderer("testPhong", Cube(QTK_DRAW_ARRAYS)));
mesh->getTransform().setTranslation(5.0f, 0.0f, 10.0f);
mesh->setShaders(":/phong.vert", ":/phong.frag");
// WARNING: Set color before reallocating normals.
mesh->setColor(QVector3D(0.0f, 0.25f, 0.0f));
mesh->reallocateNormals(mesh->getNormals());
mesh->setUniform("uMaterial.ambient", QVector3D(0.0f, 0.3f, 0.0f));
mesh->setUniform("uMaterial.diffuse", QVector3D(0.0f, 0.2f, 0.0f));
mesh->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
mesh->setUniform("uMaterial.ambientStrength", 1.0f);
mesh->setUniform("uMaterial.diffuseStrength", 1.0f);
mesh->setUniform("uMaterial.specularStrength", 1.0f);
mesh->setUniform("uMaterial.shine", 64.0f);
mesh->setUniform("uLight.ambient", QVector3D(0.25f, 0.2f, 0.075f));
mesh->setUniform("uLight.diffuse", QVector3D(0.75f, 0.6f, 0.22f));
mesh->setUniform("uLight.specular", QVector3D(0.62f, 0.55f, 0.37f));
mesh->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
// Light source for testPhong cube
mesh = addObject(
new Qtk::MeshRenderer("testLight", Triangle(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(5.0f, 1.25f, 10.0f);
mesh->getTransform().scale(0.25f);
mesh->setDrawType(GL_LINE_LOOP);
mesh->setColor(RED);
//
// Building more complex objects for showing examples of lighting techniques
/* Test alien Model with phong lighting and specular mapping. */
model = addObject(new Qtk::Model(
"alienTest", PATH("/models/alien-hominid/alien.obj"),
":/model-specular.vert", ":/model-specular.frag"));
model->getTransform().setTranslation(3.0f, -1.0f, 10.0f);
model->getTransform().scale(0.15f);
model->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
model->setUniform("uMaterial.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
model->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
model->setUniform("uMaterial.ambientStrength", 0.8f);
model->setUniform("uMaterial.diffuseStrength", 0.8f);
model->setUniform("uMaterial.specularStrength", 1.0f);
model->setUniform("uMaterial.shine", 32.0f);
model->setUniform("uLight.ambient", QVector3D(1.0f, 1.0f, 1.0f));
model->setUniform("uLight.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
model->setUniform("uLight.specular", QVector3D(1.0f, 1.0f, 1.0f));
// Light source for alienTest object.
mesh = addObject(new Qtk::MeshRenderer(
"alienTestLight", Triangle(Qtk::QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(4.0f, 1.5f, 10.0f);
mesh->getTransform().scale(0.25f);
// This function changes values we have allocated in a buffer, so init() after
mesh->setColor(GREEN);
/* Test spartan Model with phong lighting, specular and normal mapping. */
model = addObject(new Qtk::Model(
"spartanTest", PATH("/models/spartan/spartan.obj"),
":/model-normals.vert", ":/model-normals.frag"));
model->getTransform().setTranslation(0.0f, -1.0f, 10.0f);
model->getTransform().scale(2.0f);
model->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
model->setUniform("uMaterial.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
model->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
model->setUniform("uMaterial.ambientStrength", 1.0f);
model->setUniform("uMaterial.diffuseStrength", 1.0f);
model->setUniform("uMaterial.specularStrength", 1.0f);
model->setUniform("uMaterial.shine", 128.0f);
model->setUniform("uLight.ambient", QVector3D(1.0f, 1.0f, 1.0f));
model->setUniform("uLight.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
model->setUniform("uLight.specular", QVector3D(1.0f, 1.0f, 1.0f));
// Light source for spartanTest object.
mesh = addObject(
new Qtk::MeshRenderer("spartanTestLight", Triangle(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(1.0f, 1.5f, 10.0f);
mesh->getTransform().scale(0.25f);
// This function changes values we have allocated in a buffer, so init() after
mesh->setColor(GREEN);
//
// Test drawing simple geometry with various OpenGL drawing modes
// RGB Normals cube to show normals are correct with QTK_DRAW_ARRAYS
mesh = addObject(
new Qtk::MeshRenderer("rgbNormalsCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
mesh->getTransform().setTranslation(5.0f, 0.0f, 4.0f);
mesh->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
mesh->reallocateNormals(mesh->getNormals());
// RGB Normals cube to show normals are correct with QTK_DRAW_ELEMENTS_NORMALS
mesh = addObject(new Qtk::MeshRenderer(
"rgbNormalsCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
mesh->getTransform().setTranslation(5.0f, 0.0f, 2.0f);
mesh->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
mesh->reallocateNormals(mesh->getNormals());
Texture crateTexture;
crateTexture.setTexture(":/crate.png");
Cube cube;
auto * m = new MeshRenderer("Test Crate", Cube(QTK_DRAW_ARRAYS));
m->getTransform().setTranslation(0, 0, 13);
m->setShaders(":/texture2d.vert", ":/texture2d.frag");
m->setTexture(crateTexture);
m->setUniform("uTexture", 0);
m->reallocateTexCoords(cube.getTexCoords());
addObject(m);
// Texturing a cube using texture coordinates and glDrawArrays
// + Texturing with UVs using glDrawElements requires
// QTK_DRAW_ELEMENTS_NORMALS
// + UVs required duplicating element position data from QTK_DRAW_ELEMENTS
// + This is because the same position must use different UV coordinates
mesh = addObject(
new Qtk::MeshRenderer("uvCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
mesh->getTransform().setTranslation(-3.0f, 0.0f, -2.0f);
mesh->setShaders(":/texture2d.vert", ":/texture2d.frag");
mesh->setTexture(crateTexture);
mesh->setUniform("uTexture", 0);
mesh->reallocateTexCoords(mesh->getTexCoords());
// Test drawing a cube with texture coordinates using glDrawElements
mesh = addObject(new Qtk::MeshRenderer(
"uvCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
mesh->getTransform().setTranslation(-1.7f, 0.0f, -2.0f);
mesh->setTexture(":/crate.png");
mesh->setShaders(":/texture2d.vert", ":/texture2d.frag");
mesh->bindShaders();
mesh->setUniform("uTexture", 0);
mesh->reallocateNormals(mesh->getNormals());
mesh->reallocateTexCoords(mesh->getTexCoords(), 3);
mesh->releaseShaders();
mesh->getTransform().rotate(45.0f, 0.0f, 1.0f, 0.0f);
// Texturing a cube using a cube map
// + Cube map texturing works with both QTK_DRAW_ARRAYS and QTK_DRAW_ELEMENTS
mesh =
addObject(new Qtk::MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(-3.0f, 1.0f, -2.0f);
mesh->getTransform().setRotation(45.0f, 0.0f, 1.0f, 0.0f);
mesh->setShaders(":/texture-cubemap.vert", ":/texture-cubemap.frag");
mesh->setCubeMap(":/crate.png");
mesh->setUniform("uTexture", 0);
mesh->reallocateTexCoords(mesh->getTexCoords());
// Create a cube with custom shaders
// + Apply RGB normals shader and spin the cube for a neat effect
mesh =
addObject(new Qtk::MeshRenderer("rgbNormalsCube", Cube(QTK_DRAW_ARRAYS)));
mesh->getTransform().setTranslation(5.0f, 2.0f, -2.0f);
mesh->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
mesh->reallocateNormals(mesh->getNormals());
// RGB Normals triangle to show normals are correct with QTK_DRAW_ARRAYS
mesh = addObject(new Qtk::MeshRenderer(
"rgbTriangleArraysTest", Triangle(QTK_DRAW_ARRAYS)));
mesh->getTransform().setTranslation(7.0f, 0.0f, 2.0f);
mesh->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
mesh->reallocateNormals(mesh->getNormals());
// RGB Normals triangle to show normals are correct with QTK_DRAW_ELEMENTS
mesh = addObject(new Qtk::MeshRenderer(
"rgbTriangleElementsTest", Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
mesh->getTransform().setTranslation(7.0f, 0.0f, 4.0f);
mesh->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
mesh->reallocateNormals(mesh->getNormals());
// Test drawing triangle with glDrawArrays with texture coordinates
mesh = addObject(
new Qtk::MeshRenderer("testTriangleArraysUV", Triangle(QTK_DRAW_ARRAYS)));
mesh->getTransform().setTranslation(-3.0f, 2.0f, -2.0f);
mesh->setShaders(":/texture2d.vert", ":/texture2d.frag");
mesh->setTexture(":/crate.png");
mesh->setUniform("uTexture", 0);
mesh->reallocateTexCoords(mesh->getTexCoords());
// Test drawing triangle with glDrawElements with texture coordinates
mesh = addObject(new Qtk::MeshRenderer(
"testTriangleElementsUV", Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
mesh->getTransform().setTranslation(-2.5f, 0.0f, -1.0f);
mesh->setShaders(":/texture2d.vert", ":/texture2d.frag");
mesh->setTexture(":/crate.png");
mesh->setUniform("uTexture", 0);
mesh->reallocateTexCoords(mesh->getTexCoords());
}
void ExampleScene::draw() {
// WARNING: We must call the base class draw() function first.
// + This will handle rendering core scene components like the Skybox.
Scene::draw();
for(const auto & model : getModels()) {
model->draw();
}
for(const auto & mesh : getMeshes()) {
mesh->draw();
}
mTestPhong->bindShaders();
mTestPhong->setUniform(
"uModelInverseTransposed",
mTestPhong->getTransform().toMatrix().normalMatrix());
mTestPhong->setUniform(
"uLightPosition",
MeshRenderer::getInstance("phongLight")->getTransform().getTranslation());
mTestPhong->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
mTestPhong->releaseShaders();
mTestPhong->draw();
mTestAmbient->bindShaders();
mTestAmbient->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
mTestAmbient->releaseShaders();
mTestAmbient->draw();
mTestDiffuse->bindShaders();
mTestDiffuse->setUniform(
"uModelInverseTransposed",
mTestDiffuse->getTransform().toMatrix().normalMatrix());
mTestDiffuse->setUniform(
"uLightPosition", MeshRenderer::getInstance("diffuseLight")
->getTransform()
.getTranslation());
mTestDiffuse->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
mTestDiffuse->releaseShaders();
mTestDiffuse->draw();
mTestSpecular->bindShaders();
mTestSpecular->setUniform(
"uModelInverseTransposed",
mTestSpecular->getTransform().toMatrix().normalMatrix());
mTestSpecular->setUniform(
"uLightPosition", MeshRenderer::getInstance("specularLight")
->getTransform()
.getTranslation());
mTestSpecular->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
mTestSpecular->releaseShaders();
mTestSpecular->draw();
}
void ExampleScene::update() {
auto mySpartan = Model::getInstance("My spartan");
mySpartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
auto myCube = MeshRenderer::getInstance("My cube");
myCube->getTransform().rotate(-0.75f, 0.0f, 1.0f, 0.0f);
auto position = MeshRenderer::getInstance("alienTestLight")
->getTransform()
.getTranslation();
auto alien = Model::getInstance("alienTest");
alien->setUniform("uLight.position", position);
alien->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
auto posMatrix = alien->getTransform().toMatrix();
alien->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
alien->setUniform("uMVP.model", posMatrix);
alien->setUniform("uMVP.view", ExampleScene::getCamera().toMatrix());
alien->setUniform("uMVP.projection", ExampleScene::getProjectionMatrix());
alien->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
position = MeshRenderer::getInstance("spartanTestLight")
->getTransform()
.getTranslation();
auto spartan = Model::getInstance("spartanTest");
spartan->setUniform("uLight.position", position);
spartan->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
posMatrix = spartan->getTransform().toMatrix();
spartan->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
spartan->setUniform("uMVP.model", posMatrix);
spartan->setUniform("uMVP.view", ExampleScene::getCamera().toMatrix());
spartan->setUniform("uMVP.projection", ExampleScene::getProjectionMatrix());
spartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
auto phong = MeshRenderer::getInstance("testPhong");
phong->getTransform().rotate(0.75f, 1.0f, 0.5f, 0.0f);
phong->bindShaders();
position =
MeshRenderer::getInstance("testLight")->getTransform().getTranslation();
phong->setUniform("uLight.position", position);
phong->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
posMatrix = phong->getTransform().toMatrix();
phong->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
phong->setUniform("uMVP.model", posMatrix);
phong->setUniform("uMVP.view", ExampleScene::getCamera().toMatrix());
phong->setUniform("uMVP.projection", ExampleScene::getProjectionMatrix());
phong->releaseShaders();
// Rotate lighting example cubes
mTestPhong->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
MeshRenderer::getInstance("noLight")->getTransform().rotate(
0.75f, 0.5f, 0.3f, 0.2f);
mTestAmbient->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
mTestDiffuse->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
mTestSpecular->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
// Examples of various translations and rotations
// Rotate in multiple directions simultaneously
MeshRenderer::getInstance("rgbNormalsCube")
->getTransform()
.rotate(0.75f, 0.2f, 0.4f, 0.6f);
// Pitch forward and roll sideways
MeshRenderer::getInstance("leftTriangle")
->getTransform()
.rotate(0.75f, 1.0f, 0.0f, 0.0f);
MeshRenderer::getInstance("rightTriangle")
->getTransform()
.rotate(0.75f, 0.0f, 0.0f, 1.0f);
// Move between two positions over time
static float translateX = 0.025f;
float limit = -9.0f; // Origin position.x - 2.0f
float posX = MeshRenderer::getInstance("topTriangle")
->getTransform()
.getTranslation()
.x();
if(posX < limit || posX > limit + 4.0f) {
translateX = -translateX;
}
MeshRenderer::getInstance("topTriangle")
->getTransform()
.translate(translateX, 0.0f, 0.0f);
MeshRenderer::getInstance("bottomTriangle")
->getTransform()
.translate(-translateX, 0.0f, 0.0f);
// And lets rotate the triangles in two directions at once
MeshRenderer::getInstance("topTriangle")
->getTransform()
.rotate(0.75f, 0.2f, 0.0f, 0.4f);
MeshRenderer::getInstance("bottomTriangle")
->getTransform()
.rotate(0.75f, 0.0f, 0.2f, 0.4f);
// And make the bottom triangle green, instead of RGB
// Rotate center cube in several directions simultaneously
// + Not subject to gimbal lock since we are using quaternions :)
MeshRenderer::getInstance("centerCube")
->getTransform()
.rotate(0.75f, 0.2f, 0.4f, 0.6f);
}

77
src/app/examplescene.h Normal file
View File

@@ -0,0 +1,77 @@
/*##############################################################################
## 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_EXAMPLE_SCENE_H
#define QTK_EXAMPLE_SCENE_H
#include <QMatrix4x4>
#include <qtk/camera3d.h>
#include <qtk/scene.h>
#include <qtk/skybox.h>
/**
* Example scene using QtkWidget to render 3D models and simple geometry within
* QtOpenGLWidgets. This scene also shows some examples of using GLSL shaders to
* apply the basic lighting techniques leading up to Phong.
*
* The Qtk::Scene base class provides containers for N pointers to MeshRenderer
* and Model objects. We can create and insert as many as we like within this
* child class implementation. This child class does not need to manually draw
* objects inserted into these containers. The child class would only need to
* update uniform or other data that may change per-frame.
* See scene.h and `init()` for more information.
*
* To modify the scene objects should be initialized within the `init()` public
* method. Any required movement or updates should be applied within `draw()` or
* `update()`.
*
* To create your own Scene from scratch see Qtk::Scene.
*/
class ExampleScene : public Qtk::Scene {
public:
/***************************************************************************
* Contructors / Destructors
**************************************************************************/
ExampleScene();
~ExampleScene();
/***************************************************************************
* Inherited Public Overrides
**************************************************************************/
/**
* Initialize objects within the scene
*/
void init() override;
/**
* Called when OpenGL repaints the widget.
*/
void draw() override;
/**
* Called when the Qt `frameSwapped` signal is caught.
* See definition of `QtkWidget::initializeGL()`
*/
void update() override;
private:
/***************************************************************************
* Private Members
**************************************************************************/
// Additional example objects created within this example.
// + The base class Scene manages objects stored within mMeshes or mModels
Qtk::MeshRenderer * mTestPhong {};
Qtk::MeshRenderer * mTestSpecular {};
Qtk::MeshRenderer * mTestDiffuse {};
Qtk::MeshRenderer * mTestAmbient {};
};
#endif // QTK_EXAMPLE_SCENE_H

View File

@@ -1,23 +1,20 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Main window for Qt6 OpenGL widget application ##
## About: Main program for practice using Qt6 widgets and OpenGL ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#ifndef QTK_QTKAPI_H
#define QTK_QTKAPI_H
#include <QtCore/QtGlobal>
#include <QApplication>
#ifdef QTK_SHARED
#if defined(QTK_EXPORT)
#define QTKAPI Q_DECL_EXPORT
#else
#define QTKAPI Q_DECL_IMPORT
#endif
#else
#define QTKAPI
#endif
#include "qtkmainwindow.h"
#endif // QTK_QTKAPI_H
int main(int argc, char * argv[]) {
QApplication a(argc, argv);
auto window = MainWindow::getMainWindow();
window->show();
return QApplication::exec();
}

52
src/app/qtkmainwindow.cpp Normal file
View File

@@ -0,0 +1,52 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: MainWindow for Qtk application ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <qtk/qtkapi.h>
#include "examplescene.h"
#include "qtkmainwindow.h"
#include "ui_qtkmainwindow.h"
MainWindow * MainWindow::mainWindow_ = Q_NULLPTR;
MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) {
ui_ = new Ui::MainWindow;
setObjectName("MainWindow");
// For use in design mode using Qt Creator
// + We can use the `ui` member to access nested widgets by name
ui_->setupUi(this);
ui_->menuView->addAction(ui_->toolBar->toggleViewAction());
// Initialize static container for all active QtkWidgets
auto qtkWidgets = findChildren<Qtk::QtkWidget *>();
for(auto & qtkWidget : qtkWidgets) {
qtkWidget->setScene(new ExampleScene);
views_.emplace(qtkWidget->getScene()->getSceneName(), qtkWidget);
ui_->menuView->addAction(qtkWidget->getActionToggleConsole());
connect(
qtkWidget->getScene(), &Qtk::Scene::sceneUpdated, this,
&MainWindow::refreshScene);
}
auto docks = findChildren<QDockWidget *>();
for(auto & dock : docks) {
addDockWidget(Qt::RightDockWidgetArea, dock);
ui_->menuView->addAction(dock->toggleViewAction());
}
// Set the window icon used for Qtk.
setWindowIcon(Qtk::getIcon());
}
MainWindow::~MainWindow() {
delete ui_;
}
void MainWindow::refreshScene(QString sceneName) {
ui_->qtk__TreeView->updateView(getQtkWidget(sceneName)->getScene());
}

93
src/app/qtkmainwindow.h Normal file
View File

@@ -0,0 +1,93 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: MainWindow for Qtk application ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <unordered_map>
#include <QMainWindow>
#include <QPlainTextEdit>
#include "debugconsole.h"
#include "qtkwidget.h"
namespace Ui {
class MainWindow;
}
/**
* MainWindow class to provide an example of using a QtkWidget within a Qt
* window application.
*/
class MainWindow : public QMainWindow {
Q_OBJECT
public:
/***************************************************************************
* Contructors / Destructors
**************************************************************************/
/**
* This ctor also initializes the Scene for each QtkWidget in the window.
* To load a different scene this would need to be updated.
*
* @param parent The parent for this QMainWindow
*/
explicit MainWindow(QWidget * parent = nullptr);
~MainWindow() override;
/***************************************************************************
* Public Static Methods
**************************************************************************/
/**
* Allows widgets to retrieve an instance of this root QMainWindow.
* @return this
*/
inline static MainWindow * getMainWindow() {
if(mainWindow_ == Q_NULLPTR) {
mainWindow_ = new MainWindow;
}
return mainWindow_;
}
/**
* Accessor for retrieving a QtkWidget by it's objectName.
* This function will not construct a new QtkWidget if none is found.
*
* @param name The objectName associated with the QtkWidget.
* @return Pointer to an active QtkWidget or Q_NULLPTR is not found.
*/
inline Qtk::QtkWidget * getQtkWidget(const QString & name) {
if(!views_.count(name)) {
return Q_NULLPTR;
}
return views_[name];
}
public slots:
void refreshScene(QString sceneName);
private:
MainWindow(const MainWindow &) {};
/***************************************************************************
* Private Members
**************************************************************************/
Ui::MainWindow * ui_ {};
static MainWindow * mainWindow_;
/**
* Maps a scene name to the QtkWidget viewing it.
* TODO: Value should be a vector of QtkWidget * for multiple scene views.
*/
std::unordered_map<QString, Qtk::QtkWidget *> views_ {};
};
#endif // MAINWINDOW_H

336
src/app/qtkmainwindow.ui Normal file
View File

@@ -0,0 +1,336 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>824</width>
<height>601</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Qtk - MainWindow</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>../resources/icon.png</normaloff>../resources/icon.png</iconset>
</property>
<property name="unifiedTitleAndToolBarOnMac">
<bool>true</bool>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<property name="movable">
<bool>true</bool>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>View 1</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="Qtk::QtkWidget" name="qtk::QtkWidget">
<property name="toolTip">
<string>A custom widget tool tip.</string>
</property>
<property name="whatsThis">
<string>Custom widget what's this?</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>View 2</string>
</attribute>
</widget>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="Qtk::TreeView" name="qtk::TreeView">
<property name="toolTip">
<string>A custom widget tool tip.</string>
</property>
<property name="whatsThis">
<string>Custom widget what's this?</string>
</property>
</widget>
</item>
<item>
<widget class="Qtk::ToolBox" name="qtk::ToolBox">
<property name="toolTip">
<string>A custom widget tool tip.</string>
</property>
<property name="whatsThis">
<string>Custom widget what's this?</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>824</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuTest">
<property name="title">
<string>File</string>
</property>
<addaction name="actionNew"/>
<addaction name="actionOpen"/>
<addaction name="separator"/>
<addaction name="actionSave"/>
<addaction name="actionSave_as"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
<string>View</string>
</property>
<widget class="QMenu" name="menuTab_Position">
<property name="title">
<string>Tab Position</string>
</property>
<addaction name="actionTop"/>
<addaction name="actionBottom"/>
<addaction name="actionLeft"/>
<addaction name="actionRight"/>
</widget>
<addaction name="menuTab_Position"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>Edit</string>
</property>
<addaction name="actionUndo"/>
<addaction name="actionRedo"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
</property>
<addaction name="actionAbout"/>
</widget>
<addaction name="menuTest"/>
<addaction name="menuEdit"/>
<addaction name="menuView"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="movable">
<bool>true</bool>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonIconOnly</enum>
</property>
<property name="floatable">
<bool>true</bool>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionLoad_Model"/>
<addaction name="actionDelete_Object"/>
</widget>
<action name="actionOpen">
<property name="text">
<string>Open...</string>
</property>
</action>
<action name="actionSave">
<property name="icon">
<iconset>
<normaloff>:/icons/resources/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</normaloff>:/icons/resources/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</iconset>
</property>
<property name="text">
<string>Save</string>
</property>
</action>
<action name="actionSave_as">
<property name="text">
<string>Save as...</string>
</property>
</action>
<action name="actionExit">
<property name="text">
<string>Exit</string>
</property>
</action>
<action name="actionShow_Console">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show Console</string>
</property>
</action>
<action name="actionLoad_Model">
<property name="icon">
<iconset>
<normaloff>:/icons/resources/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</normaloff>:/icons/resources/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</iconset>
</property>
<property name="text">
<string>Load Model</string>
</property>
<property name="font">
<font/>
</property>
</action>
<action name="actionDelete_Object">
<property name="icon">
<iconset>
<normaloff>:/icons/resources/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</normaloff>:/icons/resources/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</iconset>
</property>
<property name="text">
<string>Delete Object</string>
</property>
</action>
<action name="actionNew">
<property name="text">
<string>New</string>
</property>
</action>
<action name="actionTop">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Top</string>
</property>
</action>
<action name="actionBottom">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Bottom</string>
</property>
</action>
<action name="actionLeft">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Left</string>
</property>
</action>
<action name="actionRight">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Right</string>
</property>
</action>
<action name="actionAbout">
<property name="text">
<string>About</string>
</property>
</action>
<action name="actionNested_Widgets">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>Nested Widgets</string>
</property>
</action>
<action name="actionUndo">
<property name="text">
<string>Undo</string>
</property>
</action>
<action name="actionRedo">
<property name="text">
<string>Redo</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>Qtk::QtkWidget</class>
<extends>QOpenGLWidget</extends>
<header>qtkwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>Qtk::TreeView</class>
<extends>QDockWidget</extends>
<header>treeview.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>Qtk::ToolBox</class>
<extends>QDockWidget</extends>
<header>toolbox.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>actionExit</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>411</x>
<y>300</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -7,11 +7,15 @@
##############################################################################*/
#include <QKeyEvent>
#include <QVBoxLayout>
#include <input.h>
#include <mesh.h>
#include <qtkwidget.h>
#include <scene.h>
#include "qtk/input.h"
#include "qtk/mesh.h"
#include "qtk/scene.h"
#include "debugconsole.h"
#include "qtkmainwindow.h"
#include "qtkwidget.h"
using namespace Qtk;
@@ -19,17 +23,26 @@ using namespace Qtk;
* Constructors, Destructors
******************************************************************************/
QtkWidget::QtkWidget() : mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR) {
initializeWidget();
}
QtkWidget::QtkWidget(QWidget * parent, const QString & name) :
QtkWidget(parent, name, Q_NULLPTR) {}
QtkWidget::QtkWidget(QWidget * parent) :
QOpenGLWidget(parent), mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR) {
initializeWidget();
}
QtkWidget::QtkWidget(const QSurfaceFormat & format) :
mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR) {
QtkWidget::QtkWidget(QWidget * parent, const QString & name, Scene * scene) :
QOpenGLWidget(parent), mDebugLogger(Q_NULLPTR),
mConsole(new DebugConsole(this, name)) {
setScene(scene);
setObjectName(name);
QSurfaceFormat format;
format.setRenderableType(QSurfaceFormat::OpenGL);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(4, 6);
// Set the number of samples used for glEnable(GL_MULTISAMPLING)
format.setSamples(4);
// Set the size of the depth bufer for glEnable(GL_DEPTH_TEST)
format.setDepthBufferSize(16);
// If QTK_DEBUG is set, enable debug context
#ifdef QTK_DEBUG
format.setOption(QSurfaceFormat::DebugContext);
#endif
setFormat(format);
setFocusPolicy(Qt::ClickFocus);
}
@@ -39,6 +52,19 @@ QtkWidget::~QtkWidget() {
teardownGL();
}
/*******************************************************************************
* Public Methods
******************************************************************************/
QAction * QtkWidget::getActionToggleConsole() {
auto action = new QAction(mScene->getSceneName() + " debug console");
action->setCheckable(true);
action->setChecked(mConsoleActive);
action->setStatusTip("Add a debug console for this QtkWidget.");
connect(action, &QAction::triggered, this, &QtkWidget::toggleConsole);
return action;
}
/*******************************************************************************
* Public Inherited Virtual Methods
******************************************************************************/
@@ -104,19 +130,24 @@ void QtkWidget::update() {
void QtkWidget::messageLogged(const QOpenGLDebugMessage & msg) {
QString error;
DebugContext context;
// Format based on severity
switch(msg.severity()) {
case QOpenGLDebugMessage::NotificationSeverity:
error += "--";
context = Status;
break;
case QOpenGLDebugMessage::HighSeverity:
error += "!!";
context = Fatal;
break;
case QOpenGLDebugMessage::MediumSeverity:
error += "!~";
context = Error;
break;
case QOpenGLDebugMessage::LowSeverity:
error += "~~";
context = Warn;
break;
}
@@ -159,8 +190,9 @@ void QtkWidget::messageLogged(const QOpenGLDebugMessage & msg) {
}
#undef CASE
error += ")";
qDebug() << qPrintable(error) << "\n" << qPrintable(msg.message()) << "\n";
error += ")\n" + msg.message() + "\n";
qDebug() << qPrintable(error);
sendLog("(OpenGL) " + error.replace("\n", "\n(OpenGL) "), context);
}
/*******************************************************************************
@@ -196,23 +228,6 @@ void QtkWidget::mouseReleaseEvent(QMouseEvent * event) {
* Private Methods
******************************************************************************/
void QtkWidget::initializeWidget() {
QSurfaceFormat format;
format.setRenderableType(QSurfaceFormat::OpenGL);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(4, 6);
// Set the number of samples used for glEnable(GL_MULTISAMPLING)
format.setSamples(4);
// Set the size of the depth bufer for glEnable(GL_DEPTH_TEST)
format.setDepthBufferSize(16);
// If QTK_DEBUG is set, enable debug context
#ifdef QTK_DEBUG
format.setOption(QSurfaceFormat::DebugContext);
#endif
setFormat(format);
setFocusPolicy(Qt::ClickFocus);
}
void QtkWidget::printContextInformation() {
QString glType;
QString glVersion;
@@ -239,11 +254,11 @@ void QtkWidget::printContextInformation() {
}
#undef CASE
// qPrintable() will print our QString w/o quotes around it.
qDebug() << qPrintable(glType) << qPrintable(glVersion) << "("
<< qPrintable(glProfile) << ")"
<< "\nOpenGL Vendor: " << qPrintable(glVendor)
<< "\nRendering Device: " << qPrintable(glRenderer) << "\n";
auto message = QString(glType) + glVersion + "(" + glProfile + ")"
+ "\nOpenGL Vendor: " + glVendor
+ "\nRendering Device: " + glRenderer;
qDebug() << qPrintable(message);
sendLog("(OpenGL) " + message.replace("\n", "\n(OpenGL) "), Status);
}
void QtkWidget::updateCameraInput() {
@@ -282,3 +297,26 @@ void QtkWidget::updateCameraInput() {
Scene::getCamera().getTransform().translate(transSpeed * translation);
}
}
void QtkWidget::toggleConsole() {
if(mConsoleActive) {
mConsole->setHidden(true);
mConsoleActive = false;
} else {
MainWindow::getMainWindow()->addDockWidget(
Qt::DockWidgetArea::BottomDockWidgetArea,
dynamic_cast<QDockWidget *>(mConsole));
mConsole->setHidden(false);
mConsoleActive = true;
}
}
void QtkWidget::setScene(Qtk::Scene * scene) {
delete mScene;
mScene = scene;
if(mScene != Q_NULLPTR) {
mConsole->setTitle(mScene->getSceneName());
} else {
mConsole->setTitle("Null Scene");
}
}

View File

@@ -10,22 +10,26 @@
#include <iostream>
#include <QDockWidget>
#include <QMatrix4x4>
#include <QOpenGLDebugLogger>
#include <QOpenGLFunctions>
#include <QOpenGLWidget>
#include <QPlainTextEdit>
#include <qtkapi.h>
#include <scene.h>
#include "qtk/qtkapi.h"
#include "qtk/scene.h"
namespace Qtk {
class DebugConsole;
/**
* QtkWidget class to define required QOpenGLWidget functionality.
*
* This object has a Scene attached which manages the objects to render.
* Client input is passed through this widget to control the camera view.
*/
class QTKAPI QtkWidget : public QOpenGLWidget, protected QOpenGLFunctions {
class QtkWidget : public QOpenGLWidget, protected QOpenGLFunctions {
Q_OBJECT;
public:
@@ -33,26 +37,36 @@ namespace Qtk {
* Contructors / Destructors
************************************************************************/
/**
* Default ctor will configure a QSurfaceFormat with default settings.
*/
QtkWidget();
/**
* Qt Designer will call this ctor when creating this widget as a child.
*
* @param parent The parent QWidget
* @param parent Pointer to a parent widget for this QtkWidget or nullptr.
*/
explicit QtkWidget(QWidget * parent);
explicit QtkWidget(QWidget * parent = nullptr) :
QtkWidget(parent, "QtkWidget") {}
/**
* Allow constructing the widget with a preconfigured QSurfaceFormat.
* Default construct a QtkWidget.
*
* @param format QSurfaceFormat already configured by the caller.
* @param parent Pointer to a parent widget or nullptr if no parent.
* @param name An objectName for the new QtkWidget.
*/
explicit QtkWidget(const QSurfaceFormat & format);
explicit QtkWidget(QWidget * parent, const QString & name);
/**
* Construct a custom QtkWidget.
*
* @param parent Pointer to a parent widget or nullptr if no parent.
* @param name An objectName for the new QtkWidget.
* @param scene Pointer to a custom class inheriting from Qtk::Scene.
*/
QtkWidget(QWidget * parent, const QString & name, Qtk::Scene * scene);
~QtkWidget() override;
/*************************************************************************
* Public Methods
************************************************************************/
QAction * getActionToggleConsole();
private:
/*************************************************************************
@@ -60,7 +74,7 @@ namespace Qtk {
************************************************************************/
// clang-format off
void teardownGL() { /* Nothing to teardown yet... */ }
void teardownGL() { /* Nothing to teardown yet... */ }
// clang-format on
public:
@@ -96,10 +110,12 @@ namespace Qtk {
* Setters
************************************************************************/
inline void setScene(Qtk::Scene * scene) {
delete mScene;
mScene = scene;
}
void setScene(Qtk::Scene * scene);
public slots:
/**
* Toggle visibility of the DebugConsole associated with this QtkWidget.
*/
void toggleConsole();
protected slots:
/*************************************************************************
@@ -119,8 +135,12 @@ namespace Qtk {
*
* @param msg The message logged.
*/
static void messageLogged(const QOpenGLDebugMessage & msg);
void messageLogged(const QOpenGLDebugMessage & msg);
#endif
public:
signals:
void sendLog(
const QString & message, Qtk::DebugContext context = Qtk::Status);
protected:
/*************************************************************************
@@ -137,19 +157,19 @@ namespace Qtk {
* Private Methods
************************************************************************/
void initializeWidget();
static void updateCameraInput();
#ifdef QTK_DEBUG
void printContextInformation();
QOpenGLDebugLogger * mDebugLogger;
#endif
/*************************************************************************
* Private Members
************************************************************************/
bool mConsoleActive = false;
Qtk::Scene * mScene;
Qtk::DebugConsole * mConsole;
};
} // namespace Qtk

8
src/app/resources.h.in Normal file
View File

@@ -0,0 +1,8 @@
#ifndef QTK_RESOURCES_H_IN_H
#define QTK_RESOURCES_H_IN_H
#define RESOURCES "@CMAKE_SOURCE_DIR@/resources"
#define PATH(a) RESOURCES a
#endif // QTK_RESOURCES_H_IN_H

20
src/app/toolbox.cpp Normal file
View File

@@ -0,0 +1,20 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Toolbox plugin for object details and options ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
################################################################################
*/
#include "toolbox.h"
#include "ui_toolbox.h"
Qtk::ToolBox::ToolBox(QWidget * parent) :
QDockWidget(parent), ui(new Ui::ToolBox) {
ui->setupUi(this);
}
Qtk::ToolBox::~ToolBox() {
delete ui;
}

33
src/app/toolbox.h Normal file
View File

@@ -0,0 +1,33 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Toolbox plugin for object details and options ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
################################################################################
*/
#ifndef TOOLBOX_H
#define TOOLBOX_H
#include <QDesignerExportWidget>
#include <QDockWidget>
namespace Ui {
class ToolBox;
}
namespace Qtk {
class QDESIGNER_WIDGET_EXPORT ToolBox : public QDockWidget {
Q_OBJECT
public:
explicit ToolBox(QWidget * parent = nullptr);
~ToolBox();
private:
Ui::ToolBox * ui;
};
} // namespace Qtk
#endif // TOOLBOX_H

56
src/app/toolbox.ui Normal file
View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ToolBox</class>
<widget class="QDockWidget" name="ToolBox">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Object Details</string>
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolBox" name="toolBox">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="page">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>382</width>
<height>201</height>
</rect>
</property>
<attribute name="label">
<string>Shaders</string>
</attribute>
</widget>
<widget class="QWidget" name="page_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>382</width>
<height>201</height>
</rect>
</property>
<attribute name="label">
<string>Properties</string>
</attribute>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

58
src/app/treeview.cpp Normal file
View File

@@ -0,0 +1,58 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: TreeView plugin for scene hierarchy ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
################################################################################
*/
#include "treeview.h"
#include "qtkmainwindow.h"
#include "ui_treeview.h"
/*******************************************************************************
* Constructors, Destructors
******************************************************************************/
Qtk::TreeView::TreeView(QWidget * parent) :
QDockWidget(parent), ui(new Ui::TreeView) {
ui->setupUi(this);
connect(
ui->treeWidget, &QTreeWidget::itemDoubleClicked, this,
&TreeView::itemFocus);
}
Qtk::TreeView::~TreeView() {
delete ui;
}
/*******************************************************************************
* Public Members
******************************************************************************/
void Qtk::TreeView::updateView(const Qtk::Scene * scene) {
ui->treeWidget->clear();
ui->treeWidget->setColumnCount(1);
mSceneName = scene->getSceneName();
auto objects = scene->getObjects();
for(const auto & object : objects) {
auto item = new QTreeWidgetItem(QStringList(QString(object->getName())));
ui->treeWidget->insertTopLevelItem(0, item);
}
}
void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column) {
QString name = item->text(column);
auto scene =
MainWindow::getMainWindow()->getQtkWidget(mSceneName)->getScene();
auto & transform = scene->getCamera().getTransform();
auto object = scene->getObject(name);
Transform3D * objectTransform;
if(object->getType() == Object::MESH) {
objectTransform = &dynamic_cast<MeshRenderer *>(object)->getTransform();
} else if(object->getType() == Object::MODEL) {
objectTransform = &dynamic_cast<Model *>(object)->getTransform();
}
transform.setTranslation(objectTransform->getTranslation());
transform.translate(0.0f, 0.0f, 3.0f);
}

61
src/app/treeview.h Normal file
View File

@@ -0,0 +1,61 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: TreeView plugin for scene hierarchy ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
################################################################################
*/
#ifndef TREEVIEW_H
#define TREEVIEW_H
#include <QDesignerCustomWidgetInterface>
#include <QDesignerExportWidget>
#include <QDockWidget>
#include <qtk/scene.h>
#include <QTreeWidgetItem>
namespace Ui {
class TreeView;
}
namespace Qtk {
class QDESIGNER_WIDGET_EXPORT TreeView : public QDockWidget {
Q_OBJECT
public:
explicit TreeView(QWidget * parent = nullptr);
~TreeView();
/**
* Updates the QTreeWidget with all objects within the scene.
* @param scene The scene to load objects from.
*/
void updateView(const Scene * scene);
public slots:
/**
* Focus the camera on an item when it is double clicked.
* Triggered by QTreeWidget::itemDoubleClicked signal.
*
* @param item The item that was double clicked
* @param column The column of the item that was double clicked.
* This param is currently not used but required for this signal.
*/
void itemFocus(QTreeWidgetItem * item, int column);
private:
Ui::TreeView * ui;
/**
* The name of the scene last loaded by this TreeWidget.
* Used to load object data from a target scene.
*/
QString mSceneName;
};
} // namespace Qtk
#endif // TREEVIEW_H

44
src/app/treeview.ui Normal file
View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TreeView</class>
<widget class="QDockWidget" name="TreeView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Scene Tree View</string>
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTreeWidget" name="treeWidget">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="indentation">
<number>10</number>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

88
src/app/widgetplugin.cpp Normal file
View File

@@ -0,0 +1,88 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Generic Qt Designer widget plugin ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
################################################################################
*/
#include <QIcon>
#include <QtPlugin>
#include <utility>
#include "qtk/qtkapi.h"
#include "widgetplugin.h"
WidgetPlugin::WidgetPlugin(
QString group, QString class_name, QString include,
WidgetPlugin::Factory factory) :
m_group(std::move(group)),
m_className(std::move(class_name)), m_includeFile(std::move(include)),
m_factory(std::move(factory)), m_objectName(class_name) {}
QString WidgetPlugin::toolTip() const {
return QStringLiteral("A custom widget tool tip.");
}
QString WidgetPlugin::whatsThis() const {
return QStringLiteral("Custom widget what's this?");
}
QIcon WidgetPlugin::icon() const {
return Qtk::getIcon();
}
bool WidgetPlugin::isContainer() const {
return true;
}
QString WidgetPlugin::group() const {
return m_group;
}
QString WidgetPlugin::name() const {
return m_className;
}
QString WidgetPlugin::includeFile() const {
return m_includeFile;
}
QWidget * WidgetPlugin::createWidget(QWidget * parent) {
return m_factory(parent);
}
bool WidgetPlugin::isInitialized() const {
return m_initialized;
}
void WidgetPlugin::initialize(QDesignerFormEditorInterface *) {
if(m_initialized) {
return;
}
m_initialized = true;
}
QString WidgetPlugin::domXml() const {
return
"<ui language=\"c++\">\n"
" <widget class=\"" + m_className + "\" name=\"" + m_objectName + "\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>100</height>\n"
" </rect>\n"
" </property>\n"
" <property name=\"toolTip\" >\n"
" <string>" + toolTip() + "</string>\n"
" </property>\n"
" <property name=\"whatsThis\" >\n"
" <string>" + whatsThis() + "</string>\n"
" </property>\n"
" </widget>\n"
"</ui>\n";
}

114
src/app/widgetplugin.h Normal file
View File

@@ -0,0 +1,114 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Generic Qt Designer widget plugin ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
################################################################################
*/
#ifndef QTK_WIDGETPLUGIN_H
#define QTK_WIDGETPLUGIN_H
#include <QDesignerCustomWidgetInterface>
#include <QDesignerExportWidget>
class QDESIGNER_WIDGET_EXPORT WidgetPlugin :
public QObject,
public QDesignerCustomWidgetInterface {
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
using Factory = std::function<QWidget *(QWidget *)>;
public:
WidgetPlugin(
QString group, QString class_name, QString include, Factory factory);
explicit WidgetPlugin(QObject * parent = nullptr) : QObject(parent) {}
~WidgetPlugin() = default;
public:
/**
* @return The name of the group to which this widget belongs.
*/
[[nodiscard]] QString group() const override;
/**
* Must return the _class name_ of the widget.
*
* @return The class name for the associated widget.
*/
[[nodiscard]] QString name() const override;
/**
* If this path changes for a custom widget, it must be removed and added
* back in Qt Designer for the XML surrounding this value to be regenerated.
*
* See the `<customwidget>` XML in any `.ui` file using a custom widget.
*
* @return Path to the include file for UIC to use when generating code.
*/
[[nodiscard]] QString includeFile() const override;
/**
* @param parent Parent widget to the new instance of this widget.
* @return A new instance of this custom widget.
*/
QWidget * createWidget(QWidget * parent) override;
/**
* @return Short description used in Qt Designer tool tips.
*/
[[nodiscard]] QString toolTip() const override;
/**
* @return Widget description used in `What's this?` within Qt Creator.
*/
[[nodiscard]] QString whatsThis() const override;
/**
* @return Icon used to represent the widget in Qt Designer's GUI.
*/
[[nodiscard]] QIcon icon() const override;
/**
* Whether or not this widget should act as a container for other widgets.
*
* @return True if this custom widget is meant to be a container.
*/
[[nodiscard]] bool isContainer() const override;
/**
* @return True if this widget has been initialized.
*/
[[nodiscard]] bool isInitialized() const override;
/**
* Initializes an instance of this custom widget.
* @param core
*/
void initialize(QDesignerFormEditorInterface * core) override;
/**
* Default XML for an instance of this custom widget within a `.ui` file.
*
* Any property available for the widget in Qt Designer can be set using XML
* properties, as seen here with `toolTip` and `whatsThis`.
*
* @return XML inserted for each instance of this widget.
*/
[[nodiscard]] QString domXml() const override;
private:
bool m_initialized = false;
QString m_group;
QString m_className;
QString m_objectName;
QString m_includeFile;
Factory m_factory;
};
#endif // QTK_WIDGETPLUGIN_H

View File

@@ -0,0 +1,34 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Collection of widget plugins for Qt Designer ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
################################################################################
*/
#include "widgetplugincollection.h"
#include "debugconsole.h"
#include "qtkwidget.h"
#include "toolbox.h"
#include "treeview.h"
#include "widgetplugin.h"
WidgetPluginCollection::WidgetPluginCollection(QObject * parent) :
QObject(parent), m_collectionName("Qtk Widget Collection") {
m_collection = {
new WidgetPlugin(
m_collectionName, "Qtk::QtkWidget", "qtkwidget.h",
[](QWidget * parent) { return new Qtk::QtkWidget(parent); }),
new WidgetPlugin(
m_collectionName, "Qtk::TreeView", "treeview.h",
[](QWidget * parent) { return new Qtk::TreeView(parent); }),
new WidgetPlugin(
m_collectionName, "Qtk::ToolBox", "toolbox.h",
[](QWidget * parent) { return new Qtk::ToolBox(parent); }),
};
}
QList<QDesignerCustomWidgetInterface *> WidgetPluginCollection::customWidgets()
const {
return m_collection;
}

View File

@@ -0,0 +1,34 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
## About: Collection of widget plugins for Qt Designer ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
################################################################################
*/
#ifndef QTK_WIDGETPLUGINCOLLECTION_H
#define QTK_WIDGETPLUGINCOLLECTION_H
#include <QDesignerCustomWidgetCollectionInterface>
class WidgetPluginCollection :
public QObject,
public QDesignerCustomWidgetCollectionInterface {
Q_OBJECT
// Since we're exporting a collection, this is the only plugin metadata
// needed.
Q_PLUGIN_METADATA(IID "com.Klips.WidgetPluginCollection")
// Tell Qt Object system that we're implementing an interface.
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
public:
explicit WidgetPluginCollection(QObject * parent = nullptr);
[[nodiscard]] QList<QDesignerCustomWidgetInterface *> customWidgets() const;
private:
QList<QDesignerCustomWidgetInterface *> m_collection;
QString m_collectionName;
};
#endif // QTK_WIDGETPLUGINCOLLECTION_H

96
src/qtk/CMakeLists.txt Normal file
View File

@@ -0,0 +1,96 @@
################################################################################
## Author: Shaun Reed | Contact: shaunrd0@gmail.com | URL: www.shaunreed.com ##
## ##
## Project for working with OpenGL and Qt6 widgets ##
################################################################################
# TODO: Provide option for linking MainWindow with plugin statically
# TODO: QtkWidget plugin should instantiate a ptr to DebugConsole and store it as a member.
# Then we can connect a signal from MainWindow for creating a console to QtkWidget
# When triggered QtkWidget slot will send signal to MainWindow
# MainWindow catches signal and runs slot to attach DebugConsole to MainWindow as QDockWidget
# TODO: Create a second repository for working on QtkApplication (MainWindow)
################################################################################
# Qtk Library
################################################################################
set(PUBLIC_HEADERS
camera3d.h
input.h
mesh.h
meshrenderer.h
model.h
object.h
qtkapi.h
scene.h
skybox.h
texture.h
transform3D.h
)
set(SOURCE_FILES
camera3d.cpp
input.cpp
mesh.cpp
meshrenderer.cpp
model.cpp
object.cpp
scene.cpp
skybox.cpp
texture.cpp
transform3D.cpp
)
qt_add_library(qtk-library SHARED)
target_sources(qtk-library PRIVATE ${SOURCE_FILES})
target_sources(qtk-library PUBLIC
FILE_SET HEADERS
BASE_DIRS ${CMAKE_SOURCE_DIR}/src
FILES ${PUBLIC_HEADERS}
)
if(QTK_DEBUG)
target_compile_definitions(qtk-library PUBLIC QTK_DEBUG)
endif()
if(QTK_SHARED)
target_compile_definitions(qtk-library PUBLIC QTK_SHARED)
endif()
set_target_properties(qtk-library PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
VERSION ${PROJECT_VERSION}
)
target_link_libraries(qtk-library PUBLIC
Qt6::Core Qt6::OpenGLWidgets Qt6::Widgets
)
if(QTK_UPDATE_SUBMODULES OR NOT ASSIMP_NEW_INTERFACE)
target_link_libraries(qtk-library PUBLIC assimp)
elseif(ASSIMP_NEW_INTERFACE)
target_link_libraries(qtk-library PUBLIC assimp::assimp)
endif()
if(WIN32)
target_link_libraries(qtk-library PUBLIC OpenGL::GL)
endif()
# System install for qtk-library
# TODO: Use RUNTIME_DEPENDENCY_SET to install Qt libraries for local builds?
install(TARGETS qtk-library
# Associate qtk-library target with qtk-export
EXPORT qtk-export
FILE_SET HEADERS DESTINATION "${QTK_INSTALL_PREFIX}/include"
BUNDLE DESTINATION ${QTK_INSTALL_PREFIX}/lib
LIBRARY DESTINATION ${QTK_INSTALL_PREFIX}/lib
ARCHIVE DESTINATION ${QTK_INSTALL_PREFIX}/lib/static
RUNTIME DESTINATION ${QTK_INSTALL_PREFIX}/bin
)
## Install qtk-library to Qt Designer to support widget plugins.
install(TARGETS qtk-library
BUNDLE DESTINATION ${QTK_PLUGIN_LIBRARY_DIR}
LIBRARY DESTINATION ${QTK_PLUGIN_LIBRARY_DIR}
ARCHIVE DESTINATION ${QTK_PLUGIN_LIBRARY_DIR}
RUNTIME DESTINATION ${QTK_PLUGIN_LIBRARY_DIR}
)

View File

@@ -6,7 +6,7 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <camera3d.h>
#include "camera3d.h"
using namespace Qtk;

View File

@@ -11,8 +11,8 @@
#include <QDebug>
#include <qtkapi.h>
#include <transform3D.h>
#include "qtkapi.h"
#include "transform3D.h"
namespace Qtk {
class QTKAPI Camera3D {

View File

@@ -11,7 +11,7 @@
#include <QCursor>
#include <input.h>
#include "input.h"
using namespace Qtk;

View File

@@ -12,8 +12,7 @@
#include <QPoint>
#include <Qt>
#include <qtkapi.h>
#include <qtkwidget.h>
#include "qtkapi.h"
namespace Qtk {
class QTKAPI Input {
@@ -21,7 +20,6 @@ namespace Qtk {
/*************************************************************************
* Typedefs
************************************************************************/
friend class Qtk::QtkWidget;
/**
* Possible key states
@@ -71,11 +69,6 @@ namespace Qtk {
static QPoint mousePosition();
static QPoint mouseDelta();
private:
/*************************************************************************
* Private Methods
************************************************************************/
// State updating
static void update();
static void registerKeyPress(int key);

View File

@@ -6,7 +6,7 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <mesh.h>
#include "mesh.h"
using namespace Qtk;

View File

@@ -8,13 +8,14 @@
#ifndef QTK_MESH_H
#define QTK_MESH_H
#include <utility>
#include <QOpenGLWidget>
#include <QVector2D>
#include <QVector3D>
#include <utility>
#include <qtkapi.h>
#include <transform3D.h>
#include "qtkapi.h"
#include "transform3D.h"
namespace Qtk {
class MeshRenderer;

View File

@@ -8,9 +8,9 @@
#include <QImageReader>
#include <meshrenderer.h>
#include <scene.h>
#include <texture.h>
#include "meshrenderer.h"
#include "scene.h"
#include "texture.h"
using namespace Qtk;
@@ -18,7 +18,7 @@ using namespace Qtk;
Qtk::MeshRenderer::MeshManager Qtk::MeshRenderer::sInstances;
MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape) :
Object(name, shape), mVertexShader(":/multi-color.vert"),
Object(name, shape, MESH), mVertexShader(":/multi-color.vert"),
mFragmentShader(":/multi-color.frag"), mDrawType(GL_TRIANGLES) {
mShape = Shape(shape);
init();

View File

@@ -8,12 +8,12 @@
#ifndef QTK_MESHRENDERER_H
#define QTK_MESHRENDERER_H
#include <mesh.h>
#include <object.h>
#include <qtkapi.h>
#include <utility>
#include "mesh.h"
#include "object.h"
#include "qtkapi.h"
namespace Qtk {
class QTKAPI MeshRenderer : public Object {
public:

View File

@@ -9,10 +9,9 @@
#include <QFileInfo>
#include <model.h>
#include <resourcemanager.h>
#include <scene.h>
#include <texture.h>
#include "model.h"
#include "scene.h"
#include "texture.h"
using namespace Qtk;
@@ -186,8 +185,7 @@ void Model::loadModel(const std::string & path) {
// JIC a relative path was used, get the absolute file path
QFileInfo info(path.c_str());
info.makeAbsolute();
mDirectory = path[0] == ':' ? RM::getPath(path)
: info.absoluteFilePath().toStdString();
mDirectory = info.absoluteFilePath().toStdString();
// Import the model, converting non-triangular geometry to triangles
// + And flipping texture UVs, etc..
@@ -215,7 +213,7 @@ void Model::loadModel(const std::string & path) {
sortModels();
// Object finished loading, insert it into ModelManager
mManager.insert(mName, this);
mManager.insert(getName(), this);
}
void Model::processNode(aiNode * node, const aiScene * scene) {

View File

@@ -23,9 +23,9 @@
#include <assimp/Importer.hpp>
// QTK
#include <object.h>
#include <qtkapi.h>
#include <transform3D.h>
#include "object.h"
#include "qtkapi.h"
#include "transform3D.h"
namespace Qtk {
/**
@@ -122,9 +122,7 @@ namespace Qtk {
* Model object that has a ModelMesh.
* Top-level object that represents 3D models stored within a scene.
*/
class QTKAPI Model : public QObject {
Q_OBJECT
class QTKAPI Model : public Object {
public:
/*************************************************************************
* Typedefs
@@ -142,13 +140,13 @@ namespace Qtk {
const char * name, const char * path,
const char * vertexShader = ":/model-basic.vert",
const char * fragmentShader = ":/model-basic.frag") :
mName(name),
Object(name, MODEL),
mModelPath(path), mVertexShader(vertexShader),
mFragmentShader(fragmentShader) {
loadModel(path);
loadModel(mModelPath);
}
inline ~Model() override { mManager.remove(mName); }
inline ~Model() override { mManager.remove(getName()); }
/*************************************************************************
* Public Methods
@@ -239,10 +237,6 @@ namespace Qtk {
/*************************************************************************
* Private Members
************************************************************************/
/* The position of this model in 3D space */
Transform3D mTransform;
/* Static QHash used to store and access models globally. */
static ModelManager mManager;
@@ -254,8 +248,6 @@ namespace Qtk {
std::string mDirectory {};
/* File names for shaders and 3D model on disk. */
const char *mVertexShader, *mFragmentShader, *mModelPath;
/* Name of the model object within the scene. */
const char * mName;
};
} // namespace Qtk

View File

@@ -6,6 +6,6 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <object.h>
#include "object.h"
using namespace Qtk;

View File

@@ -13,11 +13,13 @@
#include <QOpenGLTexture>
#include <QOpenGLVertexArrayObject>
#include <mesh.h>
#include <qtkapi.h>
#include <texture.h>
#include "mesh.h"
#include "qtkapi.h"
#include "texture.h"
namespace Qtk {
class Model;
/**
* Object base class for objects that can exist within a scene.
* An object could be a Cube, Skybox, 3D Model, or other standalone entities.
@@ -31,19 +33,26 @@ namespace Qtk {
************************************************************************/
friend MeshRenderer;
friend Model;
/**
* Enum flag to identify Object type without casting.
*/
enum Type { OBJECT, MESH, MODEL };
/*************************************************************************
* Constructors / Destructors
************************************************************************/
// Initialize an object with no shape data assigned
explicit Object(const char * name) :
mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mBound(false) {}
explicit Object(const char * name, Type type) :
mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mBound(false),
mType(type) {}
// Initialize an object with shape data assigned
Object(const char * name, const ShapeBase & shape) :
Object(const char * name, const ShapeBase & shape, Type type) :
mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mShape(shape),
mBound(false) {}
mBound(false), mType(type) {}
~Object() override = default;
@@ -77,6 +86,10 @@ namespace Qtk {
return mShape.mVertices;
}
[[nodiscard]] inline const char * getName() const { return mName; }
[[nodiscard]] inline const Type & getType() const { return mType; }
/*************************************************************************
* Setters
************************************************************************/
@@ -143,6 +156,7 @@ namespace Qtk {
Texture mTexture;
const char * mName;
bool mBound;
Type mType = OBJECT;
};
} // namespace Qtk

49
src/qtk/qtkapi.h Normal file
View File

@@ -0,0 +1,49 @@
/*##############################################################################
## 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 <QWidget>
#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
namespace Qtk {
/**
* Flag to set context for debug messages.
*/
enum DebugContext { Status, Debug, Warn, Error, Fatal };
/**
* Find top level parent for a widget.
*
* @param widget Widget to start the search from.
* @return Top level parent widget or Q_NULLPTR if no parent
*/
static QWidget * topLevelParent(QWidget * widget) {
QString name = widget->objectName();
while(widget->parentWidget() != Q_NULLPTR) {
widget = widget->parentWidget();
}
return widget;
}
static QIcon getIcon() {
return QIcon(":/icon.png");
}
} // namespace Qtk
#endif // QTK_QTKAPI_H

101
src/qtk/scene.cpp Normal file
View File

@@ -0,0 +1,101 @@
/*##############################################################################
## 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 "scene.h"
#include "camera3d.h"
using namespace Qtk;
Camera3D Scene::mCamera;
QMatrix4x4 Scene::mProjection;
/*******************************************************************************
* Constructors, Destructors
******************************************************************************/
Scene::Scene() : mSceneName("Default Scene") {
mCamera.getTransform().setTranslation(0.0f, 0.0f, 20.0f);
mCamera.getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
}
Scene::~Scene() {
for(auto & mesh : mMeshes) {
delete mesh;
}
for(auto & model : mModels) {
delete model;
}
delete mSkybox;
}
/*******************************************************************************
* Accessors
******************************************************************************/
std::vector<Object *> Scene::getObjects() const {
// All scene objects must inherit from Qtk::Object.
std::vector<Object *> objects(mMeshes.begin(), mMeshes.end());
for(auto model : mModels) {
objects.push_back(dynamic_cast<Object *>(model));
if(objects.back() == nullptr) {
return {};
}
}
return objects;
}
/*******************************************************************************
* Setters
******************************************************************************/
void Scene::setSkybox(Skybox * skybox) {
delete mSkybox;
mSkybox = skybox;
}
template <> MeshRenderer * Scene::addObject(MeshRenderer * object) {
mMeshes.push_back(object);
sceneUpdated(mSceneName);
return object;
}
template <> Model * Scene::addObject(Model * object) {
mModels.push_back(object);
sceneUpdated(mSceneName);
return object;
}
/*******************************************************************************
* Private Methods
******************************************************************************/
void Scene::privateDraw() {
if(!mInit) {
initializeOpenGLFunctions();
init();
mInit = true;
}
if(mSkybox != Q_NULLPTR) {
mSkybox->draw();
}
for(auto & model : mModels) {
model->draw();
}
for(const auto & mesh : mMeshes) {
mesh->draw();
}
}
Object * Scene::getObject(const QString & name) {
for(auto object : getObjects()) {
if(object->getName() == name) {
return object;
}
}
return Q_NULLPTR;
}

View File

@@ -9,12 +9,13 @@
#ifndef QTK_SCENE_H
#define QTK_SCENE_H
#include <camera3d.h>
#include <meshrenderer.h>
#include <model.h>
#include <skybox.h>
#include <QMatrix4x4>
#include <utility>
#include "camera3d.h"
#include "meshrenderer.h"
#include "model.h"
#include "skybox.h"
namespace Qtk {
/**
@@ -38,7 +39,9 @@ namespace Qtk {
* If the child scene adds any objects which are not managed (drawn) by this
* base class, the child scene class must also override the `draw()` method.
*/
class Scene : protected QOpenGLFunctions {
class Scene : public QObject, protected QOpenGLFunctions {
Q_OBJECT
public:
/*************************************************************************
* Contructors / Destructors
@@ -46,7 +49,7 @@ namespace Qtk {
Scene();
~Scene();
virtual ~Scene();
/*************************************************************************
* Public Methods
@@ -75,19 +78,78 @@ namespace Qtk {
* Accessors
************************************************************************/
/**
* @return Camera attached to this scene.
*/
static Camera3D & getCamera() { return mCamera; }
/**
* @return View matrix for the camera attached to this scene.
*/
static QMatrix4x4 getViewMatrix() { return mCamera.toMatrix(); }
/**
* @return Projection matrix for the current view into the scene.
*/
static QMatrix4x4 & getProjectionMatrix() { return mProjection; }
/**
* @return The active skybox for this scene.
*/
inline Skybox * getSkybox() { return mSkybox; }
/**
* @return The name for this scene. This is entirely user defined and not
* a Qt objectName.
*/
[[nodiscard]] inline QString getSceneName() const { return mSceneName; }
/**
* @return All MeshRenderers within the scene.
*/
[[nodiscard]] inline const std::vector<MeshRenderer *> & getMeshes()
const {
return mMeshes;
}
/**
* @return All Models within the scene.
*/
[[nodiscard]] inline const std::vector<Model *> & getModels() const {
return mModels;
}
/**
* @return All Qtk::Objects within the scene.
* If any object is invalid, we return an empty vector.
*/
[[nodiscard]] std::vector<Object *> getObjects() const;
[[nodiscard]] Object * getObject(const QString & name);
/*************************************************************************
* Setters
************************************************************************/
inline void setSkybox(Skybox * skybox) { mSkybox = skybox; }
/**
* @param skybox New skybox to use for this scene.
*/
void setSkybox(Skybox * skybox);
/**
* Adds objects to the scene.
* @param object The new object to add to the scene.
* @return The object added to the scene.
*/
template <typename T> T * addObject(T * object);
/**
* @param name The name to use for this scene.
*/
inline void setSceneName(QString name) { mSceneName = std::move(name); }
signals:
void sceneUpdated(QString sceneName);
private:
/*************************************************************************
@@ -108,11 +170,12 @@ namespace Qtk {
*/
void privateDraw();
protected:
private:
/*************************************************************************
* Protected Members
* Private Members
************************************************************************/
QString mSceneName;
/* The skybox for this scene. */
Skybox * mSkybox {};
/* MeshRenderers used simple geometry. */

View File

@@ -6,9 +6,9 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <scene.h>
#include <skybox.h>
#include <texture.h>
#include "skybox.h"
#include "scene.h"
#include "texture.h"
using namespace Qtk;

View File

@@ -15,10 +15,10 @@
#include <QOpenGLTexture>
#include <QOpenGLVertexArrayObject>
#include <camera3d.h>
#include <mesh.h>
#include <qtkapi.h>
#include <texture.h>
#include "camera3d.h"
#include "mesh.h"
#include "qtkapi.h"
#include "texture.h"
namespace Qtk {
/**

View File

@@ -6,11 +6,12 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <QDebug>
#include <QImageReader>
#include <utility>
#include <texture.h>
#include <QDebug>
#include <QImageReader>
#include "texture.h"
using namespace Qtk;

View File

@@ -9,11 +9,12 @@
#ifndef QTOPENGL_TEXTURE_H
#define QTOPENGL_TEXTURE_H
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <utility>
#include <qtkapi.h>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include "qtkapi.h"
namespace Qtk {
/**

View File

@@ -7,7 +7,7 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <transform3D.h>
#include "transform3D.h"
using namespace Qtk;

View File

@@ -15,12 +15,10 @@
#include <QVector3D>
#ifndef QT_NO_DEBUG_STREAM
#include <QDebug>
#endif
#include <qtkapi.h>
#include "qtkapi.h"
namespace Qtk {
/**

View File

@@ -1,2 +0,0 @@
#define QTK_RESOURCES "@QTK_RESOURCES@"

View File

@@ -1,53 +0,0 @@
/*##############################################################################
## 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 <camera3d.h>
#include <resourcemanager.h>
#include <scene.h>
#include <texture.h>
using namespace Qtk;
Camera3D Scene::mCamera;
QMatrix4x4 Scene::mProjection;
/*******************************************************************************
* Constructors, Destructors
******************************************************************************/
Scene::Scene() {
mCamera.getTransform().setTranslation(0.0f, 0.0f, 20.0f);
mCamera.getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
}
Scene::~Scene() {
for(auto & mesh : mMeshes) {
delete mesh;
}
for(auto & model : mModels) {
delete model;
}
delete mSkybox;
}
void Scene::privateDraw() {
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();
}
}