Clang format.
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				All Builds / Qtk (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), ubuntu-latest) (push) Failing after 23s
				
					
					
				
			
		
			
				
	
				All Builds / Qtk-Library (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), ubuntu-latest) (push) Failing after 22s
				
					
					
				
			
		
			
				
	
				All Builds / Qtk-Plugins (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), ubuntu-latest) (push) Failing after 20s
				
					
					
				
			
		
			
				
	
				All Builds / Qtk-Assimp-Targets (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/, ubuntu-latest) (push) Failing after 18s
				
					
					
				
			
		
			
				
	
				Linting / Tidy (push) Failing after 24s
				
					
					
				
			
		
			
				
	
				Linting / Format (app) (push) Failing after 23s
				
					
					
				
			
		
			
				
	
				Linting / Format (src) (push) Failing after 23s
				
					
					
				
			
		
			
				
	
				All Builds / Qtk (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), macos-latest) (push) Has been cancelled
				
					
					
				
			
		
			
				
	
				All Builds / Qtk (-DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/$QT_VERSION/mingw81_64/ $CONFIG, , windows-latest) (push) Has been cancelled
				
					
					
				
			
		
			
				
	
				All Builds / Qtk-Library (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), macos-latest) (push) Has been cancelled
				
					
					
				
			
		
			
				
	
				All Builds / Qtk-Library (-DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/$QT_VERSION/mingw81_64/ $CONFIG, , windows-latest) (push) Has been cancelled
				
					
					
				
			
		
			
				
	
				All Builds / Qtk-Plugins (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), macos-latest) (push) Has been cancelled
				
					
					
				
			
		
			
				
	
				All Builds / Qtk-Plugins (-DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/$QT_VERSION/mingw81_64/ $CONFIG, , windows-latest) (push) Has been cancelled
				
					
					
				
			
		
			
				
	
				All Builds / Qtk-Assimp-Targets (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/, macos-latest) (push) Has been cancelled
				
					
					
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	All Builds / Qtk (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), ubuntu-latest) (push) Failing after 23s
				All Builds / Qtk-Library (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), ubuntu-latest) (push) Failing after 22s
				All Builds / Qtk-Plugins (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), ubuntu-latest) (push) Failing after 20s
				All Builds / Qtk-Assimp-Targets (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/, ubuntu-latest) (push) Failing after 18s
				Linting / Tidy (push) Failing after 24s
				Linting / Format (app) (push) Failing after 23s
				Linting / Format (src) (push) Failing after 23s
				All Builds / Qtk (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), macos-latest) (push) Has been cancelled
				All Builds / Qtk (-DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/$QT_VERSION/mingw81_64/ $CONFIG, , windows-latest) (push) Has been cancelled
				All Builds / Qtk-Library (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), macos-latest) (push) Has been cancelled
				All Builds / Qtk-Library (-DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/$QT_VERSION/mingw81_64/ $CONFIG, , windows-latest) (push) Has been cancelled
				All Builds / Qtk-Plugins (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/ $CONFIG, -j $(nproc), macos-latest) (push) Has been cancelled
				All Builds / Qtk-Plugins (-DCMAKE_PREFIX_PATH=D:/a/qtk/qtk/Qt/$QT_VERSION/mingw81_64/ $CONFIG, , windows-latest) (push) Has been cancelled
				All Builds / Qtk-Assimp-Targets (-DCMAKE_PREFIX_PATH=/home/runner/work/qtk/Qt/$QT_VERSION/gcc_64/, macos-latest) (push) Has been cancelled
				This commit is contained in:
		
							parent
							
								
									1bed9545c9
								
							
						
					
					
						commit
						7fac6bafb4
					
				@ -59,7 +59,7 @@ SpaceAfterTemplateKeyword: true
 | 
			
		||||
SpaceBeforeAssignmentOperators: true
 | 
			
		||||
SpaceBeforeCpp11BracedList: true
 | 
			
		||||
SpaceBeforeCtorInitializerColon: true
 | 
			
		||||
SpaceBeforeParens: Never
 | 
			
		||||
SpaceBeforeParens: ControlStatementsExceptControlMacros
 | 
			
		||||
SpaceBeforeRangeBasedForLoopColon: true
 | 
			
		||||
SpacesBeforeTrailingComments: 2
 | 
			
		||||
SpaceInEmptyParentheses: false
 | 
			
		||||
 | 
			
		||||
