# HG changeset patch # User Teemu Piippo # Date 1576245356 -7200 # Node ID a5111f4e641261053c4535db2968598a34e4a5d6 # Parent aeb5f203b3eb48e16fa046262f93514ff3df2f10 added teapot rendering diff -r aeb5f203b3eb -r a5111f4e6412 CMakeLists.txt --- a/CMakeLists.txt Fri Nov 08 19:05:07 2019 +0200 +++ b/CMakeLists.txt Fri Dec 13 15:55:56 2019 +0200 @@ -10,14 +10,17 @@ find_package(Qt5OpenGL REQUIRED) find_package(Qt5Network REQUIRED) find_package(Qt5LinguistTools REQUIRED) +find_package(GLUT REQUIRED) set (CMAKE_AUTOMOC ON) find_package(OpenGL REQUIRED) include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${GLUT_INCLUDE_DIR}) set (LDFORGE_SOURCES src/document.cpp src/documentmanager.cpp src/libraries.cpp + src/invert.cpp src/main.cpp src/mainwindow.cpp src/matrix.cpp @@ -27,6 +30,8 @@ src/uiutilities.cpp src/version.cpp src/vertex.cpp + src/gl/compiler.cpp + src/gl/partrenderer.cpp src/linetypes/comment.cpp src/linetypes/conditionaledge.cpp src/linetypes/edge.cpp @@ -39,12 +44,14 @@ src/settingseditor/keyboardshortcutseditor.cpp src/settingseditor/librarieseditor.cpp src/settingseditor/settingseditor.cpp + src/types/boundingbox.cpp ) set (LDFORGE_HEADERS src/basics.h src/colors.h src/document.h src/documentmanager.h + src/invert.h src/libraries.h src/main.h src/mainwindow.h @@ -52,10 +59,14 @@ src/model.h src/modeleditcontext.h src/parser.h + src/ring.h src/uiutilities.h src/utility.h src/version.h src/vertex.h + src/gl/common.h + src/gl/compiler.h + src/gl/partrenderer.h src/linetypes/comment.h src/linetypes/conditionaledge.h src/linetypes/edge.h @@ -68,6 +79,7 @@ src/settingseditor/keyboardshortcutseditor.h src/settingseditor/librarieseditor.h src/settingseditor/settingseditor.h + src/types/boundingbox.h ) set (LDFORGE_FORMS src/document.ui @@ -127,6 +139,7 @@ set_source_files_properties(${LDFORGE_RESOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) set_target_properties(ldforge PROPERTIES AUTOMOC 1) target_link_libraries(ldforge Qt5::Widgets Qt5::Network Qt5::OpenGL ${OPENGL_LIBRARIES}) +target_link_libraries(ldforge ${GLUT_LIBRARIES}) cotire(ldforge) # Collect the current hg revision into hginfo.h diff -r aeb5f203b3eb -r a5111f4e6412 locale/fi.ts --- a/locale/fi.ts Fri Nov 08 19:05:07 2019 +0200 +++ b/locale/fi.ts Fri Dec 13 15:55:56 2019 +0200 @@ -205,7 +205,7 @@ - + System language diff -r aeb5f203b3eb -r a5111f4e6412 src/basics.h --- a/src/basics.h Fri Nov 08 19:05:07 2019 +0200 +++ b/src/basics.h Fri Dec 13 15:55:56 2019 +0200 @@ -66,4 +66,5 @@ return one; } +constexpr double infinity = std::numeric_limits::infinity(); static constexpr long double pi = M_PIl; diff -r aeb5f203b3eb -r a5111f4e6412 src/document.ui --- a/src/document.ui Fri Nov 08 19:05:07 2019 +0200 +++ b/src/document.ui Fri Dec 13 15:55:56 2019 +0200 @@ -19,12 +19,19 @@ Qt::Horizontal - + + + + PartRenderer + QOpenGLWidget +
gl/partrenderer.h
+
+
diff -r aeb5f203b3eb -r a5111f4e6412 src/documentmanager.cpp --- a/src/documentmanager.cpp Fri Nov 08 19:05:07 2019 +0200 +++ b/src/documentmanager.cpp Fri Dec 13 15:55:56 2019 +0200 @@ -55,7 +55,7 @@ const QString baseName = path.fileName(); const QString dirName = QFileInfo{path.dir().path()}.fileName(); QString result; - if (utility::contains(paths, dirName)) + if (std::find(std::begin(paths), std::end(paths), dirName) != std::end(paths)) { result = dirName + "\\" + baseName; } diff -r aeb5f203b3eb -r a5111f4e6412 src/gl/partrenderer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gl/partrenderer.cpp Fri Dec 13 15:55:56 2019 +0200 @@ -0,0 +1,118 @@ +#include +#include // teapot +#include "partrenderer.h" + +PartRenderer::PartRenderer(QWidget* parent) : + QOpenGLWidget{parent} +{ + this->setMouseTracking(true); +} + +void PartRenderer::initializeGL() +{ + this->initializeOpenGLFunctions(); + if (this->glGetError() != GL_NO_ERROR) + { + abort(); + } + this->initializeLighting(); + this->initialized = true; + this->rotation = QQuaternion::fromAxisAndAngle({1, 0, 0}, 30); + this->rotation *= QQuaternion::fromAxisAndAngle({0, 1, 0}, 330); +} + +// https://stackoverflow.com/a/12943456 +static void perspectiveGL(GLdouble fovY, GLdouble aspect, GLdouble zNear, GLdouble zFar) +{ + //fH = tan( (fovY / 2) / 180 * pi ) * zNear; + const GLdouble fH = std::tan(fovY / 360 * pi) * zNear; + const GLdouble fW = fH * aspect; + glFrustum(-fW, fW, -fH, fH, zNear, zFar); +} + +/* + * Pads a 3×3 matrix into a 4×4 one by adding cells from the identity matrix. + */ +static QMatrix4x4 padMatrix(const QMatrix3x3& stub) +{ + return { + stub(0, 0), stub(0, 1), stub(0, 2), 0, + stub(1, 0), stub(1, 1), stub(1, 2), 0, + stub(2, 0), stub(2, 1), stub(2, 2), 0, + 0, 0, 0, 1 + }; +} + + +void PartRenderer::initializeLighting() +{ + GLfloat materialShininess[] = {5.0}; + GLfloat lightPosition[] = {1.0, 1.0, 1.0, 0.0}; + GLfloat ambientLightingLevel[] = {0.5, 0.5, 0.5, 1.0}; + glShadeModel(GL_SMOOTH); + glMaterialfv(GL_FRONT, GL_SHININESS, materialShininess); + glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLightingLevel); + glLightfv(GL_LIGHT0, GL_DIFFUSE, ambientLightingLevel); + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_DEPTH_TEST); +} + +void PartRenderer::resizeGL(int width, int height) +{ + constexpr GLfloat near = 1.0f; + constexpr GLfloat far = 1.0e+05f; + glViewport (0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + ::perspectiveGL(45.0f, static_cast(width) / static_cast(height), near, far); + glMatrixMode(GL_MODELVIEW); +} + +// https://www.codemiles.com/c-opengl-examples/drawing-teapot-using-opengl-t9010.html?mobile=on +void PartRenderer::paintGL() +{ + glMatrixMode(GL_MODELVIEW); + // clear the drawing buffer. + glClear(GL_COLOR_BUFFER_BIT); + // clear the identity matrix. + glLoadIdentity(); + // traslate the draw by z = -4.0 + // Note this when you decrease z like -8.0 the drawing will looks far , or smaller. + glTranslatef(0.0,0.0,-4.5); + // Red color used to draw. + glColor3f(0.8, 0.2, 0.1); + glMultMatrixf(padMatrix(this->rotation.toRotationMatrix()).constData()); + glutSolidTeapot(1.0); + glFlush(); +} + +static QPointF pointToPointF(const QPoint& point) +{ + return {static_cast(point.x()), static_cast(point.y())}; +} + +/* +static QPoint pointFToPoint(const QPointF& point) +{ + return {static_cast(std::round(point.x())), static_cast(std::round(point.y()))}; +} +*/ + +void PartRenderer::mouseMoveEvent(QMouseEvent* event) +{ + const bool left = event->buttons() & Qt::LeftButton; + const QPointF move = pointToPointF(event->pos()) - this->lastMousePosition; + if (left and not move.isNull()) + { + const QQuaternion versor = QQuaternion::fromAxisAndAngle( + QVector3D{static_cast(move.y()), static_cast(move.x()), 0.0f}, + 0.6 * std::hypot(move.x(), move.y()) + ); + this->rotation = versor * this->rotation; + this->update(); + } + this->lastMousePosition = pointToPointF(event->pos()); +} diff -r aeb5f203b3eb -r a5111f4e6412 src/gl/partrenderer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gl/partrenderer.h Fri Dec 13 15:55:56 2019 +0200 @@ -0,0 +1,21 @@ +#pragma once +#include +#include +#include +#include "main.h" + +class PartRenderer : public QOpenGLWidget, protected QOpenGLFunctions +{ +public: + PartRenderer(QWidget* parent = nullptr); +protected: + void initializeGL() override; + void resizeGL(int width, int height) override; + void paintGL() override; + void mouseMoveEvent(QMouseEvent* event) override; +private: + QPointF lastMousePosition; + bool initialized = false; + QQuaternion rotation; + void initializeLighting(); +}; diff -r aeb5f203b3eb -r a5111f4e6412 src/linetypes/object.cpp --- a/src/linetypes/object.cpp Fri Nov 08 19:05:07 2019 +0200 +++ b/src/linetypes/object.cpp Fri Dec 13 15:55:56 2019 +0200 @@ -2,15 +2,6 @@ #include #include "object.h" -/* -static Uuid &getUuidForNewObject() -{ - static Uuid running_uuid {0, 0}; - incrementUuid(running_uuid); - return running_uuid; -} -*/ - static unsigned int getIdForNewObject() { static unsigned int id = 0; diff -r aeb5f203b3eb -r a5111f4e6412 src/linetypes/object.h --- a/src/linetypes/object.h Fri Nov 08 19:05:07 2019 +0200 +++ b/src/linetypes/object.h Fri Dec 13 15:55:56 2019 +0200 @@ -8,6 +8,7 @@ namespace linetypes { + struct Id { unsigned int value; }; enum class Property; class Object; class ColoredObject; @@ -46,7 +47,7 @@ Object(); Object(const Object&) = delete; virtual ~Object(); - const unsigned int id; + const Id id; //virtual void toString(QTextStream &out) = 0; virtual bool hasColor() const; virtual QVariant getProperty(Property id) const; @@ -75,8 +76,3 @@ { QString textRepresentation() const override; }; - -namespace linetypes -{ - using Id = std::decay_t; -} diff -r aeb5f203b3eb -r a5111f4e6412 src/main.cpp --- a/src/main.cpp Fri Nov 08 19:05:07 2019 +0200 +++ b/src/main.cpp Fri Dec 13 15:55:56 2019 +0200 @@ -1,11 +1,15 @@ #include #include +#include +#include #include "main.h" #include "mainwindow.h" #include "version.h" +#include "matrix.h" int main(int argc, char *argv[]) { + ::glutInit(&argc, argv); QCoreApplication::setApplicationName(::appName); QCoreApplication::setOrganizationName("hecknology.net"); QCoreApplication::setOrganizationDomain("hecknology.net"); diff -r aeb5f203b3eb -r a5111f4e6412 src/matrix.h --- a/src/matrix.h Fri Nov 08 19:05:07 2019 +0200 +++ b/src/matrix.h Fri Dec 13 15:55:56 2019 +0200 @@ -1,10 +1,30 @@ #pragma once #include +#include + +template +struct MatrixIterator; + +template +struct MatrixIndex +{ + int row; + int column; +}; template struct Matrix { + using Iterator = MatrixIterator; T values[Rows][Columns]; + Iterator begin() + { + return {*this, {0, 0}}; + } + Iterator end() + { + return {*this, {Rows, 0}}; + } T& operator()(int row, int column) { return this->values[row][column]; @@ -13,9 +33,78 @@ { return this->values[row][column]; } + T& operator[](const MatrixIndex& index) + { + return (*this)(index.row, index.column); + } + T operator[](const MatrixIndex& index) const + { + return (*this)(index.row, index.column); + } }; template +struct MatrixIterator +{ + struct Value + { + const MatrixIndex index; + decltype(std::declval>()(0, 0)) value; + }; + Matrix& matrix; + MatrixIndex index; +}; + +template +auto& operator++(MatrixIndex& index) +{ + index.column += 1; + if (index.column >= Columns) + { + index.row += 1; + index.column -= Columns; + } + return index; +} + +template +bool operator==( + const MatrixIndex& one, + const MatrixIndex& other) +{ + return one.row == other.row and one.column == other.column; +} +template +auto& operator++(MatrixIterator& iterator) +{ + ++iterator.index; + return iterator; +} + +template +bool operator==( + const MatrixIterator& one, + const MatrixIterator& other) +{ + return &one.matrix == &other.matrix and one.index == other.index; +} + +template +bool operator!=( + const MatrixIterator& one, + const MatrixIterator& other) +{ + return not (one == other); +} + +template +auto operator*(MatrixIterator& iterator) + -> typename MatrixIterator::Value +{ + return {iterator.index, iterator.matrix[iterator.index]}; +} + +template QGenericMatrix matrixToQGenericMatrix(const Matrix& matrix) { return {matrix.values}; @@ -25,12 +114,9 @@ Matrix matrixFromQGenericMatrix(const QGenericMatrix matrix) { Matrix result; - for (int row = 0; row < Rows; row += 1) + for (auto& cell : result) { - for (int column = 0; column < Columns; column += 1) - { - result(row, column) = matrix(row, column); - } + matrix(cell.index.row, cell.index.column) = result[cell.index]; } return result; } @@ -43,14 +129,22 @@ template QDataStream& operator<<(QDataStream& stream, const Matrix& matrix) { - return stream << matrixToQGenericMatrix(matrix); + for (auto& cell : matrix) + { + stream << cell.value; + } + return stream; } template QDataStream& operator>>(QDataStream& stream, Matrix& matrix) { - QGenericMatrix qmatrix; - stream >> qmatrix; - matrix = matrixFromQGenericMatrix(matrix); + for (auto& cell : matrix) + { + stream >> cell.value; + } return stream; } + +static constexpr Matrix3x3 identity3x3 {{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}}; +static constexpr Matrix4x4 identity4x4 {{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}}; diff -r aeb5f203b3eb -r a5111f4e6412 src/vertex.h --- a/src/vertex.h Fri Nov 08 19:05:07 2019 +0200 +++ b/src/vertex.h Fri Dec 13 15:55:56 2019 +0200 @@ -23,7 +23,7 @@ struct Vertex { - using ValueType = float; + using ValueType = double; ValueType x; ValueType y; ValueType z;