diff --git a/.github/workflows/all-builds.yml b/.github/workflows/all-builds.yml
index 65e24a4..410caa4 100644
--- a/.github/workflows/all-builds.yml
+++ b/.github/workflows/all-builds.yml
@@ -220,7 +220,7 @@ jobs:
if: matrix.os == 'windows-latest'
uses: actions/upload-artifact@v4
with:
- name: qtk-${{ matrix.os }}
+ name: libqtk-${{ matrix.os }}
path: |
build/packages/*.exe
@@ -235,7 +235,7 @@ jobs:
if: matrix.os == 'macos-latest'
uses: actions/upload-artifact@v4
with:
- name: qtk-${{ matrix.os }}
+ name: libqtk-${{ matrix.os }}
path: |
build/packages/*.tar.gz
diff --git a/README.md b/README.md
index b198392..c7c092b 100644
--- a/README.md
+++ b/README.md
@@ -9,38 +9,53 @@ that allow rendering geometry in 2D and 3D using custom GLSL shader programs.
The Qtk desktop application provides a model loader using [Assimp](https://assimp.org/) within a Qt widget application.
You can fly around the scene using WASD while holding down the right mouse button.
+Object names can be double-clicked in the tree view panel for quick camera navigation.
+Properties of the object, like shader code and translation / scale, can be viewed and modified in the side panel.
+
+
+
+All side panels and toolbars are dockable widgets that can be popped out
+and reorganized as needed. Panels can also be stacked to create a docked widget with
+tabs. The central widget that provides the camera view into the scene cannot be
+detached from the main window in this way.
+
+
+
+The small triangles floating near 3D models represent the light source being used for the shader.
+These appear on models using phong, specular, and diffuse lighting techniques.
+
+The default scene contains basic examples like texture mapping to make a crate from basic cube geometry
+
+
+
+Examples of Ambient, Diffuse, and Specular GLSL shaders.
+
+| Ambient | Diffuse | Specular |
+|-------------------------------------------------------|-------------------------------------------------------|--------------------------------------------------------|
+|
|
|
|
+
+And more advanced techniques like Phong lighting (ambient + diffuse + specular) and normal mapping.
+
+
+
+| Normal Mapping Disabled | Normal Mapping Enabled |
+|------------------------------------------------------|--------------------------------------------------------|
+|
|
|
+
+See the `View` toolbar menu to enable debug console widgets for open scenes or reopen previously closed panels.
+
Key features that are planned:
- [x] Runtime loading of `.obj` or similar 3D models.
- [x] Drag-and-drop interaction for adding objects to the scene.
+- [x] Shader / object properties panel to modify related settings.
- [ ] Runtime reloading of modified GLSL shaders attached to objects within scenes.
- [ ] Multiple views of a scene at one time.
- [ ] Camera control modes such as panning, orbiting, or following objects.
- [ ] Save / load for scene data. The current inheritance model is temporary.
- [ ] Basic text editor for quickly modifying shaders attached to objects.
-- [ ] Shader / object properties panel to modify related settings.
- [ ] Reduce size of application resources and git references.
-
-
-Spartan with no normals -
-
-
-
-Spartan with normals -
-
-
-
-Object names can be double-clicked in the tree view panel for quick camera
-navigation. All side panels and toolbars are dockable widgets that can be popped out
-and reorganized as needed. Panels can also be stacked to create a docked widget with
-tabs. The central widget that provides the camera view into the scene cannot be
-detached from the main window in this way. See the `View` menu to enable debug
-console widgets for open scenes or reopen previously closed panels.
-
-The small triangles floating near 3D models represent the light source being used for the shader.
-These appear on models using phong, specular, and diffuse lighting techniques.
-
For examples of using the Qtk API, see the `example-app` project in the root of
this repository.
diff --git a/resources/resources.qrc b/resources/resources.qrc
index 4aaf9bc..807349d 100644
--- a/resources/resources.qrc
+++ b/resources/resources.qrc
@@ -46,8 +46,8 @@
shaders/vertex/solid-phong.vert
shaders/fragment/model-basic.frag
shaders/vertex/model-basic.vert
- shaders/fragment/model-specular.frag
- shaders/vertex/model-specular.vert
+ shaders/fragment/model-phong.frag
+ shaders/vertex/model-phong.vert
shaders/fragment/model-normals.frag
shaders/vertex/model-normals.vert
skybox/skybox.frag
diff --git a/resources/screenshot.png b/resources/screenshot.png
deleted file mode 100644
index 2802538..0000000
Binary files a/resources/screenshot.png and /dev/null differ
diff --git a/resources/qtk-reference.png b/resources/screenshots/qtk-reference.png
similarity index 100%
rename from resources/qtk-reference.png
rename to resources/screenshots/qtk-reference.png
diff --git a/resources/qtk-views-setup.png b/resources/screenshots/qtk-views-setup.png
similarity index 100%
rename from resources/qtk-views-setup.png
rename to resources/screenshots/qtk-views-setup.png
diff --git a/resources/qtk-views.png b/resources/screenshots/qtk-views.png
similarity index 100%
rename from resources/qtk-views.png
rename to resources/screenshots/qtk-views.png
diff --git a/resources/screenshots/screen-1.png b/resources/screenshots/screen-1.png
new file mode 100644
index 0000000..f2f3423
Binary files /dev/null and b/resources/screenshots/screen-1.png differ
diff --git a/resources/screenshots/screen-ambient.png b/resources/screenshots/screen-ambient.png
new file mode 100644
index 0000000..630bc50
Binary files /dev/null and b/resources/screenshots/screen-ambient.png differ
diff --git a/resources/screenshots/screen-diffuse.png b/resources/screenshots/screen-diffuse.png
new file mode 100644
index 0000000..f591899
Binary files /dev/null and b/resources/screenshots/screen-diffuse.png differ
diff --git a/resources/screenshots/screen-phong.png b/resources/screenshots/screen-phong.png
new file mode 100644
index 0000000..a3370f7
Binary files /dev/null and b/resources/screenshots/screen-phong.png differ
diff --git a/resources/screenshots/screen-specular.png b/resources/screenshots/screen-specular.png
new file mode 100644
index 0000000..3fab967
Binary files /dev/null and b/resources/screenshots/screen-specular.png differ
diff --git a/resources/screenshots/screen-texture.png b/resources/screenshots/screen-texture.png
new file mode 100644
index 0000000..c4f9830
Binary files /dev/null and b/resources/screenshots/screen-texture.png differ
diff --git a/resources/screenshots/screen.png b/resources/screenshots/screen.png
new file mode 100644
index 0000000..e462c7e
Binary files /dev/null and b/resources/screenshots/screen.png differ
diff --git a/resources/screenshots/spartan-normals.png b/resources/screenshots/spartan-normals.png
new file mode 100644
index 0000000..4b7450e
Binary files /dev/null and b/resources/screenshots/spartan-normals.png differ
diff --git a/resources/screenshots/spartan-phong.png b/resources/screenshots/spartan-phong.png
new file mode 100644
index 0000000..b4e3eab
Binary files /dev/null and b/resources/screenshots/spartan-phong.png differ
diff --git a/resources/shaders/fragment/model-specular.frag b/resources/shaders/fragment/model-phong.frag
similarity index 100%
rename from resources/shaders/fragment/model-specular.frag
rename to resources/shaders/fragment/model-phong.frag
diff --git a/resources/shaders/vertex/model-specular.vert b/resources/shaders/vertex/model-phong.vert
similarity index 100%
rename from resources/shaders/vertex/model-specular.vert
rename to resources/shaders/vertex/model-phong.vert
diff --git a/resources/spartan-normals.png b/resources/spartan-normals.png
deleted file mode 100644
index e27f68f..0000000
Binary files a/resources/spartan-normals.png and /dev/null differ
diff --git a/resources/spartan-specular.png b/resources/spartan-specular.png
deleted file mode 100644
index 1cc704f..0000000
Binary files a/resources/spartan-specular.png and /dev/null differ
diff --git a/src/app/qtkmainwindow.cpp b/src/app/qtkmainwindow.cpp
index 9d7d547..dee16ef 100644
--- a/src/app/qtkmainwindow.cpp
+++ b/src/app/qtkmainwindow.cpp
@@ -33,12 +33,14 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent)
// Add GUI 'view' toolbar option to show debug console.
ui_->menuView->addAction(qtkWidget->getActionToggleConsole());
+
// Refresh GUI widgets when scene or objects are updated.
connect(qtkWidget->getScene(),
&Qtk::Scene::sceneUpdated,
this,
&MainWindow::refreshScene);
- connect(qtkWidget, &Qtk::QtkWidget::objectFocusChanged,
+ connect(qtkWidget,
+ &Qtk::QtkWidget::objectFocusChanged,
ui_->qtk__ToolBox,
&Qtk::ToolBox::updateFocus);
}
@@ -71,8 +73,8 @@ MainWindow::~MainWindow()
MainWindow * MainWindow::getMainWindow()
{
- static MainWindow window;
- return &window;
+ static auto * window = new MainWindow;
+ return window;
}
Qtk::QtkWidget * MainWindow::getQtkWidget(int64_t index)
diff --git a/src/app/qtkmainwindow.h b/src/app/qtkmainwindow.h
index 4bd2fe9..109150c 100644
--- a/src/app/qtkmainwindow.h
+++ b/src/app/qtkmainwindow.h
@@ -48,10 +48,9 @@ namespace Ui
* Any application using a QtkWidget can set a custom scene in their main
* function. See the MainWindow::MainWindow constructor as an example.
*/
-class EmptyScene : public Qtk::Scene {
- void init() override {
- setSceneName("Empty Scene");
- }
+class EmptyScene : public Qtk::Scene
+{
+ void init() override { setSceneName("Empty Scene"); }
};
/**
diff --git a/src/app/qtkscene.cpp b/src/app/qtkscene.cpp
index c93ab78..93eaa9f 100644
--- a/src/app/qtkscene.cpp
+++ b/src/app/qtkscene.cpp
@@ -260,8 +260,8 @@ void QtkScene::init()
/* Test spartan Model with phong lighting, specular and normal mapping. */
model = addObject(new Qtk::Model("spartanTest",
":/models/models/spartan/spartan.obj",
- ":/shaders/model-normals.vert",
- ":/shaders/model-normals.frag"));
+ ":/shaders/model-phong.vert",
+ ":/shaders/model-phong.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));
diff --git a/src/app/qtkwidget.cpp b/src/app/qtkwidget.cpp
index 4d0fd3c..b12cbf6 100644
--- a/src/app/qtkwidget.cpp
+++ b/src/app/qtkwidget.cpp
@@ -83,7 +83,11 @@ void QtkWidget::initializeGL()
// Connect the frameSwapped signal to call the update() function
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
- toggleConsole();
+ // Add the debug console widget to the window and set its hidden state.
+ MainWindow::getMainWindow()->addDockWidget(
+ Qt::DockWidgetArea::BottomDockWidgetArea, mConsole);
+ mConsole->setHidden(!mConsoleActive);
+
// Initialize OpenGL debug context
mDebugLogger = new QOpenGLDebugLogger(this);
if (mDebugLogger->initialize()) {
@@ -144,15 +148,8 @@ void QtkWidget::setScene(Scene * scene)
void QtkWidget::toggleConsole()
{
- if (mConsoleActive) {
- mConsole->setHidden(true);
- mConsoleActive = false;
- } else {
- MainWindow::getMainWindow()->addDockWidget(
- Qt::DockWidgetArea::BottomDockWidgetArea, mConsole);
- mConsole->setHidden(false);
- mConsoleActive = true;
- }
+ mConsole->setHidden(mConsoleActive);
+ mConsoleActive = !mConsoleActive;
}
/*******************************************************************************
diff --git a/src/app/qtkwidget.h b/src/app/qtkwidget.h
index 2937296..f2c56e9 100644
--- a/src/app/qtkwidget.h
+++ b/src/app/qtkwidget.h
@@ -210,7 +210,7 @@ namespace Qtk
QOpenGLDebugLogger * mDebugLogger;
Qtk::Scene * mScene;
Qtk::DebugConsole * mConsole;
- bool mConsoleActive = false;
+ bool mConsoleActive = true;
};
} // namespace Qtk
diff --git a/src/app/treeview.cpp b/src/app/treeview.cpp
index f173726..17a9a08 100644
--- a/src/app/treeview.cpp
+++ b/src/app/treeview.cpp
@@ -41,36 +41,33 @@ 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().c_str())));
- ui->treeWidget->insertTopLevelItem(0, item);
+ QStringList list(QStringList(QString(object->getName().c_str())));
+ ui->treeWidget->insertTopLevelItem(0, new QTreeWidgetItem(list));
}
}
void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column)
{
- QString name = item->text(column);
+ const QString & name = item->text(column);
auto scene = MainWindow::getMainWindow()->getQtkWidget()->getScene();
- auto & transform = Qtk::Scene::getCamera().getTransform();
auto object = scene->getObject(name);
- Transform3D * objectTransform;
// If the object is a mesh or model, focus the camera on it.
if (object == Q_NULLPTR) {
qDebug() << "Attempt to get non-existing object with name '" << name
<< "'\n";
- } else if (object->getType() == Object::QTK_MESH) {
- objectTransform = &dynamic_cast(object)->getTransform();
- } else if (object->getType() == Object::QTK_MODEL) {
- objectTransform = &dynamic_cast(object)->getTransform();
+ return;
}
- auto focusScale = objectTransform->getScale();
+ const Transform3D & objectTransform = object->getTransform();
+
+ auto & camera_transform = Qtk::Scene::getCamera().getTransform();
+ auto focusScale = objectTransform.getScale();
float width = focusScale.x() / 2.0f;
float height = focusScale.y() / 2.0f;
- QVector3D pos = objectTransform->getTranslation();
+ QVector3D pos = objectTransform.getTranslation();
// pos.setX(pos.x() + width);
pos.setY(pos.y() + height);
- transform.setTranslation(pos);
- transform.translate(0.0f, 0.0f, 3.0f);
+ camera_transform.setTranslation(pos);
+ camera_transform.translate(0.0f, 0.0f, 3.0f);
// Emit signal from qtk widget for new object focus. Triggers GUI updates.
emit MainWindow::getMainWindow() -> getQtkWidget()->objectFocusChanged(name);
diff --git a/src/qtk/meshrenderer.h b/src/qtk/meshrenderer.h
index 404ee95..858f4c4 100644
--- a/src/qtk/meshrenderer.h
+++ b/src/qtk/meshrenderer.h
@@ -216,7 +216,7 @@ namespace Qtk
/**
* @return Transform3D attached to this MeshRenderer.
*/
- inline Transform3D & getTransform() { return mTransform; }
+ inline Transform3D & getTransform() override { return mTransform; }
[[nodiscard]] inline std::string getVertexShader() const override
{
diff --git a/src/qtk/model.h b/src/qtk/model.h
index b11a5ec..d87f1cf 100644
--- a/src/qtk/model.h
+++ b/src/qtk/model.h
@@ -129,7 +129,7 @@ namespace Qtk
/**
* @return Transform3D attached to this Model.
*/
- inline Transform3D & getTransform() { return mTransform; }
+ inline Transform3D & getTransform() override { return mTransform; }
[[nodiscard]] inline std::string getVertexShader() const override
{
diff --git a/src/qtk/object.h b/src/qtk/object.h
index 1550d65..2046bd7 100644
--- a/src/qtk/object.h
+++ b/src/qtk/object.h
@@ -111,6 +111,11 @@ namespace Qtk
return mTransform;
}
+ [[nodiscard]] inline virtual Transform3D & getTransform()
+ {
+ return mTransform;
+ }
+
[[nodiscard]] inline virtual std::string getVertexShader() const
{
return "Base Object has no vertex shader.";
diff --git a/src/qtk/scene.cpp b/src/qtk/scene.cpp
index 6b0eb31..e0b9afa 100644
--- a/src/qtk/scene.cpp
+++ b/src/qtk/scene.cpp
@@ -118,11 +118,9 @@ void Scene::setSkybox(Skybox * skybox)
void Scene::initSceneObjectName(Object * object)
{
- if (!mObjectCount.count(object->getName())) {
- mObjectCount[object->getName()] = 1;
- } else {
- mObjectCount[object->getName()]++;
- }
+ mObjectCount[object->getName()] = mObjectCount.count(object->getName()) + 1;
+
+ // If the object exists make it's name unique.
auto count = mObjectCount[object->getName()];
if (count > 1) {
object->setName(object->getName() + " (" + std::to_string(count) + ")");