@ -93,6 +93,7 @@ void ExampleScene::update()
 | 
			
		||||
  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()
 | 
			
		||||
  MeshRenderer::getInstance("centerCube")
 | 
			
		||||
      ->getTransform()
 | 
			
		||||
      .rotate(0.75f, 0.2f, 0.4f, 0.6f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,8 @@
 | 
			
		||||
 | 
			
		||||
#include <qtk/scene.h>
 | 
			
		||||
 | 
			
		||||
class ExampleScene : public Qtk::Scene {
 | 
			
		||||
class ExampleScene : public Qtk::Scene
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    explicit ExampleScene();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,8 @@
 | 
			
		||||
#include "examplewidget.h"
 | 
			
		||||
 | 
			
		||||
ExampleWidget::ExampleWidget(QWidget * parent) :
 | 
			
		||||
    QOpenGLWidget(parent), mScene(new ExampleScene) {
 | 
			
		||||
    QOpenGLWidget(parent), mScene(new ExampleScene)
 | 
			
		||||
{
 | 
			
		||||
  // 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.
 | 
			
		||||
@ -27,7 +28,8 @@ ExampleWidget::ExampleWidget(QWidget * parent) :
 | 
			
		||||
  setFocusPolicy(Qt::ClickFocus);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ExampleWidget::initializeGL() {
 | 
			
		||||
void ExampleWidget::initializeGL()
 | 
			
		||||
{
 | 
			
		||||
  initializeOpenGLFunctions();
 | 
			
		||||
  connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
 | 
			
		||||
  glEnable(GL_MULTISAMPLE);
 | 
			
		||||
@ -40,18 +42,21 @@ void ExampleWidget::initializeGL() {
 | 
			
		||||
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ExampleWidget::resizeGL(int width, int height) {
 | 
			
		||||
void ExampleWidget::resizeGL(int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  Qtk::Scene::getProjectionMatrix().setToIdentity();
 | 
			
		||||
  Qtk::Scene::getProjectionMatrix().perspective(
 | 
			
		||||
      45.0f, float(width) / float(height), 0.1f, 1000.0f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ExampleWidget::paintGL() {
 | 
			
		||||
void ExampleWidget::paintGL()
 | 
			
		||||
{
 | 
			
		||||
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 | 
			
		||||
  mScene->draw();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ExampleWidget::update() {
 | 
			
		||||
void ExampleWidget::update()
 | 
			
		||||
{
 | 
			
		||||
  mScene->update();
 | 
			
		||||
  QWidget::update();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,8 @@
 | 
			
		||||
 | 
			
		||||
#include "examplescene.h"
 | 
			
		||||
 | 
			
		||||
class ExampleWidget : public QOpenGLWidget, protected QOpenGLFunctions {
 | 
			
		||||
class ExampleWidget : public QOpenGLWidget, protected QOpenGLFunctions
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT;
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,8 @@
 | 
			
		||||
 | 
			
		||||
#include "examplewidget.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, char * argv[]) {
 | 
			
		||||
int main(int argc, char * argv[])
 | 
			
		||||
{
 | 
			
		||||
  QApplication app(argc, argv);
 | 
			
		||||
 | 
			
		||||
  auto window = new QMainWindow;
 | 
			
		||||
 | 
			
		||||
@ -15,10 +15,13 @@
 | 
			
		||||
using namespace Qtk;
 | 
			
		||||
 | 
			
		||||
DebugConsole::DebugConsole(QWidget * owner, const QString & key) :
 | 
			
		||||
    DebugConsole(owner, key, key + "Debugger") {}
 | 
			
		||||
    DebugConsole(owner, key, key + "Debugger")
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DebugConsole::DebugConsole(
 | 
			
		||||
    QWidget * owner, const QString & key, const QString & name) {
 | 
			
		||||
DebugConsole::DebugConsole(QWidget * owner, const QString & key,
 | 
			
		||||
                           const QString & name)
 | 
			
		||||
{
 | 
			
		||||
  ui_ = new Ui::DebugConsole;
 | 
			
		||||
  ui_->setupUi(this);
 | 
			
		||||
  setObjectName(name);
 | 
			
		||||
 | 
			
		||||
@ -16,12 +16,15 @@
 | 
			
		||||
 | 
			
		||||
#include "qtkwidget.h"
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
namespace Ui
 | 
			
		||||
{
 | 
			
		||||
  class DebugConsole;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
  class DebugConsole : public QDockWidget {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  class DebugConsole : public QDockWidget
 | 
			
		||||
  {
 | 
			
		||||
      Q_OBJECT;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
@ -61,7 +64,8 @@ namespace Qtk {
 | 
			
		||||
       * @param context The DebugContext to use for the message.
 | 
			
		||||
       *    Default value is Status.
 | 
			
		||||
       */
 | 
			
		||||
      inline void sendLog(QString message, DebugContext context = Status) {
 | 
			
		||||
      inline void sendLog(QString message, DebugContext context = Status)
 | 
			
		||||
      {
 | 
			
		||||
        mConsole->setTextColor(logColor(context));
 | 
			
		||||
        mConsole->append(logPrefix(message, context));
 | 
			
		||||
      }
 | 
			
		||||
@ -72,7 +76,8 @@ namespace Qtk {
 | 
			
		||||
       *
 | 
			
		||||
       * @param name Base name for the DebugConsole window.
 | 
			
		||||
       */
 | 
			
		||||
      inline void setTitle(const QString& name) {
 | 
			
		||||
      inline void setTitle(const QString & name)
 | 
			
		||||
      {
 | 
			
		||||
        setWindowTitle(name + " Debug Console");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -81,7 +86,8 @@ namespace Qtk {
 | 
			
		||||
       * @param context Log context severity level.
 | 
			
		||||
       * @return QColor corresponding with the message context.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] QColor logColor(const DebugContext & context) const {
 | 
			
		||||
      [[nodiscard]] QColor logColor(const DebugContext & context) const
 | 
			
		||||
      {
 | 
			
		||||
        switch (context) {
 | 
			
		||||
          case Status:
 | 
			
		||||
            return Qt::GlobalColor::darkGray;
 | 
			
		||||
@ -105,8 +111,9 @@ namespace Qtk {
 | 
			
		||||
       * @param context The log context severity level.
 | 
			
		||||
       * @return The log message prefixed with the DebugContext level.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] QString logPrefix(
 | 
			
		||||
          QString & message, const DebugContext & context) {
 | 
			
		||||
      [[nodiscard]] QString logPrefix(QString & message,
 | 
			
		||||
                                      const DebugContext & context)
 | 
			
		||||
      {
 | 
			
		||||
        QString prefix;
 | 
			
		||||
        switch (context) {
 | 
			
		||||
          case Status:
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,8 @@
 | 
			
		||||
#include "qtkmainwindow.h"
 | 
			
		||||
#include "qtkscene.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, char * argv[]) {
 | 
			
		||||
int main(int argc, char * argv[])
 | 
			
		||||
{
 | 
			
		||||
  Q_INIT_RESOURCE(resources);
 | 
			
		||||
 | 
			
		||||
  QApplication a(argc, argv);
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,8 @@ MainWindow * MainWindow::mainWindow_ = Q_NULLPTR;
 | 
			
		||||
 * Constructors / Destructors
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) {
 | 
			
		||||
MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent)
 | 
			
		||||
{
 | 
			
		||||
  ui_ = new Ui::MainWindow;
 | 
			
		||||
  setObjectName("MainWindow");
 | 
			
		||||
  // For use in design mode using Qt Creator
 | 
			
		||||
@ -35,11 +36,9 @@ 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,
 | 
			
		||||
    connect(qtkWidget->getScene(), &Qtk::Scene::sceneUpdated, this,
 | 
			
		||||
            &MainWindow::refreshScene);
 | 
			
		||||
    connect(
 | 
			
		||||
        qtkWidget, &Qtk::QtkWidget::objectFocusChanged, ui_->qtk__ToolBox,
 | 
			
		||||
    connect(qtkWidget, &Qtk::QtkWidget::objectFocusChanged, ui_->qtk__ToolBox,
 | 
			
		||||
            &Qtk::ToolBox::updateFocus);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -60,7 +59,8 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) {
 | 
			
		||||
  setWindowIcon(Qtk::getIcon());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MainWindow::~MainWindow() {
 | 
			
		||||
MainWindow::~MainWindow()
 | 
			
		||||
{
 | 
			
		||||
  delete ui_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -68,14 +68,16 @@ MainWindow::~MainWindow() {
 | 
			
		||||
 * Public Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
MainWindow * MainWindow::getMainWindow() {
 | 
			
		||||
MainWindow * MainWindow::getMainWindow()
 | 
			
		||||
{
 | 
			
		||||
  if (mainWindow_ == Q_NULLPTR) {
 | 
			
		||||
    mainWindow_ = new MainWindow;
 | 
			
		||||
  }
 | 
			
		||||
  return mainWindow_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Qtk::QtkWidget * MainWindow::getQtkWidget(int64_t index) {
 | 
			
		||||
Qtk::QtkWidget * MainWindow::getQtkWidget(int64_t index)
 | 
			
		||||
{
 | 
			
		||||
  if (views_.size() <= index) {
 | 
			
		||||
    return Q_NULLPTR;
 | 
			
		||||
  }
 | 
			
		||||
@ -84,14 +86,16 @@ Qtk::QtkWidget * MainWindow::getQtkWidget(int64_t index) {
 | 
			
		||||
  return it->second;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Qtk::QtkWidget * MainWindow::getQtkWidget(const QString & name) {
 | 
			
		||||
Qtk::QtkWidget * MainWindow::getQtkWidget(const QString & name)
 | 
			
		||||
{
 | 
			
		||||
  if (!views_.count(name)) {
 | 
			
		||||
    return Q_NULLPTR;
 | 
			
		||||
  }
 | 
			
		||||
  return views_[name];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::refreshScene(const QString & sceneName) {
 | 
			
		||||
void MainWindow::refreshScene(const QString & sceneName)
 | 
			
		||||
{
 | 
			
		||||
  // TODO: Select TreeView using sceneName
 | 
			
		||||
  ui_->qtk__TreeView->updateView(getQtkWidget()->getScene());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,8 @@
 | 
			
		||||
#include "debugconsole.h"
 | 
			
		||||
#include "qtkwidget.h"
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
namespace Ui
 | 
			
		||||
{
 | 
			
		||||
  class MainWindow;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,7 +26,8 @@ namespace Ui {
 | 
			
		||||
 * MainWindow class to provide an example of using a QtkWidget within a Qt
 | 
			
		||||
 * window application.
 | 
			
		||||
 */
 | 
			
		||||
class MainWindow : public QMainWindow {
 | 
			
		||||
class MainWindow : public QMainWindow
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
@ -14,13 +14,15 @@ using namespace Qtk;
 | 
			
		||||
 * Constructors, Destructors
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
QtkScene::QtkScene() {
 | 
			
		||||
QtkScene::QtkScene()
 | 
			
		||||
{
 | 
			
		||||
  setSceneName("Qtk Scene");
 | 
			
		||||
  getCamera().getTransform().setTranslation(0.0f, 0.0f, 20.0f);
 | 
			
		||||
  getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QtkScene::~QtkScene() {
 | 
			
		||||
QtkScene::~QtkScene()
 | 
			
		||||
{
 | 
			
		||||
  delete mTestPhong;
 | 
			
		||||
  delete mTestSpecular;
 | 
			
		||||
  delete mTestDiffuse;
 | 
			
		||||
@ -31,7 +33,8 @@ QtkScene::~QtkScene() {
 | 
			
		||||
 * Public Member Functions
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void QtkScene::init() {
 | 
			
		||||
void QtkScene::init()
 | 
			
		||||
{
 | 
			
		||||
  // Add a skybox to the scene using default cube map images and settings.
 | 
			
		||||
  setSkybox(new Qtk::Skybox("Skybox"));
 | 
			
		||||
 | 
			
		||||
@ -116,8 +119,8 @@ void QtkScene::init() {
 | 
			
		||||
  // 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(
 | 
			
		||||
      ":/shaders/solid-phong.vert", ":/shaders/solid-phong.frag");
 | 
			
		||||
  mTestPhong->setShaders(":/shaders/solid-phong.vert",
 | 
			
		||||
                         ":/shaders/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,
 | 
			
		||||
@ -143,16 +146,16 @@ void QtkScene::init() {
 | 
			
		||||
  /* 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(
 | 
			
		||||
      ":/shaders/solid-perspective.vert", ":/shaders/solid-perspective.frag");
 | 
			
		||||
  mesh->setShaders(":/shaders/solid-perspective.vert",
 | 
			
		||||
                   ":/shaders/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(
 | 
			
		||||
      ":/shaders/solid-ambient.vert", ":/shaders/solid-ambient.frag");
 | 
			
		||||
  mTestAmbient->setShaders(":/shaders/solid-ambient.vert",
 | 
			
		||||
                           ":/shaders/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));
 | 
			
		||||
@ -163,8 +166,8 @@ void QtkScene::init() {
 | 
			
		||||
  /* Initialize Diffuse example cube */
 | 
			
		||||
  mTestDiffuse = new Qtk::MeshRenderer("diffuse", Cube());
 | 
			
		||||
  mTestDiffuse->getTransform().setTranslation(9.0f, 0.0f, -2.0f);
 | 
			
		||||
  mTestDiffuse->setShaders(
 | 
			
		||||
      ":/shaders/solid-diffuse.vert", ":/shaders/solid-diffuse.frag");
 | 
			
		||||
  mTestDiffuse->setShaders(":/shaders/solid-diffuse.vert",
 | 
			
		||||
                           ":/shaders/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);
 | 
			
		||||
@ -179,8 +182,8 @@ void QtkScene::init() {
 | 
			
		||||
  /* Initialize Specular example cube */
 | 
			
		||||
  mTestSpecular = new Qtk::MeshRenderer("specular", Cube());
 | 
			
		||||
  mTestSpecular->getTransform().setTranslation(11.0f, 0.0f, -2.0f);
 | 
			
		||||
  mTestSpecular->setShaders(
 | 
			
		||||
      ":/shaders/solid-specular.vert", ":/shaders/solid-specular.frag");
 | 
			
		||||
  mTestSpecular->setShaders(":/shaders/solid-specular.vert",
 | 
			
		||||
                            ":/shaders/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);
 | 
			
		||||
@ -246,8 +249,8 @@ void QtkScene::init() {
 | 
			
		||||
  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 = 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
 | 
			
		||||
@ -290,8 +293,8 @@ void QtkScene::init() {
 | 
			
		||||
  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 = addObject(new Qtk::MeshRenderer("rgbNormalsCubeElementsTest",
 | 
			
		||||
                                         Cube(QTK_DRAW_ELEMENTS_NORMALS)));
 | 
			
		||||
  mesh->getTransform().setTranslation(5.0f, 0.0f, 2.0f);
 | 
			
		||||
  mesh->setShaders(":/shaders/rgb-normals.vert", ":/shaders/rgb-normals.frag");
 | 
			
		||||
  mesh->reallocateNormals(mesh->getNormals());
 | 
			
		||||
@ -321,8 +324,8 @@ void QtkScene::init() {
 | 
			
		||||
  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 = addObject(new Qtk::MeshRenderer("uvCubeElementsTest",
 | 
			
		||||
                                         Cube(QTK_DRAW_ELEMENTS_NORMALS)));
 | 
			
		||||
  mesh->getTransform().setTranslation(-1.7f, 0.0f, -2.0f);
 | 
			
		||||
  mesh->setTexture(":/textures/crate.png");
 | 
			
		||||
  mesh->setShaders(":/shaders/texture2d.vert", ":/shaders/texture2d.frag");
 | 
			
		||||
@ -339,8 +342,8 @@ void QtkScene::init() {
 | 
			
		||||
      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(
 | 
			
		||||
      ":/shaders/texture-cubemap.vert", ":/shaders/texture-cubemap.frag");
 | 
			
		||||
  mesh->setShaders(":/shaders/texture-cubemap.vert",
 | 
			
		||||
                   ":/shaders/texture-cubemap.frag");
 | 
			
		||||
  mesh->setCubeMap(":/textures/crate.png");
 | 
			
		||||
  mesh->setUniform("uTexture", 0);
 | 
			
		||||
  mesh->reallocateTexCoords(mesh->getTexCoords());
 | 
			
		||||
@ -354,15 +357,15 @@ void QtkScene::init() {
 | 
			
		||||
  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 = addObject(new Qtk::MeshRenderer("rgbTriangleArraysTest",
 | 
			
		||||
                                         Triangle(QTK_DRAW_ARRAYS)));
 | 
			
		||||
  mesh->getTransform().setTranslation(7.0f, 0.0f, 2.0f);
 | 
			
		||||
  mesh->setShaders(":/shaders/rgb-normals.vert", ":/shaders/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 = addObject(new Qtk::MeshRenderer("rgbTriangleElementsTest",
 | 
			
		||||
                                         Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
 | 
			
		||||
  mesh->getTransform().setTranslation(7.0f, 0.0f, 4.0f);
 | 
			
		||||
  mesh->setShaders(":/shaders/rgb-normals.vert", ":/shaders/rgb-normals.frag");
 | 
			
		||||
  mesh->reallocateNormals(mesh->getNormals());
 | 
			
		||||
@ -378,8 +381,8 @@ void QtkScene::init() {
 | 
			
		||||
  mesh->reallocateTexCoords(mesh->getTexCoords());
 | 
			
		||||
 | 
			
		||||
  // Test drawing triangle with glDrawElements with texture coordinates
 | 
			
		||||
  mesh = addObject(new Qtk::MeshRenderer(
 | 
			
		||||
      "testTriangleElementsUV", Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
 | 
			
		||||
  mesh = addObject(new Qtk::MeshRenderer("testTriangleElementsUV",
 | 
			
		||||
                                         Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
 | 
			
		||||
  mesh->getTransform().setTranslation(-2.5f, 0.0f, -1.0f);
 | 
			
		||||
  mesh->setShaders(":/shaders/texture2d.vert", ":/shaders/texture2d.frag");
 | 
			
		||||
  mesh->setTexture(":/textures/crate.png");
 | 
			
		||||
@ -387,20 +390,20 @@ void QtkScene::init() {
 | 
			
		||||
  mesh->reallocateTexCoords(mesh->getTexCoords());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkScene::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();
 | 
			
		||||
 | 
			
		||||
  mTestPhong->bindShaders();
 | 
			
		||||
  mTestPhong->setUniform(
 | 
			
		||||
      "uModelInverseTransposed",
 | 
			
		||||
  mTestPhong->setUniform("uModelInverseTransposed",
 | 
			
		||||
                         mTestPhong->getTransform().toMatrix().normalMatrix());
 | 
			
		||||
  mTestPhong->setUniform(
 | 
			
		||||
      "uLightPosition",
 | 
			
		||||
      MeshRenderer::getInstance("phongLight")->getTransform().getTranslation());
 | 
			
		||||
  mTestPhong->setUniform(
 | 
			
		||||
      "uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
 | 
			
		||||
  mTestPhong->setUniform("uCameraPosition",
 | 
			
		||||
                         QtkScene::getCamera().getTransform().getTranslation());
 | 
			
		||||
  mTestPhong->releaseShaders();
 | 
			
		||||
  mTestPhong->draw();
 | 
			
		||||
 | 
			
		||||
@ -414,8 +417,8 @@ void QtkScene::draw() {
 | 
			
		||||
  mTestDiffuse->setUniform(
 | 
			
		||||
      "uModelInverseTransposed",
 | 
			
		||||
      mTestDiffuse->getTransform().toMatrix().normalMatrix());
 | 
			
		||||
  mTestDiffuse->setUniform(
 | 
			
		||||
      "uLightPosition", MeshRenderer::getInstance("diffuseLight")
 | 
			
		||||
  mTestDiffuse->setUniform("uLightPosition",
 | 
			
		||||
                           MeshRenderer::getInstance("diffuseLight")
 | 
			
		||||
                               ->getTransform()
 | 
			
		||||
                               .getTranslation());
 | 
			
		||||
  mTestDiffuse->setUniform(
 | 
			
		||||
@ -427,8 +430,8 @@ void QtkScene::draw() {
 | 
			
		||||
  mTestSpecular->setUniform(
 | 
			
		||||
      "uModelInverseTransposed",
 | 
			
		||||
      mTestSpecular->getTransform().toMatrix().normalMatrix());
 | 
			
		||||
  mTestSpecular->setUniform(
 | 
			
		||||
      "uLightPosition", MeshRenderer::getInstance("specularLight")
 | 
			
		||||
  mTestSpecular->setUniform("uLightPosition",
 | 
			
		||||
                            MeshRenderer::getInstance("specularLight")
 | 
			
		||||
                                ->getTransform()
 | 
			
		||||
                                .getTranslation());
 | 
			
		||||
  mTestSpecular->setUniform(
 | 
			
		||||
@ -437,7 +440,8 @@ void QtkScene::draw() {
 | 
			
		||||
  mTestSpecular->draw();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkScene::update() {
 | 
			
		||||
void QtkScene::update()
 | 
			
		||||
{
 | 
			
		||||
  auto mySpartan = Model::getInstance("My spartan");
 | 
			
		||||
  mySpartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
 | 
			
		||||
 | 
			
		||||
@ -449,8 +453,8 @@ void QtkScene::update() {
 | 
			
		||||
                      .getTranslation();
 | 
			
		||||
  auto alien = Model::getInstance("alienTest");
 | 
			
		||||
  alien->setUniform("uLight.position", position);
 | 
			
		||||
  alien->setUniform(
 | 
			
		||||
      "uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
 | 
			
		||||
  alien->setUniform("uCameraPosition",
 | 
			
		||||
                    QtkScene::getCamera().getTransform().getTranslation());
 | 
			
		||||
  auto posMatrix = alien->getTransform().toMatrix();
 | 
			
		||||
  alien->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
 | 
			
		||||
  alien->setUniform("uMVP.model", posMatrix);
 | 
			
		||||
@ -463,8 +467,8 @@ void QtkScene::update() {
 | 
			
		||||
                 .getTranslation();
 | 
			
		||||
  auto spartan = Model::getInstance("spartanTest");
 | 
			
		||||
  spartan->setUniform("uLight.position", position);
 | 
			
		||||
  spartan->setUniform(
 | 
			
		||||
      "uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
 | 
			
		||||
  spartan->setUniform("uCameraPosition",
 | 
			
		||||
                      QtkScene::getCamera().getTransform().getTranslation());
 | 
			
		||||
  posMatrix = spartan->getTransform().toMatrix();
 | 
			
		||||
  spartan->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
 | 
			
		||||
  spartan->setUniform("uMVP.model", posMatrix);
 | 
			
		||||
@ -478,8 +482,8 @@ void QtkScene::update() {
 | 
			
		||||
  position =
 | 
			
		||||
      MeshRenderer::getInstance("testLight")->getTransform().getTranslation();
 | 
			
		||||
  phong->setUniform("uLight.position", position);
 | 
			
		||||
  phong->setUniform(
 | 
			
		||||
      "uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
 | 
			
		||||
  phong->setUniform("uCameraPosition",
 | 
			
		||||
                    QtkScene::getCamera().getTransform().getTranslation());
 | 
			
		||||
  posMatrix = phong->getTransform().toMatrix();
 | 
			
		||||
  phong->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
 | 
			
		||||
  phong->setUniform("uMVP.model", posMatrix);
 | 
			
		||||
@ -489,8 +493,8 @@ void QtkScene::update() {
 | 
			
		||||
 | 
			
		||||
  // 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);
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,8 @@
 | 
			
		||||
 *
 | 
			
		||||
 * To create your own Scene from scratch see Qtk::Scene.
 | 
			
		||||
 */
 | 
			
		||||
class QtkScene : public Qtk::Scene {
 | 
			
		||||
class QtkScene : public Qtk::Scene
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    /***************************************************************************
 | 
			
		||||
     * Contructors / Destructors
 | 
			
		||||
 | 
			
		||||
@ -32,11 +32,14 @@ using namespace Qtk;
 | 
			
		||||
QtkWidget::QtkWidget(QWidget * parent) : QtkWidget(parent, "QtkWidget") {}
 | 
			
		||||
 | 
			
		||||
QtkWidget::QtkWidget(QWidget * parent, const QString & name) :
 | 
			
		||||
    QtkWidget(parent, name, Q_NULLPTR) {}
 | 
			
		||||
    QtkWidget(parent, name, Q_NULLPTR)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QtkWidget::QtkWidget(QWidget * parent, const QString & name, Scene * scene) :
 | 
			
		||||
    QOpenGLWidget(parent), mDebugLogger(Q_NULLPTR),
 | 
			
		||||
    mConsole(new DebugConsole(this, name)), mScene(Q_NULLPTR) {
 | 
			
		||||
    mConsole(new DebugConsole(this, name)), mScene(Q_NULLPTR)
 | 
			
		||||
{
 | 
			
		||||
  setAcceptDrops(true);
 | 
			
		||||
  setScene(scene);
 | 
			
		||||
  setObjectName(name);
 | 
			
		||||
@ -54,7 +57,8 @@ QtkWidget::QtkWidget(QWidget * parent, const QString & name, Scene * scene) :
 | 
			
		||||
  setFocusPolicy(Qt::ClickFocus);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QtkWidget::~QtkWidget() {
 | 
			
		||||
QtkWidget::~QtkWidget()
 | 
			
		||||
{
 | 
			
		||||
  makeCurrent();
 | 
			
		||||
  teardownGL();
 | 
			
		||||
}
 | 
			
		||||
@ -63,7 +67,8 @@ QtkWidget::~QtkWidget() {
 | 
			
		||||
 * Public Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
QAction * QtkWidget::getActionToggleConsole() {
 | 
			
		||||
QAction * QtkWidget::getActionToggleConsole()
 | 
			
		||||
{
 | 
			
		||||
  auto action = new QAction(mScene->getSceneName() + " debug console");
 | 
			
		||||
  action->setCheckable(true);
 | 
			
		||||
  action->setChecked(mConsoleActive);
 | 
			
		||||
@ -72,7 +77,8 @@ QAction * QtkWidget::getActionToggleConsole() {
 | 
			
		||||
  return action;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::initializeGL() {
 | 
			
		||||
void QtkWidget::initializeGL()
 | 
			
		||||
{
 | 
			
		||||
  initializeOpenGLFunctions();
 | 
			
		||||
  // Connect the frameSwapped signal to call the update() function
 | 
			
		||||
  connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
 | 
			
		||||
@ -82,8 +88,7 @@ void QtkWidget::initializeGL() {
 | 
			
		||||
  mDebugLogger = new QOpenGLDebugLogger(this);
 | 
			
		||||
  if (mDebugLogger->initialize()) {
 | 
			
		||||
    qDebug() << "GL_DEBUG Debug Logger" << mDebugLogger << "\n";
 | 
			
		||||
    connect(
 | 
			
		||||
        mDebugLogger, SIGNAL(messageLogged(QOpenGLDebugMessage)), this,
 | 
			
		||||
    connect(mDebugLogger, SIGNAL(messageLogged(QOpenGLDebugMessage)), this,
 | 
			
		||||
            SLOT(messageLogged(QOpenGLDebugMessage)));
 | 
			
		||||
    mDebugLogger->startLogging();
 | 
			
		||||
  }
 | 
			
		||||
@ -101,13 +106,15 @@ void QtkWidget::initializeGL() {
 | 
			
		||||
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::resizeGL(int width, int height) {
 | 
			
		||||
void QtkWidget::resizeGL(int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  Scene::getProjectionMatrix().setToIdentity();
 | 
			
		||||
  Scene::getProjectionMatrix().perspective(
 | 
			
		||||
      45.0f, float(width) / float(height), 0.1f, 1000.0f);
 | 
			
		||||
  Scene::getProjectionMatrix().perspective(45.0f, float(width) / float(height),
 | 
			
		||||
                                           0.1f, 1000.0f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::paintGL() {
 | 
			
		||||
void QtkWidget::paintGL()
 | 
			
		||||
{
 | 
			
		||||
  // Clear buffers and draw the scene if it is valid.
 | 
			
		||||
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 | 
			
		||||
  if (mScene != Q_NULLPTR) {
 | 
			
		||||
@ -115,11 +122,11 @@ void QtkWidget::paintGL() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::setScene(Scene * scene) {
 | 
			
		||||
void QtkWidget::setScene(Scene * scene)
 | 
			
		||||
{
 | 
			
		||||
  if (mScene != Q_NULLPTR) {
 | 
			
		||||
    delete mScene;
 | 
			
		||||
    connect(
 | 
			
		||||
        scene, &Scene::sceneUpdated, MainWindow::getMainWindow(),
 | 
			
		||||
    connect(scene, &Scene::sceneUpdated, MainWindow::getMainWindow(),
 | 
			
		||||
            &MainWindow::refreshScene);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -131,7 +138,8 @@ void QtkWidget::setScene(Scene * scene) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::toggleConsole() {
 | 
			
		||||
void QtkWidget::toggleConsole()
 | 
			
		||||
{
 | 
			
		||||
  if (mConsoleActive) {
 | 
			
		||||
    mConsole->setHidden(true);
 | 
			
		||||
    mConsoleActive = false;
 | 
			
		||||
@ -147,13 +155,15 @@ void QtkWidget::toggleConsole() {
 | 
			
		||||
 * Protected Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void QtkWidget::dragEnterEvent(QDragEnterEvent * event) {
 | 
			
		||||
void QtkWidget::dragEnterEvent(QDragEnterEvent * event)
 | 
			
		||||
{
 | 
			
		||||
  if (event->mimeData()->hasFormat("text/plain")) {
 | 
			
		||||
    event->acceptProposedAction();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::dropEvent(QDropEvent * event) {
 | 
			
		||||
void QtkWidget::dropEvent(QDropEvent * event)
 | 
			
		||||
{
 | 
			
		||||
  mConsole->sendLog(event->mimeData()->text());
 | 
			
		||||
  auto urls = event->mimeData()->urls();
 | 
			
		||||
  if (!urls.isEmpty()) {
 | 
			
		||||
@ -175,7 +185,8 @@ void QtkWidget::dropEvent(QDropEvent * event) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::keyPressEvent(QKeyEvent * event) {
 | 
			
		||||
void QtkWidget::keyPressEvent(QKeyEvent * event)
 | 
			
		||||
{
 | 
			
		||||
  if (event->isAutoRepeat()) {
 | 
			
		||||
    // Do not repeat input while a key is held down
 | 
			
		||||
    event->ignore();
 | 
			
		||||
@ -184,7 +195,8 @@ void QtkWidget::keyPressEvent(QKeyEvent * event) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::keyReleaseEvent(QKeyEvent * event) {
 | 
			
		||||
void QtkWidget::keyReleaseEvent(QKeyEvent * event)
 | 
			
		||||
{
 | 
			
		||||
  if (event->isAutoRepeat()) {
 | 
			
		||||
    event->ignore();
 | 
			
		||||
  } else {
 | 
			
		||||
@ -192,15 +204,18 @@ void QtkWidget::keyReleaseEvent(QKeyEvent * event) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::mousePressEvent(QMouseEvent * event) {
 | 
			
		||||
void QtkWidget::mousePressEvent(QMouseEvent * event)
 | 
			
		||||
{
 | 
			
		||||
  Input::registerMousePress(event->button());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::mouseReleaseEvent(QMouseEvent * event) {
 | 
			
		||||
void QtkWidget::mouseReleaseEvent(QMouseEvent * event)
 | 
			
		||||
{
 | 
			
		||||
  Input::registerMouseRelease(event->button());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::update() {
 | 
			
		||||
void QtkWidget::update()
 | 
			
		||||
{
 | 
			
		||||
  updateCameraInput();
 | 
			
		||||
 | 
			
		||||
  if (mScene != Q_NULLPTR) {
 | 
			
		||||
@ -210,7 +225,8 @@ void QtkWidget::update() {
 | 
			
		||||
  QWidget::update();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::messageLogged(const QOpenGLDebugMessage & msg) {
 | 
			
		||||
void QtkWidget::messageLogged(const QOpenGLDebugMessage & msg)
 | 
			
		||||
{
 | 
			
		||||
  QString error;
 | 
			
		||||
 | 
			
		||||
  DebugContext context;
 | 
			
		||||
@ -282,10 +298,12 @@ void QtkWidget::messageLogged(const QOpenGLDebugMessage & msg) {
 | 
			
		||||
 * Private Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void QtkWidget::teardownGL() { /* Nothing to teardown yet... */
 | 
			
		||||
void QtkWidget::teardownGL()
 | 
			
		||||
{ /* Nothing to teardown yet... */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::updateCameraInput() {
 | 
			
		||||
void QtkWidget::updateCameraInput()
 | 
			
		||||
{
 | 
			
		||||
  Input::update();
 | 
			
		||||
  // Camera Transformation
 | 
			
		||||
  if (Input::buttonPressed(Qt::LeftButton)
 | 
			
		||||
@ -323,7 +341,8 @@ void QtkWidget::updateCameraInput() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkWidget::printContextInformation() {
 | 
			
		||||
void QtkWidget::printContextInformation()
 | 
			
		||||
{
 | 
			
		||||
  QString glType;
 | 
			
		||||
  QString glVersion;
 | 
			
		||||
  QString glProfile;
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,8 @@
 | 
			
		||||
#include <qtk/qtkapi.h>
 | 
			
		||||
#include <qtk/scene.h>
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  class DebugConsole;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@ -29,7 +30,8 @@ namespace Qtk {
 | 
			
		||||
   * 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 QtkWidget : public QOpenGLWidget, protected QOpenGLFunctions {
 | 
			
		||||
  class QtkWidget : public QOpenGLWidget, protected QOpenGLFunctions
 | 
			
		||||
  {
 | 
			
		||||
      Q_OBJECT;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
@ -103,7 +105,8 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Pointer to the QOpenGLDebugLogger attached to this widget.
 | 
			
		||||
       */
 | 
			
		||||
      inline QOpenGLDebugLogger * getOpenGLDebugLogger() {
 | 
			
		||||
      inline QOpenGLDebugLogger * getOpenGLDebugLogger()
 | 
			
		||||
      {
 | 
			
		||||
        return mDebugLogger;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -16,12 +16,14 @@
 | 
			
		||||
 | 
			
		||||
using namespace Qtk;
 | 
			
		||||
 | 
			
		||||
ToolBox::ToolBox(QWidget * parent) : QDockWidget(parent), ui(new Ui::ToolBox) {
 | 
			
		||||
ToolBox::ToolBox(QWidget * parent) : QDockWidget(parent), ui(new Ui::ToolBox)
 | 
			
		||||
{
 | 
			
		||||
  ui->setupUi(this);
 | 
			
		||||
  setMinimumWidth(350);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ToolBox::updateFocus(const QString & name) {
 | 
			
		||||
void ToolBox::updateFocus(const QString & name)
 | 
			
		||||
{
 | 
			
		||||
  auto object =
 | 
			
		||||
      MainWindow::getMainWindow()->getQtkWidget()->getScene()->getObject(name);
 | 
			
		||||
  if (object != Q_NULLPTR) {
 | 
			
		||||
@ -31,11 +33,13 @@ void ToolBox::updateFocus(const QString & name) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ToolBox::~ToolBox() {
 | 
			
		||||
ToolBox::~ToolBox()
 | 
			
		||||
{
 | 
			
		||||
  delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ToolBox::removePages() {
 | 
			
		||||
void ToolBox::removePages()
 | 
			
		||||
{
 | 
			
		||||
  // Remove all existing pages.
 | 
			
		||||
  for (size_t i = 0; i < ui->toolBox->count(); i++) {
 | 
			
		||||
    delete ui->toolBox->widget(i);
 | 
			
		||||
@ -43,7 +47,8 @@ void ToolBox::removePages() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ToolBox::createPageProperties(const Object * object) {
 | 
			
		||||
void ToolBox::createPageProperties(const Object * object)
 | 
			
		||||
{
 | 
			
		||||
  auto transform = object->getTransform();
 | 
			
		||||
  auto type = object->getType();
 | 
			
		||||
  auto * widget = new QWidget;
 | 
			
		||||
@ -51,11 +56,10 @@ void ToolBox::createPageProperties(const Object * object) {
 | 
			
		||||
  ui->toolBox->setCurrentWidget(widget);
 | 
			
		||||
 | 
			
		||||
  auto * layout = new QFormLayout;
 | 
			
		||||
  layout->addRow(
 | 
			
		||||
      new QLabel(tr("Name:")), new QLabel(object->getName().c_str()));
 | 
			
		||||
  layout->addRow(new QLabel(tr("Name:")),
 | 
			
		||||
                 new QLabel(object->getName().c_str()));
 | 
			
		||||
 | 
			
		||||
  layout->addRow(
 | 
			
		||||
      new QLabel(tr("Type:")),
 | 
			
		||||
  layout->addRow(new QLabel(tr("Type:")),
 | 
			
		||||
                 new QLabel(type == Object::Type::QTK_MESH ? "Mesh" : "Model"));
 | 
			
		||||
 | 
			
		||||
  auto rowLayout = new QHBoxLayout;
 | 
			
		||||
@ -70,16 +74,13 @@ void ToolBox::createPageProperties(const Object * object) {
 | 
			
		||||
    rowLayout->addWidget(spinBox);
 | 
			
		||||
 | 
			
		||||
    if (i == 0) {
 | 
			
		||||
      connect(
 | 
			
		||||
          spinBox, &QDoubleSpinBox::valueChanged, object,
 | 
			
		||||
      connect(spinBox, &QDoubleSpinBox::valueChanged, object,
 | 
			
		||||
              &Object::setTranslationX);
 | 
			
		||||
    } else if (i == 1) {
 | 
			
		||||
      connect(
 | 
			
		||||
          spinBox, &QDoubleSpinBox::valueChanged, object,
 | 
			
		||||
      connect(spinBox, &QDoubleSpinBox::valueChanged, object,
 | 
			
		||||
              &Object::setTranslationY);
 | 
			
		||||
    } else if (i == 2) {
 | 
			
		||||
      connect(
 | 
			
		||||
          spinBox, &QDoubleSpinBox::valueChanged, object,
 | 
			
		||||
      connect(spinBox, &QDoubleSpinBox::valueChanged, object,
 | 
			
		||||
              &Object::setTranslationZ);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -96,21 +97,22 @@ void ToolBox::createPageProperties(const Object * object) {
 | 
			
		||||
    rowLayout->addWidget(spinBox);
 | 
			
		||||
 | 
			
		||||
    if (i == 0) {
 | 
			
		||||
      connect(
 | 
			
		||||
          spinBox, &QDoubleSpinBox::valueChanged, object, &Object::setScaleX);
 | 
			
		||||
      connect(spinBox, &QDoubleSpinBox::valueChanged, object,
 | 
			
		||||
              &Object::setScaleX);
 | 
			
		||||
    } else if (i == 1) {
 | 
			
		||||
      connect(
 | 
			
		||||
          spinBox, &QDoubleSpinBox::valueChanged, object, &Object::setScaleY);
 | 
			
		||||
      connect(spinBox, &QDoubleSpinBox::valueChanged, object,
 | 
			
		||||
              &Object::setScaleY);
 | 
			
		||||
    } else if (i == 2) {
 | 
			
		||||
      connect(
 | 
			
		||||
          spinBox, &QDoubleSpinBox::valueChanged, object, &Object::setScaleZ);
 | 
			
		||||
      connect(spinBox, &QDoubleSpinBox::valueChanged, object,
 | 
			
		||||
              &Object::setScaleZ);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  layout->addRow(rowLayout);
 | 
			
		||||
  widget->setLayout(layout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ToolBox::createPageShader(const Object * object) {
 | 
			
		||||
void ToolBox::createPageShader(const Object * object)
 | 
			
		||||
{
 | 
			
		||||
  // Shaders page.
 | 
			
		||||
  auto widget = new QWidget;
 | 
			
		||||
  ui->toolBox->addItem(widget, "Shaders");
 | 
			
		||||
 | 
			
		||||
@ -18,12 +18,15 @@
 | 
			
		||||
 | 
			
		||||
#include "qtk/scene.h"
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
namespace Ui
 | 
			
		||||
{
 | 
			
		||||
  class ToolBox;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
  class ToolBox : public QDockWidget {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  class ToolBox : public QDockWidget
 | 
			
		||||
  {
 | 
			
		||||
      Q_OBJECT
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
@ -16,14 +16,15 @@
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
Qtk::TreeView::TreeView(QWidget * parent) :
 | 
			
		||||
    QDockWidget(parent), ui(new Ui::TreeView) {
 | 
			
		||||
    QDockWidget(parent), ui(new Ui::TreeView)
 | 
			
		||||
{
 | 
			
		||||
  ui->setupUi(this);
 | 
			
		||||
  connect(
 | 
			
		||||
      ui->treeWidget, &QTreeWidget::itemDoubleClicked, this,
 | 
			
		||||
  connect(ui->treeWidget, &QTreeWidget::itemDoubleClicked, this,
 | 
			
		||||
          &TreeView::itemFocus);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Qtk::TreeView::~TreeView() {
 | 
			
		||||
Qtk::TreeView::~TreeView()
 | 
			
		||||
{
 | 
			
		||||
  delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,7 +32,8 @@ Qtk::TreeView::~TreeView() {
 | 
			
		||||
 * Public Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void Qtk::TreeView::updateView(const Qtk::Scene * scene) {
 | 
			
		||||
void Qtk::TreeView::updateView(const Qtk::Scene * scene)
 | 
			
		||||
{
 | 
			
		||||
  ui->treeWidget->clear();
 | 
			
		||||
  ui->treeWidget->setColumnCount(1);
 | 
			
		||||
  mSceneName = scene->getSceneName();
 | 
			
		||||
@ -43,7 +45,8 @@ void Qtk::TreeView::updateView(const Qtk::Scene * scene) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column) {
 | 
			
		||||
void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column)
 | 
			
		||||
{
 | 
			
		||||
  QString name = item->text(column);
 | 
			
		||||
  auto scene = MainWindow::getMainWindow()->getQtkWidget()->getScene();
 | 
			
		||||
  auto & transform = Qtk::Scene::getCamera().getTransform();
 | 
			
		||||
 | 
			
		||||
@ -17,12 +17,15 @@
 | 
			
		||||
#include <qtk/scene.h>
 | 
			
		||||
#include <QTreeWidgetItem>
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
namespace Ui
 | 
			
		||||
{
 | 
			
		||||
  class TreeView;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
  class TreeView : public QDockWidget {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  class TreeView : public QDockWidget
 | 
			
		||||
  {
 | 
			
		||||
      Q_OBJECT
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
@ -19,12 +19,13 @@
 | 
			
		||||
 * Constructors, Destructors
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
WidgetPlugin::WidgetPlugin(
 | 
			
		||||
    QString group, QString class_name, QString include,
 | 
			
		||||
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(m_className) {}
 | 
			
		||||
    m_group(std::move(group)), m_className(std::move(class_name)),
 | 
			
		||||
    m_includeFile(std::move(include)), m_factory(std::move(factory)),
 | 
			
		||||
    m_objectName(m_className)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WidgetPlugin::WidgetPlugin(QObject * parent) : QObject(parent) {}
 | 
			
		||||
 | 
			
		||||
@ -32,50 +33,61 @@ WidgetPlugin::WidgetPlugin(QObject * parent) : QObject(parent) {}
 | 
			
		||||
 * Public Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
QString WidgetPlugin::group() const {
 | 
			
		||||
QString WidgetPlugin::group() const
 | 
			
		||||
{
 | 
			
		||||
  return m_group;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString WidgetPlugin::name() const {
 | 
			
		||||
QString WidgetPlugin::name() const
 | 
			
		||||
{
 | 
			
		||||
  return m_className;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString WidgetPlugin::includeFile() const {
 | 
			
		||||
QString WidgetPlugin::includeFile() const
 | 
			
		||||
{
 | 
			
		||||
  return m_includeFile;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QWidget * WidgetPlugin::createWidget(QWidget * parent) {
 | 
			
		||||
QWidget * WidgetPlugin::createWidget(QWidget * parent)
 | 
			
		||||
{
 | 
			
		||||
  return m_factory(parent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString WidgetPlugin::toolTip() const {
 | 
			
		||||
QString WidgetPlugin::toolTip() const
 | 
			
		||||
{
 | 
			
		||||
  return QStringLiteral("A custom widget tool tip.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString WidgetPlugin::whatsThis() const {
 | 
			
		||||
QString WidgetPlugin::whatsThis() const
 | 
			
		||||
{
 | 
			
		||||
  return QStringLiteral("Custom widget what's this?");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QIcon WidgetPlugin::icon() const {
 | 
			
		||||
QIcon WidgetPlugin::icon() const
 | 
			
		||||
{
 | 
			
		||||
  return Qtk::getIcon();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool WidgetPlugin::isContainer() const {
 | 
			
		||||
bool WidgetPlugin::isContainer() const
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool WidgetPlugin::isInitialized() const {
 | 
			
		||||
bool WidgetPlugin::isInitialized() const
 | 
			
		||||
{
 | 
			
		||||
  return m_initialized;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WidgetPlugin::initialize(QDesignerFormEditorInterface *) {
 | 
			
		||||
void WidgetPlugin::initialize(QDesignerFormEditorInterface *)
 | 
			
		||||
{
 | 
			
		||||
  if (m_initialized) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  m_initialized = true;
 | 
			
		||||
}
 | 
			
		||||
QString WidgetPlugin::domXml() const {
 | 
			
		||||
QString WidgetPlugin::domXml() const
 | 
			
		||||
{
 | 
			
		||||
  return
 | 
			
		||||
      "<ui language=\"c++\">\n"
 | 
			
		||||
       " <widget class=\"" + m_className + "\" name=\"" + m_objectName + "\">\n"
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,8 @@
 | 
			
		||||
 | 
			
		||||
class QDESIGNER_WIDGET_EXPORT WidgetPlugin :
 | 
			
		||||
    public QObject,
 | 
			
		||||
    public QDesignerCustomWidgetInterface {
 | 
			
		||||
    public QDesignerCustomWidgetInterface
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
    Q_INTERFACES(QDesignerCustomWidgetInterface)
 | 
			
		||||
 | 
			
		||||
@ -26,8 +27,8 @@ class QDESIGNER_WIDGET_EXPORT WidgetPlugin :
 | 
			
		||||
     * Contructors / Destructors
 | 
			
		||||
     **************************************************************************/
 | 
			
		||||
 | 
			
		||||
    WidgetPlugin(
 | 
			
		||||
        QString group, QString class_name, QString include, Factory factory);
 | 
			
		||||
    WidgetPlugin(QString group, QString class_name, QString include,
 | 
			
		||||
                 Factory factory);
 | 
			
		||||
 | 
			
		||||
    explicit WidgetPlugin(QObject * parent = nullptr);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,8 @@
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
WidgetPluginCollection::WidgetPluginCollection(QObject * parent) :
 | 
			
		||||
    QObject(parent), m_collectionName("Qtk Widget Collection") {
 | 
			
		||||
    QObject(parent), m_collectionName("Qtk Widget Collection")
 | 
			
		||||
{
 | 
			
		||||
  m_collection = {
 | 
			
		||||
      new WidgetPlugin(
 | 
			
		||||
          m_collectionName, "Qtk::QtkWidget", "qtkwidget.h",
 | 
			
		||||
@ -38,6 +39,7 @@ WidgetPluginCollection::WidgetPluginCollection(QObject * parent) :
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
QList<QDesignerCustomWidgetInterface *> WidgetPluginCollection::customWidgets()
 | 
			
		||||
    const {
 | 
			
		||||
    const
 | 
			
		||||
{
 | 
			
		||||
  return m_collection;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,8 @@
 | 
			
		||||
 | 
			
		||||
class WidgetPluginCollection :
 | 
			
		||||
    public QObject,
 | 
			
		||||
    public QDesignerCustomWidgetCollectionInterface {
 | 
			
		||||
    public QDesignerCustomWidgetCollectionInterface
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
    // Since we're exporting a collection, this is the only plugin metadata
 | 
			
		||||
    // needed. We don't need this for-each widget in the collection.
 | 
			
		||||
@ -36,7 +37,8 @@ class WidgetPluginCollection :
 | 
			
		||||
    /**
 | 
			
		||||
     * @return QList of all custom widgets pointers.
 | 
			
		||||
     */
 | 
			
		||||
    [[nodiscard]] QList<QDesignerCustomWidgetInterface *> customWidgets() const override;
 | 
			
		||||
    [[nodiscard]] QList<QDesignerCustomWidgetInterface *> customWidgets()
 | 
			
		||||
        const override;
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    /***************************************************************************
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,8 @@ const QVector3D Camera3D::LocalRight(1.0f, 0.0f, 0.0f);
 | 
			
		||||
 * Public Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
const QMatrix4x4 & Camera3D::toMatrix() {
 | 
			
		||||
const QMatrix4x4 & Camera3D::toMatrix()
 | 
			
		||||
{
 | 
			
		||||
  mWorld.setToIdentity();
 | 
			
		||||
  // Qt6 renamed QMatrix4x4::conjugate() to conjugated()
 | 
			
		||||
  mWorld.rotate(mTransform.getRotation().conjugated());
 | 
			
		||||
@ -34,17 +35,20 @@ const QMatrix4x4 & Camera3D::toMatrix() {
 | 
			
		||||
 * Qt Streams
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
QDataStream & operator<<(QDataStream & out, Camera3D & transform) {
 | 
			
		||||
QDataStream & operator<<(QDataStream & out, Camera3D & transform)
 | 
			
		||||
{
 | 
			
		||||
  out << transform.getTransform();
 | 
			
		||||
  return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QDataStream & operator>>(QDataStream & in, Camera3D & transform) {
 | 
			
		||||
QDataStream & operator>>(QDataStream & in, Camera3D & transform)
 | 
			
		||||
{
 | 
			
		||||
  in >> transform.getTransform();
 | 
			
		||||
  return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QDebug operator<<(QDebug dbg, const Camera3D & transform) {
 | 
			
		||||
QDebug operator<<(QDebug dbg, const Camera3D & transform)
 | 
			
		||||
{
 | 
			
		||||
  dbg << "Camera3D\n{\n";
 | 
			
		||||
  dbg << "Position: <" << transform.getTranslation().x() << ", "
 | 
			
		||||
      << transform.getTranslation().y() << ", "
 | 
			
		||||
 | 
			
		||||
@ -14,8 +14,10 @@
 | 
			
		||||
#include "qtkapi.h"
 | 
			
		||||
#include "transform3D.h"
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
  class QTKAPI Camera3D {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  class QTKAPI Camera3D
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Static Public Constants
 | 
			
		||||
@ -37,35 +39,40 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Current translation of the camera as a QVector3D.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline const QVector3D & getTranslation() const {
 | 
			
		||||
      [[nodiscard]] inline const QVector3D & getTranslation() const
 | 
			
		||||
      {
 | 
			
		||||
        return mTransform.getTranslation();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Current rotation of this camera as a QQuaternion.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline const QQuaternion & getRotation() const {
 | 
			
		||||
      [[nodiscard]] inline const QQuaternion & getRotation() const
 | 
			
		||||
      {
 | 
			
		||||
        return mTransform.getRotation();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @return QVector3D for the forward vector of the camera.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline QVector3D getForward() const {
 | 
			
		||||
      [[nodiscard]] inline QVector3D getForward() const
 | 
			
		||||
      {
 | 
			
		||||
        return mTransform.getRotation().rotatedVector(LocalForward);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @return QVector3D for the right vector of the camera.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline QVector3D getRight() const {
 | 
			
		||||
      [[nodiscard]] inline QVector3D getRight() const
 | 
			
		||||
      {
 | 
			
		||||
        return mTransform.getRotation().rotatedVector(LocalRight);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @return QVector3D for the up vector of the camera.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline QVector3D getUp() const {
 | 
			
		||||
      [[nodiscard]] inline QVector3D getUp() const
 | 
			
		||||
      {
 | 
			
		||||
        return mTransform.getRotation().rotatedVector(LocalUp);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -33,10 +33,13 @@ template <typename T> struct InputInstance : std::pair<T, Input::InputState> {
 | 
			
		||||
    inline InputInstance(T value) : base_class(value, Input::InputInvalid) {}
 | 
			
		||||
 | 
			
		||||
    inline InputInstance(T value, Input::InputState state) :
 | 
			
		||||
        base_class(value, state) {}
 | 
			
		||||
        base_class(value, state)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Allows use of std::find to search for a key's InputInstance
 | 
			
		||||
    inline bool operator==(const InputInstance & rhs) const {
 | 
			
		||||
    inline bool operator==(const InputInstance & rhs) const
 | 
			
		||||
    {
 | 
			
		||||
      return this->first == rhs.first;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@ -67,7 +70,8 @@ static QPoint sg_mouseDelta;
 | 
			
		||||
 * @param value The key to search for.
 | 
			
		||||
 * @return Iterator to the found element or the end iterator if not found.
 | 
			
		||||
 */
 | 
			
		||||
static inline KeyContainer::iterator FindKey(Qt::Key value) {
 | 
			
		||||
static inline KeyContainer::iterator FindKey(Qt::Key value)
 | 
			
		||||
{
 | 
			
		||||
  return std::find(sg_keyInstances.begin(), sg_keyInstances.end(), value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -77,7 +81,8 @@ static inline KeyContainer::iterator FindKey(Qt::Key value) {
 | 
			
		||||
 * @param value The mouse button to search for.
 | 
			
		||||
 * @return Iterator to the found element or the end iterator if not found.
 | 
			
		||||
 */
 | 
			
		||||
static inline ButtonContainer::iterator FindButton(Qt::MouseButton value) {
 | 
			
		||||
static inline ButtonContainer::iterator FindButton(Qt::MouseButton value)
 | 
			
		||||
{
 | 
			
		||||
  return std::find(sg_buttonInstances.begin(), sg_buttonInstances.end(), value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -89,7 +94,8 @@ static inline ButtonContainer::iterator FindButton(Qt::MouseButton value) {
 | 
			
		||||
 * @return True if the InputInstance is in the released state.
 | 
			
		||||
 */
 | 
			
		||||
template <typename TPair>
 | 
			
		||||
static inline bool CheckReleased(const TPair & instance) {
 | 
			
		||||
static inline bool CheckReleased(const TPair & instance)
 | 
			
		||||
{
 | 
			
		||||
  return instance.second == Input::InputReleased;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -99,7 +105,8 @@ static inline bool CheckReleased(const TPair & instance) {
 | 
			
		||||
 * @tparam TPair KeyInstance or ButtonInstance.
 | 
			
		||||
 * @param instance The InputInstance to update.
 | 
			
		||||
 */
 | 
			
		||||
template <typename TPair> static inline void UpdateStates(TPair & instance) {
 | 
			
		||||
template <typename TPair> static inline void UpdateStates(TPair & instance)
 | 
			
		||||
{
 | 
			
		||||
  switch (instance.second) {
 | 
			
		||||
    case Input::InputRegistered:
 | 
			
		||||
      instance.second = Input::InputTriggered;
 | 
			
		||||
@ -121,7 +128,8 @@ template <typename TPair> static inline void UpdateStates(TPair & instance) {
 | 
			
		||||
 * @tparam Container The type of container, KeyContainer or ButtonContainer.
 | 
			
		||||
 * @param container The InputInstance container to update.
 | 
			
		||||
 */
 | 
			
		||||
template <typename Container> static inline void Update(Container & container) {
 | 
			
		||||
template <typename Container> static inline void Update(Container & container)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename Container::iterator Iter;
 | 
			
		||||
  typedef typename Container::value_type TPair;
 | 
			
		||||
 | 
			
		||||
@ -138,7 +146,8 @@ template <typename Container> static inline void Update(Container & container) {
 | 
			
		||||
 * Static Public Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void Input::update() {
 | 
			
		||||
void Input::update()
 | 
			
		||||
{
 | 
			
		||||
  // Update Mouse Delta
 | 
			
		||||
  sg_mousePrevPosition = sg_mouseCurrPosition;
 | 
			
		||||
  sg_mouseCurrPosition = QCursor::pos();
 | 
			
		||||
@ -149,53 +158,62 @@ void Input::update() {
 | 
			
		||||
  Update(sg_keyInstances);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Input::registerKeyPress(int k) {
 | 
			
		||||
void Input::registerKeyPress(int k)
 | 
			
		||||
{
 | 
			
		||||
  auto it = FindKey((Qt::Key)k);
 | 
			
		||||
  if (it == sg_keyInstances.end()) {
 | 
			
		||||
    sg_keyInstances.emplace_back((Qt::Key)k, InputRegistered);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Input::registerKeyRelease(int k) {
 | 
			
		||||
void Input::registerKeyRelease(int k)
 | 
			
		||||
{
 | 
			
		||||
  auto it = FindKey((Qt::Key)k);
 | 
			
		||||
  if (it != sg_keyInstances.end()) {
 | 
			
		||||
    it->second = InputUnregistered;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Input::registerMousePress(Qt::MouseButton button) {
 | 
			
		||||
void Input::registerMousePress(Qt::MouseButton button)
 | 
			
		||||
{
 | 
			
		||||
  auto it = FindButton(button);
 | 
			
		||||
  if (it == sg_buttonInstances.end()) {
 | 
			
		||||
    sg_buttonInstances.emplace_back(button, InputRegistered);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Input::registerMouseRelease(Qt::MouseButton button) {
 | 
			
		||||
void Input::registerMouseRelease(Qt::MouseButton button)
 | 
			
		||||
{
 | 
			
		||||
  auto it = FindButton(button);
 | 
			
		||||
  if (it != sg_buttonInstances.end()) {
 | 
			
		||||
    it->second = InputUnregistered;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Input::reset() {
 | 
			
		||||
void Input::reset()
 | 
			
		||||
{
 | 
			
		||||
  sg_keyInstances.clear();
 | 
			
		||||
  sg_buttonInstances.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Input::InputState Input::keyState(Qt::Key k) {
 | 
			
		||||
Input::InputState Input::keyState(Qt::Key k)
 | 
			
		||||
{
 | 
			
		||||
  auto it = FindKey(k);
 | 
			
		||||
  return (it != sg_keyInstances.end()) ? it->second : InputInvalid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Input::InputState Input::buttonState(Qt::MouseButton button) {
 | 
			
		||||
Input::InputState Input::buttonState(Qt::MouseButton button)
 | 
			
		||||
{
 | 
			
		||||
  auto it = FindButton(button);
 | 
			
		||||
  return (it != sg_buttonInstances.end()) ? it->second : InputInvalid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QPoint Input::mousePosition() {
 | 
			
		||||
QPoint Input::mousePosition()
 | 
			
		||||
{
 | 
			
		||||
  return QCursor::pos();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QPoint Input::mouseDelta() {
 | 
			
		||||
QPoint Input::mouseDelta()
 | 
			
		||||
{
 | 
			
		||||
  return sg_mouseDelta;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -14,8 +14,10 @@
 | 
			
		||||
 | 
			
		||||
#include "qtkapi.h"
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
  class QTKAPI Input {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  class QTKAPI Input
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Typedefs
 | 
			
		||||
@ -84,7 +86,8 @@ namespace Qtk {
 | 
			
		||||
       * @param key Key to check state.
 | 
			
		||||
       * @return True if the key is in InputTriggered state.
 | 
			
		||||
       */
 | 
			
		||||
      inline static bool keyTriggered(Qt::Key key) {
 | 
			
		||||
      inline static bool keyTriggered(Qt::Key key)
 | 
			
		||||
      {
 | 
			
		||||
        return keyState(key) == InputTriggered;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -92,7 +95,8 @@ namespace Qtk {
 | 
			
		||||
       * @param key Key to check state.
 | 
			
		||||
       * @return True if the key is in InputPressed state.
 | 
			
		||||
       */
 | 
			
		||||
      inline static bool keyPressed(Qt::Key key) {
 | 
			
		||||
      inline static bool keyPressed(Qt::Key key)
 | 
			
		||||
      {
 | 
			
		||||
        return keyState(key) == InputPressed;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -100,7 +104,8 @@ namespace Qtk {
 | 
			
		||||
       * @param key Key to check state.
 | 
			
		||||
       * @return True if the key is in InputReleased state.
 | 
			
		||||
       */
 | 
			
		||||
      inline static bool keyReleased(Qt::Key key) {
 | 
			
		||||
      inline static bool keyReleased(Qt::Key key)
 | 
			
		||||
      {
 | 
			
		||||
        return keyState(key) == InputReleased;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -108,7 +113,8 @@ namespace Qtk {
 | 
			
		||||
       * @param button Mouse button to check state.
 | 
			
		||||
       * @return True if the key is in InputTriggered state.
 | 
			
		||||
       */
 | 
			
		||||
      inline static bool buttonTriggered(Qt::MouseButton button) {
 | 
			
		||||
      inline static bool buttonTriggered(Qt::MouseButton button)
 | 
			
		||||
      {
 | 
			
		||||
        return buttonState(button) == InputTriggered;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -116,7 +122,8 @@ namespace Qtk {
 | 
			
		||||
       * @param button Mouse button to check state.
 | 
			
		||||
       * @return True if the key is in InputPressed state.
 | 
			
		||||
       */
 | 
			
		||||
      inline static bool buttonPressed(Qt::MouseButton button) {
 | 
			
		||||
      inline static bool buttonPressed(Qt::MouseButton button)
 | 
			
		||||
      {
 | 
			
		||||
        return buttonState(button) == InputPressed;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -124,7 +131,8 @@ namespace Qtk {
 | 
			
		||||
       * @param button Mouse button to check state.
 | 
			
		||||
       * @return True if the key is in InputReleased state.
 | 
			
		||||
       */
 | 
			
		||||
      inline static bool buttonReleased(Qt::MouseButton button) {
 | 
			
		||||
      inline static bool buttonReleased(Qt::MouseButton button)
 | 
			
		||||
      {
 | 
			
		||||
        return buttonState(button) == InputReleased;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -21,23 +21,28 @@ Qtk::MeshRenderer::MeshManager Qtk::MeshRenderer::sInstances;
 | 
			
		||||
 * Constructors / Destructors
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
MeshRenderer::MeshRenderer(
 | 
			
		||||
    const char * name, Vertices vertices, Indices indices, DrawMode mode) :
 | 
			
		||||
    MeshRenderer(
 | 
			
		||||
        name, ShapeBase(mode, std::move(vertices), std::move(indices))) {}
 | 
			
		||||
MeshRenderer::MeshRenderer(const char * name, Vertices vertices,
 | 
			
		||||
                           Indices indices, DrawMode mode) :
 | 
			
		||||
    MeshRenderer(name, ShapeBase(mode, std::move(vertices), std::move(indices)))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MeshRenderer::MeshRenderer(const char * name) :
 | 
			
		||||
    MeshRenderer(name, Cube(QTK_DRAW_ELEMENTS)) {}
 | 
			
		||||
    MeshRenderer(name, Cube(QTK_DRAW_ELEMENTS))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape) :
 | 
			
		||||
    Object(name, shape, QTK_MESH), mVertexShader(":/shaders/multi-color.vert"),
 | 
			
		||||
    mFragmentShader(":/shaders/multi-color.frag"), mDrawType(GL_TRIANGLES) {
 | 
			
		||||
    mFragmentShader(":/shaders/multi-color.frag"), mDrawType(GL_TRIANGLES)
 | 
			
		||||
{
 | 
			
		||||
  mShape = Shape(shape);
 | 
			
		||||
  init();
 | 
			
		||||
  sInstances.insert(name, this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MeshRenderer::~MeshRenderer() {
 | 
			
		||||
MeshRenderer::~MeshRenderer()
 | 
			
		||||
{
 | 
			
		||||
  sInstances.remove(mName.c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -45,7 +50,8 @@ MeshRenderer::~MeshRenderer() {
 | 
			
		||||
 * Public Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void MeshRenderer::init() {
 | 
			
		||||
void MeshRenderer::init()
 | 
			
		||||
{
 | 
			
		||||
  if (mVAO.isCreated()) {
 | 
			
		||||
    mVAO.destroy();
 | 
			
		||||
  }
 | 
			
		||||
@ -60,10 +66,10 @@ void MeshRenderer::init() {
 | 
			
		||||
  mVAO.bind();
 | 
			
		||||
 | 
			
		||||
  mProgram.create();
 | 
			
		||||
  mProgram.addShaderFromSourceFile(
 | 
			
		||||
      QOpenGLShader::Vertex, mVertexShader.c_str());
 | 
			
		||||
  mProgram.addShaderFromSourceFile(
 | 
			
		||||
      QOpenGLShader::Fragment, mFragmentShader.c_str());
 | 
			
		||||
  mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,
 | 
			
		||||
                                   mVertexShader.c_str());
 | 
			
		||||
  mProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,
 | 
			
		||||
                                   mFragmentShader.c_str());
 | 
			
		||||
  mProgram.link();
 | 
			
		||||
  mProgram.bind();
 | 
			
		||||
 | 
			
		||||
@ -84,9 +90,9 @@ void MeshRenderer::init() {
 | 
			
		||||
  mProgram.setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(QVector3D));
 | 
			
		||||
  // Enable color attribute, setting offset to total size of vertices()
 | 
			
		||||
  mProgram.enableAttributeArray(1);
 | 
			
		||||
  mProgram.setAttributeBuffer(
 | 
			
		||||
      1, GL_FLOAT, getVertices().size() * sizeof(getVertices()[0]), 3,
 | 
			
		||||
      sizeof(QVector3D));
 | 
			
		||||
  mProgram.setAttributeBuffer(1, GL_FLOAT,
 | 
			
		||||
                              getVertices().size() * sizeof(getVertices()[0]),
 | 
			
		||||
                              3, sizeof(QVector3D));
 | 
			
		||||
 | 
			
		||||
  mVBO.release();
 | 
			
		||||
 | 
			
		||||
@ -94,7 +100,8 @@ void MeshRenderer::init() {
 | 
			
		||||
  mVAO.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MeshRenderer::draw() {
 | 
			
		||||
void MeshRenderer::draw()
 | 
			
		||||
{
 | 
			
		||||
  bindShaders();
 | 
			
		||||
  mVAO.bind();
 | 
			
		||||
 | 
			
		||||
@ -107,11 +114,9 @@ void MeshRenderer::draw() {
 | 
			
		||||
 | 
			
		||||
  if (mShape.mDrawMode == QTK_DRAW_ARRAYS) {
 | 
			
		||||
    glDrawArrays(mDrawType, 0, getVertices().size());
 | 
			
		||||
  } else if(
 | 
			
		||||
      mShape.mDrawMode == QTK_DRAW_ELEMENTS
 | 
			
		||||
  } else if (mShape.mDrawMode == QTK_DRAW_ELEMENTS
 | 
			
		||||
             || mShape.mDrawMode == QTK_DRAW_ELEMENTS_NORMALS) {
 | 
			
		||||
    glDrawElements(
 | 
			
		||||
        mDrawType, mShape.mIndices.size(), GL_UNSIGNED_INT,
 | 
			
		||||
    glDrawElements(mDrawType, mShape.mIndices.size(), GL_UNSIGNED_INT,
 | 
			
		||||
                   mShape.mIndices.data());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -123,14 +128,16 @@ void MeshRenderer::draw() {
 | 
			
		||||
  releaseShaders();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MeshRenderer::enableAttributeArray(int location) {
 | 
			
		||||
void MeshRenderer::enableAttributeArray(int location)
 | 
			
		||||
{
 | 
			
		||||
  ShaderBindScope lock(&mProgram, mBound);
 | 
			
		||||
  mVAO.bind();
 | 
			
		||||
  mProgram.enableAttributeArray(location);
 | 
			
		||||
  mVAO.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MeshRenderer::reallocateTexCoords(const TexCoords & t, unsigned dims) {
 | 
			
		||||
void MeshRenderer::reallocateTexCoords(const TexCoords & t, unsigned dims)
 | 
			
		||||
{
 | 
			
		||||
  mVAO.bind();
 | 
			
		||||
  mNBO.destroy();
 | 
			
		||||
  mNBO.create();
 | 
			
		||||
@ -146,7 +153,8 @@ void MeshRenderer::reallocateTexCoords(const TexCoords & t, unsigned dims) {
 | 
			
		||||
  mVAO.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MeshRenderer::reallocateNormals(const Normals & n, unsigned dims) {
 | 
			
		||||
void MeshRenderer::reallocateNormals(const Normals & n, unsigned dims)
 | 
			
		||||
{
 | 
			
		||||
  // TODO: Store state to track if buffer objects are bound
 | 
			
		||||
  mVAO.bind();
 | 
			
		||||
  mNBO.destroy();
 | 
			
		||||
@ -163,27 +171,31 @@ void MeshRenderer::reallocateNormals(const Normals & n, unsigned dims) {
 | 
			
		||||
  mVAO.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MeshRenderer::setShaders(
 | 
			
		||||
    const std::string & vert, const std::string & frag) {
 | 
			
		||||
void MeshRenderer::setShaders(const std::string & vert,
 | 
			
		||||
                              const std::string & frag)
 | 
			
		||||
{
 | 
			
		||||
  mVertexShader = vert;
 | 
			
		||||
  mFragmentShader = frag;
 | 
			
		||||
  init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MeshRenderer::setUniformMVP(
 | 
			
		||||
    const char * model, const char * view, const char * projection) {
 | 
			
		||||
void MeshRenderer::setUniformMVP(const char * model, const char * view,
 | 
			
		||||
                                 const char * projection)
 | 
			
		||||
{
 | 
			
		||||
  ShaderBindScope lock(&mProgram, mBound);
 | 
			
		||||
  mProgram.setUniformValue(projection, Scene::getProjectionMatrix());
 | 
			
		||||
  mProgram.setUniformValue(view, Scene::getViewMatrix());
 | 
			
		||||
  mProgram.setUniformValue(model, mTransform.toMatrix());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MeshRenderer::setShape(const Shape & value) {
 | 
			
		||||
void MeshRenderer::setShape(const Shape & value)
 | 
			
		||||
{
 | 
			
		||||
  Object::setShape(value);
 | 
			
		||||
  init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MeshRenderer::setColor(const QVector3D & color) {
 | 
			
		||||
void MeshRenderer::setColor(const QVector3D & color)
 | 
			
		||||
{
 | 
			
		||||
  if (mShape.mColors.empty()) {
 | 
			
		||||
    for (const auto & vertex : mShape.getVertices()) {
 | 
			
		||||
      mShape.mColors.push_back(color);
 | 
			
		||||
@ -197,8 +209,9 @@ void MeshRenderer::setColor(const QVector3D & color) {
 | 
			
		||||
  init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MeshRenderer::setAttributeBuffer(
 | 
			
		||||
    int location, GLenum type, int offset, int tupleSize, int stride) {
 | 
			
		||||
void MeshRenderer::setAttributeBuffer(int location, GLenum type, int offset,
 | 
			
		||||
                                      int tupleSize, int stride)
 | 
			
		||||
{
 | 
			
		||||
  ShaderBindScope lock(&mProgram, mBound);
 | 
			
		||||
  mVAO.bind();
 | 
			
		||||
  mProgram.setAttributeBuffer(location, type, offset, tupleSize, stride);
 | 
			
		||||
@ -210,7 +223,8 @@ void MeshRenderer::setAttributeBuffer(
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
// Static member function to retrieve instances of MeshRenderers
 | 
			
		||||
MeshRenderer * MeshRenderer::getInstance(const QString & name) {
 | 
			
		||||
MeshRenderer * MeshRenderer::getInstance(const QString & name)
 | 
			
		||||
{
 | 
			
		||||
  if (!sInstances.contains(name)) {
 | 
			
		||||
#if QTK_DEBUG
 | 
			
		||||
    qDebug() << "Attempt to access MeshRenderer instance that does not exist! ("
 | 
			
		||||
 | 
			
		||||
@ -14,8 +14,10 @@
 | 
			
		||||
#include "qtkapi.h"
 | 
			
		||||
#include "shape.h"
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
  class QTKAPI MeshRenderer : public Object {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  class QTKAPI MeshRenderer : public Object
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Typedefs
 | 
			
		||||
@ -38,8 +40,7 @@ namespace Qtk {
 | 
			
		||||
       * @param indices Indicess to use for initializes geometry shape.
 | 
			
		||||
       * @param mode OpenGL draw mode. Supported modes are prefixed with QTK_*
 | 
			
		||||
       */
 | 
			
		||||
      MeshRenderer(
 | 
			
		||||
          const char * name, Vertices vertices, Indices indices,
 | 
			
		||||
      MeshRenderer(const char * name, Vertices vertices, Indices indices,
 | 
			
		||||
                   DrawMode mode = QTK_DRAW_ARRAYS);
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
@ -112,14 +113,16 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @param vert Path to vertex shader to use for this MeshRenderer.
 | 
			
		||||
       */
 | 
			
		||||
      inline void setShaderVertex(const std::string & vert) {
 | 
			
		||||
      inline void setShaderVertex(const std::string & vert)
 | 
			
		||||
      {
 | 
			
		||||
        mVertexShader = vert;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @param frag Path to fragment shader to use for this MeshRenderer.
 | 
			
		||||
       */
 | 
			
		||||
      inline void setShaderFragment(const std::string & frag) {
 | 
			
		||||
      inline void setShaderFragment(const std::string & frag)
 | 
			
		||||
      {
 | 
			
		||||
        mFragmentShader = frag;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -134,7 +137,8 @@ namespace Qtk {
 | 
			
		||||
       * @param location Index location of the uniform value we are setting.
 | 
			
		||||
       * @param value The value to use for the uniform.
 | 
			
		||||
       */
 | 
			
		||||
      template <typename T> inline void setUniform(int location, T value) {
 | 
			
		||||
      template <typename T> inline void setUniform(int location, T value)
 | 
			
		||||
      {
 | 
			
		||||
        ShaderBindScope lock(&mProgram, mBound);
 | 
			
		||||
        mProgram.setUniformValue(location, value);
 | 
			
		||||
      }
 | 
			
		||||
@ -145,7 +149,8 @@ namespace Qtk {
 | 
			
		||||
       * @param value The value to use for the uniform.
 | 
			
		||||
       */
 | 
			
		||||
      template <typename T>
 | 
			
		||||
      inline void setUniform(const char * location, T value) {
 | 
			
		||||
      inline void setUniform(const char * location, T value)
 | 
			
		||||
      {
 | 
			
		||||
        ShaderBindScope lock(&mProgram, mBound);
 | 
			
		||||
        mProgram.setUniformValue(location, value);
 | 
			
		||||
      }
 | 
			
		||||
@ -159,8 +164,8 @@ namespace Qtk {
 | 
			
		||||
       * @param view Name of the uniform to store the View matrix.
 | 
			
		||||
       * @param projection Name of the uniform to store the Projection matrix.
 | 
			
		||||
       */
 | 
			
		||||
      void setUniformMVP(
 | 
			
		||||
          const char * model = "uModel", const char * view = "uView",
 | 
			
		||||
      void setUniformMVP(const char * model = "uModel",
 | 
			
		||||
                         const char * view = "uView",
 | 
			
		||||
                         const char * projection = "uProjection");
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
@ -192,8 +197,8 @@ namespace Qtk {
 | 
			
		||||
       * @param stride Stride between groups of elements in the buffer.
 | 
			
		||||
       *    For example (x, y) data stride is `2 * sizeof(type)`
 | 
			
		||||
       */
 | 
			
		||||
      void setAttributeBuffer(
 | 
			
		||||
          int location, GLenum type, int offset, int tupleSize, int stride = 0);
 | 
			
		||||
      void setAttributeBuffer(int location, GLenum type, int offset,
 | 
			
		||||
                              int tupleSize, int stride = 0);
 | 
			
		||||
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Accessors
 | 
			
		||||
@ -211,11 +216,13 @@ namespace Qtk {
 | 
			
		||||
       */
 | 
			
		||||
      inline Transform3D & getTransform() { return mTransform; }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline std::string getVertexShader() const override {
 | 
			
		||||
      [[nodiscard]] inline std::string getVertexShader() const override
 | 
			
		||||
      {
 | 
			
		||||
        return mVertexShader;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline std::string getFragmentShader() const override {
 | 
			
		||||
      [[nodiscard]] inline std::string getFragmentShader() const override
 | 
			
		||||
      {
 | 
			
		||||
        return mFragmentShader;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -21,21 +21,24 @@ Model::ModelManager Model::mManager;
 | 
			
		||||
 * Public Member Functions
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void Model::draw() {
 | 
			
		||||
void Model::draw()
 | 
			
		||||
{
 | 
			
		||||
  for (auto & mesh : mMeshes) {
 | 
			
		||||
    mesh.mTransform = mTransform;
 | 
			
		||||
    mesh.draw();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Model::draw(QOpenGLShaderProgram & shader) {
 | 
			
		||||
void Model::draw(QOpenGLShaderProgram & shader)
 | 
			
		||||
{
 | 
			
		||||
  for (auto & mesh : mMeshes) {
 | 
			
		||||
    mesh.mTransform = mTransform;
 | 
			
		||||
    mesh.draw(shader);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Model::flipTexture(const std::string & fileName, bool flipX, bool flipY) {
 | 
			
		||||
void Model::flipTexture(const std::string & fileName, bool flipX, bool flipY)
 | 
			
		||||
{
 | 
			
		||||
  bool modified = false;
 | 
			
		||||
  std::string fullPath = mDirectory + '/' + fileName;
 | 
			
		||||
  for (auto & texture : mTexturesLoaded) {
 | 
			
		||||
@ -54,7 +57,8 @@ void Model::flipTexture(const std::string & fileName, bool flipX, bool flipY) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Static function to access ModelManager for getting Models by name
 | 
			
		||||
Model * Qtk::Model::getInstance(const char * name) {
 | 
			
		||||
Model * Qtk::Model::getInstance(const char * name)
 | 
			
		||||
{
 | 
			
		||||
  return mManager[name];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -62,7 +66,8 @@ Model * Qtk::Model::getInstance(const char * name) {
 | 
			
		||||
 * Private Member Functions
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void Model::loadModel(const std::string & path) {
 | 
			
		||||
void Model::loadModel(const std::string & path)
 | 
			
		||||
{
 | 
			
		||||
  Assimp::Importer import;
 | 
			
		||||
  // If using a Qt Resource path, use QtkIOSystem for file handling.
 | 
			
		||||
  if (path.front() == ':') {
 | 
			
		||||
@ -81,7 +86,8 @@ void Model::loadModel(const std::string & path) {
 | 
			
		||||
                        | aiProcess_SplitLargeMeshes);
 | 
			
		||||
 | 
			
		||||
  // If there were errors, print and return
 | 
			
		||||
  if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
 | 
			
		||||
  if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE
 | 
			
		||||
      || !scene->mRootNode) {
 | 
			
		||||
    qDebug() << "Error::ASSIMP::" << import.GetErrorString() << "\n";
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
@ -99,7 +105,8 @@ void Model::loadModel(const std::string & path) {
 | 
			
		||||
  mManager.insert(getName().c_str(), this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Model::processNode(aiNode * node, const aiScene * scene) {
 | 
			
		||||
void Model::processNode(aiNode * node, const aiScene * scene)
 | 
			
		||||
{
 | 
			
		||||
  // Process each mesh that is available for this node
 | 
			
		||||
  for (GLuint i = 0; i < node->mNumMeshes; i++) {
 | 
			
		||||
    aiMesh * mesh = scene->mMeshes[node->mMeshes[i]];
 | 
			
		||||
@ -112,7 +119,8 @@ void Model::processNode(aiNode * node, const aiScene * scene) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModelMesh Model::processMesh(aiMesh * mesh, const aiScene * scene) {
 | 
			
		||||
ModelMesh Model::processMesh(aiMesh * mesh, const aiScene * scene)
 | 
			
		||||
{
 | 
			
		||||
  ModelMesh::Vertices vertices;
 | 
			
		||||
  ModelMesh::Indices indices;
 | 
			
		||||
  ModelMesh::Textures textures;
 | 
			
		||||
@ -200,13 +208,14 @@ ModelMesh Model::processMesh(aiMesh * mesh, const aiScene * scene) {
 | 
			
		||||
    textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
      vertices, indices, textures, mVertexShader.c_str(),
 | 
			
		||||
  return {vertices, indices, textures, mVertexShader.c_str(),
 | 
			
		||||
          mFragmentShader.c_str()};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModelMesh::Textures Model::loadMaterialTextures(
 | 
			
		||||
    aiMaterial * mat, aiTextureType type, const std::string & typeName) {
 | 
			
		||||
ModelMesh::Textures Model::loadMaterialTextures(aiMaterial * mat,
 | 
			
		||||
                                                aiTextureType type,
 | 
			
		||||
                                                const std::string & typeName)
 | 
			
		||||
{
 | 
			
		||||
  ModelMesh::Textures textures;
 | 
			
		||||
 | 
			
		||||
  for (GLuint i = 0; i < mat->GetTextureCount(type); i++) {
 | 
			
		||||
@ -246,7 +255,8 @@ ModelMesh::Textures Model::loadMaterialTextures(
 | 
			
		||||
  return textures;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Model::sortModelMeshes() {
 | 
			
		||||
void Model::sortModelMeshes()
 | 
			
		||||
{
 | 
			
		||||
  auto cameraPos = Scene::getCamera().getTransform();
 | 
			
		||||
  auto cameraDistance = [&cameraPos](const ModelMesh & a, const ModelMesh & b) {
 | 
			
		||||
    // Sort by the first vertex position in the model
 | 
			
		||||
 | 
			
		||||
@ -24,12 +24,14 @@
 | 
			
		||||
#include "modelmesh.h"
 | 
			
		||||
#include "qtkapi.h"
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Model object that has a ModelMesh.
 | 
			
		||||
   * Top-level object that represents 3D models stored within a scene.
 | 
			
		||||
   */
 | 
			
		||||
  class QTKAPI Model : public Object {
 | 
			
		||||
  class QTKAPI Model : public Object
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Typedefs
 | 
			
		||||
@ -51,13 +53,12 @@ namespace Qtk {
 | 
			
		||||
       * @param vertexShader Optional path to custom vertex shader.
 | 
			
		||||
       * @param fragmentShader Optional path to custom fragment shader.
 | 
			
		||||
       */
 | 
			
		||||
      inline Model(
 | 
			
		||||
          const char * name, const char * path,
 | 
			
		||||
      inline Model(const char * name, const char * path,
 | 
			
		||||
                   const char * vertexShader = ":/shaders/model-basic.vert",
 | 
			
		||||
                   const char * fragmentShader = ":/shaders/model-basic.frag") :
 | 
			
		||||
          Object(name, QTK_MODEL),
 | 
			
		||||
          mModelPath(path), mVertexShader(vertexShader),
 | 
			
		||||
          mFragmentShader(fragmentShader) {
 | 
			
		||||
          Object(name, QTK_MODEL), mModelPath(path),
 | 
			
		||||
          mVertexShader(vertexShader), mFragmentShader(fragmentShader)
 | 
			
		||||
      {
 | 
			
		||||
        loadModel(mModelPath);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -86,8 +87,8 @@ namespace Qtk {
 | 
			
		||||
       * @param flipX Flip the texture along the X axis
 | 
			
		||||
       * @param flipY Flip the texture along the Y axis
 | 
			
		||||
       */
 | 
			
		||||
      void flipTexture(
 | 
			
		||||
          const std::string & fileName, bool flipX = false, bool flipY = true);
 | 
			
		||||
      void flipTexture(const std::string & fileName, bool flipX = false,
 | 
			
		||||
                       bool flipY = true);
 | 
			
		||||
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Setters
 | 
			
		||||
@ -101,7 +102,8 @@ namespace Qtk {
 | 
			
		||||
       * @param value The value to assign to the uniform
 | 
			
		||||
       */
 | 
			
		||||
      template <typename T>
 | 
			
		||||
      inline void setUniform(const char * location, T value) {
 | 
			
		||||
      inline void setUniform(const char * location, T value)
 | 
			
		||||
      {
 | 
			
		||||
        for (auto & mesh : mMeshes) {
 | 
			
		||||
          mesh.mProgram->bind();
 | 
			
		||||
          mesh.mProgram->setUniformValue(location, value);
 | 
			
		||||
@ -127,11 +129,13 @@ namespace Qtk {
 | 
			
		||||
       */
 | 
			
		||||
      inline Transform3D & getTransform() { return mTransform; }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline std::string getVertexShader() const override {
 | 
			
		||||
      [[nodiscard]] inline std::string getVertexShader() const override
 | 
			
		||||
      {
 | 
			
		||||
        return mVertexShader;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline std::string getFragmentShader() const override {
 | 
			
		||||
      [[nodiscard]] inline std::string getFragmentShader() const override
 | 
			
		||||
      {
 | 
			
		||||
        return mFragmentShader;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -183,8 +187,9 @@ namespace Qtk {
 | 
			
		||||
       * @param typeName Texture type name in string format.
 | 
			
		||||
       * @return Collection of all textures for a single ModelMesh.
 | 
			
		||||
       */
 | 
			
		||||
      ModelMesh::Textures loadMaterialTextures(
 | 
			
		||||
          aiMaterial * mat, aiTextureType type, const std::string & typeName);
 | 
			
		||||
      ModelMesh::Textures loadMaterialTextures(aiMaterial * mat,
 | 
			
		||||
                                               aiTextureType type,
 | 
			
		||||
                                               const std::string & typeName);
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Sorts each mesh in the Model based on distance from the camera.
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,8 @@ using namespace Qtk;
 | 
			
		||||
 * Public Member Functions
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void ModelMesh::draw(QOpenGLShaderProgram & shader) {
 | 
			
		||||
void ModelMesh::draw(QOpenGLShaderProgram & shader)
 | 
			
		||||
{
 | 
			
		||||
  mVAO->bind();
 | 
			
		||||
  // Bind shader
 | 
			
		||||
  shader.bind();
 | 
			
		||||
@ -57,8 +58,8 @@ void ModelMesh::draw(QOpenGLShaderProgram & shader) {
 | 
			
		||||
  glActiveTexture(GL_TEXTURE0);
 | 
			
		||||
 | 
			
		||||
  // Draw the mesh
 | 
			
		||||
  glDrawElements(
 | 
			
		||||
      GL_TRIANGLES, mIndices.size(), GL_UNSIGNED_INT, mIndices.data());
 | 
			
		||||
  glDrawElements(GL_TRIANGLES, mIndices.size(), GL_UNSIGNED_INT,
 | 
			
		||||
                 mIndices.data());
 | 
			
		||||
 | 
			
		||||
  // Release shader, textures
 | 
			
		||||
  for (const auto & texture : mTextures) {
 | 
			
		||||
@ -72,7 +73,8 @@ void ModelMesh::draw(QOpenGLShaderProgram & shader) {
 | 
			
		||||
 * Private Member Functions
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void ModelMesh::initMesh(const char * vert, const char * frag) {
 | 
			
		||||
void ModelMesh::initMesh(const char * vert, const char * frag)
 | 
			
		||||
{
 | 
			
		||||
  initializeOpenGLFunctions();
 | 
			
		||||
 | 
			
		||||
  // Create VAO, VBO, EBO
 | 
			
		||||
@ -102,29 +104,29 @@ void ModelMesh::initMesh(const char * vert, const char * frag) {
 | 
			
		||||
 | 
			
		||||
  // Positions
 | 
			
		||||
  mProgram->enableAttributeArray(0);
 | 
			
		||||
  mProgram->setAttributeBuffer(
 | 
			
		||||
      0, GL_FLOAT, offsetof(ModelVertex, mPosition), 3, sizeof(ModelVertex));
 | 
			
		||||
  mProgram->setAttributeBuffer(0, GL_FLOAT, offsetof(ModelVertex, mPosition), 3,
 | 
			
		||||
                               sizeof(ModelVertex));
 | 
			
		||||
 | 
			
		||||
  // Normals
 | 
			
		||||
  mProgram->enableAttributeArray(1);
 | 
			
		||||
  mProgram->setAttributeBuffer(
 | 
			
		||||
      1, GL_FLOAT, offsetof(ModelVertex, mNormal), 3, sizeof(ModelVertex));
 | 
			
		||||
  mProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(ModelVertex, mNormal), 3,
 | 
			
		||||
                               sizeof(ModelVertex));
 | 
			
		||||
 | 
			
		||||
  // Texture Coordinates
 | 
			
		||||
  mProgram->enableAttributeArray(2);
 | 
			
		||||
  mProgram->setAttributeBuffer(
 | 
			
		||||
      2, GL_FLOAT, offsetof(ModelVertex, mTextureCoord), 2,
 | 
			
		||||
  mProgram->setAttributeBuffer(2, GL_FLOAT,
 | 
			
		||||
                               offsetof(ModelVertex, mTextureCoord), 2,
 | 
			
		||||
                               sizeof(ModelVertex));
 | 
			
		||||
 | 
			
		||||
  // Vertex tangents
 | 
			
		||||
  mProgram->enableAttributeArray(3);
 | 
			
		||||
  mProgram->setAttributeBuffer(
 | 
			
		||||
      3, GL_FLOAT, offsetof(ModelVertex, mTangent), 3, sizeof(ModelVertex));
 | 
			
		||||
  mProgram->setAttributeBuffer(3, GL_FLOAT, offsetof(ModelVertex, mTangent), 3,
 | 
			
		||||
                               sizeof(ModelVertex));
 | 
			
		||||
 | 
			
		||||
  // Vertex bitangents
 | 
			
		||||
  mProgram->enableAttributeArray(4);
 | 
			
		||||
  mProgram->setAttributeBuffer(
 | 
			
		||||
      4, GL_FLOAT, offsetof(ModelVertex, mBitangent), 3, sizeof(ModelVertex));
 | 
			
		||||
  mProgram->setAttributeBuffer(4, GL_FLOAT, offsetof(ModelVertex, mBitangent),
 | 
			
		||||
                               3, sizeof(ModelVertex));
 | 
			
		||||
 | 
			
		||||
  mProgram->release();
 | 
			
		||||
  mVBO->release();
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,8 @@
 | 
			
		||||
#include "object.h"
 | 
			
		||||
#include "transform3D.h"
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * 3D models will store this data for each vertex in geometry.
 | 
			
		||||
   */
 | 
			
		||||
@ -42,7 +43,8 @@ namespace Qtk {
 | 
			
		||||
       * @param path Path to the texture on disk.
 | 
			
		||||
       */
 | 
			
		||||
      ModelTexture(std::string type, const std::string & path) :
 | 
			
		||||
          mType(std::move(type)), mPath(path) {
 | 
			
		||||
          mType(std::move(type)), mPath(path)
 | 
			
		||||
      {
 | 
			
		||||
        mTexture = OpenGLTextureFactory::initTexture(path.c_str());
 | 
			
		||||
        mID = mTexture->textureId();
 | 
			
		||||
      }
 | 
			
		||||
@ -66,7 +68,8 @@ namespace Qtk {
 | 
			
		||||
   * Mesh class specialized for storing 3D model data.
 | 
			
		||||
   * Eventually this can be consolidated into a more generic class.
 | 
			
		||||
   */
 | 
			
		||||
  class QTKAPI ModelMesh : protected QOpenGLFunctions {
 | 
			
		||||
  class QTKAPI ModelMesh : protected QOpenGLFunctions
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Typedefs
 | 
			
		||||
@ -91,8 +94,7 @@ namespace Qtk {
 | 
			
		||||
       * @param vertexShader Path to vertex shader for this ModelMesh.
 | 
			
		||||
       * @param fragmentShader Path to fragment shader for this ModelMesh.
 | 
			
		||||
       */
 | 
			
		||||
      ModelMesh(
 | 
			
		||||
          Vertices vertices, Indices indices, Textures textures,
 | 
			
		||||
      ModelMesh(Vertices vertices, Indices indices, Textures textures,
 | 
			
		||||
                const char * vertexShader = ":/model-basic.vert",
 | 
			
		||||
                const char * fragmentShader = ":/model-basic.frag") :
 | 
			
		||||
          mProgram(new QOpenGLShaderProgram),
 | 
			
		||||
@ -100,7 +102,8 @@ namespace Qtk {
 | 
			
		||||
          mVBO(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)),
 | 
			
		||||
          mEBO(new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer)),
 | 
			
		||||
          mVertices(std::move(vertices)), mIndices(std::move(indices)),
 | 
			
		||||
          mTextures(std::move(textures)) {
 | 
			
		||||
          mTextures(std::move(textures))
 | 
			
		||||
      {
 | 
			
		||||
        initMesh(vertexShader, fragmentShader);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										112
									
								
								src/qtk/object.h
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								src/qtk/object.h
									
									
									
									
									
								
							@ -17,14 +17,16 @@
 | 
			
		||||
#include "shape.h"
 | 
			
		||||
#include "texture.h"
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
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.
 | 
			
		||||
   */
 | 
			
		||||
  class QTKAPI Object : public QObject {
 | 
			
		||||
  class QTKAPI Object : public QObject
 | 
			
		||||
  {
 | 
			
		||||
      Q_OBJECT
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
@ -47,7 +49,8 @@ namespace Qtk {
 | 
			
		||||
      // Initialize an object with no shape data assigned
 | 
			
		||||
      explicit Object(const char * name, Type type) :
 | 
			
		||||
          mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mBound(false),
 | 
			
		||||
          mType(type) {
 | 
			
		||||
          mType(type)
 | 
			
		||||
      {
 | 
			
		||||
        initResources();
 | 
			
		||||
        setObjectName(name);
 | 
			
		||||
      }
 | 
			
		||||
@ -55,7 +58,8 @@ namespace Qtk {
 | 
			
		||||
      // Initialize an object with shape data assigned
 | 
			
		||||
      Object(const char * name, const ShapeBase & shape, Type type) :
 | 
			
		||||
          mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mShape(shape),
 | 
			
		||||
          mBound(false), mType(type) {
 | 
			
		||||
          mBound(false), mType(type)
 | 
			
		||||
      {
 | 
			
		||||
        initResources();
 | 
			
		||||
        setObjectName(name);
 | 
			
		||||
      }
 | 
			
		||||
@ -66,29 +70,35 @@ namespace Qtk {
 | 
			
		||||
       * Accessors
 | 
			
		||||
       ************************************************************************/
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline const Colors & getColors() const {
 | 
			
		||||
      [[nodiscard]] inline const Colors & getColors() const
 | 
			
		||||
      {
 | 
			
		||||
        return mShape.mColors;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline const Indices & getIndexData() const {
 | 
			
		||||
      [[nodiscard]] inline const Indices & getIndexData() const
 | 
			
		||||
      {
 | 
			
		||||
        return mShape.mIndices;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline const Normals & getNormals() const {
 | 
			
		||||
      [[nodiscard]] inline const Normals & getNormals() const
 | 
			
		||||
      {
 | 
			
		||||
        return mShape.mNormals;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline const Shape & getShape() const { return mShape; }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline const TexCoords & getTexCoords() const {
 | 
			
		||||
      [[nodiscard]] inline const TexCoords & getTexCoords() const
 | 
			
		||||
      {
 | 
			
		||||
        return mShape.mTexCoords;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline const Texture & getTexture() const {
 | 
			
		||||
      [[nodiscard]] inline const Texture & getTexture() const
 | 
			
		||||
      {
 | 
			
		||||
        return mTexture;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline const Vertices & getVertices() const {
 | 
			
		||||
      [[nodiscard]] inline const Vertices & getVertices() const
 | 
			
		||||
      {
 | 
			
		||||
        return mShape.mVertices;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -96,15 +106,18 @@ namespace Qtk {
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline const Type & getType() const { return mType; }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline virtual const Transform3D & getTransform() const {
 | 
			
		||||
      [[nodiscard]] inline virtual const Transform3D & getTransform() const
 | 
			
		||||
      {
 | 
			
		||||
        return mTransform;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline virtual std::string getVertexShader() const {
 | 
			
		||||
      [[nodiscard]] inline virtual std::string getVertexShader() const
 | 
			
		||||
      {
 | 
			
		||||
        return "Base Object has no vertex shader.";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] virtual inline std::string getFragmentShader() const {
 | 
			
		||||
      [[nodiscard]] virtual inline std::string getFragmentShader() const
 | 
			
		||||
      {
 | 
			
		||||
        return "Base Object has no fragment shader.";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -114,84 +127,97 @@ namespace Qtk {
 | 
			
		||||
 | 
			
		||||
      virtual inline void setName(const std::string & name) { mName = name; }
 | 
			
		||||
 | 
			
		||||
      virtual inline void setColors(const Colors & value) {
 | 
			
		||||
      virtual inline void setColors(const Colors & value)
 | 
			
		||||
      {
 | 
			
		||||
        mShape.mColors = value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      virtual inline void setIndices(const Indices & value) {
 | 
			
		||||
      virtual inline void setIndices(const Indices & value)
 | 
			
		||||
      {
 | 
			
		||||
        mShape.mIndices = value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      virtual inline void setNormals(const Normals & value) {
 | 
			
		||||
      virtual inline void setNormals(const Normals & value)
 | 
			
		||||
      {
 | 
			
		||||
        mShape.mNormals = value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      virtual inline void setShape(const Shape & value) { mShape = value; }
 | 
			
		||||
 | 
			
		||||
      virtual inline void setTexCoords(const TexCoords & value) {
 | 
			
		||||
      virtual inline void setTexCoords(const TexCoords & value)
 | 
			
		||||
      {
 | 
			
		||||
        mShape.mTexCoords = value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      virtual inline void setTexture(
 | 
			
		||||
          const char * path, bool flipX = false, bool flipY = false) {
 | 
			
		||||
      virtual inline void setTexture(const char * path, bool flipX = false,
 | 
			
		||||
                                     bool flipY = false)
 | 
			
		||||
      {
 | 
			
		||||
        mTexture.setTexture(path, flipX, flipY);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      virtual inline void setCubeMap(const char * path) {
 | 
			
		||||
      virtual inline void setCubeMap(const char * path)
 | 
			
		||||
      {
 | 
			
		||||
        mTexture.setCubeMap(path);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      virtual inline void setTexture(const Texture & t) {
 | 
			
		||||
      virtual inline void setTexture(const Texture & t)
 | 
			
		||||
      {
 | 
			
		||||
        mTexture.setTexture(t.getPath());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      virtual inline void setVertices(const Vertices & value) {
 | 
			
		||||
      virtual inline void setVertices(const Vertices & value)
 | 
			
		||||
      {
 | 
			
		||||
        mShape.mVertices = value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      inline void setScaleX(double x) {
 | 
			
		||||
        mTransform.setScale(
 | 
			
		||||
            x, mTransform.getScale().y(), mTransform.getScale().z());
 | 
			
		||||
      inline void setScaleX(double x)
 | 
			
		||||
      {
 | 
			
		||||
        mTransform.setScale(x, mTransform.getScale().y(),
 | 
			
		||||
                            mTransform.getScale().z());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      inline void setScaleY(double y) {
 | 
			
		||||
        mTransform.setScale(
 | 
			
		||||
            mTransform.getScale().x(), y, mTransform.getScale().z());
 | 
			
		||||
      inline void setScaleY(double y)
 | 
			
		||||
      {
 | 
			
		||||
        mTransform.setScale(mTransform.getScale().x(), y,
 | 
			
		||||
                            mTransform.getScale().z());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      inline void setScaleZ(double z) {
 | 
			
		||||
        mTransform.setScale(
 | 
			
		||||
            mTransform.getScale().x(), mTransform.getScale().y(), z);
 | 
			
		||||
      inline void setScaleZ(double z)
 | 
			
		||||
      {
 | 
			
		||||
        mTransform.setScale(mTransform.getScale().x(),
 | 
			
		||||
                            mTransform.getScale().y(), z);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      inline void setTranslationX(double x) {
 | 
			
		||||
        mTransform.setTranslation(
 | 
			
		||||
            x, mTransform.getTranslation().y(),
 | 
			
		||||
      inline void setTranslationX(double x)
 | 
			
		||||
      {
 | 
			
		||||
        mTransform.setTranslation(x, mTransform.getTranslation().y(),
 | 
			
		||||
                                  mTransform.getTranslation().z());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      inline void setTranslationY(double y) {
 | 
			
		||||
        mTransform.setTranslation(
 | 
			
		||||
            mTransform.getTranslation().x(), y,
 | 
			
		||||
      inline void setTranslationY(double y)
 | 
			
		||||
      {
 | 
			
		||||
        mTransform.setTranslation(mTransform.getTranslation().x(), y,
 | 
			
		||||
                                  mTransform.getTranslation().z());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      inline void setTranslationZ(double z) {
 | 
			
		||||
        mTransform.setTranslation(
 | 
			
		||||
            mTransform.getTranslation().x(), mTransform.getTranslation().y(),
 | 
			
		||||
            z);
 | 
			
		||||
      inline void setTranslationZ(double z)
 | 
			
		||||
      {
 | 
			
		||||
        mTransform.setTranslation(mTransform.getTranslation().x(),
 | 
			
		||||
                                  mTransform.getTranslation().y(), z);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Public Methods
 | 
			
		||||
       ************************************************************************/
 | 
			
		||||
 | 
			
		||||
      virtual inline void bindShaders() {
 | 
			
		||||
      virtual inline void bindShaders()
 | 
			
		||||
      {
 | 
			
		||||
        mBound = true;
 | 
			
		||||
        mProgram.bind();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      virtual inline void releaseShaders() {
 | 
			
		||||
      virtual inline void releaseShaders()
 | 
			
		||||
      {
 | 
			
		||||
        mBound = false;
 | 
			
		||||
        mProgram.release();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -27,11 +27,13 @@
 | 
			
		||||
 * This cannot be defined within any namespace, but can be called by ctors.
 | 
			
		||||
 * See object.h for example.
 | 
			
		||||
 */
 | 
			
		||||
inline void initResources() {
 | 
			
		||||
inline void initResources()
 | 
			
		||||
{
 | 
			
		||||
  Q_INIT_RESOURCE(resources);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Flag to set context for debug messages.
 | 
			
		||||
   */
 | 
			
		||||
@ -43,7 +45,8 @@ namespace Qtk {
 | 
			
		||||
   * @param widget Widget to start the search from.
 | 
			
		||||
   * @return Top level parent widget or Q_NULLPTR if no parent
 | 
			
		||||
   */
 | 
			
		||||
  static QWidget * topLevelParent(QWidget * widget) {
 | 
			
		||||
  static QWidget * topLevelParent(QWidget * widget)
 | 
			
		||||
  {
 | 
			
		||||
    QString name = widget->objectName();
 | 
			
		||||
    while (widget->parentWidget() != Q_NULLPTR) {
 | 
			
		||||
      widget = widget->parentWidget();
 | 
			
		||||
@ -54,7 +57,8 @@ namespace Qtk {
 | 
			
		||||
  /**
 | 
			
		||||
   * @return Default icon to use for Qtk desktop application.
 | 
			
		||||
   */
 | 
			
		||||
  static QIcon getIcon() {
 | 
			
		||||
  static QIcon getIcon()
 | 
			
		||||
  {
 | 
			
		||||
    return QIcon(":/icons/icon.png");
 | 
			
		||||
  }
 | 
			
		||||
}  // namespace Qtk
 | 
			
		||||
 | 
			
		||||
@ -14,8 +14,8 @@ using namespace Qtk;
 | 
			
		||||
 * Constructors, Destructors
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
QtkIOStream::QtkIOStream(const char * pFile, const char * pMode) :
 | 
			
		||||
    mFile(pFile) {
 | 
			
		||||
QtkIOStream::QtkIOStream(const char * pFile, const char * pMode) : mFile(pFile)
 | 
			
		||||
{
 | 
			
		||||
  QString mode(pMode);
 | 
			
		||||
  bool open = false;
 | 
			
		||||
  if (mode == "w" || mode == "wb") {
 | 
			
		||||
@ -40,7 +40,8 @@ QtkIOStream::QtkIOStream(const char * pFile, const char * pMode) :
 | 
			
		||||
 * Public Member Functions
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
size_t QtkIOStream::Read(void * pvBuffer, size_t pSize, size_t pCount) {
 | 
			
		||||
size_t QtkIOStream::Read(void * pvBuffer, size_t pSize, size_t pCount)
 | 
			
		||||
{
 | 
			
		||||
  qint64 readSize = mFile.read((char *)pvBuffer, pSize * pCount);
 | 
			
		||||
  if (readSize < 0) {
 | 
			
		||||
    qDebug() << "[Qtk::QtkIOStream] Failed to read (" << pSize
 | 
			
		||||
@ -51,7 +52,8 @@ size_t QtkIOStream::Read(void * pvBuffer, size_t pSize, size_t pCount) {
 | 
			
		||||
  return readSize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t QtkIOStream::Write(const void * pvBuffer, size_t pSize, size_t pCount) {
 | 
			
		||||
size_t QtkIOStream::Write(const void * pvBuffer, size_t pSize, size_t pCount)
 | 
			
		||||
{
 | 
			
		||||
  qint64 writeSize = mFile.write((char *)pvBuffer, pSize * pCount);
 | 
			
		||||
  if (writeSize < 0) {
 | 
			
		||||
    qDebug() << "[Qtk::QtkIOStream] Failed to write buffer with size (" << pSize
 | 
			
		||||
@ -61,18 +63,22 @@ size_t QtkIOStream::Write(const void * pvBuffer, size_t pSize, size_t pCount) {
 | 
			
		||||
  return writeSize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
aiReturn QtkIOStream::Seek(size_t pOffset, aiOrigin pOrigin) {
 | 
			
		||||
aiReturn QtkIOStream::Seek(size_t pOffset, aiOrigin pOrigin)
 | 
			
		||||
{
 | 
			
		||||
  return mFile.seek(pOffset) ? aiReturn_SUCCESS : aiReturn_FAILURE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t QtkIOStream::Tell() const {
 | 
			
		||||
size_t QtkIOStream::Tell() const
 | 
			
		||||
{
 | 
			
		||||
  return mFile.pos();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t QtkIOStream::FileSize() const {
 | 
			
		||||
size_t QtkIOStream::FileSize() const
 | 
			
		||||
{
 | 
			
		||||
  return mFile.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkIOStream::Flush() {
 | 
			
		||||
void QtkIOStream::Flush()
 | 
			
		||||
{
 | 
			
		||||
  mFile.flush();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -15,12 +15,14 @@
 | 
			
		||||
#ifndef QTK_QTKIOSTREAM_H
 | 
			
		||||
#define QTK_QTKIOSTREAM_H
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Custom Assimp IO stream to support QtkIOSystem file handling.
 | 
			
		||||
   * Allows direct use of Qt Resource paths for loading models in Assimp.
 | 
			
		||||
   */
 | 
			
		||||
  class QtkIOStream : public Assimp::IOStream {
 | 
			
		||||
  class QtkIOStream : public Assimp::IOStream
 | 
			
		||||
  {
 | 
			
		||||
      friend class QtkIOSystem;
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
 | 
			
		||||
@ -15,15 +15,18 @@ using namespace Qtk;
 | 
			
		||||
 * Public Member Functions
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
bool QtkIOSystem::Exists(const char * pFile) const {
 | 
			
		||||
bool QtkIOSystem::Exists(const char * pFile) const
 | 
			
		||||
{
 | 
			
		||||
  return QFileInfo::exists(pFile);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char QtkIOSystem::getOsSeparator() const {
 | 
			
		||||
char QtkIOSystem::getOsSeparator() const
 | 
			
		||||
{
 | 
			
		||||
  return QDir::separator().toLatin1();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Assimp::IOStream * QtkIOSystem::Open(const char * pFile, const char * pMode) {
 | 
			
		||||
Assimp::IOStream * QtkIOSystem::Open(const char * pFile, const char * pMode)
 | 
			
		||||
{
 | 
			
		||||
  if (!Exists(pFile)) {
 | 
			
		||||
    qDebug() << "[Qtk::QtkIOSystem] failed to open file: " << pFile << "\n";
 | 
			
		||||
    return nullptr;
 | 
			
		||||
@ -31,6 +34,7 @@ Assimp::IOStream * QtkIOSystem::Open(const char * pFile, const char * pMode) {
 | 
			
		||||
  return new QtkIOStream(pFile, pMode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtkIOSystem::Close(Assimp::IOStream * pFile) {
 | 
			
		||||
void QtkIOSystem::Close(Assimp::IOStream * pFile)
 | 
			
		||||
{
 | 
			
		||||
  delete pFile;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -15,11 +15,13 @@
 | 
			
		||||
#ifndef QTK_QTKIOSYSTEM_H
 | 
			
		||||
#define QTK_QTKIOSYSTEM_H
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Assimp IO system for loading models with assimp, using Qt Resource paths.
 | 
			
		||||
   */
 | 
			
		||||
  class QtkIOSystem : public Assimp::IOSystem {
 | 
			
		||||
  class QtkIOSystem : public Assimp::IOSystem
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      QtkIOSystem() = default;
 | 
			
		||||
      ~QtkIOSystem() = default;
 | 
			
		||||
@ -40,8 +42,8 @@ namespace Qtk {
 | 
			
		||||
       * @param pMode Mode to open file. See `man fopen`.
 | 
			
		||||
       * @return QtkIOStream for the opened file.
 | 
			
		||||
       */
 | 
			
		||||
      Assimp::IOStream * Open(
 | 
			
		||||
          const char * pFile, const char * pMode = "rb") override;
 | 
			
		||||
      Assimp::IOStream * Open(const char * pFile,
 | 
			
		||||
                              const char * pMode = "rb") override;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @param pFile File to close.
 | 
			
		||||
 | 
			
		||||
@ -18,12 +18,14 @@ QMatrix4x4 Scene::mProjection;
 | 
			
		||||
 * Constructors / Destructors
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
Scene::Scene() : mSceneName("Default Scene") {
 | 
			
		||||
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() {
 | 
			
		||||
Scene::~Scene()
 | 
			
		||||
{
 | 
			
		||||
  for (auto & mesh : mMeshes) {
 | 
			
		||||
    delete mesh;
 | 
			
		||||
  }
 | 
			
		||||
@ -37,21 +39,24 @@ Scene::~Scene() {
 | 
			
		||||
 * Public Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
template <> MeshRenderer * Scene::addObject(MeshRenderer * object) {
 | 
			
		||||
template <> MeshRenderer * Scene::addObject(MeshRenderer * object)
 | 
			
		||||
{
 | 
			
		||||
  initSceneObjectName(object);
 | 
			
		||||
  mMeshes.push_back(object);
 | 
			
		||||
  sceneUpdated(mSceneName);
 | 
			
		||||
  return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <> Model * Scene::addObject(Model * object) {
 | 
			
		||||
template <> Model * Scene::addObject(Model * object)
 | 
			
		||||
{
 | 
			
		||||
  initSceneObjectName(object);
 | 
			
		||||
  mModels.push_back(object);
 | 
			
		||||
  sceneUpdated(mSceneName);
 | 
			
		||||
  return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Scene::draw() {
 | 
			
		||||
void Scene::draw()
 | 
			
		||||
{
 | 
			
		||||
  if (!mInit) {
 | 
			
		||||
    initializeOpenGLFunctions();
 | 
			
		||||
    init();
 | 
			
		||||
@ -82,7 +87,8 @@ void Scene::draw() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<Object *> Scene::getObjects() const {
 | 
			
		||||
std::vector<Object *> Scene::getObjects() const
 | 
			
		||||
{
 | 
			
		||||
  // All scene objects must inherit from Qtk::Object.
 | 
			
		||||
  std::vector<Object *> objects(mMeshes.begin(), mMeshes.end());
 | 
			
		||||
  for (const auto & model : mModels) {
 | 
			
		||||
@ -94,7 +100,8 @@ std::vector<Object *> Scene::getObjects() const {
 | 
			
		||||
  return objects;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Object * Scene::getObject(const QString & name) const {
 | 
			
		||||
Object * Scene::getObject(const QString & name) const
 | 
			
		||||
{
 | 
			
		||||
  for (const auto & object : getObjects()) {
 | 
			
		||||
    if (object->getName() == name.toStdString()) {
 | 
			
		||||
      return object;
 | 
			
		||||
@ -103,12 +110,14 @@ Object * Scene::getObject(const QString & name) const {
 | 
			
		||||
  return Q_NULLPTR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Scene::setSkybox(Skybox * skybox) {
 | 
			
		||||
void Scene::setSkybox(Skybox * skybox)
 | 
			
		||||
{
 | 
			
		||||
  delete mSkybox;
 | 
			
		||||
  mSkybox = skybox;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Scene::initSceneObjectName(Object * object) {
 | 
			
		||||
void Scene::initSceneObjectName(Object * object)
 | 
			
		||||
{
 | 
			
		||||
  if (!mObjectCount.count(object->getName())) {
 | 
			
		||||
    mObjectCount[object->getName()] = 1;
 | 
			
		||||
  } else {
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,8 @@
 | 
			
		||||
#include "model.h"
 | 
			
		||||
#include "skybox.h"
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * An abstract Scene class to inherit from when building new scenes.
 | 
			
		||||
   *
 | 
			
		||||
@ -43,7 +44,8 @@ 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 : public QObject, protected QOpenGLFunctions {
 | 
			
		||||
  class Scene : public QObject, protected QOpenGLFunctions
 | 
			
		||||
  {
 | 
			
		||||
      Q_OBJECT
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
@ -81,13 +83,15 @@ namespace Qtk {
 | 
			
		||||
       */
 | 
			
		||||
      virtual void update() {}
 | 
			
		||||
 | 
			
		||||
      void loadModel(const QUrl & url) {
 | 
			
		||||
      void loadModel(const QUrl & url)
 | 
			
		||||
      {
 | 
			
		||||
        auto fileName = url.fileName().replace(".obj", "").toStdString();
 | 
			
		||||
        auto filePath = url.toLocalFile().toStdString();
 | 
			
		||||
        loadModel(fileName, filePath);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void loadModel(const std::string & name, const std::string & path) {
 | 
			
		||||
      void loadModel(const std::string & name, const std::string & path)
 | 
			
		||||
      {
 | 
			
		||||
        // Add the dropped model to the load queue.
 | 
			
		||||
        // This is consumed during rendering of the scene if not empty.
 | 
			
		||||
        mModelLoadQueue.emplace(name, path);
 | 
			
		||||
@ -114,7 +118,8 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return The number of objects within the scene with the given name.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] uint64_t getObjectCount(const QString & name) {
 | 
			
		||||
      [[nodiscard]] uint64_t getObjectCount(const QString & name)
 | 
			
		||||
      {
 | 
			
		||||
        return mObjectCount.count(name.toStdString())
 | 
			
		||||
                   ? mObjectCount[name.toStdString()]
 | 
			
		||||
                   : 0;
 | 
			
		||||
@ -128,14 +133,16 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return View matrix for the camera attached to this scene.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline static QMatrix4x4 getViewMatrix() {
 | 
			
		||||
      [[nodiscard]] inline static QMatrix4x4 getViewMatrix()
 | 
			
		||||
      {
 | 
			
		||||
        return mCamera.toMatrix();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Projection matrix for the current view into the scene.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline static QMatrix4x4 & getProjectionMatrix() {
 | 
			
		||||
      [[nodiscard]] inline static QMatrix4x4 & getProjectionMatrix()
 | 
			
		||||
      {
 | 
			
		||||
        return mProjection;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -153,15 +160,16 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return All MeshRenderers within the scene.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline const std::vector<MeshRenderer *> & getMeshes()
 | 
			
		||||
          const {
 | 
			
		||||
      [[nodiscard]] inline const std::vector<MeshRenderer *> & getMeshes() const
 | 
			
		||||
      {
 | 
			
		||||
        return mMeshes;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @return All Models within the scene.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline const std::vector<Model *> & getModels() const {
 | 
			
		||||
      [[nodiscard]] inline const std::vector<Model *> & getModels() const
 | 
			
		||||
      {
 | 
			
		||||
        return mModels;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,8 @@
 | 
			
		||||
 | 
			
		||||
using namespace Qtk;
 | 
			
		||||
 | 
			
		||||
Cube::Cube(DrawMode mode) {
 | 
			
		||||
Cube::Cube(DrawMode mode)
 | 
			
		||||
{
 | 
			
		||||
  mDrawMode = mode;
 | 
			
		||||
  switch (mode) {
 | 
			
		||||
    // The order of the following assignment values helps to visualize.
 | 
			
		||||
@ -203,7 +204,8 @@ Cube::Cube(DrawMode mode) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Triangle::Triangle(DrawMode mode) {
 | 
			
		||||
Triangle::Triangle(DrawMode mode)
 | 
			
		||||
{
 | 
			
		||||
  mDrawMode = mode;
 | 
			
		||||
  const QVector3D triangleTop = QVector3D(0.0f, 0.5f, 0.0f);
 | 
			
		||||
  switch (mode) {
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,8 @@
 | 
			
		||||
#define UV_RIGHT  QVector2D(0.0f, 1.0f)
 | 
			
		||||
#define UV_CORNER QVector2D(1.0f, 1.0f)
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  class MeshRenderer;
 | 
			
		||||
 | 
			
		||||
  class Object;
 | 
			
		||||
@ -114,13 +115,14 @@ namespace Qtk {
 | 
			
		||||
       * @param t Texture coordinates for this shape.
 | 
			
		||||
       * @param n Normals for this shape.
 | 
			
		||||
       */
 | 
			
		||||
      explicit ShapeBase(
 | 
			
		||||
          DrawMode mode = QTK_DRAW_ARRAYS, Vertices v = {}, Indices i = {},
 | 
			
		||||
          Colors c = {}, TexCoords t = {}, Normals n = {}) :
 | 
			
		||||
          mDrawMode(mode),
 | 
			
		||||
          mVertices(std::move(v)), mColors(std::move(c)),
 | 
			
		||||
      explicit ShapeBase(DrawMode mode = QTK_DRAW_ARRAYS, Vertices v = {},
 | 
			
		||||
                         Indices i = {}, Colors c = {}, TexCoords t = {},
 | 
			
		||||
                         Normals n = {}) :
 | 
			
		||||
          mDrawMode(mode), mVertices(std::move(v)), mColors(std::move(c)),
 | 
			
		||||
          mIndices(std::move(i)), mTexCoords(std::move(t)),
 | 
			
		||||
          mNormals(std::move(n)) {}
 | 
			
		||||
          mNormals(std::move(n))
 | 
			
		||||
      {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Accessors
 | 
			
		||||
@ -129,14 +131,16 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Vertex data for this shape.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline const Vertices & getVertices() const {
 | 
			
		||||
      [[nodiscard]] inline const Vertices & getVertices() const
 | 
			
		||||
      {
 | 
			
		||||
        return mVertices;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Index data for this shape.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline const Indices & getIndexData() const {
 | 
			
		||||
      [[nodiscard]] inline const Indices & getIndexData() const
 | 
			
		||||
      {
 | 
			
		||||
        return mIndices;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -148,21 +152,24 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Texture coordinates for this shape.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline const TexCoords & getTexCoords() const {
 | 
			
		||||
      [[nodiscard]] inline const TexCoords & getTexCoords() const
 | 
			
		||||
      {
 | 
			
		||||
        return mTexCoords;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Normals for this shape.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline const Normals & getNormals() const {
 | 
			
		||||
      [[nodiscard]] inline const Normals & getNormals() const
 | 
			
		||||
      {
 | 
			
		||||
        return mNormals;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Stride for texture coordinates on this shape.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline size_t getTexCoordsStride() const {
 | 
			
		||||
      [[nodiscard]] inline size_t getTexCoordsStride() const
 | 
			
		||||
      {
 | 
			
		||||
        return mTexCoords.size() * sizeof(mTexCoords[0]);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -204,14 +211,16 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @param value Vertex data to use for this shape.
 | 
			
		||||
       */
 | 
			
		||||
      virtual inline void setVertices(const Vertices & value) {
 | 
			
		||||
      virtual inline void setVertices(const Vertices & value)
 | 
			
		||||
      {
 | 
			
		||||
        mVertices = value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @param value Index data to use for this shape.
 | 
			
		||||
       */
 | 
			
		||||
      virtual inline void setIndices(const Indices & value) {
 | 
			
		||||
      virtual inline void setIndices(const Indices & value)
 | 
			
		||||
      {
 | 
			
		||||
        mIndices = value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -223,14 +232,16 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @param value Texture coordinates to use for this shape.
 | 
			
		||||
       */
 | 
			
		||||
      virtual inline void setTexCoords(const TexCoords & value) {
 | 
			
		||||
      virtual inline void setTexCoords(const TexCoords & value)
 | 
			
		||||
      {
 | 
			
		||||
        mTexCoords = value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @param value Normals to use for this shape.
 | 
			
		||||
       */
 | 
			
		||||
      virtual inline void setNormals(const Normals & value) {
 | 
			
		||||
      virtual inline void setNormals(const Normals & value)
 | 
			
		||||
      {
 | 
			
		||||
        mNormals = value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,36 +17,38 @@ using namespace Qtk;
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
Skybox::Skybox(const std::string & name) :
 | 
			
		||||
    Skybox(
 | 
			
		||||
        ":/textures/skybox/right.png", ":/textures/skybox/top.png",
 | 
			
		||||
    Skybox(":/textures/skybox/right.png", ":/textures/skybox/top.png",
 | 
			
		||||
           ":/textures/skybox/front.png", ":/textures/skybox/left.png",
 | 
			
		||||
        ":/textures/skybox/bottom.png", ":/textures/skybox/back.png", name) {}
 | 
			
		||||
           ":/textures/skybox/bottom.png", ":/textures/skybox/back.png", name)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Skybox::Skybox(QOpenGLTexture * cubeMap, const std::string & name) {
 | 
			
		||||
Skybox::Skybox(QOpenGLTexture * cubeMap, const std::string & name)
 | 
			
		||||
{
 | 
			
		||||
  mTexture.setTexture(cubeMap);
 | 
			
		||||
  init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Skybox::Skybox(
 | 
			
		||||
    const std::string & right, const std::string & top,
 | 
			
		||||
Skybox::Skybox(const std::string & right, const std::string & top,
 | 
			
		||||
               const std::string & front, const std::string & left,
 | 
			
		||||
               const std::string & bottom, const std::string & back,
 | 
			
		||||
               const std::string & name) :
 | 
			
		||||
    mVBO(QOpenGLBuffer::VertexBuffer),
 | 
			
		||||
    mVertices(Cube(QTK_DRAW_ELEMENTS).getVertices()),
 | 
			
		||||
    mIndices(Cube(QTK_DRAW_ELEMENTS).getIndexData()) {
 | 
			
		||||
    mIndices(Cube(QTK_DRAW_ELEMENTS).getIndexData())
 | 
			
		||||
{
 | 
			
		||||
  init();
 | 
			
		||||
  mTexture.setCubeMap(
 | 
			
		||||
      QImage(right.c_str()).mirrored(), QImage(top.c_str()),
 | 
			
		||||
      QImage(front.c_str()), QImage(left.c_str()), QImage(bottom.c_str()),
 | 
			
		||||
      QImage(back.c_str()));
 | 
			
		||||
  mTexture.setCubeMap(QImage(right.c_str()).mirrored(), QImage(top.c_str()),
 | 
			
		||||
                      QImage(front.c_str()), QImage(left.c_str()),
 | 
			
		||||
                      QImage(bottom.c_str()), QImage(back.c_str()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Public Member Functions
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void Skybox::draw() {
 | 
			
		||||
void Skybox::draw()
 | 
			
		||||
{
 | 
			
		||||
  glDepthFunc(GL_LEQUAL);
 | 
			
		||||
  glDepthMask(GL_FALSE);
 | 
			
		||||
 | 
			
		||||
@ -57,8 +59,8 @@ void Skybox::draw() {
 | 
			
		||||
  mProgram.setUniformValue("uProjectionMatrix", Scene::getProjectionMatrix());
 | 
			
		||||
  mProgram.setUniformValue("uViewMatrix", Scene::getCamera().toMatrix());
 | 
			
		||||
  mProgram.setUniformValue("uTexture", 0);
 | 
			
		||||
  glDrawElements(
 | 
			
		||||
      GL_TRIANGLES, mIndices.size(), GL_UNSIGNED_INT, mIndices.data());
 | 
			
		||||
  glDrawElements(GL_TRIANGLES, mIndices.size(), GL_UNSIGNED_INT,
 | 
			
		||||
                 mIndices.data());
 | 
			
		||||
 | 
			
		||||
  mTexture.getOpenGLTexture().bind();
 | 
			
		||||
  mProgram.release();
 | 
			
		||||
@ -73,15 +75,16 @@ void Skybox::draw() {
 | 
			
		||||
 * Private Member Functions
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void Skybox::init() {
 | 
			
		||||
void Skybox::init()
 | 
			
		||||
{
 | 
			
		||||
  initializeOpenGLFunctions();
 | 
			
		||||
 | 
			
		||||
  // Set up shader program
 | 
			
		||||
  mProgram.create();
 | 
			
		||||
  mProgram.addShaderFromSourceFile(
 | 
			
		||||
      QOpenGLShader::Vertex, ":/shaders/skybox.vert");
 | 
			
		||||
  mProgram.addShaderFromSourceFile(
 | 
			
		||||
      QOpenGLShader::Fragment, ":/shaders/skybox.frag");
 | 
			
		||||
  mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,
 | 
			
		||||
                                   ":/shaders/skybox.vert");
 | 
			
		||||
  mProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,
 | 
			
		||||
                                   ":/shaders/skybox.frag");
 | 
			
		||||
  mProgram.link();
 | 
			
		||||
  mProgram.bind();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -20,13 +20,15 @@
 | 
			
		||||
#include "shape.h"
 | 
			
		||||
#include "texture.h"
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Skybox object for rendering a skybox within a Scene.
 | 
			
		||||
   * A skybox is typically implemented using a cube map texture centered around
 | 
			
		||||
   * the camera and projected outwards in all directions.
 | 
			
		||||
   */
 | 
			
		||||
  class QTKAPI Skybox : protected QOpenGLFunctions {
 | 
			
		||||
  class QTKAPI Skybox : protected QOpenGLFunctions
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Constructors / Destructors
 | 
			
		||||
@ -48,8 +50,8 @@ namespace Qtk {
 | 
			
		||||
       * @param cubeMap QOpenGLTexture to use for the new Skybox.
 | 
			
		||||
       * @param name The objectName to use for the Skybox.
 | 
			
		||||
       */
 | 
			
		||||
      explicit Skybox(
 | 
			
		||||
          QOpenGLTexture * cubeMap, const std::string & name = "Skybox");
 | 
			
		||||
      explicit Skybox(QOpenGLTexture * cubeMap,
 | 
			
		||||
                      const std::string & name = "Skybox");
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Construct a Skybox.
 | 
			
		||||
@ -62,8 +64,7 @@ namespace Qtk {
 | 
			
		||||
       * @param back Image to use for the back side of the Skybox.
 | 
			
		||||
       * @param name The objectName to use for this Skybox.
 | 
			
		||||
       */
 | 
			
		||||
      Skybox(
 | 
			
		||||
          const std::string & right, const std::string & top,
 | 
			
		||||
      Skybox(const std::string & right, const std::string & top,
 | 
			
		||||
             const std::string & front, const std::string & left,
 | 
			
		||||
             const std::string & bottom, const std::string & back,
 | 
			
		||||
             const std::string & name = "Skybox");
 | 
			
		||||
 | 
			
		||||
@ -14,8 +14,9 @@
 | 
			
		||||
 | 
			
		||||
using namespace Qtk;
 | 
			
		||||
 | 
			
		||||
QImage OpenGLTextureFactory::initImage(
 | 
			
		||||
    const char * image, bool flipX, bool flipY) {
 | 
			
		||||
QImage OpenGLTextureFactory::initImage(const char * image, bool flipX,
 | 
			
		||||
                                       bool flipY)
 | 
			
		||||
{
 | 
			
		||||
  // Qt6 limits loaded images to 256MB by default
 | 
			
		||||
  QImageReader::setAllocationLimit(1024);
 | 
			
		||||
  auto loadedImage = QImage(image).mirrored(flipX, flipY);
 | 
			
		||||
@ -26,34 +27,36 @@ QImage OpenGLTextureFactory::initImage(
 | 
			
		||||
  return loadedImage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QOpenGLTexture * OpenGLTextureFactory::initTexture(
 | 
			
		||||
    const char * texture, bool flipX, bool flipY) {
 | 
			
		||||
QOpenGLTexture * OpenGLTextureFactory::initTexture(const char * texture,
 | 
			
		||||
                                                   bool flipX, bool flipY)
 | 
			
		||||
{
 | 
			
		||||
  QImage image = initImage(texture, flipX, flipY);
 | 
			
		||||
  auto newTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
 | 
			
		||||
  newTexture->setData(image);
 | 
			
		||||
  newTexture->setWrapMode(QOpenGLTexture::Repeat);
 | 
			
		||||
  newTexture->setMinMagFilters(
 | 
			
		||||
      QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
 | 
			
		||||
  newTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear,
 | 
			
		||||
                               QOpenGLTexture::Linear);
 | 
			
		||||
  return newTexture;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(const char * tile) {
 | 
			
		||||
  return initCubeMap(
 | 
			
		||||
      QImage(tile), QImage(tile), QImage(tile), QImage(tile), QImage(tile),
 | 
			
		||||
      QImage(tile));
 | 
			
		||||
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(const char * tile)
 | 
			
		||||
{
 | 
			
		||||
  return initCubeMap(QImage(tile), QImage(tile), QImage(tile), QImage(tile),
 | 
			
		||||
                     QImage(tile), QImage(tile));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
 | 
			
		||||
    const char * right, const char * top, const char * front, const char * left,
 | 
			
		||||
    const char * bottom, const char * back) {
 | 
			
		||||
  return initCubeMap(
 | 
			
		||||
      QImage(right), QImage(top), QImage(front), QImage(left), QImage(bottom),
 | 
			
		||||
      QImage(back));
 | 
			
		||||
    const char * bottom, const char * back)
 | 
			
		||||
{
 | 
			
		||||
  return initCubeMap(QImage(right), QImage(top), QImage(front), QImage(left),
 | 
			
		||||
                     QImage(bottom), QImage(back));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
 | 
			
		||||
    const QImage & right, const QImage & top, const QImage & front,
 | 
			
		||||
    const QImage & left, const QImage & bottom, const QImage & back) {
 | 
			
		||||
    const QImage & left, const QImage & bottom, const QImage & back)
 | 
			
		||||
{
 | 
			
		||||
  auto texture = new QOpenGLTexture(QOpenGLTexture::TargetCubeMap);
 | 
			
		||||
  std::vector<QImage> faceTextures = {right, top, front, left, bottom, back};
 | 
			
		||||
  // Initialize skybox cubemap texture
 | 
			
		||||
@ -76,14 +79,13 @@ QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
 | 
			
		||||
    // On the first iteration, set format and allocate texture storage
 | 
			
		||||
    if (face == QOpenGLTexture::CubeMapPositiveX) {
 | 
			
		||||
      // This also needs to happen on the first iteration, anyways
 | 
			
		||||
      texture->setSize(
 | 
			
		||||
          faceImage.width(), faceImage.height(), faceImage.depth());
 | 
			
		||||
      texture->setSize(faceImage.width(), faceImage.height(),
 | 
			
		||||
                       faceImage.depth());
 | 
			
		||||
      texture->setFormat(QOpenGLTexture::RGBA8_UNorm);
 | 
			
		||||
      texture->allocateStorage();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    texture->setData(
 | 
			
		||||
        0, 0, face, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8,
 | 
			
		||||
    texture->setData(0, 0, face, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8,
 | 
			
		||||
                     faceImage.constBits());
 | 
			
		||||
    i++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -16,29 +16,32 @@
 | 
			
		||||
 | 
			
		||||
#include "qtkapi.h"
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Binds shader programs until the end of scope.
 | 
			
		||||
   * Does nothing if the shader program was already bound.
 | 
			
		||||
   *
 | 
			
		||||
   * See MeshRenderer::setUniform() for example.
 | 
			
		||||
   */
 | 
			
		||||
  class QTKAPI ShaderBindScope {
 | 
			
		||||
  class QTKAPI ShaderBindScope
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Constructors / Destructors
 | 
			
		||||
       ************************************************************************/
 | 
			
		||||
 | 
			
		||||
      explicit ShaderBindScope(
 | 
			
		||||
          QOpenGLShaderProgram * program, bool was_locked) :
 | 
			
		||||
          mWasBound(was_locked) {
 | 
			
		||||
      explicit ShaderBindScope(QOpenGLShaderProgram * program,
 | 
			
		||||
                               bool was_locked) : mWasBound(was_locked)
 | 
			
		||||
      {
 | 
			
		||||
        mProgram = program;
 | 
			
		||||
        if (!mWasBound) {
 | 
			
		||||
          mProgram->bind();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      ~ShaderBindScope() {
 | 
			
		||||
      ~ShaderBindScope()
 | 
			
		||||
      {
 | 
			
		||||
        if (!mWasBound) {
 | 
			
		||||
          mProgram->release();
 | 
			
		||||
        }
 | 
			
		||||
@ -56,7 +59,8 @@ namespace Qtk {
 | 
			
		||||
  /**
 | 
			
		||||
   * Factories for initializing various OpenGL textures
 | 
			
		||||
   */
 | 
			
		||||
  class QTKAPI OpenGLTextureFactory {
 | 
			
		||||
  class QTKAPI OpenGLTextureFactory
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Constructors / Destructors
 | 
			
		||||
@ -76,8 +80,8 @@ namespace Qtk {
 | 
			
		||||
       * @param flipY If true the image will be flipped on Y axis.
 | 
			
		||||
       * @return QImage object.
 | 
			
		||||
       */
 | 
			
		||||
      static QImage initImage(
 | 
			
		||||
          const char * image, bool flipX = false, bool flipY = false);
 | 
			
		||||
      static QImage initImage(const char * image, bool flipX = false,
 | 
			
		||||
                              bool flipY = false);
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * QOpenGLTexture factory
 | 
			
		||||
@ -88,8 +92,9 @@ namespace Qtk {
 | 
			
		||||
       * @param flipY If true the image will be flipped on Y axis.
 | 
			
		||||
       * @return Pointer to an initialized QOpenGLTexture object.
 | 
			
		||||
       */
 | 
			
		||||
      static QOpenGLTexture * initTexture(
 | 
			
		||||
          const char * texture, bool flipX = false, bool flipY = false);
 | 
			
		||||
      static QOpenGLTexture * initTexture(const char * texture,
 | 
			
		||||
                                          bool flipX = false,
 | 
			
		||||
                                          bool flipY = false);
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Cube map factory for initializing all sides of a CubeMap.
 | 
			
		||||
@ -128,12 +133,14 @@ namespace Qtk {
 | 
			
		||||
       * @param back Path to image for the back side of the CubeMap.
 | 
			
		||||
       * @return Pointer to an initialized QOpenGLTexture object.
 | 
			
		||||
       */
 | 
			
		||||
      static QOpenGLTexture * initCubeMap(
 | 
			
		||||
          const char * right, const char * top, const char * front,
 | 
			
		||||
          const char * left, const char * bottom, const char * back);
 | 
			
		||||
      static QOpenGLTexture * initCubeMap(const char * right, const char * top,
 | 
			
		||||
                                          const char * front, const char * left,
 | 
			
		||||
                                          const char * bottom,
 | 
			
		||||
                                          const char * back);
 | 
			
		||||
 | 
			
		||||
      /// The texture used in place of a missing texture.
 | 
			
		||||
      static QImage defaultTexture() {
 | 
			
		||||
      static QImage defaultTexture()
 | 
			
		||||
      {
 | 
			
		||||
        // Use plaster for default texture if image fails to load.
 | 
			
		||||
        // This prevents segfaults when loading a texture that doesn't exist.
 | 
			
		||||
        // TODO: Replace with a '?' texture to indicate missing texture.
 | 
			
		||||
@ -151,7 +158,8 @@ namespace Qtk {
 | 
			
		||||
   * TODO: Struct for (re)storing texture state
 | 
			
		||||
   * A struct to store flipX, flipY and other initial state needed to copy
 | 
			
		||||
   */
 | 
			
		||||
  class Texture {
 | 
			
		||||
  class Texture
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Typedefs
 | 
			
		||||
@ -169,7 +177,8 @@ namespace Qtk {
 | 
			
		||||
       *
 | 
			
		||||
       * @param value Texture to copy.
 | 
			
		||||
       */
 | 
			
		||||
      Texture(const Texture & value) {
 | 
			
		||||
      Texture(const Texture & value)
 | 
			
		||||
      {
 | 
			
		||||
        mOpenGLTexture = OpenGLTextureFactory::initTexture(value.mPath);
 | 
			
		||||
        mPath = value.mPath;
 | 
			
		||||
      }
 | 
			
		||||
@ -179,10 +188,12 @@ namespace Qtk {
 | 
			
		||||
       * @param flipX True if texture is to be flipped on the X axis.
 | 
			
		||||
       * @param flipY True if texture is to be flipped on the Y axis.
 | 
			
		||||
       */
 | 
			
		||||
      explicit Texture(
 | 
			
		||||
          const char * path, bool flipX = false, bool flipY = false) :
 | 
			
		||||
      explicit Texture(const char * path, bool flipX = false,
 | 
			
		||||
                       bool flipY = false) :
 | 
			
		||||
          mOpenGLTexture(OpenGLTextureFactory::initTexture(path, flipX, flipY)),
 | 
			
		||||
          mPath(path) {}
 | 
			
		||||
          mPath(path)
 | 
			
		||||
      {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Construct a Texture using an existing QOpenGLTexture.
 | 
			
		||||
@ -200,7 +211,8 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return True if the OpenGL texture has been initialized.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline bool hasTexture() const {
 | 
			
		||||
      [[nodiscard]] inline bool hasTexture() const
 | 
			
		||||
      {
 | 
			
		||||
        return mOpenGLTexture != Q_NULLPTR;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -211,7 +223,8 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return QOpenGLTexture associated with this Texture.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline QOpenGLTexture & getOpenGLTexture() const {
 | 
			
		||||
      [[nodiscard]] inline QOpenGLTexture & getOpenGLTexture() const
 | 
			
		||||
      {
 | 
			
		||||
        return *mOpenGLTexture;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -231,8 +244,9 @@ namespace Qtk {
 | 
			
		||||
       * @param flipX True if texture is to be flipped on the X axis.
 | 
			
		||||
       * @param flipY True if texture is to be flipped on the Y axis.
 | 
			
		||||
       */
 | 
			
		||||
      inline void setTexture(
 | 
			
		||||
          const std::string & path, bool flipX = false, bool flipY = false) {
 | 
			
		||||
      inline void setTexture(const std::string & path, bool flipX = false,
 | 
			
		||||
                             bool flipY = false)
 | 
			
		||||
      {
 | 
			
		||||
        setTexture(path.c_str(), flipX, flipY);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -241,8 +255,9 @@ namespace Qtk {
 | 
			
		||||
       * @param flipX True if texture is to be flipped on the X axis.
 | 
			
		||||
       * @param flipY True if texture is to be flipped on the Y axis.
 | 
			
		||||
       */
 | 
			
		||||
      inline void setTexture(
 | 
			
		||||
          const char * path, bool flipX = false, bool flipY = false) {
 | 
			
		||||
      inline void setTexture(const char * path, bool flipX = false,
 | 
			
		||||
                             bool flipY = false)
 | 
			
		||||
      {
 | 
			
		||||
        mOpenGLTexture = OpenGLTextureFactory::initTexture(path, flipX, flipY);
 | 
			
		||||
        mPath = path;
 | 
			
		||||
      }
 | 
			
		||||
@ -252,7 +267,8 @@ namespace Qtk {
 | 
			
		||||
       *
 | 
			
		||||
       * @param path Path to texture to use for all sides of the cube map.
 | 
			
		||||
       */
 | 
			
		||||
      virtual inline void setCubeMap(const char * path) {
 | 
			
		||||
      virtual inline void setCubeMap(const char * path)
 | 
			
		||||
      {
 | 
			
		||||
        mOpenGLTexture = OpenGLTextureFactory::initCubeMap(path);
 | 
			
		||||
        mPath = path;
 | 
			
		||||
      }
 | 
			
		||||
@ -267,11 +283,12 @@ namespace Qtk {
 | 
			
		||||
       * @param bottom Path to texture to use for bottom cube map side.
 | 
			
		||||
       * @param back Path to texture to use for back cube map side.
 | 
			
		||||
       */
 | 
			
		||||
      virtual inline void setCubeMap(
 | 
			
		||||
          const char * right, const char * top, const char * front,
 | 
			
		||||
          const char * left, const char * bottom, const char * back) {
 | 
			
		||||
        mOpenGLTexture = OpenGLTextureFactory::initCubeMap(
 | 
			
		||||
            right, top, front, left, bottom, back);
 | 
			
		||||
      virtual inline void setCubeMap(const char * right, const char * top,
 | 
			
		||||
                                     const char * front, const char * left,
 | 
			
		||||
                                     const char * bottom, const char * back)
 | 
			
		||||
      {
 | 
			
		||||
        mOpenGLTexture = OpenGLTextureFactory::initCubeMap(right, top, front,
 | 
			
		||||
                                                           left, bottom, back);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
@ -284,11 +301,12 @@ namespace Qtk {
 | 
			
		||||
       * @param bottom Path to texture to use for bottom cube map side.
 | 
			
		||||
       * @param back Path to texture to use for back cube map side.
 | 
			
		||||
       */
 | 
			
		||||
      virtual inline void setCubeMap(
 | 
			
		||||
          const QImage & right, const QImage & top, const QImage & front,
 | 
			
		||||
          const QImage & left, const QImage & bottom, const QImage & back) {
 | 
			
		||||
        mOpenGLTexture = OpenGLTextureFactory::initCubeMap(
 | 
			
		||||
            right, top, front, left, bottom, back);
 | 
			
		||||
      virtual inline void setCubeMap(const QImage & right, const QImage & top,
 | 
			
		||||
                                     const QImage & front, const QImage & left,
 | 
			
		||||
                                     const QImage & bottom, const QImage & back)
 | 
			
		||||
      {
 | 
			
		||||
        mOpenGLTexture = OpenGLTextureFactory::initCubeMap(right, top, front,
 | 
			
		||||
                                                           left, bottom, back);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
@ -299,7 +317,8 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @param texture QOpenGLTexture to use for this Texture.
 | 
			
		||||
       */
 | 
			
		||||
      inline void setTexture(QOpenGLTexture * texture) {
 | 
			
		||||
      inline void setTexture(QOpenGLTexture * texture)
 | 
			
		||||
      {
 | 
			
		||||
        mOpenGLTexture = texture;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,43 +19,51 @@ const QVector3D Transform3D::LocalRight(1.0f, 0.0f, 0.0f);
 | 
			
		||||
 * Public Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
void Transform3D::translate(const QVector3D & dt) {
 | 
			
		||||
void Transform3D::translate(const QVector3D & dt)
 | 
			
		||||
{
 | 
			
		||||
  m_dirty = true;
 | 
			
		||||
  mTranslation += dt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform3D::scale(const QVector3D & ds) {
 | 
			
		||||
void Transform3D::scale(const QVector3D & ds)
 | 
			
		||||
{
 | 
			
		||||
  m_dirty = true;
 | 
			
		||||
  mScale *= ds;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Transform3D::grow(const QVector3D & ds) {
 | 
			
		||||
void Transform3D::grow(const QVector3D & ds)
 | 
			
		||||
{
 | 
			
		||||
  m_dirty = true;
 | 
			
		||||
  mScale += ds;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform3D::rotate(const QQuaternion & dr) {
 | 
			
		||||
void Transform3D::rotate(const QQuaternion & dr)
 | 
			
		||||
{
 | 
			
		||||
  m_dirty = true;
 | 
			
		||||
  mRotation = dr * mRotation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform3D::setTranslation(const QVector3D & t) {
 | 
			
		||||
void Transform3D::setTranslation(const QVector3D & t)
 | 
			
		||||
{
 | 
			
		||||
  m_dirty = true;
 | 
			
		||||
  mTranslation = t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform3D::setScale(const QVector3D & s) {
 | 
			
		||||
void Transform3D::setScale(const QVector3D & s)
 | 
			
		||||
{
 | 
			
		||||
  m_dirty = true;
 | 
			
		||||
  mScale = s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform3D::setRotation(const QQuaternion & r) {
 | 
			
		||||
void Transform3D::setRotation(const QQuaternion & r)
 | 
			
		||||
{
 | 
			
		||||
  m_dirty = true;
 | 
			
		||||
  mRotation = r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const QMatrix4x4 & Transform3D::toMatrix() {
 | 
			
		||||
const QMatrix4x4 & Transform3D::toMatrix()
 | 
			
		||||
{
 | 
			
		||||
  if (m_dirty) {
 | 
			
		||||
    m_dirty = false;
 | 
			
		||||
    mWorld.setToIdentity();
 | 
			
		||||
@ -66,15 +74,18 @@ const QMatrix4x4 & Transform3D::toMatrix() {
 | 
			
		||||
  return mWorld;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVector3D Transform3D::getForward() const {
 | 
			
		||||
QVector3D Transform3D::getForward() const
 | 
			
		||||
{
 | 
			
		||||
  return mRotation.rotatedVector(LocalForward);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVector3D Transform3D::getUp() const {
 | 
			
		||||
QVector3D Transform3D::getUp() const
 | 
			
		||||
{
 | 
			
		||||
  return mRotation.rotatedVector(LocalUp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVector3D Transform3D::getRight() const {
 | 
			
		||||
QVector3D Transform3D::getRight() const
 | 
			
		||||
{
 | 
			
		||||
  return mRotation.rotatedVector(LocalRight);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -82,10 +93,12 @@ QVector3D Transform3D::getRight() const {
 | 
			
		||||
 * Private Methods
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
#ifndef QT_NO_DEBUG_STREAM
 | 
			
		||||
 | 
			
		||||
  QDebug operator<<(QDebug dbg, const Transform3D & transform) {
 | 
			
		||||
  QDebug operator<<(QDebug dbg, const Transform3D & transform)
 | 
			
		||||
  {
 | 
			
		||||
    dbg << "Transform3D\n{\n";
 | 
			
		||||
    dbg << "Position: <" << transform.getTranslation().x() << ", "
 | 
			
		||||
        << transform.getTranslation().y() << ", "
 | 
			
		||||
@ -102,14 +115,16 @@ namespace Qtk {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef QT_NO_DATASTREAM
 | 
			
		||||
  QDataStream & operator<<(QDataStream & out, const Transform3D & transform) {
 | 
			
		||||
  QDataStream & operator<<(QDataStream & out, const Transform3D & transform)
 | 
			
		||||
  {
 | 
			
		||||
    out << transform.mTranslation;
 | 
			
		||||
    out << transform.mScale;
 | 
			
		||||
    out << transform.mRotation;
 | 
			
		||||
    return out;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QDataStream & operator>>(QDataStream & in, Transform3D & transform) {
 | 
			
		||||
  QDataStream & operator>>(QDataStream & in, Transform3D & transform)
 | 
			
		||||
  {
 | 
			
		||||
    in >> transform.mTranslation;
 | 
			
		||||
    in >> transform.mScale;
 | 
			
		||||
    in >> transform.mRotation;
 | 
			
		||||
 | 
			
		||||
@ -20,11 +20,13 @@
 | 
			
		||||
 | 
			
		||||
#include "qtkapi.h"
 | 
			
		||||
 | 
			
		||||
namespace Qtk {
 | 
			
		||||
namespace Qtk
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Transform3D class to represent and modify object position in 3D space.
 | 
			
		||||
   */
 | 
			
		||||
  class QTKAPI Transform3D {
 | 
			
		||||
  class QTKAPI Transform3D
 | 
			
		||||
  {
 | 
			
		||||
    public:
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Constructors, Destructors
 | 
			
		||||
@ -32,7 +34,9 @@ namespace Qtk {
 | 
			
		||||
 | 
			
		||||
      inline Transform3D() :
 | 
			
		||||
          m_dirty(true), mScale(1.0f, 1.0f, 1.0f),
 | 
			
		||||
          mTranslation(0.0f, 0.0f, 0.0f) {}
 | 
			
		||||
          mTranslation(0.0f, 0.0f, 0.0f)
 | 
			
		||||
      {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /*************************************************************************
 | 
			
		||||
       * Public Methods
 | 
			
		||||
@ -48,7 +52,8 @@ namespace Qtk {
 | 
			
		||||
       * @param dy Y translation from last to current position.
 | 
			
		||||
       * @param dz Z translation from last to current position.
 | 
			
		||||
       */
 | 
			
		||||
      inline void translate(float dx, float dy, float dz) {
 | 
			
		||||
      inline void translate(float dx, float dy, float dz)
 | 
			
		||||
      {
 | 
			
		||||
        translate(QVector3D(dx, dy, dz));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -66,7 +71,8 @@ namespace Qtk {
 | 
			
		||||
       * @param dy Amount to scale on the Y axis.
 | 
			
		||||
       * @param dz Amount to scale on the Z axis.
 | 
			
		||||
       */
 | 
			
		||||
      inline void scale(float dx, float dy, float dz) {
 | 
			
		||||
      inline void scale(float dx, float dy, float dz)
 | 
			
		||||
      {
 | 
			
		||||
        scale(QVector3D(dx, dy, dz));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -75,7 +81,8 @@ namespace Qtk {
 | 
			
		||||
       *
 | 
			
		||||
       * @param factor Scalar to apply to all axis of the object.
 | 
			
		||||
       */
 | 
			
		||||
      inline void scale(float factor) {
 | 
			
		||||
      inline void scale(float factor)
 | 
			
		||||
      {
 | 
			
		||||
        scale(QVector3D(factor, factor, factor));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -89,14 +96,16 @@ namespace Qtk {
 | 
			
		||||
       * @param dy Amount to grow Y axis.
 | 
			
		||||
       * @param dz Amount to grow Z axis.
 | 
			
		||||
       */
 | 
			
		||||
      inline void grow(float dx, float dy, float dz) {
 | 
			
		||||
      inline void grow(float dx, float dy, float dz)
 | 
			
		||||
      {
 | 
			
		||||
        grow(QVector3D(dx, dy, dz));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * @param factor Amount to grow all axis equally.
 | 
			
		||||
       */
 | 
			
		||||
      inline void grow(float factor) {
 | 
			
		||||
      inline void grow(float factor)
 | 
			
		||||
      {
 | 
			
		||||
        grow(QVector3D(factor, factor, factor));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -109,7 +118,8 @@ namespace Qtk {
 | 
			
		||||
       * @param angle Angle to rotate.
 | 
			
		||||
       * @param axis Axis to rotate apply the rotation on.
 | 
			
		||||
       */
 | 
			
		||||
      inline void rotate(float angle, const QVector3D & axis) {
 | 
			
		||||
      inline void rotate(float angle, const QVector3D & axis)
 | 
			
		||||
      {
 | 
			
		||||
        rotate(QQuaternion::fromAxisAndAngle(axis, angle));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -121,7 +131,8 @@ namespace Qtk {
 | 
			
		||||
       * @param ay Y axis to apply the rotation on.
 | 
			
		||||
       * @param az Z axis to apply the rotation on.
 | 
			
		||||
       */
 | 
			
		||||
      inline void rotate(float angle, float ax, float ay, float az) {
 | 
			
		||||
      inline void rotate(float angle, float ax, float ay, float az)
 | 
			
		||||
      {
 | 
			
		||||
        rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -139,7 +150,8 @@ namespace Qtk {
 | 
			
		||||
       * @param y Y position to set transform.
 | 
			
		||||
       * @param z Z position to set transform.
 | 
			
		||||
       */
 | 
			
		||||
      inline void setTranslation(float x, float y, float z) {
 | 
			
		||||
      inline void setTranslation(float x, float y, float z)
 | 
			
		||||
      {
 | 
			
		||||
        setTranslation(QVector3D(x, y, z));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -153,7 +165,8 @@ namespace Qtk {
 | 
			
		||||
       * @param y Y axis scale to set for this transform.
 | 
			
		||||
       * @param z Z axis scale to set for this transform.
 | 
			
		||||
       */
 | 
			
		||||
      inline void setScale(float x, float y, float z) {
 | 
			
		||||
      inline void setScale(float x, float y, float z)
 | 
			
		||||
      {
 | 
			
		||||
        setScale(QVector3D(x, y, z));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -171,7 +184,8 @@ namespace Qtk {
 | 
			
		||||
       * @param angle Angle to set for rotation.
 | 
			
		||||
       * @param axis Axis to set rotation for.
 | 
			
		||||
       */
 | 
			
		||||
      inline void setRotation(float angle, const QVector3D & axis) {
 | 
			
		||||
      inline void setRotation(float angle, const QVector3D & axis)
 | 
			
		||||
      {
 | 
			
		||||
        setRotation(QQuaternion::fromAxisAndAngle(axis, angle));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -183,7 +197,8 @@ namespace Qtk {
 | 
			
		||||
       * @param ay Y axis to set angle for.
 | 
			
		||||
       * @param az Z axis to set angle for.
 | 
			
		||||
       */
 | 
			
		||||
      inline void setRotation(float angle, float ax, float ay, float az) {
 | 
			
		||||
      inline void setRotation(float angle, float ax, float ay, float az)
 | 
			
		||||
      {
 | 
			
		||||
        setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -194,7 +209,8 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Translation for this transform.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline const QVector3D & getTranslation() const {
 | 
			
		||||
      [[nodiscard]] inline const QVector3D & getTranslation() const
 | 
			
		||||
      {
 | 
			
		||||
        return mTranslation;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -206,7 +222,8 @@ namespace Qtk {
 | 
			
		||||
      /**
 | 
			
		||||
       * @return Rotation for this transform.
 | 
			
		||||
       */
 | 
			
		||||
      [[nodiscard]] inline const QQuaternion & getRotation() const {
 | 
			
		||||
      [[nodiscard]] inline const QQuaternion & getRotation() const
 | 
			
		||||
      {
 | 
			
		||||
        return mRotation;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -250,10 +267,10 @@ namespace Qtk {
 | 
			
		||||
      bool m_dirty;
 | 
			
		||||
 | 
			
		||||
#ifndef QT_NO_DATASTREAM
 | 
			
		||||
      friend QDataStream & operator<<(
 | 
			
		||||
          QDataStream & out, const Transform3D & transform);
 | 
			
		||||
      friend QDataStream & operator>>(
 | 
			
		||||
          QDataStream & in, Transform3D & transform);
 | 
			
		||||
      friend QDataStream & operator<<(QDataStream & out,
 | 
			
		||||
                                      const Transform3D & transform);
 | 
			
		||||
      friend QDataStream & operator>>(QDataStream & in,
 | 
			
		||||
                                      Transform3D & transform);
 | 
			
		||||
#endif
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user