Wed, 25 Mar 2020 16:07:20 +0200
added PolygonObject and refactored away a lot of boilerplate
/* * LDForge: LDraw parts authoring CAD * Copyright (C) 2013 - 2018 Teemu Piippo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #pragma once #include "main.h" #include "gl/common.h" #include "types/boundingbox.h" #include <glm/gtc/type_ptr.hpp> #include <QMap> #include <QSet> #include <QOpenGLVertexArrayObject> #include <QOpenGLBuffer> #include <QOpenGLShaderProgram> #include <QOpenGLExtraFunctions> class Model; class DocumentManager; namespace gl { class Compiler; } class gl::Compiler : public QObject, protected QOpenGLExtraFunctions { Q_OBJECT public: Compiler(const ldraw::ColorTable& colorTable, QObject* parent); ~Compiler(); void build(Model* model, DocumentManager* context, const RenderPreferences& preferences); std::size_t vertexCount(gl::ArrayClass arrayClass) const; QColor getColorForPolygon(const gl::Polygon& polygon, const RenderPreferences& preferences); glm::vec3 modelCenter() const; double modelDistance() const; void initialize(); void bindVertexArray(gl::ArrayClass arrayClass); void releaseVertexArray(gl::ArrayClass arrayClass); void buildShaders(int arrayId); void setSelectedObjects(const QSet<ldraw::id_t> ids); static ldraw::id_t idFromColor(const std::array<GLubyte, 3>& data); template<typename T> void setUniform(const char* uniformName, T&& value) { Q_ASSERT(this->initialized); for (auto& object : this->glObjects) { object.program->bind(); const int location = glGetUniformLocation(object.program->programId(), uniformName); Q_ASSERT(location != -1); object.program->setUniformValue(location, std::forward<T>(value)); object.program->release(); } } template<typename Float, glm::qualifier Prec> void setUniformMatrix(const char* uniformName, const glm::mat<4, 4, Float, Prec>& value) { const float (*array)[4][4] = reinterpret_cast<const float(*)[4][4]>(glm::value_ptr(value)); this->setUniform(uniformName, *array); } private: struct Vertex { glm::vec3 position; glm::vec4 color; glm::vec3 normal; glm::int32 id; glm::int32 selected = 0; }; void buildPolygon(Polygon polygon, std::vector<Vertex>* vboData, const gl::RenderPreferences& preferences); std::size_t storedVertexCounts[gl::NUM_POLYGON_TYPES] = {0}; bool initialized = false; BoundingBox boundingBox; const ldraw::ColorTable& colorTable; ldraw::id_t hovered = ldraw::NULL_ID; struct { QOpenGLShaderProgram* program = nullptr; QOpenGLShaderProgram* pickSceneProgram = nullptr; QOpenGLBuffer buffer{QOpenGLBuffer::VertexBuffer}; QOpenGLVertexArrayObject vertexArray; std::vector<Vertex> cachedData; } glObjects[gl::NUM_POLYGON_TYPES]; }; #define CHECK_GL_ERROR() { checkGLError(__FILE__, __LINE__); } void checkGLError (QString file, int line);