Add SceneInterface

+ Renames binaries qtk_main->qtk_app and example->example_app
This commit is contained in:
2023-03-11 10:58:49 -05:00
parent 0dcb6d337b
commit 0659df94bd
24 changed files with 139 additions and 100 deletions

View File

@@ -32,7 +32,7 @@ if (QTK_INSTALL_GUI OR QTK_INSTALL_PLUGINS)
if(QTK_INSTALL_GUI)
install(
TARGETS qtk_main qtk_library
TARGETS qtk_app qtk_library
COMPONENT qtk
BUNDLE DESTINATION .
LIBRARY DESTINATION lib
@@ -41,7 +41,7 @@ if (QTK_INSTALL_GUI OR QTK_INSTALL_PLUGINS)
)
qt_generate_deploy_app_script(
TARGET qtk_main
TARGET qtk_app
OUTPUT_SCRIPT QTK_DEPLOY_SCRIPT
NO_UNSUPPORTED_PLATFORM_ERROR
)
@@ -58,7 +58,7 @@ if (QTK_INSTALL_GUI OR QTK_INSTALL_PLUGINS)
)
file(TO_NATIVE_PATH "${QT6_INSTALL_PREFIX}/bin" QT6_INSTALL_PREFIX)
set(VSUSER_FILE "${CMAKE_CURRENT_BINARY_DIR}/qtk_main.vcxproj.user")
set(VSUSER_FILE "${CMAKE_CURRENT_BINARY_DIR}/qtk_app.vcxproj.user")
file(WRITE ${VSUSER_FILE} "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
file(APPEND ${VSUSER_FILE} "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n")
file(APPEND ${VSUSER_FILE} " <PropertyGroup>\n")
@@ -137,11 +137,11 @@ set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
# https://nsis.sourceforge.io/Reference/CreateShortCut
set(
CPACK_NSIS_CREATE_ICONS_EXTRA
"CreateShortCut '$SMPROGRAMS\\$STARTMENU_FOLDER\\Qtk.lnk' '$INSTDIR\\bin\\qtk_main.exe'"
"CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Qtk.lnk' '$INSTDIR\\\\bin\\\\qtk_app.exe'"
)
set(
CPACK_NSIS_DELETE_ICONS_EXTRA
"Delete '$SMPROGRAMS\\$START_MENU\\Qtk.lnk'"
"Delete '$SMPROGRAMS\\\\$START_MENU\\\\Qtk.lnk'"
)
# TODO: Icons for NSIS installer.
#set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/resources/icon.png")
@@ -154,9 +154,8 @@ set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
#set(CPACK_PACKAGING_INSTALL_PREFIX /usr/local/)
# OSX
# TODO: Fix OSX appbundle error.
set(CPACK_BUNDLE_NAME ${PROJECT_NAME})
set(CPACK_BUNDLE_PLIST $<TARGET_BUNDLE_CONTENT_DIR:qtk_main>/Info.plist)
set(CPACK_BUNDLE_PLIST $<TARGET_BUNDLE_CONTENT_DIR:qtk_app>/Info.plist)
set(CPACK_BUNDLE_ICON ${QTK_OSX_ICONS})
# Platform defaults for source bundles.

View File

@@ -50,7 +50,7 @@ target_link_libraries(qtk_collection PUBLIC qtk_plugin_library)
set(
QTK_APP_SOURCES
examplescene.cpp examplescene.h
qtkscene.cpp qtkscene.h
main.cpp
)
@@ -61,11 +61,11 @@ configure_file(
@ONLY
)
qt_add_executable(qtk_main ${QTK_APP_SOURCES})
target_link_libraries(qtk_main PRIVATE qtk_plugin_library)
qt_add_executable(qtk_app ${QTK_APP_SOURCES})
target_link_libraries(qtk_app PRIVATE qtk_plugin_library)
set_target_properties(
qtk_main PROPERTIES
qtk_app PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_BUNDLE_NAME Qtk

View File

@@ -9,6 +9,7 @@
#include <QApplication>
#include "qtkmainwindow.h"
#include "qtkscene.h"
int main(int argc, char * argv[]) {
Q_INIT_RESOURCE(resources);
@@ -16,7 +17,12 @@ int main(int argc, char * argv[]) {
QApplication a(argc, argv);
auto window = MainWindow::getMainWindow();
window->show();
// Qtk currently uses the decorator pattern to save / load scenes.
// This is a temporary solution and will be improved in the future.
auto emptyScene = new Qtk::SceneEmpty;
window->getQtkWidget()->setScene(new QtkScene(emptyScene));
window->show();
return QApplication::exec();
}

View File

@@ -7,7 +7,7 @@
##############################################################################*/
#include "qtkmainwindow.h"
#include "examplescene.h"
#include "qtkscene.h"
#include "ui_qtkmainwindow.h"
MainWindow * MainWindow::mainWindow_ = Q_NULLPTR;
@@ -27,7 +27,7 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) {
// Initialize static container for all active QtkWidgets
auto qtkWidgets = findChildren<Qtk::QtkWidget *>();
for(auto & qtkWidget : qtkWidgets) {
qtkWidget->setScene(new ExampleScene);
qtkWidget->setScene(new Qtk::SceneEmpty);
views_.emplace(qtkWidget->getScene()->getSceneName(), qtkWidget);
ui_->menuView->addAction(qtkWidget->getActionToggleConsole());
connect(
@@ -60,6 +60,13 @@ MainWindow * MainWindow::getMainWindow() {
return mainWindow_;
}
Qtk::QtkWidget * MainWindow::getQtkWidget(int64_t index) {
if(views_.size() <= index) {
return Q_NULLPTR;
}
return views_.begin(index)->second;
}
Qtk::QtkWidget * MainWindow::getQtkWidget(const QString & name) {
if(!views_.count(name)) {
return Q_NULLPTR;

View File

@@ -53,6 +53,8 @@ class MainWindow : public QMainWindow {
*/
static MainWindow * getMainWindow();
Qtk::QtkWidget * getQtkWidget(int64_t index = 0);
/**
* Accessor for retrieving a QtkWidget by it's objectName.
* This function will not construct a new QtkWidget if none is found.

View File

@@ -6,7 +6,7 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include "examplescene.h"
#include "qtkscene.h"
#include "resources.h"
using namespace Qtk;
@@ -15,13 +15,14 @@ using namespace Qtk;
* Constructors, Destructors
******************************************************************************/
ExampleScene::ExampleScene() {
setSceneName("Example Scene");
QtkScene::QtkScene(Qtk::Scene * scene) :
Qtk::SceneInterface(scene) {
setSceneName("Qtk Scene");
getCamera().getTransform().setTranslation(0.0f, 0.0f, 20.0f);
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
}
ExampleScene::~ExampleScene() {
QtkScene::~QtkScene() {
delete mTestPhong;
delete mTestSpecular;
delete mTestDiffuse;
@@ -32,7 +33,7 @@ ExampleScene::~ExampleScene() {
* Public Member Functions
******************************************************************************/
void ExampleScene::init() {
void QtkScene::init() {
// Add a skybox to the scene using default cube map images and settings.
setSkybox(new Qtk::Skybox("Skybox"));
@@ -97,7 +98,7 @@ void ExampleScene::init() {
model->getTransform().scale(0.15f);
model =
addObject(new Qtk::Model("scythe", ":/models/models/scythe/scythe.obj"));
addObject(new Qtk::Model("My scythe", ":/models/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);
@@ -387,19 +388,11 @@ void ExampleScene::init() {
mesh->reallocateTexCoords(mesh->getTexCoords());
}
void ExampleScene::draw() {
void QtkScene::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",
@@ -409,14 +402,14 @@ void ExampleScene::draw() {
MeshRenderer::getInstance("phongLight")->getTransform().getTranslation());
mTestPhong->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
QtkScene::getCamera().getTransform().getTranslation());
mTestPhong->releaseShaders();
mTestPhong->draw();
mTestAmbient->bindShaders();
mTestAmbient->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
QtkScene::getCamera().getTransform().getTranslation());
mTestAmbient->releaseShaders();
mTestAmbient->draw();
@@ -430,7 +423,7 @@ void ExampleScene::draw() {
.getTranslation());
mTestDiffuse->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
QtkScene::getCamera().getTransform().getTranslation());
mTestDiffuse->releaseShaders();
mTestDiffuse->draw();
@@ -444,12 +437,12 @@ void ExampleScene::draw() {
.getTranslation());
mTestSpecular->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
QtkScene::getCamera().getTransform().getTranslation());
mTestSpecular->releaseShaders();
mTestSpecular->draw();
}
void ExampleScene::update() {
void QtkScene::update() {
auto mySpartan = Model::getInstance("My spartan");
mySpartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
@@ -463,12 +456,12 @@ void ExampleScene::update() {
alien->setUniform("uLight.position", position);
alien->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
QtkScene::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->setUniform("uMVP.view", QtkScene::getCamera().toMatrix());
alien->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
alien->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
position = MeshRenderer::getInstance("spartanTestLight")
@@ -478,12 +471,12 @@ void ExampleScene::update() {
spartan->setUniform("uLight.position", position);
spartan->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
QtkScene::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->setUniform("uMVP.view", QtkScene::getCamera().toMatrix());
spartan->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
spartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
auto phong = MeshRenderer::getInstance("testPhong");
@@ -494,12 +487,12 @@ void ExampleScene::update() {
phong->setUniform("uLight.position", position);
phong->setUniform(
"uCameraPosition",
ExampleScene::getCamera().getTransform().getTranslation());
QtkScene::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->setUniform("uMVP.view", QtkScene::getCamera().toMatrix());
phong->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
phong->releaseShaders();
// Rotate lighting example cubes

View File

@@ -29,15 +29,15 @@
*
* To create your own Scene from scratch see Qtk::Scene.
*/
class ExampleScene : public Qtk::Scene {
class QtkScene : public Qtk::SceneInterface {
public:
/***************************************************************************
* Contructors / Destructors
**************************************************************************/
ExampleScene();
QtkScene(Qtk::Scene * scene);
~ExampleScene();
~QtkScene();
/***************************************************************************
* Inherited Public Overrides

View File

@@ -100,6 +100,13 @@ namespace Qtk {
*/
inline Qtk::Scene * getScene() { return mScene; }
/**
* @return Pointer to the QOpenGLDebugLogger attached to this widget.
*/
inline QOpenGLDebugLogger * getOpenGLDebugLogger() {
return mDebugLogger;
}
/*************************************************************************
* Setters
************************************************************************/

View File

@@ -37,7 +37,7 @@ void Qtk::TreeView::updateView(const Qtk::Scene * scene) {
mSceneName = scene->getSceneName();
auto objects = scene->getObjects();
for(const auto & object : objects) {
auto item = new QTreeWidgetItem(QStringList(QString(object->getName())));
auto item = new QTreeWidgetItem(QStringList(QString(object->getName().c_str())));
ui->treeWidget->insertTopLevelItem(0, item);
}
}
@@ -48,6 +48,10 @@ void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column) {
MainWindow::getMainWindow()->getQtkWidget(mSceneName)->getScene();
auto & transform = scene->getCamera().getTransform();
auto object = scene->getObject(name);
if (object == Q_NULLPTR) {
qDebug() << "Attempt to get non-existing object with name '" << name
<< "'\n";
}
Transform3D * objectTransform;
if(object->getType() == Object::QTK_MESH) {
objectTransform = &dynamic_cast<MeshRenderer *>(object)->getTransform();

View File

@@ -38,7 +38,7 @@ MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape) :
}
MeshRenderer::~MeshRenderer() {
sInstances.remove(mName);
sInstances.remove(mName.c_str());
}
/*******************************************************************************

View File

@@ -96,7 +96,7 @@ void Model::loadModel(const std::string & path) {
sortModelMeshes();
// Object finished loading, insert it into ModelManager
mManager.insert(getName(), this);
mManager.insert(getName().c_str(), this);
}
void Model::processNode(aiNode * node, const aiScene * scene) {
@@ -200,7 +200,7 @@ ModelMesh Model::processMesh(aiMesh * mesh, const aiScene * scene) {
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
}
return {vertices, indices, textures, mVertexShader, mFragmentShader};
return {vertices, indices, textures, mVertexShader.c_str(), mFragmentShader.c_str()};
}
ModelMesh::Textures Model::loadMaterialTextures(

View File

@@ -58,7 +58,7 @@ namespace Qtk {
loadModel(mModelPath);
}
inline ~Model() override { mManager.remove(getName()); }
inline ~Model() override { mManager.remove(getName().c_str()); }
/*************************************************************************
* Public Methods
@@ -197,7 +197,7 @@ namespace Qtk {
/** The directory this model and it's textures are stored. */
std::string mDirectory {};
/** File names for shaders and 3D model on disk. */
const char *mVertexShader, *mFragmentShader, *mModelPath;
std::string mVertexShader, mFragmentShader, mModelPath;
};
} // namespace Qtk

View File

@@ -73,7 +73,7 @@ void ModelMesh::initMesh(const char * vert, const char * frag) {
initializeOpenGLFunctions();
// Create VAO, VBO, EBO
mVAO->create();
bool status = mVAO->create();
mVBO->create();
mEBO->create();

View File

@@ -92,7 +92,7 @@ namespace Qtk {
return mShape.mVertices;
}
[[nodiscard]] inline const char * getName() const { return mName; }
[[nodiscard]] inline std::string getName() const { return mName; }
[[nodiscard]] inline const Type & getType() const { return mType; }
@@ -160,7 +160,7 @@ namespace Qtk {
Transform3D mTransform;
Shape mShape;
Texture mTexture;
const char * mName;
std::string mName;
bool mBound;
Type mType = QTK_OBJECT;
};

View File

@@ -37,6 +37,23 @@ Scene::~Scene() {
* Public Methods
******************************************************************************/
void Scene::draw() {
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();
}
}
std::vector<Object *> Scene::getObjects() const {
// All scene objects must inherit from Qtk::Object.
std::vector<Object *> objects(mMeshes.begin(), mMeshes.end());
@@ -51,7 +68,7 @@ std::vector<Object *> Scene::getObjects() const {
Object * Scene::getObject(const QString & name) {
for(auto object : getObjects()) {
if(object->getName() == name) {
if(object->getName() == name.toStdString()) {
return object;
}
}
@@ -74,24 +91,3 @@ template <> Model * Scene::addObject(Model * 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();
}
}

View File

@@ -10,6 +10,7 @@
#define QTK_SCENE_H
#include <QMatrix4x4>
#include <utility>
#include "camera3d.h"
@@ -65,7 +66,7 @@ namespace Qtk {
*
* This function is only called when the widget is redrawn.
*/
virtual void draw() { privateDraw(); };
virtual void draw();
/**
* Function called to update the QOpenGLWidget. Does not trigger a redraw.
@@ -165,6 +166,7 @@ namespace Qtk {
*/
inline void setSceneName(QString name) { mSceneName = std::move(name); }
std::vector<Model *> mModels {};
signals:
/**
* Signal thrown when the scene is modified by adding or removing objects.
@@ -175,16 +177,6 @@ namespace Qtk {
void sceneUpdated(QString sceneName);
private:
/*************************************************************************
* Private Methods
************************************************************************/
/**
* Handles drawing members encapsulated by this base class.
* Child classes do not need to draw these objects manually.
*/
void privateDraw();
/*************************************************************************
* Private Members
************************************************************************/
@@ -199,8 +191,33 @@ namespace Qtk {
/* MeshRenderers used simple geometry. */
std::vector<MeshRenderer *> mMeshes {};
/* Models used for storing 3D models in the scene. */
std::vector<Model *> mModels {};
};
class SceneEmpty : public Scene {
public:
void init() override {
setSceneName("Empty Scene");
}
void draw() override { Scene::draw(); }
void update() override { Scene::update(); }
};
class SceneInterface : public Scene {
public:
explicit SceneInterface(Scene * scene) : mScene(scene) {}
void init() override { mScene->init(); }
void draw() override { mScene->draw(); }
void update() override { mScene->update(); }
protected:
Scene * mScene;
};
} // namespace Qtk
#endif // QTK_SCENE_H