Clean up example code.

+ Fix spartan path.
+ Fix triangle draw mode.
This commit is contained in:
Shaun Reed 2025-03-08 10:29:35 -05:00
parent 68bfff7bcd
commit 32641acd8d
5 changed files with 51 additions and 59 deletions

View File

@ -11,7 +11,8 @@
using namespace Qtk; using namespace Qtk;
ExampleScene::ExampleScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) { ExampleScene::ExampleScene()
{
setSceneName("Example Scene"); setSceneName("Example Scene");
getCamera().getTransform().setTranslation(-8.0f, 0.0f, 10.0f); getCamera().getTransform().setTranslation(-8.0f, 0.0f, 10.0f);
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f); getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
@ -19,18 +20,17 @@ ExampleScene::ExampleScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) {
ExampleScene::~ExampleScene() = default; ExampleScene::~ExampleScene() = default;
void ExampleScene::init() { void ExampleScene::init()
auto skybox = new Qtk::Skybox("Skybox"); {
setSkybox(skybox); setSkybox(new Qtk::Skybox("Skybox"));
std::string spartanPath = QTK_EXAMPLE_SOURCE_DIR; std::string spartanPath = QTK_EXAMPLE_SOURCE_DIR;
spartanPath += "/resources/models/spartan/spartan.obj"; spartanPath += "/../resources/models/spartan/spartan.obj";
auto spartan = new Model("spartan", spartanPath.c_str()); auto spartan = addObject(new Model("spartan", spartanPath.c_str()));
addObject(spartan);
spartan->getTransform().setTranslation(-4.0f, 0.0f, 0.0f); spartan->getTransform().setTranslation(-4.0f, 0.0f, 0.0f);
auto mesh = addObject( auto mesh = addObject(
new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ARRAYS))); new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ELEMENTS)));
mesh->getTransform().setTranslation(-5.0f, 0.0f, -2.0f); mesh->getTransform().setTranslation(-5.0f, 0.0f, -2.0f);
// QTK_DRAW_ARRAYS is the default for generic shapes in qtk/shape.h // QTK_DRAW_ARRAYS is the default for generic shapes in qtk/shape.h
@ -56,11 +56,17 @@ void ExampleScene::init() {
mesh->setColor(GREEN); mesh->setColor(GREEN);
} }
void ExampleScene::draw() { void ExampleScene::draw()
{
// No custom draw logic for this example.
Scene::draw(); Scene::draw();
} }
void ExampleScene::update() { void ExampleScene::update()
{
auto top_triangle = MeshRenderer::getInstance("topTriangle");
auto bottom_triangle = MeshRenderer::getInstance("bottomTriangle");
// Pitch forward and roll sideways // Pitch forward and roll sideways
MeshRenderer::getInstance("leftTriangle") MeshRenderer::getInstance("leftTriangle")
->getTransform() ->getTransform()
@ -69,29 +75,21 @@ void ExampleScene::update() {
->getTransform() ->getTransform()
.rotate(0.75f, 0.0f, 0.0f, 1.0f); .rotate(0.75f, 0.0f, 0.0f, 1.0f);
// Make the top and bottom triangles slide left-to-right.
static float translateX = 0.025f; static float translateX = 0.025f;
float limit = -9.0f; // Origin position.x - 2.0f float limit = -9.0f; // Origin position.x - 2.0f
float posX = MeshRenderer::getInstance("topTriangle") float posX = top_triangle->getTransform().getTranslation().x();
->getTransform() if (posX < limit || posX > limit + 4.0f) {
.getTranslation()
.x();
if(posX < limit || posX > limit + 4.0f) {
translateX = -translateX; translateX = -translateX;
} }
MeshRenderer::getInstance("topTriangle")
->getTransform()
.translate(translateX, 0.0f, 0.0f);
MeshRenderer::getInstance("bottomTriangle")
->getTransform()
.translate(-translateX, 0.0f, 0.0f);
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);
MeshRenderer::getInstance("centerCube") top_triangle->getTransform().translate(translateX, 0.0f, 0.0f);
->getTransform() bottom_triangle->getTransform().translate(-translateX, 0.0f, 0.0f);
// Apply some rotation to the triangles as they move left-to-right.
top_triangle->getTransform().rotate(0.75f, 0.2f, 0.0f, 0.4f);
bottom_triangle->getTransform().rotate(0.75f, 0.0f, 0.2f, 0.4f);
MeshRenderer::getInstance("centerCube")->getTransform()
.rotate(0.75f, 0.2f, 0.4f, 0.6f); .rotate(0.75f, 0.2f, 0.4f, 0.6f);
} }

