From 5faf584d842c360adbcd1448cebedd026728ced5 Mon Sep 17 00:00:00 2001 From: Anakin Date: Sat, 10 Dec 2016 14:42:00 +0100 Subject: [PATCH] First triangle drawn in Qt Project --- MeshViewerQt/Form Files/MainWindow.ui | 36 ++++++++------ MeshViewerQt/Header/MainWindow.h | 10 ++++ MeshViewerQt/Header/OpenGlViewer.h | 13 +++++ MeshViewerQt/Header/Vertex.h | 55 +++++++++++++++++++++ MeshViewerQt/Resources/MainWindow.qrc | 4 ++ MeshViewerQt/Resources/simple.frag | 8 +++ MeshViewerQt/Resources/simple.vert | 10 ++++ MeshViewerQt/Source/MainWindow.cpp | 33 ++++++++++++- MeshViewerQt/Source/OpenGlViewer.cpp | 70 ++++++++++++++++++++++++++- 9 files changed, 220 insertions(+), 19 deletions(-) create mode 100644 MeshViewerQt/Header/Vertex.h create mode 100644 MeshViewerQt/Resources/simple.frag create mode 100644 MeshViewerQt/Resources/simple.vert diff --git a/MeshViewerQt/Form Files/MainWindow.ui b/MeshViewerQt/Form Files/MainWindow.ui index 2dbb7bb..739421a 100644 --- a/MeshViewerQt/Form Files/MainWindow.ui +++ b/MeshViewerQt/Form Files/MainWindow.ui @@ -1,10 +1,8 @@ - + + MainWindowClass - - - MainWindowClass - - + + 0 0 @@ -12,18 +10,26 @@ 400 - + MainWindow - - - - + + + + false + + + TopToolBarArea + + + false + + + - - + - + - + diff --git a/MeshViewerQt/Header/MainWindow.h b/MeshViewerQt/Header/MainWindow.h index cc4f020..2d0a131 100644 --- a/MeshViewerQt/Header/MainWindow.h +++ b/MeshViewerQt/Header/MainWindow.h @@ -11,11 +11,21 @@ public: MainWindow(QWidget *parent = Q_NULLPTR); ~MainWindow(); +// Variables private: Ui::MainWindowClass* ui; +// Functions +private: void setupWindow(); +// Slots +private slots: + void openFile(); + void aboutFile(); + + +// Override Functions protected: virtual void keyPressEvent(QKeyEvent * keyEvent) override final; }; diff --git a/MeshViewerQt/Header/OpenGlViewer.h b/MeshViewerQt/Header/OpenGlViewer.h index c5ef150..0077076 100644 --- a/MeshViewerQt/Header/OpenGlViewer.h +++ b/MeshViewerQt/Header/OpenGlViewer.h @@ -2,6 +2,9 @@ #include #include +#include +#include +#include class OpenGlViewer : public QOpenGLWidget, protected QOpenGLFunctions { @@ -11,8 +14,18 @@ public: OpenGlViewer(QWidget *parent); ~OpenGlViewer(); +private: + QOpenGLBuffer mVertexBuffer; + QOpenGLVertexArrayObject mVertexArray; + QOpenGLShaderProgram* mProgram = nullptr; + +private: + void printContextInformation(); + protected: virtual void initializeGL() override final; virtual void resizeGL(int w, int h) override final; virtual void paintGL() override final; + +public: }; diff --git a/MeshViewerQt/Header/Vertex.h b/MeshViewerQt/Header/Vertex.h new file mode 100644 index 0000000..d0fbdd0 --- /dev/null +++ b/MeshViewerQt/Header/Vertex.h @@ -0,0 +1,55 @@ +#ifndef VERTEX_H +#define VERTEX_H + +#include + +class Vertex +{ +public: + // Constructors + Q_DECL_CONSTEXPR Vertex(); + Q_DECL_CONSTEXPR explicit Vertex(const QVector3D &position); + Q_DECL_CONSTEXPR Vertex(const QVector3D &position, const QVector3D &color); + + // Accessors / Mutators + Q_DECL_CONSTEXPR const QVector3D& position() const; + Q_DECL_CONSTEXPR const QVector3D& color() const; + void setPosition(const QVector3D& position); + void setColor(const QVector3D& color); + + // OpenGL Helpers + static const int PositionTupleSize = 3; + static const int ColorTupleSize = 3; + static Q_DECL_CONSTEXPR int positionOffset(); + static Q_DECL_CONSTEXPR int colorOffset(); + static Q_DECL_CONSTEXPR int stride(); + +private: + QVector3D m_position; + QVector3D m_color; +}; + +/******************************************************************************* +* Inline Implementation +******************************************************************************/ + +// Note: Q_MOVABLE_TYPE means it can be memcpy'd. +Q_DECLARE_TYPEINFO(Vertex, Q_MOVABLE_TYPE); + +// Constructors +Q_DECL_CONSTEXPR inline Vertex::Vertex() {} +Q_DECL_CONSTEXPR inline Vertex::Vertex(const QVector3D &position) : m_position(position) {} +Q_DECL_CONSTEXPR inline Vertex::Vertex(const QVector3D &position, const QVector3D &color) : m_position(position), m_color(color) {} + +// Accessors / Mutators +Q_DECL_CONSTEXPR inline const QVector3D& Vertex::position() const { return m_position; } +Q_DECL_CONSTEXPR inline const QVector3D& Vertex::color() const { return m_color; } +void inline Vertex::setPosition(const QVector3D& position) { m_position = position; } +void inline Vertex::setColor(const QVector3D& color) { m_color = color; } + +// OpenGL Helpers +Q_DECL_CONSTEXPR inline int Vertex::positionOffset() { return offsetof(Vertex, m_position); } +Q_DECL_CONSTEXPR inline int Vertex::colorOffset() { return offsetof(Vertex, m_color); } +Q_DECL_CONSTEXPR inline int Vertex::stride() { return sizeof(Vertex); } + +#endif // VERTEX_H \ No newline at end of file diff --git a/MeshViewerQt/Resources/MainWindow.qrc b/MeshViewerQt/Resources/MainWindow.qrc index 3ec5688..d399190 100644 --- a/MeshViewerQt/Resources/MainWindow.qrc +++ b/MeshViewerQt/Resources/MainWindow.qrc @@ -2,4 +2,8 @@ icon.ico + + simple.frag + simple.vert + diff --git a/MeshViewerQt/Resources/simple.frag b/MeshViewerQt/Resources/simple.frag new file mode 100644 index 0000000..9844eff --- /dev/null +++ b/MeshViewerQt/Resources/simple.frag @@ -0,0 +1,8 @@ +#version 330 +in vec4 vColor; +out vec4 fColor; + +void main() +{ + fColor = vColor; +} \ No newline at end of file diff --git a/MeshViewerQt/Resources/simple.vert b/MeshViewerQt/Resources/simple.vert new file mode 100644 index 0000000..fad59f5 --- /dev/null +++ b/MeshViewerQt/Resources/simple.vert @@ -0,0 +1,10 @@ +#version 330 +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 color; +out vec4 vColor; + +void main() +{ + gl_Position = vec4(position, 1.0); + vColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/MeshViewerQt/Source/MainWindow.cpp b/MeshViewerQt/Source/MainWindow.cpp index 1bd8441..969ce64 100644 --- a/MeshViewerQt/Source/MainWindow.cpp +++ b/MeshViewerQt/Source/MainWindow.cpp @@ -2,8 +2,12 @@ #include "OpenGlViewer.h" #include "defines.h" #include +#include +///////////////////////////////////////////////////////////////////////// +// constructor/destructor + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui (new Ui::MainWindowClass) @@ -16,6 +20,10 @@ MainWindow::~MainWindow() delete ui; } + +///////////////////////////////////////////////////////////////////////// +// private functions + void MainWindow::setupWindow() { ui->setupUi(this); @@ -26,11 +34,32 @@ void MainWindow::setupWindow() this->setCentralWidget(new OpenGlViewer(this)); + ui->mainToolBar->addAction("File Info", this, &MainWindow::aboutFile); + ui->statusBar->showMessage(DEFAULT_STATUS_MESSAGE); - - } + +///////////////////////////////////////////////////////////////////////// +// private slots + +void MainWindow::openFile() +{ + //TODO: Open file +} + +void MainWindow::aboutFile() +{ + //TODO: Open Window with file information + QMessageBox* dialog = new QMessageBox(QMessageBox::Information, WINDOW_NAME, "File Info", QMessageBox::StandardButton::Close, this, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); + dialog->setDetailedText("This is the cool detailed text\n"); + dialog->exec(); +} + + +///////////////////////////////////////////////////////////////////////// +// events + void MainWindow::keyPressEvent(QKeyEvent * keyEvent) { switch (keyEvent->key()) diff --git a/MeshViewerQt/Source/OpenGlViewer.cpp b/MeshViewerQt/Source/OpenGlViewer.cpp index 46d884e..292c76d 100644 --- a/MeshViewerQt/Source/OpenGlViewer.cpp +++ b/MeshViewerQt/Source/OpenGlViewer.cpp @@ -1,25 +1,84 @@ #include "OpenGlViewer.h" #include "defines.h" +#include "Vertex.h" + +#include + +static const Vertex sg_vertexes[] = { + Vertex(QVector3D(0.00f, 0.75f, 1.0f), QVector3D(1.0f, 0.0f, 0.0f)), + Vertex(QVector3D(0.75f, -0.75f, 1.0f), QVector3D(0.0f, 1.0f, 0.0f)), + Vertex(QVector3D(-0.75f, -0.75f, 1.0f), QVector3D(0.0f, 0.0f, 1.0f)) +}; OpenGlViewer::OpenGlViewer(QWidget *parent) : QOpenGLWidget(parent) { QSurfaceFormat format; + format.setRenderableType(QSurfaceFormat::OpenGL); + format.setProfile(QSurfaceFormat::CompatibilityProfile); format.setVersion(DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION); - format.setProfile(QSurfaceFormat::CoreProfile); - this->setFormat(format); + setFormat(format); } OpenGlViewer::~OpenGlViewer() { + mVertexArray.destroy(); + mVertexBuffer.destroy(); + delete mProgram; +} + +void OpenGlViewer::printContextInformation() +{ + QString glType; + QString glVersion; + QString glProfile; + + glType = (context()->isOpenGLES()) ? "OpenGL ES" : "OpenGL"; + glVersion = reinterpret_cast(glGetString(GL_VERSION)); + +#define CASE(c) case QSurfaceFormat::c: glProfile = #c; break + switch (format().profile()) + { + CASE(NoProfile); + CASE(CoreProfile); + CASE(CompatibilityProfile); + } +#undef CASE + + std::cout << glType.toStdString() << " - " << glVersion.toStdString() << " (" << glProfile.toStdString() << ")"; } void OpenGlViewer::initializeGL() { initializeOpenGLFunctions(); + printContextInformation(); + //glEnable(GL_DEPTH_TEST); glClearColor(DEAFAULT_BACKGROUND); + + mProgram = new QOpenGLShaderProgram(); + mProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/simple.vert"); + mProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/simple.frag"); + mProgram->link(); + mProgram->bind(); + + mVertexBuffer.create(); + mVertexBuffer.bind(); + mVertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw); + mVertexBuffer.allocate(sg_vertexes, sizeof(sg_vertexes)); + + mVertexArray.create(); + mVertexArray.bind(); + mProgram->enableAttributeArray(0); + mProgram->enableAttributeArray(1); + mProgram->setAttributeBuffer(0, GL_FLOAT, Vertex::positionOffset(), Vertex::PositionTupleSize, Vertex::stride()); + mProgram->setAttributeBuffer(1, GL_FLOAT, Vertex::colorOffset(), Vertex::ColorTupleSize, Vertex::stride()); + + mVertexArray.release(); + mVertexBuffer.release(); + mProgram->release(); + } void OpenGlViewer::resizeGL(int w, int h) @@ -30,5 +89,12 @@ void OpenGlViewer::resizeGL(int w, int h) void OpenGlViewer::paintGL() { //TODO: paint here + glClear(GL_COLOR_BUFFER_BIT); + + mProgram->bind(); + mVertexArray.bind(); + glDrawArrays(GL_TRIANGLES, 0, sizeof(sg_vertexes) / sizeof(sg_vertexes[0])); + mVertexArray.release(); + mProgram->release(); }