Work on separating widget from main application
+ Thanks @OgreTransporter for help in #4! + Closes #4
This commit is contained in:
48
src/abstractscene.cpp
Normal file
48
src/abstractscene.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*##############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
||||
## About: Classes for managing objects and data within a scene ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################*/
|
||||
|
||||
#include <abstractscene.h>
|
||||
#include <camera3d.h>
|
||||
#include <resourcemanager.h>
|
||||
#include <texture.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
Camera3D Scene::mCamera;
|
||||
QMatrix4x4 Scene::mProjection;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Constructors, Destructors
|
||||
******************************************************************************/
|
||||
|
||||
Scene::Scene()
|
||||
{
|
||||
mCamera.transform().setTranslation(0.0f, 0.0f, 20.0f);
|
||||
mCamera.transform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
for (auto & mesh : mMeshes) delete mesh;
|
||||
for (auto & model : mModels) delete model;
|
||||
if (mSkybox != Q_NULLPTR) delete mSkybox;
|
||||
}
|
||||
|
||||
void Scene::privDraw()
|
||||
{
|
||||
if (!mInit) {
|
||||
initializeOpenGLFunctions();
|
||||
init();
|
||||
mInit = true;
|
||||
}
|
||||
if (mSkybox != Q_NULLPTR) mSkybox->draw();
|
||||
for (auto & model : mModels) model->draw();
|
||||
for (const auto & mesh : mMeshes) mesh->draw();
|
||||
}
|
||||
|
||||
54
src/abstractscene.h
Normal file
54
src/abstractscene.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*##############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
||||
## About: Classes for managing objects and data within a scene ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################*/
|
||||
|
||||
#ifndef QTK_SCENE_H
|
||||
#define QTK_SCENE_H
|
||||
|
||||
#include <camera3d.h>
|
||||
#include <meshrenderer.h>
|
||||
#include <model.h>
|
||||
#include <skybox.h>
|
||||
|
||||
#include <QMatrix4x4>
|
||||
|
||||
|
||||
namespace Qtk {
|
||||
class Scene : protected QOpenGLFunctions {
|
||||
friend class MainWidget;
|
||||
public:
|
||||
Scene();
|
||||
~Scene();
|
||||
|
||||
virtual void init() = 0;
|
||||
virtual void draw() = 0;
|
||||
virtual void update() = 0;
|
||||
|
||||
static Camera3D & Camera() { return mCamera;}
|
||||
static QMatrix4x4 View() { return mCamera.toMatrix();}
|
||||
static QMatrix4x4 & Projection() { return mProjection;}
|
||||
|
||||
inline Skybox * getSkybox() {return mSkybox;}
|
||||
inline void setSkybox(Skybox * skybox) {
|
||||
mSkybox = skybox;
|
||||
}
|
||||
|
||||
private:
|
||||
static Camera3D mCamera;
|
||||
static QMatrix4x4 mProjection;
|
||||
bool mInit = false;
|
||||
|
||||
void privDraw();
|
||||
|
||||
protected:
|
||||
Skybox * mSkybox;
|
||||
std::vector<MeshRenderer *> mMeshes;
|
||||
std::vector<Model *> mModels;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QTK_SCENE_H
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <camera3d.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
const QVector3D Camera3D::LocalForward(0.0f, 0.0f, -1.0f);
|
||||
const QVector3D Camera3D::LocalUp(0.0f, 1.0f, 0.0f);
|
||||
|
||||
@@ -12,51 +12,53 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include <transform3D.h>
|
||||
#include <qtkapi.h>
|
||||
|
||||
namespace Qtk {
|
||||
class QTKAPI Camera3D {
|
||||
public:
|
||||
// Constants
|
||||
static const QVector3D LocalForward;
|
||||
static const QVector3D LocalUp;
|
||||
static const QVector3D LocalRight;
|
||||
|
||||
class Camera3D {
|
||||
public:
|
||||
// Constants
|
||||
static const QVector3D LocalForward;
|
||||
static const QVector3D LocalUp;
|
||||
static const QVector3D LocalRight;
|
||||
// Accessors
|
||||
inline Transform3D & transform() { return mTransform;}
|
||||
inline const QVector3D & translation() const
|
||||
{ return mTransform.translation();}
|
||||
inline const QQuaternion & rotation() const
|
||||
{ return mTransform.rotation();}
|
||||
const QMatrix4x4 & toMatrix();
|
||||
|
||||
// Accessors
|
||||
inline Transform3D & transform() { return mTransform;}
|
||||
inline const QVector3D & translation() const
|
||||
{ return mTransform.translation();}
|
||||
inline const QQuaternion & rotation() const
|
||||
{ return mTransform.rotation();}
|
||||
const QMatrix4x4 & toMatrix();
|
||||
// Queries
|
||||
inline QVector3D forward() const
|
||||
{ return mTransform.rotation().rotatedVector(LocalForward);}
|
||||
inline QVector3D right() const
|
||||
{ return mTransform.rotation().rotatedVector(LocalRight);}
|
||||
inline QVector3D up() const
|
||||
{ return mTransform.rotation().rotatedVector(LocalUp);}
|
||||
|
||||
// Queries
|
||||
inline QVector3D forward() const
|
||||
{ return mTransform.rotation().rotatedVector(LocalForward);}
|
||||
inline QVector3D right() const
|
||||
{ return mTransform.rotation().rotatedVector(LocalRight);}
|
||||
inline QVector3D up() const
|
||||
{ return mTransform.rotation().rotatedVector(LocalUp);}
|
||||
|
||||
private:
|
||||
Transform3D mTransform;
|
||||
QMatrix4x4 mWorld;
|
||||
private:
|
||||
Transform3D mTransform;
|
||||
QMatrix4x4 mWorld;
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
friend QDataStream & operator<<(QDataStream & out, Camera3D & transform);
|
||||
friend QDataStream & operator>>(QDataStream & in, Camera3D & transform);
|
||||
friend QDataStream & operator<<(QDataStream & out, Camera3D & transform);
|
||||
friend QDataStream & operator>>(QDataStream & in, Camera3D & transform);
|
||||
#endif
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(Camera3D, Q_MOVABLE_TYPE);
|
||||
};
|
||||
|
||||
// Qt Streams
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
QDataStream & operator<<(QDataStream & out, const Camera3D & transform);
|
||||
QDataStream & operator>>(QDataStream & in, Camera3D & transform);
|
||||
QDataStream & operator<<(QDataStream & out, const Camera3D & transform);
|
||||
QDataStream & operator>>(QDataStream & in, Camera3D & transform);
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug dbg, const Camera3D & transform);
|
||||
QDebug operator<<(QDebug dbg, const Camera3D & transform);
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_DECLARE_TYPEINFO(Qtk::Camera3D, Q_MOVABLE_TYPE);
|
||||
|
||||
#endif // QTK_CAMERA3D_H
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <input.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
/*******************************************************************************
|
||||
* Static Helper Structs
|
||||
|
||||
89
src/input.h
89
src/input.h
@@ -12,52 +12,53 @@
|
||||
#include <QPoint>
|
||||
#include <Qt>
|
||||
|
||||
#include <qtkapi.h>
|
||||
|
||||
class Input {
|
||||
friend class MainWidget;
|
||||
public:
|
||||
namespace Qtk {
|
||||
class QTKAPI Input {
|
||||
friend class MainWidget;
|
||||
public:
|
||||
// Possible key states
|
||||
enum InputState
|
||||
{
|
||||
InputInvalid,
|
||||
InputRegistered,
|
||||
InputUnregistered,
|
||||
InputTriggered,
|
||||
InputPressed,
|
||||
InputReleased
|
||||
};
|
||||
|
||||
// Possible key states
|
||||
enum InputState
|
||||
{
|
||||
InputInvalid,
|
||||
InputRegistered,
|
||||
InputUnregistered,
|
||||
InputTriggered,
|
||||
InputPressed,
|
||||
InputReleased
|
||||
// State checking
|
||||
inline static bool keyTriggered(Qt::Key key)
|
||||
{ return keyState(key) == InputTriggered;}
|
||||
inline static bool keyPressed(Qt::Key key)
|
||||
{ return keyState(key) == InputPressed;}
|
||||
inline static bool keyReleased(Qt::Key key)
|
||||
{ return keyState(key) == InputReleased;}
|
||||
inline static bool buttonTriggered(Qt::MouseButton button)
|
||||
{ return buttonState(button) == InputTriggered;}
|
||||
inline static bool buttonPressed(Qt::MouseButton button)
|
||||
{ return buttonState(button) == InputPressed;}
|
||||
inline static bool buttonReleased(Qt::MouseButton button)
|
||||
{ return buttonState(button) == InputReleased;}
|
||||
|
||||
// Implementation
|
||||
static InputState keyState(Qt::Key key);
|
||||
static InputState buttonState(Qt::MouseButton button);
|
||||
|
||||
static QPoint mousePosition();
|
||||
static QPoint mouseDelta();
|
||||
|
||||
private:
|
||||
// State updating
|
||||
static void update();
|
||||
static void registerKeyPress(int key);
|
||||
static void registerKeyRelease(int key);
|
||||
static void registerMousePress(Qt::MouseButton button);
|
||||
static void registerMouseRelease(Qt::MouseButton button);
|
||||
static void reset();
|
||||
};
|
||||
|
||||
// State checking
|
||||
inline static bool keyTriggered(Qt::Key key)
|
||||
{ return keyState(key) == InputTriggered;}
|
||||
inline static bool keyPressed(Qt::Key key)
|
||||
{ return keyState(key) == InputPressed;}
|
||||
inline static bool keyReleased(Qt::Key key)
|
||||
{ return keyState(key) == InputReleased;}
|
||||
inline static bool buttonTriggered(Qt::MouseButton button)
|
||||
{ return buttonState(button) == InputTriggered;}
|
||||
inline static bool buttonPressed(Qt::MouseButton button)
|
||||
{ return buttonState(button) == InputPressed;}
|
||||
inline static bool buttonReleased(Qt::MouseButton button)
|
||||
{ return buttonState(button) == InputReleased;}
|
||||
|
||||
// Implementation
|
||||
static InputState keyState(Qt::Key key);
|
||||
static InputState buttonState(Qt::MouseButton button);
|
||||
|
||||
static QPoint mousePosition();
|
||||
static QPoint mouseDelta();
|
||||
|
||||
private:
|
||||
|
||||
// State updating
|
||||
static void update();
|
||||
static void registerKeyPress(int key);
|
||||
static void registerKeyRelease(int key);
|
||||
static void registerMousePress(Qt::MouseButton button);
|
||||
static void registerMouseRelease(Qt::MouseButton button);
|
||||
static void reset();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QTOPENGL_INPUT_H
|
||||
|
||||
@@ -9,30 +9,30 @@
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include <input.h>
|
||||
#include <mesh.h>
|
||||
#include <object.h>
|
||||
#include <scene.h>
|
||||
|
||||
#include <mainwidget.h>
|
||||
#include <mesh.h>
|
||||
#include <abstractscene.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
/*******************************************************************************
|
||||
* Constructors, Destructors
|
||||
******************************************************************************/
|
||||
|
||||
MainWidget::MainWidget() : mDebugLogger(Q_NULLPTR)
|
||||
MainWidget::MainWidget() : mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
|
||||
{
|
||||
initializeWidget();
|
||||
}
|
||||
|
||||
// Constructor for using this widget in QtDesigner
|
||||
MainWidget::MainWidget(QWidget *parent) : QOpenGLWidget(parent), mDebugLogger(Q_NULLPTR)
|
||||
MainWidget::MainWidget(QWidget *parent) : QOpenGLWidget(parent),
|
||||
mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
|
||||
{
|
||||
initializeWidget();
|
||||
}
|
||||
|
||||
MainWidget::MainWidget(const QSurfaceFormat &format)
|
||||
: mDebugLogger(Q_NULLPTR)
|
||||
: mScene(Q_NULLPTR), mDebugLogger(Q_NULLPTR)
|
||||
{
|
||||
setFormat(format);
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
@@ -54,49 +54,6 @@ void MainWidget::teardownGL()
|
||||
// Nothing to teardown yet...
|
||||
}
|
||||
|
||||
void MainWidget::initObjects()
|
||||
{
|
||||
mScene = new Scene;
|
||||
|
||||
// Drawing a primitive object using Qt and OpenGL
|
||||
// The Object class only stores basic QOpenGL* members and shape data
|
||||
// + Within mainwidget, mObject serves as a basic QOpenGL example
|
||||
mObject = new Object("testObject");
|
||||
mObject->setVertices(Cube(QTK_DRAW_ELEMENTS).vertices());
|
||||
mObject->setIndices(Cube(QTK_DRAW_ELEMENTS).indices());
|
||||
mObject->mProgram.create();
|
||||
mObject->mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,
|
||||
":/solid-ambient.vert");
|
||||
mObject->mProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,
|
||||
":/solid-ambient.frag");
|
||||
mObject->mProgram.link();
|
||||
mObject->mProgram.bind();
|
||||
|
||||
mObject->mVAO.create();
|
||||
mObject->mVAO.bind();
|
||||
|
||||
mObject->mVBO.create();
|
||||
mObject->mVBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
|
||||
mObject->mVBO.bind();
|
||||
|
||||
mObject->mVBO.allocate(mObject->vertices().data(),
|
||||
mObject->vertices().size()
|
||||
* sizeof(mObject->vertices()[0]));
|
||||
|
||||
mObject->mProgram.enableAttributeArray(0);
|
||||
mObject->mProgram.setAttributeBuffer(0, GL_FLOAT, 0,
|
||||
3, sizeof(mObject->vertices()[0]));
|
||||
mObject->mProgram.setUniformValue("uColor", QVector3D(1.0f, 0.0f, 0.0f));
|
||||
mObject->mProgram.setUniformValue("uLightColor", WHITE);
|
||||
mObject->mProgram.setUniformValue("uAmbientStrength", 0.75f);
|
||||
|
||||
mObject->mVBO.release();
|
||||
mObject->mVAO.release();
|
||||
mObject->mProgram.release();
|
||||
|
||||
mObject->mTransform.setTranslation(13.0f, 0.0f, -2.0f);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Inherited Virtual Member Functions
|
||||
@@ -108,18 +65,7 @@ void MainWidget::paintGL()
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Draw the scene first, since it handles drawing our skybox
|
||||
mScene->draw();
|
||||
|
||||
// Draw any additional objects within mainwidget manually
|
||||
mObject->mProgram.bind();
|
||||
mObject->mVAO.bind();
|
||||
mObject->mProgram.setUniformValue("uModel", mObject->mTransform.toMatrix());
|
||||
mObject->mProgram.setUniformValue("uView", Scene::Camera().toMatrix());
|
||||
mObject->mProgram.setUniformValue("uProjection", Scene::Projection());
|
||||
glDrawElements(GL_TRIANGLES, mObject->indices().size(),
|
||||
GL_UNSIGNED_INT, mObject->indices().data());
|
||||
mObject->mVAO.release();
|
||||
mObject->mProgram.release();
|
||||
if (mScene != Q_NULLPTR) mScene->privDraw();
|
||||
}
|
||||
|
||||
void MainWidget::initializeGL()
|
||||
@@ -150,9 +96,6 @@ void MainWidget::initializeGL()
|
||||
glClearDepth(1.0f);
|
||||
glClearColor(0.0f, 0.25f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Initialize default objects within the scene
|
||||
initObjects();
|
||||
}
|
||||
|
||||
void MainWidget::resizeGL(int width, int height)
|
||||
@@ -172,7 +115,7 @@ void MainWidget::update()
|
||||
{
|
||||
updateCameraInput();
|
||||
|
||||
mScene->update();
|
||||
if (mScene != Q_NULLPTR) mScene->update();
|
||||
|
||||
QWidget::update();
|
||||
}
|
||||
|
||||
@@ -15,57 +15,61 @@
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLWidget>
|
||||
|
||||
#define QTK_DEBUG
|
||||
#include <qtkapi.h>
|
||||
#include <abstractscene.h>
|
||||
|
||||
class MeshRenderer;
|
||||
class Model;
|
||||
class Object;
|
||||
class Scene;
|
||||
class Skybox;
|
||||
class Texture;
|
||||
|
||||
class MainWidget : public QOpenGLWidget,
|
||||
protected QOpenGLFunctions {
|
||||
Q_OBJECT;
|
||||
namespace Qtk {
|
||||
class QTKAPI MainWidget : public QOpenGLWidget,
|
||||
protected QOpenGLFunctions {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
MainWidget();
|
||||
explicit MainWidget(QWidget *parent);
|
||||
explicit MainWidget(const QSurfaceFormat &format);
|
||||
~MainWidget() override;
|
||||
public:
|
||||
// Constructors
|
||||
MainWidget();
|
||||
explicit MainWidget(QWidget *parent);
|
||||
explicit MainWidget(const QSurfaceFormat &format);
|
||||
~MainWidget() override;
|
||||
|
||||
private:
|
||||
void teardownGL();
|
||||
void initObjects();
|
||||
private:
|
||||
void teardownGL();
|
||||
|
||||
public:
|
||||
// Inherited virtual Members
|
||||
void paintGL() override;
|
||||
void initializeGL() override;
|
||||
void resizeGL(int width, int height) override;
|
||||
public:
|
||||
// Inherited virtual Members
|
||||
void paintGL() override;
|
||||
void initializeGL() override;
|
||||
void resizeGL(int width, int height) override;
|
||||
|
||||
protected slots:
|
||||
void update();
|
||||
void messageLogged(const QOpenGLDebugMessage &msg);
|
||||
inline Scene * getScene() {return mScene;}
|
||||
inline void setScene(Scene * scene) {
|
||||
if (mScene != Q_NULLPTR) delete mScene;
|
||||
mScene = scene;
|
||||
}
|
||||
|
||||
// Protected Helpers
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void keyReleaseEvent(QKeyEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
protected slots:
|
||||
void update();
|
||||
#ifdef QTK_DEBUG
|
||||
void messageLogged(const QOpenGLDebugMessage &msg);
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Private helpers
|
||||
void initializeWidget();
|
||||
void printContextInformation();
|
||||
void updateCameraInput();
|
||||
// Protected Helpers
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void keyReleaseEvent(QKeyEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
|
||||
Scene * mScene;
|
||||
Object * mObject;
|
||||
private:
|
||||
// Private helpers
|
||||
void initializeWidget();
|
||||
void updateCameraInput();
|
||||
|
||||
QOpenGLDebugLogger * mDebugLogger;
|
||||
};
|
||||
Scene * mScene;
|
||||
#ifdef QTK_DEBUG
|
||||
void printContextInformation();
|
||||
QOpenGLDebugLogger * mDebugLogger;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QTK_MAINWIDGET_H
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(QIcon("../resources/icon.png"));
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "main-widget_export.h"
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MAIN_WIDGET_EXPORT MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
@@ -1,104 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Qtk - MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="MainWidget" name="openGLWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>775</width>
|
||||
<height>550</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuTest">
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<addaction name="actionOpen"/>
|
||||
<addaction name="actionSave_2"/>
|
||||
<addaction name="actionSave_as"/>
|
||||
<addaction name="actionExit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
<string>View</string>
|
||||
</property>
|
||||
<addaction name="actionShow_Console"/>
|
||||
</widget>
|
||||
<addaction name="menuTest"/>
|
||||
<addaction name="menuView"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<action name="actionOtherTest">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpen">
|
||||
<property name="text">
|
||||
<string>Open...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave_2">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave_as">
|
||||
<property name="text">
|
||||
<string>Save as...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExit">
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShow_Console">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Console</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>MainWidget</class>
|
||||
<extends>QOpenGLWidget</extends>
|
||||
<header>mainwidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <mesh.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
Cube::Cube(DrawMode mode)
|
||||
{
|
||||
|
||||
122
src/mesh.h
122
src/mesh.h
@@ -12,25 +12,27 @@
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
|
||||
#include <qtkapi.h>
|
||||
#include <transform3D.h>
|
||||
|
||||
class MeshRenderer;
|
||||
class Object;
|
||||
namespace Qtk {
|
||||
class MeshRenderer;
|
||||
class Object;
|
||||
|
||||
// Define vertices for drawing a cube using two faces (8 vertex points)
|
||||
// Front Vertices
|
||||
// Define vertices for drawing a cube using two faces (8 vertex points)
|
||||
// Front Vertices
|
||||
#define VERTEX_FTR QVector3D( 0.5f, 0.5f, 0.5f) // 1
|
||||
#define VERTEX_FTL QVector3D(-0.5f, 0.5f, 0.5f) // 2
|
||||
#define VERTEX_FBL QVector3D(-0.5f, -0.5f, 0.5f) // 3
|
||||
#define VERTEX_FBR QVector3D( 0.5f, -0.5f, 0.5f) // 4
|
||||
|
||||
// Back Vertices
|
||||
// Back Vertices
|
||||
#define VERTEX_BTR QVector3D( 0.5f, 0.5f, -0.5f) // 5
|
||||
#define VERTEX_BTL QVector3D(-0.5f, 0.5f, -0.5f) // 6
|
||||
#define VERTEX_BBL QVector3D(-0.5f, -0.5f, -0.5f) // 7
|
||||
#define VERTEX_BBR QVector3D( 0.5f, -0.5f, -0.5f) // 8
|
||||
|
||||
// Direction vectors
|
||||
// Direction vectors
|
||||
#define VECTOR_UP QVector3D(0.0f, 1.0f, 0.0f)
|
||||
#define VECTOR_DOWN QVector3D(0.0f, -1.0f, 0.0f)
|
||||
#define VECTOR_LEFT QVector3D(-1.0f, 0.0f, 0.0f)
|
||||
@@ -38,25 +40,25 @@ class Object;
|
||||
#define VECTOR_FORWARD QVector3D(0.0f, 0.0f, 1.0f)
|
||||
#define VECTOR_BACK QVector3D(0.0f, 0.0f, -1.0f)
|
||||
|
||||
// Identity and zero vectors
|
||||
// Identity and zero vectors
|
||||
#define VECTOR_ONE QVector3D(1.0f, 1.0f, 1.0f)
|
||||
#define VECTOR_ZERO QVector3D(0.0f, 0.0f, 0.0f)
|
||||
|
||||
// A series of direction vectors to represent cube face normal
|
||||
// A series of direction vectors to represent cube face normal
|
||||
#define FACE_TOP VECTOR_UP, VECTOR_UP, VECTOR_UP, \
|
||||
VECTOR_UP, VECTOR_UP, VECTOR_UP
|
||||
VECTOR_UP, VECTOR_UP, VECTOR_UP
|
||||
#define FACE_BOTTOM VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN, \
|
||||
VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN
|
||||
VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN
|
||||
#define FACE_LEFT VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT, \
|
||||
VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT
|
||||
VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT
|
||||
#define FACE_RIGHT VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT, \
|
||||
VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT
|
||||
VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT
|
||||
#define FACE_FRONT VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD, \
|
||||
VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD
|
||||
VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD
|
||||
#define FACE_BACK VECTOR_BACK, VECTOR_BACK, VECTOR_BACK, \
|
||||
VECTOR_BACK, VECTOR_BACK, VECTOR_BACK
|
||||
VECTOR_BACK, VECTOR_BACK, VECTOR_BACK
|
||||
|
||||
// Colors using QVector3Ds as RGB values
|
||||
// Colors using QVector3Ds as RGB values
|
||||
#define WHITE VECTOR_ONE
|
||||
#define BLACK VECTOR_ZERO
|
||||
#define RED QVector3D(1.0f, 0.0f, 0.0f)
|
||||
@@ -71,62 +73,62 @@ class Object;
|
||||
#define UV_RIGHT QVector2D(0.0f, 1.0f)
|
||||
#define UV_CORNER QVector2D(1.0f, 1.0f)
|
||||
|
||||
typedef std::vector<QVector3D> Vertices;
|
||||
typedef std::vector<QVector3D> Colors;
|
||||
typedef std::vector<GLuint> Indices;
|
||||
typedef std::vector<QVector2D> TexCoords;
|
||||
typedef std::vector<QVector3D> Normals;
|
||||
|
||||
typedef std::vector<QVector3D> Vertices;
|
||||
typedef std::vector<QVector3D> Colors;
|
||||
typedef std::vector<GLuint> Indices;
|
||||
typedef std::vector<QVector2D> TexCoords;
|
||||
typedef std::vector<QVector3D> Normals;
|
||||
enum DrawMode { QTK_DRAW_ARRAYS, QTK_DRAW_ELEMENTS, QTK_DRAW_ELEMENTS_NORMALS };
|
||||
|
||||
enum DrawMode { QTK_DRAW_ARRAYS, QTK_DRAW_ELEMENTS, QTK_DRAW_ELEMENTS_NORMALS };
|
||||
struct QTKAPI ShapeBase {
|
||||
ShapeBase(DrawMode mode=QTK_DRAW_ARRAYS, Vertices v={},Indices i={}, Colors c={},
|
||||
TexCoords t={}, Normals n={})
|
||||
: mVertices(v), mColors(c), mIndices(i), mTexCoords(t), mNormals(n)
|
||||
{}
|
||||
|
||||
struct ShapeBase {
|
||||
ShapeBase(DrawMode mode=QTK_DRAW_ARRAYS, Vertices v={},Indices i={}, Colors c={},
|
||||
TexCoords t={}, Normals n={})
|
||||
: mVertices(v), mColors(c), mIndices(i), mTexCoords(t), mNormals(n)
|
||||
{}
|
||||
inline const Vertices & vertices() const { return mVertices;}
|
||||
inline const Indices & indices() const { return mIndices;}
|
||||
inline const Colors & colors() const { return mColors;}
|
||||
inline const TexCoords & texCoords() const { return mTexCoords;}
|
||||
inline const Normals & normals() const { return mNormals;}
|
||||
|
||||
inline const Vertices & vertices() const { return mVertices;}
|
||||
inline const Indices & indices() const { return mIndices;}
|
||||
inline const Colors & colors() const { return mColors;}
|
||||
inline const TexCoords & texCoords() const { return mTexCoords;}
|
||||
inline const Normals & normals() const { return mNormals;}
|
||||
protected:
|
||||
DrawMode mDrawMode;
|
||||
|
||||
protected:
|
||||
DrawMode mDrawMode;
|
||||
Vertices mVertices;
|
||||
Colors mColors;
|
||||
Indices mIndices;
|
||||
TexCoords mTexCoords;
|
||||
Normals mNormals;
|
||||
};
|
||||
|
||||
Vertices mVertices;
|
||||
Colors mColors;
|
||||
Indices mIndices;
|
||||
TexCoords mTexCoords;
|
||||
Normals mNormals;
|
||||
};
|
||||
struct Shape : public ShapeBase {
|
||||
friend MeshRenderer;
|
||||
friend Object;
|
||||
Shape () {}
|
||||
Shape(const ShapeBase & rhs) : ShapeBase(rhs) {}
|
||||
|
||||
struct Shape : public ShapeBase {
|
||||
friend MeshRenderer;
|
||||
friend Object;
|
||||
Shape () {}
|
||||
Shape(const ShapeBase & rhs) : ShapeBase(rhs) {}
|
||||
|
||||
virtual inline void setVertices(const Vertices & value) {mVertices = value;}
|
||||
virtual inline void setIndices(const Indices & value) {mIndices = value;}
|
||||
virtual inline void setColors(const Colors & value) {mColors = value;}
|
||||
virtual inline void setTexCoords(const TexCoords & value) {mTexCoords = value;}
|
||||
virtual inline void setNormals(const Normals & value) {mNormals = value;}
|
||||
virtual inline void setShape(const Shape & value) { *this = value;}
|
||||
};
|
||||
virtual inline void setVertices(const Vertices & value) {mVertices = value;}
|
||||
virtual inline void setIndices(const Indices & value) {mIndices = value;}
|
||||
virtual inline void setColors(const Colors & value) {mColors = value;}
|
||||
virtual inline void setTexCoords(const TexCoords & value) {mTexCoords = value;}
|
||||
virtual inline void setNormals(const Normals & value) {mNormals = value;}
|
||||
virtual inline void setShape(const Shape & value) { *this = value;}
|
||||
};
|
||||
|
||||
// Primitives inherit from ShapeBase, does not allow setting of shape values
|
||||
class Mesh {
|
||||
class QTKAPI Mesh {
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
struct Cube : public ShapeBase {
|
||||
Cube(DrawMode mode=QTK_DRAW_ARRAYS);
|
||||
};
|
||||
struct QTKAPI Cube : public ShapeBase {
|
||||
Cube(DrawMode mode=QTK_DRAW_ARRAYS);
|
||||
};
|
||||
|
||||
struct Triangle : public ShapeBase {
|
||||
Triangle(DrawMode mode=QTK_DRAW_ARRAYS);
|
||||
};
|
||||
struct QTKAPI Triangle : public ShapeBase {
|
||||
Triangle(DrawMode mode=QTK_DRAW_ARRAYS);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QTK_MESH_H
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
|
||||
#include <QImageReader>
|
||||
|
||||
#include <scene.h>
|
||||
#include <abstractscene.h>
|
||||
#include <meshrenderer.h>
|
||||
#include <texture.h>
|
||||
|
||||
#include <meshrenderer.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
// Static QHash that holds all MeshRenderer instances using their mName as keys
|
||||
MeshRenderer::MeshManager MeshRenderer::sInstances;
|
||||
Qtk::MeshRenderer::MeshManager Qtk::MeshRenderer::sInstances;
|
||||
|
||||
MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape)
|
||||
: Object(name, shape), mVertexShader(":/multi-color.vert"),
|
||||
|
||||
@@ -10,68 +10,71 @@
|
||||
|
||||
#include <mesh.h>
|
||||
#include <object.h>
|
||||
#include <qtkapi.h>
|
||||
|
||||
|
||||
class MeshRenderer : public Object {
|
||||
public:
|
||||
// Delegate constructors
|
||||
MeshRenderer(const char * name, Vertices vertices, Indices indices,
|
||||
DrawMode mode=QTK_DRAW_ARRAYS)
|
||||
: MeshRenderer(name, ShapeBase(mode, vertices, indices))
|
||||
{}
|
||||
MeshRenderer(const char * name)
|
||||
: MeshRenderer(name, Cube(QTK_DRAW_ELEMENTS))
|
||||
{}
|
||||
// Constructor
|
||||
MeshRenderer(const char * name, const ShapeBase &shape);
|
||||
~MeshRenderer();
|
||||
namespace Qtk {
|
||||
class QTKAPI MeshRenderer : public Object {
|
||||
public:
|
||||
// Delegate constructors
|
||||
MeshRenderer(const char * name, Vertices vertices, Indices indices,
|
||||
DrawMode mode=QTK_DRAW_ARRAYS)
|
||||
: MeshRenderer(name, ShapeBase(mode, vertices, indices))
|
||||
{}
|
||||
MeshRenderer(const char * name)
|
||||
: MeshRenderer(name, Cube(QTK_DRAW_ELEMENTS))
|
||||
{}
|
||||
// Constructor
|
||||
MeshRenderer(const char * name, const ShapeBase &shape);
|
||||
~MeshRenderer();
|
||||
|
||||
// Retrieve a mesh by name stored within a static QHash
|
||||
static MeshRenderer * getInstance(const QString & name);
|
||||
// Retrieve a mesh by name stored within a static QHash
|
||||
static MeshRenderer * getInstance(const QString & name);
|
||||
|
||||
void init();
|
||||
void draw();
|
||||
void init();
|
||||
void draw();
|
||||
|
||||
// Draw types like GL_TRIANGLES, GL_POINTS, GL_LINES, etc
|
||||
void setDrawType(int drawType) { mDrawType = drawType;}
|
||||
// Draw types like GL_TRIANGLES, GL_POINTS, GL_LINES, etc
|
||||
void setDrawType(int drawType) { mDrawType = drawType;}
|
||||
|
||||
// Shader settings
|
||||
inline void setShaderVertex(const std::string & vert) { mVertexShader = vert;}
|
||||
inline void setShaderFragment(const std::string & frag)
|
||||
{ mFragmentShader = frag;}
|
||||
void setShaders(const std::string & vert, const std::string & frag);
|
||||
// Shader settings
|
||||
inline void setShaderVertex(const std::string & vert) { mVertexShader = vert;}
|
||||
inline void setShaderFragment(const std::string & frag)
|
||||
{ mFragmentShader = frag;}
|
||||
void setShaders(const std::string & vert, const std::string & frag);
|
||||
|
||||
template <typename T>
|
||||
inline void setUniform(int location, T value)
|
||||
{ mProgram.setUniformValue(location, value);}
|
||||
template <typename T>
|
||||
inline void setUniform(int location, T value)
|
||||
{ mProgram.setUniformValue(location, value);}
|
||||
|
||||
template <typename T>
|
||||
inline void setUniform(const char * location, T value)
|
||||
{ mProgram.setUniformValue(location, value);}
|
||||
template <typename T>
|
||||
inline void setUniform(const char * location, T value)
|
||||
{ mProgram.setUniformValue(location, value);}
|
||||
|
||||
// Set MVP matrix using this Object's transform
|
||||
// + View and projection provided by MainWidget static members
|
||||
void setUniformMVP(const char * model="uModel", const char * view="uView",
|
||||
const char * projection="uProjection");
|
||||
// Set MVP matrix using this Object's transform
|
||||
// + View and projection provided by MainWidget static members
|
||||
void setUniformMVP(const char * model="uModel", const char * view="uView",
|
||||
const char * projection="uProjection");
|
||||
|
||||
// Sets the texture to the image at the given path
|
||||
// + Sets mHasTexture to enable texture binding in draw()
|
||||
void setTexture(const char * path);
|
||||
void setTexture(QOpenGLTexture * texture);
|
||||
// Sets the texture to the image at the given path
|
||||
// + Sets mHasTexture to enable texture binding in draw()
|
||||
void setTexture(const char * path);
|
||||
void setTexture(QOpenGLTexture * texture);
|
||||
|
||||
// These functions modify data stored in a VBO
|
||||
// + After calling them, the VBO will need to be reallocated
|
||||
void setShape(const Shape & value) override;
|
||||
void setColor(const QVector3D & color);
|
||||
// These functions modify data stored in a VBO
|
||||
// + After calling them, the VBO will need to be reallocated
|
||||
void setShape(const Shape & value) override;
|
||||
void setColor(const QVector3D & color);
|
||||
|
||||
// Static QHash of all mesh objects within the scene
|
||||
typedef QHash<QString, MeshRenderer *> MeshManager;
|
||||
private:
|
||||
static MeshManager sInstances;
|
||||
// Static QHash of all mesh objects within the scene
|
||||
typedef QHash<QString, MeshRenderer *> MeshManager;
|
||||
private:
|
||||
static MeshManager sInstances;
|
||||
|
||||
int mDrawType;
|
||||
bool mHasTexture;
|
||||
std::string mVertexShader, mFragmentShader;
|
||||
};
|
||||
int mDrawType;
|
||||
bool mHasTexture;
|
||||
std::string mVertexShader, mFragmentShader;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QTK_MESHRENDERER_H
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <scene.h>
|
||||
#include <texture.h>
|
||||
#include <resourcemanager.h>
|
||||
|
||||
#include <abstractscene.h>
|
||||
#include <model.h>
|
||||
#include <resourcemanager.h>
|
||||
#include <texture.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
Model::ModelManager Model::mManager;
|
||||
|
||||
|
||||
165
src/model.h
165
src/model.h
@@ -16,7 +16,6 @@
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
// Assimp
|
||||
#include <assimp/Importer.hpp>
|
||||
@@ -24,117 +23,119 @@
|
||||
#include <assimp/scene.h>
|
||||
|
||||
// QTK
|
||||
#include <qtkapi.h>
|
||||
#include <transform3D.h>
|
||||
|
||||
namespace Qtk {
|
||||
struct QTKAPI ModelVertex {
|
||||
QVector3D mPosition;
|
||||
QVector3D mNormal;
|
||||
QVector3D mTangent;
|
||||
QVector3D mBitangent;
|
||||
QVector2D mTextureCoord;
|
||||
};
|
||||
|
||||
struct ModelVertex {
|
||||
QVector3D mPosition;
|
||||
QVector3D mNormal;
|
||||
QVector3D mTangent;
|
||||
QVector3D mBitangent;
|
||||
QVector2D mTextureCoord;
|
||||
};
|
||||
struct QTKAPI ModelTexture {
|
||||
GLuint mID;
|
||||
QOpenGLTexture * mTexture;
|
||||
std::string mType;
|
||||
std::string mPath;
|
||||
};
|
||||
|
||||
struct ModelTexture {
|
||||
GLuint mID;
|
||||
QOpenGLTexture * mTexture;
|
||||
std::string mType;
|
||||
std::string mPath;
|
||||
};
|
||||
class Model;
|
||||
|
||||
class Model;
|
||||
class QTKAPI ModelMesh : protected QOpenGLFunctions {
|
||||
public:
|
||||
friend Model;
|
||||
typedef std::vector<ModelVertex> Vertices;
|
||||
typedef std::vector<GLuint> Indices;
|
||||
typedef std::vector<ModelTexture> Textures;
|
||||
|
||||
class ModelMesh : protected QOpenGLFunctions {
|
||||
public:
|
||||
friend Model;
|
||||
typedef std::vector<ModelVertex> Vertices;
|
||||
typedef std::vector<GLuint> Indices;
|
||||
typedef std::vector<ModelTexture> Textures;
|
||||
|
||||
// Constructors, Destructors
|
||||
ModelMesh(Vertices vertices, Indices indices, Textures textures,
|
||||
const char * vertexShader=":/model-basic.vert",
|
||||
const char * fragmentShader=":/model-basic.frag")
|
||||
: mProgram(new QOpenGLShaderProgram),
|
||||
// Constructors, Destructors
|
||||
ModelMesh(Vertices vertices, Indices indices, Textures textures,
|
||||
const char * vertexShader=":/model-basic.vert",
|
||||
const char * fragmentShader=":/model-basic.frag")
|
||||
: mProgram(new QOpenGLShaderProgram),
|
||||
mVAO(new QOpenGLVertexArrayObject),
|
||||
mVBO(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)),
|
||||
mEBO(new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer)),
|
||||
mVertices(std::move(vertices)),
|
||||
mIndices(std::move(indices)),
|
||||
mTextures(std::move(textures))
|
||||
{ initMesh(vertexShader, fragmentShader);}
|
||||
~ModelMesh() {}
|
||||
{ initMesh(vertexShader, fragmentShader);}
|
||||
~ModelMesh() {}
|
||||
|
||||
private:
|
||||
void initMesh(const char * vert, const char * frag);
|
||||
private:
|
||||
void initMesh(const char * vert, const char * frag);
|
||||
|
||||
// ModelMesh Private Members
|
||||
QOpenGLBuffer * mVBO, * mEBO;
|
||||
QOpenGLVertexArrayObject * mVAO;
|
||||
QOpenGLShaderProgram * mProgram;
|
||||
// ModelMesh Private Members
|
||||
QOpenGLBuffer * mVBO, * mEBO;
|
||||
QOpenGLVertexArrayObject * mVAO;
|
||||
QOpenGLShaderProgram * mProgram;
|
||||
|
||||
public:
|
||||
inline void draw() { draw(*mProgram);}
|
||||
void draw(QOpenGLShaderProgram & shader);
|
||||
public:
|
||||
inline void draw() { draw(*mProgram);}
|
||||
void draw(QOpenGLShaderProgram & shader);
|
||||
|
||||
// ModelMesh Public Members
|
||||
Vertices mVertices;
|
||||
Indices mIndices;
|
||||
Textures mTextures;
|
||||
Transform3D mTransform;
|
||||
};
|
||||
// ModelMesh Public Members
|
||||
Vertices mVertices;
|
||||
Indices mIndices;
|
||||
Textures mTextures;
|
||||
Transform3D mTransform;
|
||||
};
|
||||
|
||||
|
||||
class Model : public QObject {
|
||||
Q_OBJECT
|
||||
class QTKAPI Model : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
inline Model(const char * name, const char * path,
|
||||
const char * vertexShader=":/model-basic.vert",
|
||||
const char * fragmentShader=":/model-basic.frag")
|
||||
: mName(name), mVertexShader(vertexShader),
|
||||
public:
|
||||
inline Model(const char * name, const char * path,
|
||||
const char * vertexShader=":/model-basic.vert",
|
||||
const char * fragmentShader=":/model-basic.frag")
|
||||
: mName(name), mVertexShader(vertexShader),
|
||||
mFragmentShader(fragmentShader)
|
||||
{ loadModel(path);}
|
||||
inline ~Model() { mManager.remove(mName);}
|
||||
{ loadModel(path);}
|
||||
inline ~Model() { mManager.remove(mName);}
|
||||
|
||||
void draw();
|
||||
void draw(QOpenGLShaderProgram & shader);
|
||||
void draw();
|
||||
void draw(QOpenGLShaderProgram & shader);
|
||||
|
||||
void flipTexture(const std::string & fileName,
|
||||
bool flipX=false, bool flipY=true);
|
||||
void flipTexture(const std::string & fileName,
|
||||
bool flipX=false, bool flipY=true);
|
||||
|
||||
template <typename T>
|
||||
void setUniform(const char * location, T value)
|
||||
{
|
||||
for (auto & mesh : mMeshes) {
|
||||
mesh.mProgram->bind();
|
||||
template <typename T>
|
||||
void setUniform(const char * location, T value)
|
||||
{
|
||||
for (auto & mesh : mMeshes) {
|
||||
mesh.mProgram->bind();
|
||||
|
||||
mesh.mProgram->setUniformValue(location, value);
|
||||
mesh.mProgram->setUniformValue(location, value);
|
||||
|
||||
mesh.mProgram->release();
|
||||
mesh.mProgram->release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Transform3D mTransform;
|
||||
Transform3D mTransform;
|
||||
|
||||
static Model * getInstance(const char * name);
|
||||
static Model * getInstance(const char * name);
|
||||
|
||||
typedef QHash<QString, Model *> ModelManager;
|
||||
private:
|
||||
static ModelManager mManager;
|
||||
void loadModel(const std::string & path);
|
||||
void processNode(aiNode * node, const aiScene * scene);
|
||||
ModelMesh processMesh(aiMesh * mesh, const aiScene * scene);
|
||||
ModelMesh::Textures loadMaterialTextures(aiMaterial * mat, aiTextureType type,
|
||||
const std::string & typeName);
|
||||
void sortModels();
|
||||
typedef QHash<QString, Model *> ModelManager;
|
||||
private:
|
||||
static ModelManager mManager;
|
||||
void loadModel(const std::string & path);
|
||||
void processNode(aiNode * node, const aiScene * scene);
|
||||
ModelMesh processMesh(aiMesh * mesh, const aiScene * scene);
|
||||
ModelMesh::Textures loadMaterialTextures(aiMaterial * mat, aiTextureType type,
|
||||
const std::string & typeName);
|
||||
void sortModels();
|
||||
|
||||
// Model Private Members
|
||||
// Model Private Members
|
||||
|
||||
ModelMesh::Textures mTexturesLoaded;
|
||||
std::vector<ModelMesh> mMeshes;
|
||||
std::string mDirectory;
|
||||
const char * mVertexShader, * mFragmentShader, * mName;
|
||||
};
|
||||
ModelMesh::Textures mTexturesLoaded;
|
||||
std::vector<ModelMesh> mMeshes;
|
||||
std::string mDirectory;
|
||||
const char * mVertexShader, * mFragmentShader, * mName;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QTK_MODEL_H
|
||||
|
||||
@@ -7,3 +7,5 @@
|
||||
##############################################################################*/
|
||||
|
||||
#include <object.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
72
src/object.h
72
src/object.h
@@ -14,48 +14,50 @@
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
|
||||
#include <mesh.h>
|
||||
#include <qtkapi.h>
|
||||
|
||||
namespace Qtk {
|
||||
class QTKAPI Object : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
class Object : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
friend MeshRenderer;
|
||||
// Initialize an object with no shape data assigned
|
||||
Object(const char * name)
|
||||
: mName(name), mVBO(QOpenGLBuffer::VertexBuffer)
|
||||
{ }
|
||||
// Initialize an object with shape data assigned
|
||||
Object(const char * name, const ShapeBase & shape)
|
||||
: mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mShape(shape)
|
||||
{ }
|
||||
|
||||
public:
|
||||
friend MeshRenderer;
|
||||
// Initialize an object with no shape data assigned
|
||||
Object(const char * name)
|
||||
: mName(name), mVBO(QOpenGLBuffer::VertexBuffer)
|
||||
{ }
|
||||
// Initialize an object with shape data assigned
|
||||
Object(const char * name, const ShapeBase & shape)
|
||||
: mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mShape(shape)
|
||||
{ }
|
||||
~Object() {}
|
||||
|
||||
~Object() {}
|
||||
inline const Vertices & vertices() { return mShape.mVertices;}
|
||||
inline const Indices & indices() { return mShape.mIndices;}
|
||||
inline const Colors & colors() { return mShape.mColors;}
|
||||
inline const TexCoords & texCoords() { return mShape.mTexCoords;}
|
||||
inline const Normals & normals() { return mShape.mNormals;}
|
||||
inline QOpenGLTexture & texture() const { return *mTexture;}
|
||||
|
||||
inline const Vertices & vertices() { return mShape.mVertices;}
|
||||
inline const Indices & indices() { return mShape.mIndices;}
|
||||
inline const Colors & colors() { return mShape.mColors;}
|
||||
inline const TexCoords & texCoords() { return mShape.mTexCoords;}
|
||||
inline const Normals & normals() { return mShape.mNormals;}
|
||||
inline QOpenGLTexture & texture() const { return *mTexture;}
|
||||
virtual inline void setVertices(const Vertices & value) { mShape.mVertices = value;}
|
||||
virtual inline void setIndices(const Indices & value) { mShape.mIndices = value;}
|
||||
virtual inline void setColors(const Colors & value) { mShape.mColors = value;}
|
||||
virtual inline void setTexCoords(const TexCoords & value) { mShape.mTexCoords = value;}
|
||||
virtual inline void setNormals(const Normals & value) { mShape.mNormals = value;}
|
||||
virtual inline void setShape(const Shape & value) { mShape = value;}
|
||||
|
||||
virtual inline void setVertices(const Vertices & value) { mShape.mVertices = value;}
|
||||
virtual inline void setIndices(const Indices & value) { mShape.mIndices = value;}
|
||||
virtual inline void setColors(const Colors & value) { mShape.mColors = value;}
|
||||
virtual inline void setTexCoords(const TexCoords & value) { mShape.mTexCoords = value;}
|
||||
virtual inline void setNormals(const Normals & value) { mShape.mNormals = value;}
|
||||
virtual inline void setShape(const Shape & value) { mShape = value;}
|
||||
QOpenGLBuffer mVBO, mNBO;
|
||||
QOpenGLVertexArrayObject mVAO;
|
||||
QOpenGLShaderProgram mProgram;
|
||||
|
||||
QOpenGLBuffer mVBO, mNBO;
|
||||
QOpenGLVertexArrayObject mVAO;
|
||||
QOpenGLShaderProgram mProgram;
|
||||
Transform3D mTransform;
|
||||
Shape mShape;
|
||||
|
||||
Transform3D mTransform;
|
||||
Shape mShape;
|
||||
|
||||
const char * mName;
|
||||
private:
|
||||
QOpenGLTexture * mTexture;
|
||||
};
|
||||
const char * mName;
|
||||
private:
|
||||
QOpenGLTexture * mTexture;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QTK_OBJECT_H
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
/*##############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
||||
## About: Manage files and resources used by qtk ##
|
||||
## About: Main window for Qt6 OpenGL widget application ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################*/
|
||||
#ifndef QTK_QTKAPI_H
|
||||
#define QTK_QTKAPI_H
|
||||
|
||||
#include "resourcemanager.h"
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <QtGlobal>
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
static std::string nixPath(std::string path)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
std::replace(path.begin(), path.end(), '\\', '/');
|
||||
#ifdef QTK_SHARED
|
||||
# if defined(QTK_EXPORT)
|
||||
# define QTKAPI Q_DECL_EXPORT
|
||||
# else
|
||||
# define QTKAPI Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define QTKAPI
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string RM::resourcesDir =
|
||||
std::string(__FILE__).substr(0, nixPath(__FILE__).find("src/"))
|
||||
+ "resources/";
|
||||
#endif //QTK_QTKAPI_H
|
||||
@@ -1,35 +0,0 @@
|
||||
/*##############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
||||
## About: Manage files and resources used by qtk ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifndef QTK_RESOURCEMANAGER_H
|
||||
#define QTK_RESOURCEMANAGER_H
|
||||
|
||||
typedef class ResourceManager {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Takes a path using qrc format and constructs full system path to qtk assets
|
||||
* Qrc format prefix ':/' is trimmed from the path for the caller
|
||||
* Assets used with RM may (or may not) appear in qtk/resources.qrc
|
||||
*
|
||||
* @param path Path relative to qtk/resources/; ie) ':/models/backpack/backpack.obj'
|
||||
* An asset at location qtk/resources/path/to/asset.obj
|
||||
* Should be given in qrc format: ':/path/to/asset.obj'
|
||||
* @return Absoulte system path to a qtk asset
|
||||
*/
|
||||
static std::string getPath(const std::string & path) {
|
||||
// Only construct qtk resource path if in qrc format; else return it as-is
|
||||
return path[0] == ':' ? resourcesDir + path.substr(2) : path;
|
||||
}
|
||||
|
||||
static std::string resourcesDir;
|
||||
} RM;
|
||||
|
||||
#endif //QTK_RESOURCEMANAGER_H
|
||||
749
src/scene.cpp
749
src/scene.cpp
@@ -1,749 +0,0 @@
|
||||
/*##############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
||||
## About: Classes for managing objects and data within a scene ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################*/
|
||||
|
||||
#include <camera3d.h>
|
||||
#include <texture.h>
|
||||
#include <meshrenderer.h>
|
||||
#include <model.h>
|
||||
#include <resourcemanager.h>
|
||||
|
||||
#include <scene.h>
|
||||
|
||||
|
||||
Camera3D Scene::mCamera;
|
||||
QMatrix4x4 Scene::mProjection;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Constructors, Destructors
|
||||
******************************************************************************/
|
||||
|
||||
Scene::Scene()
|
||||
{
|
||||
mCamera.transform().setTranslation(0.0f, 0.0f, 20.0f);
|
||||
mCamera.transform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
delete mTestPhong;
|
||||
delete mTestSpecular;
|
||||
delete mTestDiffuse;
|
||||
delete mTestAmbient;
|
||||
for (auto & mesh : mMeshes) delete mesh;
|
||||
for (auto & model : mModels) delete model;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Public Member Functions
|
||||
******************************************************************************/
|
||||
|
||||
void Scene::init()
|
||||
{
|
||||
// Initialize Phong example cube
|
||||
mTestPhong = new MeshRenderer("phong", Cube());
|
||||
mTestPhong->mTransform.setTranslation(3.0f, 0.0f, -2.0f);
|
||||
mTestPhong->setShaders(":/solid-phong.vert", ":/solid-phong.frag");
|
||||
mTestPhong->init();
|
||||
mTestPhong->mProgram.bind();
|
||||
mTestPhong->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
||||
mTestPhong->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mTestPhong->setUniform("uAmbientStrength", 0.2f);
|
||||
mTestPhong->setUniform("uSpecularStrength", 0.50f);
|
||||
mTestPhong->setUniform("uSpecularShine", 256);
|
||||
|
||||
mTestPhong->mVAO.bind();
|
||||
mTestPhong->mNBO.create();
|
||||
mTestPhong->mNBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
|
||||
mTestPhong->mNBO.bind();
|
||||
mTestPhong->mNBO.allocate(mTestPhong->normals().data(),
|
||||
mTestPhong->normals().size()
|
||||
* sizeof(mTestPhong->normals()[0]));
|
||||
mTestPhong->mProgram.enableAttributeArray(1);
|
||||
mTestPhong->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
mTestPhong->mNBO.release();
|
||||
mTestPhong->mVAO.release();
|
||||
mTestPhong->mProgram.release();
|
||||
|
||||
|
||||
// Initialize Ambient example cube
|
||||
mTestAmbient = new MeshRenderer("ambient", Cube());
|
||||
mTestAmbient->mTransform.setTranslation(7.0f, 0.0f, -2.0f);
|
||||
mTestAmbient->setShaders(":/solid-ambient.vert", ":/solid-ambient.frag");
|
||||
mTestAmbient->init();
|
||||
mTestAmbient->mProgram.bind();
|
||||
mTestAmbient->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
||||
mTestAmbient->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mTestAmbient->setUniform("uAmbientStrength", 0.2f);
|
||||
|
||||
mTestAmbient->mVAO.bind();
|
||||
mTestAmbient->mNBO.create();
|
||||
mTestAmbient->mNBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
|
||||
mTestAmbient->mNBO.bind();
|
||||
mTestAmbient->mNBO.allocate(mTestAmbient->normals().data(),
|
||||
mTestAmbient->normals().size()
|
||||
* sizeof(mTestAmbient->normals()[0]));
|
||||
mTestAmbient->mProgram.enableAttributeArray(1);
|
||||
mTestAmbient->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
mTestAmbient->mNBO.release();
|
||||
mTestAmbient->mVAO.release();
|
||||
mTestAmbient->mProgram.release();
|
||||
|
||||
// Initialize Diffuse example cube
|
||||
mTestDiffuse = new MeshRenderer("diffuse", Cube());
|
||||
mTestDiffuse->mTransform.setTranslation(9.0f, 0.0f, -2.0f);
|
||||
mTestDiffuse->setShaders(":/solid-diffuse.vert", ":/solid-diffuse.frag");
|
||||
mTestDiffuse->init();
|
||||
mTestDiffuse->mProgram.bind();
|
||||
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);
|
||||
|
||||
mTestDiffuse->mVAO.bind();
|
||||
mTestDiffuse->mNBO.create();
|
||||
mTestDiffuse->mNBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
|
||||
mTestDiffuse->mNBO.bind();
|
||||
mTestDiffuse->mNBO.allocate(mTestDiffuse->normals().data(),
|
||||
mTestDiffuse->normals().size()
|
||||
* sizeof(mTestDiffuse->normals()[0]));
|
||||
mTestDiffuse->mProgram.enableAttributeArray(1);
|
||||
mTestDiffuse->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
mTestDiffuse->mNBO.release();
|
||||
mTestDiffuse->mVAO.release();
|
||||
mTestDiffuse->mProgram.release();
|
||||
|
||||
// Initialize Specular example cube
|
||||
mTestSpecular = new MeshRenderer("specular", Cube());
|
||||
mTestSpecular->mTransform.setTranslation(11.0f, 0.0f, -2.0f);
|
||||
mTestSpecular->setShaders(":/solid-specular.vert", ":/solid-specular.frag");
|
||||
mTestSpecular->init();
|
||||
mTestSpecular->mProgram.bind();
|
||||
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);
|
||||
mTestSpecular->setUniform("uSpecularStrength", 0.50f);
|
||||
mTestSpecular->setUniform("uSpecularShine", 256);
|
||||
|
||||
mTestSpecular->mVAO.bind();
|
||||
mTestSpecular->mNBO.create();
|
||||
mTestSpecular->mNBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
|
||||
mTestSpecular->mNBO.bind();
|
||||
mTestSpecular->mNBO.allocate(mTestSpecular->normals().data(),
|
||||
mTestSpecular->normals().size()
|
||||
* sizeof(mTestSpecular->normals()[0]));
|
||||
mTestSpecular->mProgram.enableAttributeArray(1);
|
||||
mTestSpecular->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
mTestSpecular->mNBO.release();
|
||||
mTestSpecular->mVAO.release();
|
||||
mTestSpecular->mProgram.release();
|
||||
|
||||
//
|
||||
// Model loading
|
||||
|
||||
mModels.push_back(new Model("backpack", ":/models/backpack/backpack.obj"));
|
||||
// Sometimes model textures need flipped in certain directions
|
||||
mModels.back()->flipTexture("diffuse.jpg", false, true);
|
||||
mModels.back()->mTransform.setTranslation(0.0f, 0.0f, -10.0f);
|
||||
|
||||
mModels.push_back(new Model("bird", ":/models/bird/bird.obj"));
|
||||
mModels.back()->mTransform.setTranslation(2.0f, 2.0f, -10.0f);
|
||||
// Sometimes the models are very large
|
||||
mModels.back()->mTransform.scale(0.0025f);
|
||||
mModels.back()->mTransform.rotate(-110.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
mModels.push_back(new Model("lion", ":/models/lion/lion.obj"));
|
||||
mModels.back()->mTransform.setTranslation(-3.0f, -1.0f, -10.0f);
|
||||
mModels.back()->mTransform.scale(0.15f);
|
||||
|
||||
mModels.push_back(new Model("alien", ":/models/alien-hominid/alien.obj"));
|
||||
mModels.back()->mTransform.setTranslation(2.0f, -1.0f, -5.0f);
|
||||
mModels.back()->mTransform.scale(0.15f);
|
||||
|
||||
mModels.push_back(new Model("scythe", ":/models/scythe/scythe.obj"));
|
||||
mModels.back()->mTransform.setTranslation(-6.0f, 0.0f, -10.0f);
|
||||
mModels.back()->mTransform.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
|
||||
mModels.back()->mTransform.rotate(90.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
mModels.push_back(new Model("masterChief", ":/models/spartan/spartan.obj"));
|
||||
mModels.back()->mTransform.setTranslation(-1.5f, 0.5f, -2.0f);
|
||||
|
||||
|
||||
//
|
||||
// Building example mesh objects
|
||||
|
||||
// Render an alien with specular
|
||||
// Test alien Model with phong lighting and specular mapping
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("alienTestLight", Triangle(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(4.0f, 1.5f, 10.0f);
|
||||
mMeshes.back()->mTransform.scale(0.25f);
|
||||
// This function changes values we have allocated in a buffer, so init() after
|
||||
mMeshes.back()->setColor(GREEN);
|
||||
mMeshes.back()->init();
|
||||
|
||||
mModels.push_back(
|
||||
new Model("alienTest", ":/models/alien-hominid/alien.obj",
|
||||
":/model-specular.vert", ":/model-specular.frag")
|
||||
);
|
||||
mModels.back()->mTransform.setTranslation(3.0f, -1.0f, 10.0f);
|
||||
mModels.back()->mTransform.scale(0.15f);
|
||||
mModels.back()->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mModels.back()->setUniform("uMaterial.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mModels.back()->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mModels.back()->setUniform("uMaterial.ambientStrength", 0.8f);
|
||||
mModels.back()->setUniform("uMaterial.diffuseStrength", 0.8f);
|
||||
mModels.back()->setUniform("uMaterial.specularStrength", 1.0f);
|
||||
mModels.back()->setUniform("uMaterial.shine", 32.0f);
|
||||
|
||||
mModels.back()->setUniform("uLight.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mModels.back()->setUniform("uLight.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mModels.back()->setUniform("uLight.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
|
||||
|
||||
// Test spartan Model with phong lighting, specular and normal mapping
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("spartanTestLight", Triangle(QTK_DRAW_ELEMENTS))
|
||||
);
|
||||
mMeshes.back()->mTransform.setTranslation(1.0f, 1.5f, 10.0f);
|
||||
mMeshes.back()->mTransform.scale(0.25f);
|
||||
// This function changes values we have allocated in a buffer, so init() after
|
||||
mMeshes.back()->setColor(GREEN);
|
||||
mMeshes.back()->init();
|
||||
|
||||
mModels.push_back(
|
||||
new Model("spartanTest", ":/models/spartan/spartan.obj",
|
||||
":/model-normals.vert", ":/model-normals.frag")
|
||||
);
|
||||
mModels.back()->mTransform.setTranslation(0.0f, -1.0f, 10.0f);
|
||||
mModels.back()->mTransform.scale(2.0f);
|
||||
mModels.back()->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mModels.back()->setUniform("uMaterial.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mModels.back()->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mModels.back()->setUniform("uMaterial.ambientStrength", 1.0f);
|
||||
mModels.back()->setUniform("uMaterial.diffuseStrength", 1.0f);
|
||||
mModels.back()->setUniform("uMaterial.specularStrength", 1.0f);
|
||||
mModels.back()->setUniform("uMaterial.shine", 128.0f);
|
||||
mModels.back()->setUniform("uLight.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mModels.back()->setUniform("uLight.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mModels.back()->setUniform("uLight.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
|
||||
|
||||
// Test basic cube with phong.vert and phong.frag shaders
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("testLight", Triangle(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(5.0f, 1.25f, 10.0f);
|
||||
mMeshes.back()->mTransform.scale(0.25f);
|
||||
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
||||
// This function changes values we have allocated in a buffer, so init() after
|
||||
mMeshes.back()->setColor(GREEN);
|
||||
mMeshes.back()->init();
|
||||
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("testPhong", Cube(QTK_DRAW_ARRAYS)));
|
||||
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 10.0f);
|
||||
mMeshes.back()->setShaders(":/phong.vert", ":/phong.frag");
|
||||
mMeshes.back()->setColor(QVector3D(0.0f, 0.25f, 0.0f));
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->normals().data(),
|
||||
mMeshes.back()->normals().size()
|
||||
* sizeof(mMeshes.back()->normals()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
|
||||
mMeshes.back()->setUniform("uMaterial.ambient", QVector3D(0.0f, 0.3f, 0.0f));
|
||||
mMeshes.back()->setUniform("uMaterial.diffuse", QVector3D(0.0f, 0.2f, 0.0f));
|
||||
|
||||
mMeshes.back()->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
||||
mMeshes.back()->setUniform("uMaterial.ambientStrength", 1.0f);
|
||||
mMeshes.back()->setUniform("uMaterial.diffuseStrength", 1.0f);
|
||||
mMeshes.back()->setUniform("uMaterial.specularStrength", 1.0f);
|
||||
mMeshes.back()->setUniform("uMaterial.shine", 64.0f);
|
||||
mMeshes.back()->setUniform("uLight.ambient", QVector3D(0.25f, 0.2f, 0.075f));
|
||||
mMeshes.back()->setUniform("uLight.diffuse", QVector3D(0.75f, 0.6f, 0.22f));
|
||||
mMeshes.back()->setUniform("uLight.specular", QVector3D(0.62f, 0.55f, 0.37f));
|
||||
mMeshes.back()->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
||||
|
||||
mMeshes.back()->mProgram.release();
|
||||
|
||||
//
|
||||
// Create simple shapes using MeshRenderer class and data in mesh.h
|
||||
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(-5.0f, 0.0f, -2.0f);
|
||||
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("centerCube", Cube(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(-7.0f, 0.0f, -2.0f);
|
||||
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("leftTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(-9.0f, 0.0f, -2.0f);
|
||||
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
||||
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("topTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(-7.0f, 2.0f, -2.0f);
|
||||
mMeshes.back()->mTransform.scale(0.25f);
|
||||
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("bottomTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(-7.0f, -2.0f, -2.0f);
|
||||
mMeshes.back()->mTransform.scale(0.25f);
|
||||
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
||||
// This function changes values we have allocated in a buffer, so init() after
|
||||
mMeshes.back()->setColor(GREEN);
|
||||
mMeshes.back()->init();
|
||||
|
||||
//
|
||||
// Testing for normals, texture coordinates
|
||||
|
||||
// RGB Normals cube to show normals are correct with QTK_DRAW_ARRAYS
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("rgbNormalsCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
|
||||
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 4.0f);
|
||||
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->normals().data(),
|
||||
mMeshes.back()->normals().size()
|
||||
* sizeof(mMeshes.back()->normals()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
|
||||
mMeshes.back()->mProgram.release();
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
|
||||
// RGB Normals cube to show normals are correct with QTK_DRAW_ELEMENTS_NORMALS
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("rgbNormalsCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, 2.0f);
|
||||
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->normals().data(),
|
||||
mMeshes.back()->normals().size()
|
||||
* sizeof(mMeshes.back()->normals()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
|
||||
mMeshes.back()->mProgram.release();
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
|
||||
// Texturing a cube using texture coordinates and glDrawArrays
|
||||
// + Texturing with UVs using glDrawElements requires QTK_DRAW_ELEMENTS_NORMALS
|
||||
// + UVs required duplicating element position data from QTK_DRAW_ELEMENTS
|
||||
// + This is because the same position must use different UV coordinates
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("uvCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
|
||||
mMeshes.back()->mTransform.setTranslation(-3.0f, 0.0f, -2.0f);
|
||||
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->setTexture(Texture::initTexture2D(":/crate.png"));
|
||||
mMeshes.back()->setUniform("uTexture", 0);
|
||||
mMeshes.back()->texture().bind();
|
||||
|
||||
mMeshes.back()->texture().release();
|
||||
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.destroy();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->mShape.texCoords().data(),
|
||||
mMeshes.back()->mShape.texCoords().size()
|
||||
* sizeof(mMeshes.back()->mShape.texCoords()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
2, sizeof(QVector2D));
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
mMeshes.back()->mProgram.release();
|
||||
|
||||
// Test drawing a cube with texture coordinates using glDrawElements
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("uvCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||
mMeshes.back()->mTransform.setTranslation(-1.7f, 0.0f, -2.0f);
|
||||
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->texCoords().data(),
|
||||
mMeshes.back()->texCoords().size()
|
||||
* sizeof(mMeshes.back()->texCoords()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
mMeshes.back()->setTexture(Texture::initTexture2D(":/crate.png"));
|
||||
|
||||
mMeshes.back()->mProgram.setUniformValue("uTexture", 0);
|
||||
mMeshes.back()->mProgram.release();
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
mMeshes.back()->mTransform.rotate(45.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
// Texturing a cube using a cube map
|
||||
// + Cube map texturing works with both QTK_DRAW_ARRAYS and QTK_DRAW_ELEMENTS
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(-3.0f, 1.0f, -2.0f);
|
||||
mMeshes.back()->mTransform.setRotation(45.0f, 0.0f, 1.0f, 0.0f);
|
||||
mMeshes.back()->setShaders(":/texture-cubemap.vert", ":/texture-cubemap.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->setTexture(Texture::initCubeMap(":/crate.png"));
|
||||
mMeshes.back()->setUniform("uTexture", 0);
|
||||
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.destroy();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->mShape.texCoords().data(),
|
||||
mMeshes.back()->mShape.texCoords().size()
|
||||
* sizeof(mMeshes.back()->mShape.texCoords()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
2, sizeof(QVector2D));
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
mMeshes.back()->mProgram.release();
|
||||
|
||||
// Create a cube with custom shaders
|
||||
// + Apply RGB normals shader and spin the cube for a neat effect
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("rgbNormalsCube", Cube(QTK_DRAW_ARRAYS)));
|
||||
mMeshes.back()->mTransform.setTranslation(5.0f, 2.0f, -2.0f);
|
||||
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->normals().data(),
|
||||
mMeshes.back()->normals().size()
|
||||
* sizeof(mMeshes.back()->normals()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
|
||||
mMeshes.back()->mProgram.release();
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
|
||||
// RGB Normals triangle to show normals are correct with QTK_DRAW_ARRAYS
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("rgbTriangleArraysTest", Triangle(QTK_DRAW_ARRAYS)));
|
||||
mMeshes.back()->mTransform.setTranslation(7.0f, 0.0f, 2.0f);
|
||||
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->normals().data(),
|
||||
mMeshes.back()->normals().size()
|
||||
* sizeof(mMeshes.back()->normals()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
mMeshes.back()->mProgram.release();
|
||||
|
||||
// RGB Normals triangle to show normals are correct with QTK_DRAW_ELEMENTS
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("rgbTriangleElementsTest",
|
||||
Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||
mMeshes.back()->mTransform.setTranslation(7.0f, 0.0f, 4.0f);
|
||||
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->normals().data(),
|
||||
mMeshes.back()->normals().size()
|
||||
* sizeof(mMeshes.back()->normals()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
3, sizeof(QVector3D));
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
mMeshes.back()->mProgram.release();
|
||||
|
||||
// Test drawing triangle with glDrawArrays with texture coordinates
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("testTriangleArraysUV", Triangle(QTK_DRAW_ARRAYS)));
|
||||
mMeshes.back()->mTransform.setTranslation(-3.0f, 2.0f, -2.0f);
|
||||
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->setTexture(Texture::initTexture2D(":/crate.png"));
|
||||
mMeshes.back()->setUniform("uTexture", 0);
|
||||
mMeshes.back()->texture().bind();
|
||||
|
||||
mMeshes.back()->texture().release();
|
||||
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.destroy();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->mShape.texCoords().data(),
|
||||
mMeshes.back()->mShape.texCoords().size()
|
||||
* sizeof(mMeshes.back()->mShape.texCoords()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
2, sizeof(QVector2D));
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
mMeshes.back()->mProgram.release();
|
||||
|
||||
// Test drawing triangle with glDrawElements with texture coordinates
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("testTriangleElementsUV",
|
||||
Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||
mMeshes.back()->mTransform.setTranslation(-2.5f, 0.0f, -1.0f);
|
||||
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
|
||||
mMeshes.back()->setTexture(Texture::initTexture2D(":/crate.png"));
|
||||
mMeshes.back()->setUniform("uTexture", 0);
|
||||
mMeshes.back()->texture().bind();
|
||||
|
||||
mMeshes.back()->texture().release();
|
||||
|
||||
mMeshes.back()->mVAO.bind();
|
||||
mMeshes.back()->mNBO.destroy();
|
||||
mMeshes.back()->mNBO.create();
|
||||
mMeshes.back()->mNBO.bind();
|
||||
mMeshes.back()->mNBO.allocate(mMeshes.back()->mShape.texCoords().data(),
|
||||
mMeshes.back()->mShape.texCoords().size()
|
||||
* sizeof(mMeshes.back()->mShape.texCoords()[0]));
|
||||
mMeshes.back()->mProgram.enableAttributeArray(1);
|
||||
mMeshes.back()->mProgram.setAttributeBuffer(1, GL_FLOAT, 0,
|
||||
2, sizeof(QVector2D));
|
||||
mMeshes.back()->mNBO.release();
|
||||
mMeshes.back()->mVAO.release();
|
||||
mMeshes.back()->mProgram.release();
|
||||
|
||||
//
|
||||
// Lighting cube examples
|
||||
|
||||
// Example of a cube with no lighting applied
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("noLight", Cube(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(5.0f, 0.0f, -2.0f);
|
||||
mMeshes.back()->setShaders(":/solid-perspective.vert",
|
||||
":/solid-perspective.frag");
|
||||
mMeshes.back()->init();
|
||||
mMeshes.back()->mProgram.bind();
|
||||
mMeshes.back()->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
||||
mMeshes.back()->mProgram.release();
|
||||
|
||||
// Create objects that represent light sources for lighting examples
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("phongLight", Triangle(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(3.0f, 2.0f, -2.0f);
|
||||
mMeshes.back()->mTransform.scale(0.25f);
|
||||
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("diffuseLight", Triangle(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(9.0f, 2.0f, -2.0f);
|
||||
mMeshes.back()->mTransform.scale(0.25f);
|
||||
|
||||
mMeshes.push_back(
|
||||
new MeshRenderer("specularLight", Triangle(QTK_DRAW_ELEMENTS)));
|
||||
mMeshes.back()->mTransform.setTranslation(11.0f, 2.0f, -2.0f);
|
||||
mMeshes.back()->mTransform.scale(0.25f);
|
||||
}
|
||||
|
||||
void Scene::draw()
|
||||
{
|
||||
mSkybox.draw();
|
||||
|
||||
for (auto & model : mModels) model->draw();
|
||||
|
||||
for (const auto &mesh : mMeshes) mesh->draw();
|
||||
|
||||
mTestPhong->mProgram.bind();
|
||||
mTestPhong->setUniform("uModelInverseTransposed",
|
||||
mTestPhong->mTransform.toMatrix().normalMatrix());
|
||||
mTestPhong->setUniform(
|
||||
"uLightPosition",
|
||||
MeshRenderer::getInstance("phongLight")->mTransform.translation());
|
||||
mTestPhong->setUniform("uCameraPosition",
|
||||
Scene::Camera().transform().translation());
|
||||
mTestPhong->mProgram.release();
|
||||
mTestPhong->draw();
|
||||
|
||||
mTestAmbient->mProgram.bind();
|
||||
mTestAmbient->setUniform("uCameraPosition",
|
||||
Scene::Camera().transform().translation());
|
||||
mTestAmbient->mProgram.release();
|
||||
mTestAmbient->draw();
|
||||
|
||||
mTestDiffuse->mProgram.bind();
|
||||
mTestDiffuse->setUniform("uModelInverseTransposed",
|
||||
mTestDiffuse->mTransform.toMatrix().normalMatrix());
|
||||
mTestDiffuse->setUniform(
|
||||
"uLightPosition",
|
||||
MeshRenderer::getInstance("diffuseLight")->mTransform.translation());
|
||||
mTestDiffuse->setUniform("uCameraPosition", Scene::Camera().transform().translation());
|
||||
mTestDiffuse->mProgram.release();
|
||||
mTestDiffuse->draw();
|
||||
|
||||
mTestSpecular->mProgram.bind();
|
||||
mTestSpecular->setUniform(
|
||||
"uModelInverseTransposed",
|
||||
mTestSpecular->mTransform.toMatrix().normalMatrix());
|
||||
mTestSpecular->setUniform(
|
||||
"uLightPosition",
|
||||
MeshRenderer::getInstance("specularLight")->mTransform.translation());
|
||||
mTestSpecular->setUniform("uCameraPosition", Scene::Camera().transform().translation());
|
||||
mTestSpecular->mProgram.release();
|
||||
mTestSpecular->draw();
|
||||
}
|
||||
|
||||
void Scene::update()
|
||||
{
|
||||
auto position = MeshRenderer::getInstance("alienTestLight")->mTransform.translation();
|
||||
Model::getInstance("alienTest")->setUniform(
|
||||
"uLight.position", position);
|
||||
Model::getInstance("alienTest")->setUniform(
|
||||
"uCameraPosition", Scene::Camera().transform().translation());
|
||||
auto posMatrix = Model::getInstance("alienTest")->mTransform.toMatrix();
|
||||
Model::getInstance("alienTest")->setUniform(
|
||||
"uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||
Model::getInstance("alienTest")->setUniform(
|
||||
"uMVP.model", posMatrix);
|
||||
Model::getInstance("alienTest")->setUniform(
|
||||
"uMVP.view", Scene::Camera().toMatrix());
|
||||
Model::getInstance("alienTest")->setUniform(
|
||||
"uMVP.projection", Scene::Projection());
|
||||
Model::getInstance("alienTest")->mTransform.rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
position = MeshRenderer::getInstance("spartanTestLight")->mTransform.translation();
|
||||
Model::getInstance("spartanTest")->setUniform(
|
||||
"uLight.position", position);
|
||||
Model::getInstance("spartanTest")->setUniform(
|
||||
"uCameraPosition", Scene::Camera().transform().translation());
|
||||
posMatrix = Model::getInstance("spartanTest")->mTransform.toMatrix();
|
||||
Model::getInstance("spartanTest")->setUniform(
|
||||
"uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||
Model::getInstance("spartanTest")->setUniform(
|
||||
"uMVP.model", posMatrix);
|
||||
Model::getInstance("spartanTest")->setUniform(
|
||||
"uMVP.view", Scene::Camera().toMatrix());
|
||||
Model::getInstance("spartanTest")->setUniform(
|
||||
"uMVP.projection", Scene::Projection());
|
||||
Model::getInstance("spartanTest")->mTransform.rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
|
||||
|
||||
MeshRenderer::getInstance("testPhong")->mTransform.rotate(
|
||||
0.75f, 1.0f, 0.5f, 0.0f);
|
||||
MeshRenderer::getInstance("testPhong")->mProgram.bind();
|
||||
position = MeshRenderer::getInstance("testLight")->mTransform.translation();
|
||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||
"uLight.position", position);
|
||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||
"uCameraPosition", Scene::Camera().transform().translation());
|
||||
posMatrix = MeshRenderer::getInstance("testPhong")->mTransform.toMatrix();
|
||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||
"uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||
"uMVP.model", posMatrix);
|
||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||
"uMVP.view", Scene::Camera().toMatrix());
|
||||
MeshRenderer::getInstance("testPhong")->setUniform(
|
||||
"uMVP.projection", Scene::Projection());
|
||||
MeshRenderer::getInstance("testPhong")->mProgram.release();
|
||||
|
||||
// Rotate lighting example cubes
|
||||
mTestPhong->mTransform.rotate(0.75f, 0.5f, 0.3f, 0.2f);
|
||||
MeshRenderer::getInstance("noLight")->mTransform.rotate(
|
||||
0.75f, 0.5f, 0.3f, 0.2f);
|
||||
mTestAmbient->mTransform.rotate(0.75f, 0.5f, 0.3f, 0.2f);
|
||||
mTestDiffuse->mTransform.rotate(0.75f, 0.5f, 0.3f, 0.2f);
|
||||
mTestSpecular->mTransform.rotate(0.75f, 0.5f, 0.3f, 0.2f);
|
||||
|
||||
// Examples of various translations and rotations
|
||||
|
||||
// Rotate in multiple directions simultaneously
|
||||
MeshRenderer::getInstance("rgbNormalsCube")->mTransform.rotate(
|
||||
0.75f, 0.2f, 0.4f, 0.6f);
|
||||
|
||||
// Pitch forward and roll sideways
|
||||
MeshRenderer::getInstance("leftTriangle")->mTransform.rotate(
|
||||
0.75f, 1.0f, 0.0f, 0.0f);
|
||||
MeshRenderer::getInstance("rightTriangle")->mTransform.rotate(
|
||||
0.75f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
// Move between two positions over time
|
||||
static float translateX = 0.025f;
|
||||
float limit = -9.0f; // Origin position.x - 2.0f
|
||||
float posX =
|
||||
MeshRenderer::getInstance("topTriangle")->mTransform.translation().x();
|
||||
if (posX < limit || posX > limit + 4.0f) {
|
||||
translateX = -translateX;
|
||||
}
|
||||
MeshRenderer::getInstance("topTriangle")->mTransform.translate(
|
||||
translateX, 0.0f, 0.0f);
|
||||
MeshRenderer::getInstance("bottomTriangle")->mTransform.translate(
|
||||
-translateX, 0.0f, 0.0f);
|
||||
// And lets rotate the triangles in two directions at once
|
||||
MeshRenderer::getInstance("topTriangle")->mTransform.rotate(
|
||||
0.75f, 0.2f, 0.0f, 0.4f);
|
||||
MeshRenderer::getInstance("bottomTriangle")->mTransform.rotate(
|
||||
0.75f, 0.0f, 0.2f, 0.4f);
|
||||
// And make the bottom triangle green, instead of RGB
|
||||
|
||||
// Rotate center cube in several directions simultaneously
|
||||
// + Not subject to gimbal lock since we are using quaternions :)
|
||||
MeshRenderer::getInstance("centerCube")->mTransform.rotate(
|
||||
0.75f, 0.2f, 0.4f, 0.6f);
|
||||
}
|
||||
45
src/scene.h
45
src/scene.h
@@ -1,45 +0,0 @@
|
||||
/*##############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
||||
## About: Classes for managing objects and data within a scene ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################*/
|
||||
|
||||
#ifndef QTK_SCENE_H
|
||||
#define QTK_SCENE_H
|
||||
|
||||
#include <camera3d.h>
|
||||
#include <skybox.h>
|
||||
|
||||
#include <QMatrix4x4>
|
||||
|
||||
class MeshRenderer;
|
||||
class Model;
|
||||
|
||||
class Scene {
|
||||
public:
|
||||
Scene();
|
||||
~Scene();
|
||||
|
||||
void init();
|
||||
void draw();
|
||||
void update();
|
||||
|
||||
static Camera3D & Camera() { return mCamera;}
|
||||
static QMatrix4x4 View() { return mCamera.toMatrix();}
|
||||
static QMatrix4x4 & Projection() { return mProjection;}
|
||||
private:
|
||||
static Camera3D mCamera;
|
||||
static QMatrix4x4 mProjection;
|
||||
|
||||
Skybox mSkybox;
|
||||
MeshRenderer * mTestPhong;
|
||||
MeshRenderer * mTestSpecular;
|
||||
MeshRenderer * mTestDiffuse;
|
||||
MeshRenderer * mTestAmbient;
|
||||
std::vector<MeshRenderer *> mMeshes;
|
||||
std::vector<Model *> mModels;
|
||||
};
|
||||
|
||||
#endif // QTK_SCENE_H
|
||||
@@ -6,11 +6,11 @@
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################*/
|
||||
|
||||
#include <scene.h>
|
||||
#include <abstractscene.h>
|
||||
#include <skybox.h>
|
||||
#include <texture.h>
|
||||
|
||||
#include <skybox.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
Skybox::Skybox(std::string right, std::string top, std::string front,
|
||||
std::string left, std::string bottom, std::string back,
|
||||
|
||||
47
src/skybox.h
47
src/skybox.h
@@ -10,39 +10,42 @@
|
||||
|
||||
#include <QImage>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
#include <camera3d.h>
|
||||
#include <mesh.h>
|
||||
#include <qtkapi.h>
|
||||
|
||||
|
||||
class Skybox : protected QOpenGLFunctions {
|
||||
public:
|
||||
// Delegate this constructor to use default skybox images
|
||||
// + This allows creating a skybox with no arguments ( auto s = new Skybox; )
|
||||
explicit Skybox(std::string name="Skybox");
|
||||
explicit Skybox(QOpenGLTexture * cubeMap, const std::string & name="Skybox");
|
||||
// Constructor, Destructor
|
||||
Skybox(std::string right, std::string top, std::string front,
|
||||
std::string left, std::string bottom, std::string back,
|
||||
const std::string & name="Skybox");
|
||||
~Skybox() {}
|
||||
namespace Qtk {
|
||||
class QTKAPI Skybox : protected QOpenGLFunctions {
|
||||
public:
|
||||
// Delegate this constructor to use default skybox images
|
||||
// + This allows creating a skybox with no arguments ( auto s = new Skybox; )
|
||||
explicit Skybox(std::string name="Skybox");
|
||||
explicit Skybox(QOpenGLTexture * cubeMap, const std::string & name="Skybox");
|
||||
// Constructor, Destructor
|
||||
Skybox(std::string right, std::string top, std::string front,
|
||||
std::string left, std::string bottom, std::string back,
|
||||
const std::string & name="Skybox");
|
||||
~Skybox() {}
|
||||
|
||||
void draw();
|
||||
void draw();
|
||||
|
||||
private:
|
||||
void init();
|
||||
private:
|
||||
void init();
|
||||
|
||||
Vertices mVertices;
|
||||
Indices mIndices;
|
||||
Vertices mVertices;
|
||||
Indices mIndices;
|
||||
|
||||
QOpenGLShaderProgram mProgram;
|
||||
QOpenGLVertexArrayObject mVAO;
|
||||
QOpenGLBuffer mVBO;
|
||||
QOpenGLTexture * mCubeMap;
|
||||
};
|
||||
QOpenGLShaderProgram mProgram;
|
||||
QOpenGLVertexArrayObject mVAO;
|
||||
QOpenGLBuffer mVBO;
|
||||
QOpenGLTexture * mCubeMap;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QTK_SKYBOX_H
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <texture.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
QImage * Texture::initImage(const char * image, bool flipX, bool flipY)
|
||||
{
|
||||
|
||||
@@ -11,32 +11,35 @@
|
||||
|
||||
#include <QOpenGLTexture>
|
||||
|
||||
#include <qtkapi.h>
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
~Texture() {}
|
||||
namespace Qtk {
|
||||
class QTKAPI Texture {
|
||||
public:
|
||||
~Texture() {}
|
||||
|
||||
// QImage
|
||||
static QImage * initImage(const char * image,
|
||||
bool flipX=false, bool flipY=false);
|
||||
// QImage
|
||||
static QImage * initImage(const char * image,
|
||||
bool flipX=false, bool flipY=false);
|
||||
|
||||
// 2D Texture
|
||||
static QOpenGLTexture * initTexture2D(const char * texture,
|
||||
bool flipX=false, bool flipY=false);
|
||||
// 2D Texture
|
||||
static QOpenGLTexture * initTexture2D(const char * texture,
|
||||
bool flipX=false, bool flipY=false);
|
||||
|
||||
// Cube maps
|
||||
static QOpenGLTexture * initCubeMap(QImage right, QImage top,
|
||||
QImage front, QImage left,
|
||||
QImage bottom, QImage back);
|
||||
// Overloads for cube map initialization
|
||||
static QOpenGLTexture * initCubeMap(const char * tile);
|
||||
static QOpenGLTexture * initCubeMap(const char * right, const char * top,
|
||||
const char * front, const char * left,
|
||||
const char * bottom, const char * back);
|
||||
// Cube maps
|
||||
static QOpenGLTexture * initCubeMap(QImage right, QImage top,
|
||||
QImage front, QImage left,
|
||||
QImage bottom, QImage back);
|
||||
// Overloads for cube map initialization
|
||||
static QOpenGLTexture * initCubeMap(const char * tile);
|
||||
static QOpenGLTexture * initCubeMap(const char * right, const char * top,
|
||||
const char * front, const char * left,
|
||||
const char * bottom, const char * back);
|
||||
|
||||
private:
|
||||
// Private ctor to prevent creating instances of this class
|
||||
Texture() {}
|
||||
};
|
||||
private:
|
||||
// Private ctor to prevent creating instances of this class
|
||||
Texture() {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QTOPENGL_TEXTURE_H
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <transform3D.h>
|
||||
|
||||
using namespace Qtk;
|
||||
|
||||
const QVector3D Transform3D::LocalForward(0.0f, 0.0f, 1.0f);
|
||||
const QVector3D Transform3D::LocalUp(0.0f, 1.0f, 0.0f);
|
||||
@@ -110,35 +111,41 @@ QVector3D Transform3D::right() const
|
||||
* QT Streams
|
||||
******************************************************************************/
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Transform3D & transform)
|
||||
{
|
||||
dbg << "Transform3D\n{\n";
|
||||
dbg << "Position: <" << transform.translation().x() << ", "
|
||||
<< transform.translation().y() << ", "
|
||||
<< transform.translation().z() << ">\n";
|
||||
dbg << "Scale: <" << transform.scale().x() << ", "
|
||||
<< transform.scale().y() << ", "
|
||||
<< transform.scale().z() << ">\n";
|
||||
dbg << "Rotation: <" << transform.rotation().x() << ", "
|
||||
<< transform.rotation().y() << ", "
|
||||
<< transform.rotation().z() << " | " <<
|
||||
transform.rotation().scalar() << ">\n}";
|
||||
return dbg;
|
||||
namespace Qtk {
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug dbg, const Transform3D & transform)
|
||||
{
|
||||
dbg << "Transform3D\n{\n";
|
||||
dbg << "Position: <" << transform.translation().x() << ", "
|
||||
<< transform.translation().y() << ", "
|
||||
<< transform.translation().z() << ">\n";
|
||||
dbg << "Scale: <" << transform.scale().x() << ", "
|
||||
<< transform.scale().y() << ", "
|
||||
<< transform.scale().z() << ">\n";
|
||||
dbg << "Rotation: <" << transform.rotation().x() << ", "
|
||||
<< transform.rotation().y() << ", "
|
||||
<< transform.rotation().z() << " | " <<
|
||||
transform.rotation().scalar() << ">\n}";
|
||||
return dbg;
|
||||
}
|
||||
#endif
|
||||
|
||||
QDataStream & operator<<(QDataStream & out, const Transform3D & transform)
|
||||
{
|
||||
out << transform.mTranslation;
|
||||
out << transform.mScale;
|
||||
out << transform.mRotation;
|
||||
return out;
|
||||
}
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
QDataStream & operator<<(QDataStream & out, const Transform3D & transform)
|
||||
{
|
||||
out << transform.mTranslation;
|
||||
out << transform.mScale;
|
||||
out << transform.mRotation;
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream & operator>>(QDataStream & in, Transform3D & transform)
|
||||
{
|
||||
in >> transform.mTranslation;
|
||||
in >> transform.mScale;
|
||||
in >> transform.mRotation;
|
||||
transform.m_dirty = true;
|
||||
return in;
|
||||
QDataStream & operator>>(QDataStream & in, Transform3D & transform)
|
||||
{
|
||||
in >> transform.mTranslation;
|
||||
in >> transform.mScale;
|
||||
in >> transform.mRotation;
|
||||
transform.m_dirty = true;
|
||||
return in;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -10,108 +10,116 @@
|
||||
#ifndef QTK_TRANSFORM3D_H
|
||||
#define QTK_TRANSFORM3D_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMatrix4x4>
|
||||
#include <QQuaternion>
|
||||
#include <QVector3D>
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
#include <QDebug>
|
||||
#endif
|
||||
|
||||
class Transform3D
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
inline Transform3D() : m_dirty(true),
|
||||
mScale(1.0f, 1.0f, 1.0f),
|
||||
mTranslation(0.0f, 0.0f, 0.0f) { }
|
||||
#include <qtkapi.h>
|
||||
|
||||
//
|
||||
// Transformations
|
||||
namespace Qtk {
|
||||
class QTKAPI Transform3D
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
inline Transform3D() : m_dirty(true),
|
||||
mScale(1.0f, 1.0f, 1.0f),
|
||||
mTranslation(0.0f, 0.0f, 0.0f) { }
|
||||
|
||||
void translate(const QVector3D & dt);
|
||||
inline void translate(float dx, float dy, float dz)
|
||||
{ translate(QVector3D(dx, dy, dz));}
|
||||
//
|
||||
// Transformations
|
||||
|
||||
// Scale object with multiplication
|
||||
void scale(const QVector3D & ds);
|
||||
inline void scale(float dx, float dy, float dz)
|
||||
{ scale(QVector3D(dx, dy, dz));}
|
||||
inline void scale(float factor)
|
||||
{ scale(QVector3D(factor, factor, factor));}
|
||||
void translate(const QVector3D & dt);
|
||||
inline void translate(float dx, float dy, float dz)
|
||||
{ translate(QVector3D(dx, dy, dz));}
|
||||
|
||||
// Multiplying by a rotation
|
||||
void rotate(const QQuaternion & dr);
|
||||
inline void rotate(float angle, const QVector3D & axis)
|
||||
{ rotate(QQuaternion::fromAxisAndAngle(axis, angle));}
|
||||
inline void rotate(float angle, float ax, float ay, float az)
|
||||
{ rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));}
|
||||
// Scale object with multiplication
|
||||
void scale(const QVector3D & ds);
|
||||
inline void scale(float dx, float dy, float dz)
|
||||
{ scale(QVector3D(dx, dy, dz));}
|
||||
inline void scale(float factor)
|
||||
{ scale(QVector3D(factor, factor, factor));}
|
||||
|
||||
// Scale object by addition
|
||||
void grow(const QVector3D & ds);
|
||||
inline void grow(float dx, float dy, float dz)
|
||||
{ grow(QVector3D(dx, dy, dz));}
|
||||
inline void grow(float factor)
|
||||
{ grow(QVector3D(factor, factor, factor));}
|
||||
// Multiplying by a rotation
|
||||
void rotate(const QQuaternion & dr);
|
||||
inline void rotate(float angle, const QVector3D & axis)
|
||||
{ rotate(QQuaternion::fromAxisAndAngle(axis, angle));}
|
||||
inline void rotate(float angle, float ax, float ay, float az)
|
||||
{ rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));}
|
||||
|
||||
//
|
||||
// Setters
|
||||
// Scale object by addition
|
||||
void grow(const QVector3D & ds);
|
||||
inline void grow(float dx, float dy, float dz)
|
||||
{ grow(QVector3D(dx, dy, dz));}
|
||||
inline void grow(float factor)
|
||||
{ grow(QVector3D(factor, factor, factor));}
|
||||
|
||||
// Set object position
|
||||
void setTranslation(const QVector3D & t);
|
||||
inline void setTranslation(float x, float y, float z)
|
||||
{ setTranslation(QVector3D(x, y, z));}
|
||||
//
|
||||
// Setters
|
||||
|
||||
// Set object scale
|
||||
void setScale(const QVector3D & s);
|
||||
inline void setScale(float x, float y, float z)
|
||||
{ setScale(QVector3D(x, y, z));}
|
||||
inline void setScale(float k)
|
||||
{ setScale(QVector3D(k, k, k));}
|
||||
// Set object position
|
||||
void setTranslation(const QVector3D & t);
|
||||
inline void setTranslation(float x, float y, float z)
|
||||
{ setTranslation(QVector3D(x, y, z));}
|
||||
|
||||
// Set object rotation
|
||||
void setRotation(const QQuaternion & r);
|
||||
inline void setRotation(float angle, const QVector3D & axis)
|
||||
{ setRotation(QQuaternion::fromAxisAndAngle(axis, angle));}
|
||||
inline void setRotation(float angle, float ax, float ay, float az)
|
||||
{ setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));}
|
||||
// Set object scale
|
||||
void setScale(const QVector3D & s);
|
||||
inline void setScale(float x, float y, float z)
|
||||
{ setScale(QVector3D(x, y, z));}
|
||||
inline void setScale(float k)
|
||||
{ setScale(QVector3D(k, k, k));}
|
||||
|
||||
//
|
||||
// Accessors
|
||||
// Set object rotation
|
||||
void setRotation(const QQuaternion & r);
|
||||
inline void setRotation(float angle, const QVector3D & axis)
|
||||
{ setRotation(QQuaternion::fromAxisAndAngle(axis, angle));}
|
||||
inline void setRotation(float angle, float ax, float ay, float az)
|
||||
{ setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));}
|
||||
|
||||
inline const QVector3D & translation() const { return mTranslation;}
|
||||
inline const QVector3D & scale() const { return mScale; }
|
||||
inline const QQuaternion & rotation() const { return mRotation; }
|
||||
const QMatrix4x4 & toMatrix();
|
||||
//
|
||||
// Accessors
|
||||
|
||||
QVector3D forward() const;
|
||||
QVector3D up() const;
|
||||
QVector3D right() const;
|
||||
inline const QVector3D & translation() const { return mTranslation;}
|
||||
inline const QVector3D & scale() const { return mScale; }
|
||||
inline const QQuaternion & rotation() const { return mRotation; }
|
||||
const QMatrix4x4 & toMatrix();
|
||||
|
||||
static const QVector3D LocalForward, LocalUp, LocalRight;
|
||||
QVector3D forward() const;
|
||||
QVector3D up() const;
|
||||
QVector3D right() const;
|
||||
|
||||
private:
|
||||
QVector3D mTranslation;
|
||||
QQuaternion mRotation;
|
||||
QVector3D mScale;
|
||||
QMatrix4x4 mWorld;
|
||||
static const QVector3D LocalForward, LocalUp, LocalRight;
|
||||
|
||||
private:
|
||||
QVector3D mTranslation;
|
||||
QQuaternion mRotation;
|
||||
QVector3D mScale;
|
||||
QMatrix4x4 mWorld;
|
||||
|
||||
bool m_dirty;
|
||||
|
||||
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
|
||||
};
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(Transform3D, Q_MOVABLE_TYPE);
|
||||
|
||||
// Qt Streams
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug dbg, const Transform3D & transform);
|
||||
QDebug operator<<(QDebug dbg, const Transform3D & transform);
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
QDataStream &operator<<(QDataStream & out, const Transform3D & transform);
|
||||
QDataStream &operator>>(QDataStream & in, Transform3D & transform);
|
||||
QDataStream &operator<<(QDataStream & out, const Transform3D & transform);
|
||||
QDataStream &operator>>(QDataStream & in, Transform3D & transform);
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_DECLARE_TYPEINFO(Qtk::Transform3D, Q_MOVABLE_TYPE);
|
||||
|
||||
#endif // QTK_TRANSFORM3D_H
|
||||
|
||||
Reference in New Issue
Block a user