diff --git a/README.md b/README.md index 751424a..6d636de 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ We can install this library on a system path or a custom path and then set `CMAK Below is an example of installing on a system path. ```bash -cmake -S qtk/ -B qtk/build/ -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64 -DQTK_INSTALL_GUI=OFF -DQTK_INSTALL_PLUGINS=OFF +cmake -S qtk/ -B qtk/build/ -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64 -DQTK_INSTALL_GUI=OFF -DQTK_INSTALL_PLUGINS=OFF -DQTK_DEBUG=OFF cmake --build qtk/build/ -j $(nproc --ignore=2) sudo cmake --install . --prefix=/usr/local -- Install configuration: "Release" diff --git a/cmake/templates/Config.cmake.in b/cmake/templates/Config.cmake.in index 4440982..8026caa 100644 --- a/cmake/templates/Config.cmake.in +++ b/cmake/templates/Config.cmake.in @@ -2,7 +2,7 @@ include("${CMAKE_CURRENT_LIST_DIR}/QtkTargets.cmake") -set_and_check(QTK_EXECUTABLE "${PACKAGE_PREFIX_DIR}/bin/qtk_main") +set_and_check(QTK_EXECUTABLE "${PACKAGE_PREFIX_DIR}/bin/qtk_app") set_and_check(QTK_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include") set_and_check(QTK_LIBRARIES "${PACKAGE_PREFIX_DIR}/lib") diff --git a/example-app/CMakeLists.txt b/example-app/CMakeLists.txt index 05d4284..673b8a3 100644 --- a/example-app/CMakeLists.txt +++ b/example-app/CMakeLists.txt @@ -65,6 +65,6 @@ set( examplewidget.cpp examplewidget.h ) -add_executable(example ${EXAMPLE_SOURCES}) -target_link_libraries(example PUBLIC Qt6::Widgets Qt6::OpenGLWidgets Qt6::Core) -target_link_libraries(example PUBLIC Qtk::qtk_library) +add_executable(example_app ${EXAMPLE_SOURCES}) +target_link_libraries(example_app PUBLIC Qt6::Widgets Qt6::OpenGLWidgets Qt6::Core) +target_link_libraries(example_app PUBLIC Qtk::qtk_library) diff --git a/example-app/README.md b/example-app/README.md index ee1c551..afa1358 100644 --- a/example-app/README.md +++ b/example-app/README.md @@ -1,7 +1,10 @@ This is an example application that is using the Qtk API to create custom Qt OpenGL widgets. This is very similar to `QtkWidget` in the Qtk desktop -application, but could be modified for different uses if needed. +application source code, but could be modified for different uses if needed. + +There are no camera controls supported in this example. The camera is fixed. +If these controls are desired, they can be implemented by the client. You can import your own models within `examplescene.cpp`, inside the `ExampleScene::init()` function. Rotations and translations diff --git a/example-app/examplescene.cpp b/example-app/examplescene.cpp index 400a96a..8e14f36 100644 --- a/example-app/examplescene.cpp +++ b/example-app/examplescene.cpp @@ -10,7 +10,7 @@ using namespace Qtk; -ExampleScene::ExampleScene() { +ExampleScene::ExampleScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) { setSceneName("Example Scene"); getCamera().getTransform().setTranslation(-8.0f, 0.0f, 10.0f); getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f); diff --git a/example-app/examplescene.h b/example-app/examplescene.h index ad9dab1..8d2b1e9 100644 --- a/example-app/examplescene.h +++ b/example-app/examplescene.h @@ -11,9 +11,9 @@ #include -class ExampleScene : public Qtk::Scene { +class ExampleScene : public Qtk::SceneInterface { public: - ExampleScene(); + ExampleScene(Qtk::Scene * scene); ~ExampleScene(); diff --git a/example-app/examplewidget.cpp b/example-app/examplewidget.cpp index ddbd6f2..fc5a97b 100644 --- a/example-app/examplewidget.cpp +++ b/example-app/examplewidget.cpp @@ -11,7 +11,12 @@ #include "examplewidget.h" ExampleWidget::ExampleWidget(QWidget * parent) : - QOpenGLWidget(parent), mScene(new ExampleScene) { + QOpenGLWidget(parent), mScene(new ExampleScene(new Qtk::SceneEmpty)) { + // NOTE: The decorator pattern is used to save / load scenes in Qtk currently. + // The initializer above sets mScene to the concrete decorator ExampleScene. + // Qtk::SceneEmpty provides an empty scene as the concrete component. + // ExampleScene is defined in client source, deriving Qtk::SceneInterface. + QSurfaceFormat format; format.setRenderableType(QSurfaceFormat::OpenGL); format.setProfile(QSurfaceFormat::CoreProfile); diff --git a/example-app/examplewidget.h b/example-app/examplewidget.h index 05b061d..eeb73d4 100644 --- a/example-app/examplewidget.h +++ b/example-app/examplewidget.h @@ -32,7 +32,7 @@ class ExampleWidget : public QOpenGLWidget, protected QOpenGLFunctions { void update(); private: - ExampleScene * mScene; + Qtk::Scene * mScene; }; #endif // QTKCLIENT_EXAMPLEWIDGET_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 126dc1a..5af1cac 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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} "\n") file(APPEND ${VSUSER_FILE} "\n") file(APPEND ${VSUSER_FILE} " \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 $/Info.plist) +set(CPACK_BUNDLE_PLIST $/Info.plist) set(CPACK_BUNDLE_ICON ${QTK_OSX_ICONS}) # Platform defaults for source bundles. diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 7029f47..e42867d 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -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 diff --git a/src/app/main.cpp b/src/app/main.cpp index b4c78c5..cb1801f 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -9,6 +9,7 @@ #include #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(); } diff --git a/src/app/qtkmainwindow.cpp b/src/app/qtkmainwindow.cpp index f36a328..8f5df71 100644 --- a/src/app/qtkmainwindow.cpp +++ b/src/app/qtkmainwindow.cpp @@ -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(); 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; diff --git a/src/app/qtkmainwindow.h b/src/app/qtkmainwindow.h index 5f797a8..844adf0 100644 --- a/src/app/qtkmainwindow.h +++ b/src/app/qtkmainwindow.h @@ -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. diff --git a/src/app/examplescene.cpp b/src/app/qtkscene.cpp similarity index 94% rename from src/app/examplescene.cpp rename to src/app/qtkscene.cpp index 9657e43..3985b65 100644 --- a/src/app/examplescene.cpp +++ b/src/app/qtkscene.cpp @@ -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 diff --git a/src/app/examplescene.h b/src/app/qtkscene.h similarity index 96% rename from src/app/examplescene.h rename to src/app/qtkscene.h index 6f0c187..eca09e0 100644 --- a/src/app/examplescene.h +++ b/src/app/qtkscene.h @@ -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 diff --git a/src/app/qtkwidget.h b/src/app/qtkwidget.h index 61b980c..81f9114 100644 --- a/src/app/qtkwidget.h +++ b/src/app/qtkwidget.h @@ -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 ************************************************************************/ diff --git a/src/app/treeview.cpp b/src/app/treeview.cpp index 1fc95c5..86f5609 100644 --- a/src/app/treeview.cpp +++ b/src/app/treeview.cpp @@ -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(object)->getTransform(); diff --git a/src/qtk/meshrenderer.cpp b/src/qtk/meshrenderer.cpp index b64e6d7..c654491 100644 --- a/src/qtk/meshrenderer.cpp +++ b/src/qtk/meshrenderer.cpp @@ -38,7 +38,7 @@ MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape) : } MeshRenderer::~MeshRenderer() { - sInstances.remove(mName); + sInstances.remove(mName.c_str()); } /******************************************************************************* diff --git a/src/qtk/model.cpp b/src/qtk/model.cpp index 071476c..14a77b8 100644 --- a/src/qtk/model.cpp +++ b/src/qtk/model.cpp @@ -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( diff --git a/src/qtk/model.h b/src/qtk/model.h index f7654f4..66f18c2 100644 --- a/src/qtk/model.h +++ b/src/qtk/model.h @@ -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 diff --git a/src/qtk/modelmesh.cpp b/src/qtk/modelmesh.cpp index a5dd800..79b2e3e 100644 --- a/src/qtk/modelmesh.cpp +++ b/src/qtk/modelmesh.cpp @@ -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(); diff --git a/src/qtk/object.h b/src/qtk/object.h index 0ae50f2..6092608 100644 --- a/src/qtk/object.h +++ b/src/qtk/object.h @@ -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; }; diff --git a/src/qtk/scene.cpp b/src/qtk/scene.cpp index 08cc2b3..8585c21 100644 --- a/src/qtk/scene.cpp +++ b/src/qtk/scene.cpp @@ -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 Scene::getObjects() const { // All scene objects must inherit from Qtk::Object. std::vector objects(mMeshes.begin(), mMeshes.end()); @@ -51,7 +68,7 @@ std::vector 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(); - } -} diff --git a/src/qtk/scene.h b/src/qtk/scene.h index 4971251..f55ac52 100644 --- a/src/qtk/scene.h +++ b/src/qtk/scene.h @@ -10,6 +10,7 @@ #define QTK_SCENE_H #include + #include #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 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 mMeshes {}; /* Models used for storing 3D models in the scene. */ - std::vector 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