View File

@ -11,16 +11,29 @@
#include <qtk/scene.h> #include <qtk/scene.h>
class ExampleScene : public Qtk::SceneInterface { class ExampleScene : public Qtk::Scene {
public: public:
explicit ExampleScene(Qtk::Scene * scene); explicit ExampleScene();
~ExampleScene(); ~ExampleScene();
/**
* Override the initialization logic for the scene.
* This method should up the scene's objects, skybox, etc.
*/
void init() override; void init() override;
/**
* Optionally override the draw method for the scene.
*
* This is just here for example, it should be omitted entirely if we don't
* want to provide a custom implementation for the ExampleScene.
*/
void draw() override; void draw() override;
/**
* Update objects in the scene for translation or rotation.
*/
void update() override; void update() override;
}; };

View File

@ -11,7 +11,7 @@
#include "examplewidget.h" #include "examplewidget.h"
ExampleWidget::ExampleWidget(QWidget * parent) : ExampleWidget::ExampleWidget(QWidget * parent) :
QOpenGLWidget(parent), mScene(new ExampleScene(new Qtk::SceneEmpty)) { QOpenGLWidget(parent), mScene(new ExampleScene) {
// NOTE: The decorator pattern is used to save / load scenes in Qtk currently. // NOTE: The decorator pattern is used to save / load scenes in Qtk currently.
// The initializer above sets mScene to the concrete decorator ExampleScene. // The initializer above sets mScene to the concrete decorator ExampleScene.
// Qtk::SceneEmpty provides an empty scene as the concrete component. // Qtk::SceneEmpty provides an empty scene as the concrete component.

View File

@ -58,6 +58,8 @@ void Scene::draw() {
mInit = true; mInit = true;
} }
// Check if there were new models added that still need to be loaded.
// This is for objects added at runtime via click-and-drag events, etc.
while(!mModelLoadQueue.empty()) { while(!mModelLoadQueue.empty()) {
auto modelSpec = mModelLoadQueue.front(); auto modelSpec = mModelLoadQueue.front();
// Load the model and add it to the scene. // Load the model and add it to the scene.

View File

@ -53,7 +53,7 @@ namespace Qtk {
Scene(); Scene();
virtual ~Scene(); ~Scene() override;
/************************************************************************* /*************************************************************************
* Public Methods * Public Methods
@ -73,10 +73,13 @@ namespace Qtk {
/** /**
* Function called to update the QOpenGLWidget. Does not trigger a redraw. * Function called to update the QOpenGLWidget. Does not trigger a redraw.
* * This method can translate or rotate objects to simulate movement.
* Calling this several times will still result in only one repaint. * Calling this several times will still result in only one repaint.
*
* It's very possible a client will not want to move objects in the scene
* using this method. This is intentially not pure virtual.
*/ */
virtual void update() {} virtual void update() { }
void loadModel(const QUrl & url) { void loadModel(const QUrl & url) {
auto fileName = url.fileName().replace(".obj", "").toStdString(); auto fileName = url.fileName().replace(".obj", "").toStdString();
@ -239,30 +242,6 @@ namespace Qtk {
/* Track count of objects with same initial name. */ /* Track count of objects with same initial name. */
std::unordered_map<std::string, uint64_t> mObjectCount; std::unordered_map<std::string, uint64_t> mObjectCount;
}; };
class SceneEmpty : public Scene {
public:
void init() override { setSceneName("Empty Scene"); }
void draw() override { Scene::draw(); }
void update() override { Scene::update(); }
};
class SceneInterface : public Scene {
public:
explicit SceneInterface(Scene * scene) : mScene(scene) {}
void init() override { mScene->init(); }
void draw() override { mScene->draw(); }
void update() override { mScene->update(); }
protected:
Scene * mScene;
};
} // namespace Qtk } // namespace Qtk
#endif // QTK_SCENE_H #endif // QTK_SCENE_H