# HG changeset patch # User Teemu Piippo # Date 1653469318 -10800 # Node ID 815fbaae9cb2eff880abf79c17a79a8249fb575c # Parent 64ea7282611e743a3cce9dc31caaa489dc23e4a4 cleanup, gl::Compiler changed to gl::ModelShaders diff -r 64ea7282611e -r 815fbaae9cb2 src/gl/common.h --- a/src/gl/common.h Tue May 24 16:11:10 2022 +0300 +++ b/src/gl/common.h Wed May 25 12:01:58 2022 +0300 @@ -110,6 +110,7 @@ }; Q_DECLARE_METATYPE(gl::Polygon) +extern QOpenGLFunctions glfunc; namespace gl { diff -r 64ea7282611e -r 815fbaae9cb2 src/gl/compiler.cpp --- a/src/gl/compiler.cpp Tue May 24 16:11:10 2022 +0300 +++ b/src/gl/compiler.cpp Wed May 25 12:01:58 2022 +0300 @@ -125,17 +125,6 @@ } )"; -gl::Compiler::Compiler(Model *model, const ldraw::ColorTable& colorTable, QObject* parent) : - QObject{parent}, - model{model}, - colorTable{colorTable} -{ -} - -gl::Compiler::~Compiler() -{ -} - void gl::buildShaders( QOpenGLShaderProgram* shaderProgram, const char* vertexShaderSource, @@ -174,69 +163,40 @@ } } -void gl::Compiler::initialize() +void gl::initializeModelShaders(gl::ModelShaders *modelShaders) { - if (not this->initialized) + if (not modelShaders->initialized) { - this->initializeOpenGLFunctions(); - for (auto& object : this->glObjects) + for (auto& shader : modelShaders->shaderObjects) { - object.program = new QOpenGLShaderProgram; - gl::buildShaders(object.program, ::vertexShaderSource, ::fragmentShaderSource); - object.program->bind(); - object.buffer.create(); - object.buffer.bind(); - object.buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); - object.vertexArray.create(); - object.vertexArray.bind(); + shader.program = std::make_unique(); + gl::buildShaders(shader.program.get(), ::vertexShaderSource, ::fragmentShaderSource); + shader.program->bind(); + shader.buffer.create(); + shader.buffer.bind(); + shader.buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); + shader.vertexArray.create(); + shader.vertexArray.bind(); for (int k : {0, 1, 2, 3, 4}) { - object.program->enableAttributeArray(k); + shader.program->enableAttributeArray(k); } + using Vertex = ModelShaders::Vertex; constexpr int stride = sizeof(Vertex); - object.program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride); - object.program->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, color), 4, stride); - object.program->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, normal), 3, stride); + shader.program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride); + shader.program->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, color), 4, stride); + shader.program->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, normal), 3, stride); glVertexAttribIPointer(3, 1, GL_INT, stride, reinterpret_cast(offsetof(Vertex, id))); glVertexAttribIPointer(4, 1, GL_INT, stride, reinterpret_cast(offsetof(Vertex, selected))); - object.vertexArray.release(); - object.buffer.release(); - object.program->release(); + shader.vertexArray.release(); + shader.buffer.release(); + shader.program->release(); } - this->initialized = true; + modelShaders->initialized = true; } } -void gl::Compiler::build(DocumentManager* context, const gl::RenderPreferences& preferences) -{ - this->boundingBox = {}; - std::vector vboData[gl::NUM_POLYGON_TYPES]; - std::optional modelId = context->findIdForModel(this->model); - if (modelId.has_value()) - { - PolygonCache* polygonBuilder = context->getPolygonCacheForModel(modelId.value()); - if (polygonBuilder != nullptr) - { - const std::vector polygons = polygonBuilder->getPolygons(context); - for (const gl::Polygon& polygon : polygons) - { - this->buildPolygon(polygon, vboData, preferences); - } - for (int arrayId = 0; arrayId < gl::NUM_POLYGON_TYPES; arrayId += 1) - { - auto& buffer = this->glObjects[arrayId].buffer; - auto& vector = vboData[arrayId]; - this->storedVertexCounts[arrayId] = vector.size(); - this->glObjects[arrayId].cachedData = vector; // todo: get rid of this copy - buffer.bind(); - buffer.allocate(vector.data(), static_cast(vector.size() * sizeof vector[0])); - buffer.release(); - } - } - } -} - -gl::ArrayClass classifyPolygon(const gl::Polygon& polygon) +static gl::ArrayClass classifyPolygon(const gl::Polygon& polygon) { switch (polygon.type) { @@ -252,36 +212,27 @@ return gl::ArrayClass::Lines; } -ldraw::id_t gl::Compiler::idFromColor(const std::array& data) -{ - return {data[0] * std::int32_t{0x10000} + data[1] * std::int32_t{0x100} + data[2]}; -} - -void gl::Compiler::buildPolygon( - gl::Polygon polygon, - std::vector* vboData, - const gl::RenderPreferences& preferences) +template +void iterateModelPolygons(Model* model, DocumentManager* context, Fn&& fn) { - const gl::ArrayClass vboClass = classifyPolygon(polygon); - std::vector& vertexBuffer = vboData[static_cast(vboClass)]; - auto vertexRing = iter::ring(polygon.vertices, polygon.numPolygonVertices()); - reserveMore(vertexBuffer, polygon.numPolygonVertices()); - const QColor color = this->getColorForPolygon(polygon, preferences); - for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) + std::optional modelId = context->findIdForModel(model); + if (modelId.has_value()) { - const glm::vec3& v1 = vertexRing[i - 1]; - const glm::vec3& v2 = vertexRing[i]; - const glm::vec3& v3 = vertexRing[i + 1]; - this->boundingBox.consider(polygon.vertices[i]); - Vertex& vertex = vertexBuffer.emplace_back(); - vertex.position = polygon.vertices[i]; - vertex.normal = glm::normalize(glm::cross(v1 - v2, v3 - v2)); - vertex.color = glm::vec4{color.redF(), color.greenF(), color.blueF(), color.alphaF()}; - vertex.id = polygon.id.value; + PolygonCache* polygonCache= context->getPolygonCacheForModel(modelId.value()); + if (polygonCache != nullptr) + { + for (const gl::Polygon& polygon : polygonCache->getPolygons(context)) + { + fn(polygon); + } + } } } -QColor gl::Compiler::getColorForPolygon(const gl::Polygon& polygon, const gl::RenderPreferences& preferences) +static QColor getColorForPolygon( + const gl::Polygon& polygon, + const gl::RenderPreferences& preferences, + const ldraw::ColorTable& colorTable) { QColor color; // For normal colors, use the polygon's color. @@ -297,41 +248,94 @@ else { // Not main or edge color, use the polygon's color as is. - color = this->colorTable[polygon.color].faceColor; + color = colorTable[polygon.color].faceColor; } return color; } -glm::vec3 gl::Compiler::modelCenter() const +/** + * @brief Computes the minimum bounding box for a model + */ +BoundingBox gl::boundingBoxForModel(Model* model, DocumentManager* context) { - return boxCenter(this->boundingBox); -} - -double gl::Compiler::modelDistance() const -{ - return static_cast(longestMeasure(this->boundingBox)); + BoundingBox result = emptyBoundingBox; + iterateModelPolygons(model, context, [&](const gl::Polygon& polygon) + { + for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) + { + addPointToBox(result, polygon.vertices[i]); + } + }); + return result; } -void gl::Compiler::bindVertexArray(gl::ArrayClass arrayClass) +/** + * @brief gl::build Creates GL vertices for objects in the model and buffers them to shaders. + */ +void gl::build( + gl::ModelShaders* shaders, + Model* model, + const ldraw::ColorTable& colorTable, + DocumentManager* context, + const gl::RenderPreferences& preferences) { - auto& object = this->glObjects[static_cast(arrayClass)]; - object.vertexArray.bind(); - object.program->bind(); + for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) { + shader.cachedData.clear(); + } + iterateModelPolygons(model, context, [&](const Polygon& polygon) + { + const int index = static_cast(classifyPolygon(polygon)); + std::vector& vertexBuffer = shaders->shaderObjects[index].cachedData; + auto vertexRing = iter::ring(polygon.vertices, polygon.numPolygonVertices()); + reserveMore(vertexBuffer, polygon.numPolygonVertices()); + const QColor color = getColorForPolygon(polygon, preferences, colorTable); + for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) + { + const glm::vec3& v1 = vertexRing[i - 1]; + const glm::vec3& v2 = vertexRing[i]; + const glm::vec3& v3 = vertexRing[i + 1]; + gl::ModelShaders::Vertex& vertex = vertexBuffer.emplace_back(); + vertex.position = polygon.vertices[i]; + vertex.normal = glm::normalize(glm::cross(v1 - v2, v3 - v2)); + vertex.color = glm::vec4{color.redF(), color.greenF(), color.blueF(), color.alphaF()}; + vertex.id = polygon.id.value; + } + }); + for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) + { + shader.vertexCount = shader.cachedData.size(); + shader.buffer.bind(); + const int bytes = static_cast(shader.cachedData.size() * sizeof shader.cachedData[0]); + shader.buffer.allocate(shader.cachedData.data(), bytes); + shader.buffer.release(); + } } -void gl::Compiler::releaseVertexArray(gl::ArrayClass arrayClass) +ldraw::id_t gl::idFromColor(const std::array& data) { - auto& object = this->glObjects[static_cast(arrayClass)]; - object.program->release(); - object.vertexArray.release(); + return {data[0] * std::int32_t{0x10000} + data[1] * std::int32_t{0x100} + data[2]}; +} + +void gl::bindModelShaderVertexArray(gl::ModelShaders* shaders, gl::ArrayClass arrayClass) +{ + ModelShaders::ShaderObject& shaderObject = shaders->shaderObjects[static_cast(arrayClass)]; + shaderObject.vertexArray.bind(); + shaderObject.program->bind(); } -void gl::Compiler::setSelectedObjects(const QSet ids) +void gl::releaseModelShaderVertexArray(gl::ModelShaders* shaders, gl::ArrayClass arrayClass) { - for (auto& object : this->glObjects) + ModelShaders::ShaderObject& shaderObject = shaders->shaderObjects[static_cast(arrayClass)]; + shaderObject.program->release(); + shaderObject.vertexArray.release(); +} + +void gl::setModelShaderSelectedObjects(gl::ModelShaders* shaders, const QSet& ids) +{ + for (ModelShaders::ShaderObject& object : shaders->shaderObjects) { - std::vector& vector = object.cachedData; - for (Vertex& vertex : vector) + std::vector& vector = object.cachedData; + for (ModelShaders::Vertex& vertex : vector) { vertex.selected = (ids.contains({vertex.id})) ? 1 : 0; } @@ -342,7 +346,7 @@ } } -std::size_t gl::Compiler::vertexCount(const gl::ArrayClass arrayClass) const +std::size_t gl::vertexCount(const gl::ModelShaders* shaders, const gl::ArrayClass arrayClass) { - return this->storedVertexCounts[static_cast(arrayClass)]; + return shaders->shaderObjects[static_cast(arrayClass)].vertexCount; } diff -r 64ea7282611e -r 815fbaae9cb2 src/gl/compiler.h --- a/src/gl/compiler.h Tue May 24 16:11:10 2022 +0300 +++ b/src/gl/compiler.h Wed May 25 12:01:58 2022 +0300 @@ -33,73 +33,66 @@ namespace gl { - class Compiler; -} + struct ModelShaders + { + struct Vertex + { + glm::vec3 position; + glm::vec4 color; + glm::vec3 normal; + glm::int32 id; + glm::int32 selected = 0; + }; + bool initialized = false; + struct ShaderObject + { + std::unique_ptr program = nullptr; + QOpenGLShaderProgram* pickSceneProgram = nullptr; + QOpenGLBuffer buffer{QOpenGLBuffer::VertexBuffer}; + QOpenGLVertexArrayObject vertexArray; + std::vector cachedData; + std::size_t vertexCount; + } shaderObjects[gl::NUM_POLYGON_TYPES]; + }; -class gl::Compiler : public QObject, protected QOpenGLExtraFunctions -{ - Q_OBJECT -public: - Compiler(Model* model, const ldraw::ColorTable& colorTable, QObject* parent); - ~Compiler(); - void build(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 ids); - - static ldraw::id_t idFromColor(const std::array& data); + void build( + ModelShaders* shaders, + Model *model, + const ldraw::ColorTable& colorTable, + DocumentManager* context, + const RenderPreferences& preferences); + void initializeModelShaders(ModelShaders* modelShaders); + void bindModelShaderVertexArray(gl::ModelShaders* shaders, gl::ArrayClass arrayClass); + void releaseModelShaderVertexArray(gl::ModelShaders* shaders, gl::ArrayClass arrayClass); + void setModelShaderSelectedObjects(gl::ModelShaders* shaders, const QSet& ids); + std::size_t vertexCount(const ModelShaders *shaders, gl::ArrayClass arrayClass); + ldraw::id_t idFromColor(const std::array& data); template - void setUniform(const char* uniformName, T&& value) + void setShaderUniform(gl::ModelShaders* shaders, const char* uniformName, T&& value) { - Q_ASSERT(this->initialized); - for (auto& object : this->glObjects) + for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) { - object.program->bind(); - const int location = glGetUniformLocation(object.program->programId(), uniformName); + shader.program->bind(); + const int location = glfunc.glGetUniformLocation(shader.program->programId(), uniformName); Q_ASSERT(location != -1); - object.program->setUniformValue(location, std::forward(value)); - object.program->release(); + shader.program->setUniformValue(location, std::forward(value)); + shader.program->release(); } } template - void setUniformMatrix(const char* uniformName, const glm::mat<4, 4, Float, Prec>& value) + void setShaderUniformMatrix( + gl::ModelShaders* shaders, + const char* uniformName, + const glm::mat<4, 4, Float, Prec>& value) { const float (*array)[4][4] = reinterpret_cast(glm::value_ptr(value)); - this->setUniform(uniformName, *array); + setShaderUniform(shaders, 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* vboData, const gl::RenderPreferences& preferences); - Model* const model; - 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 cachedData; - } glObjects[gl::NUM_POLYGON_TYPES]; -}; + + BoundingBox boundingBoxForModel(Model* model, DocumentManager* context); +} #define CHECK_GL_ERROR() { checkGLError(__FILE__, __LINE__); } void checkGLError (QString file, int line); diff -r 64ea7282611e -r 815fbaae9cb2 src/gl/partrenderer.cpp --- a/src/gl/partrenderer.cpp Tue May 24 16:11:10 2022 +0300 +++ b/src/gl/partrenderer.cpp Wed May 25 12:01:58 2022 +0300 @@ -28,6 +28,7 @@ static constexpr double MIN_ZOOM = -3.0; static constexpr double MAX_ZOOM = 3.0; +QOpenGLFunctions glfunc; PartRenderer::PartRenderer( Model* model, @@ -37,8 +38,7 @@ QOpenGLWidget{parent}, model{model}, documents{documents}, - colorTable{colorTable}, - compiler{new gl::Compiler{model, this->colorTable, this}} + colorTable{colorTable} { this->setMouseTracking(true); connect(model, &Model::rowsInserted, [&]{ @@ -51,7 +51,7 @@ { } -static QVector3D vec3FromQColor(const QColor& color) +static QVector3D calcQVector3DFromQColor(const QColor& color) { return { toFloat(color.redF()), @@ -62,17 +62,16 @@ void PartRenderer::initializeGL() { - this->initializeOpenGLFunctions(); + ::glfunc.initializeOpenGLFunctions(); if (glGetError() != GL_NO_ERROR) { abort(); } - this->compiler->initialize(); + gl::initializeModelShaders(&this->shaders); connect(this->model, &Model::dataChanged, this, &PartRenderer::build); this->initialized = true; this->modelQuaternion = glm::angleAxis(glm::radians(30.0f), glm::vec3{-1, 0, 0}); this->modelQuaternion *= glm::angleAxis(glm::radians(225.0f), glm::vec3{-0, 1, 0}); - this->setupBackgroundColor(); this->updateModelMatrix(); this->updateViewMatrix(); this->update(); @@ -87,11 +86,11 @@ static_cast(width) / static_cast(height), 0.1f, 10000.f); - this->compiler->setUniformMatrix("projectionMatrix", this->projectionMatrix); + gl::setShaderUniformMatrix(&this->shaders, "projectionMatrix", this->projectionMatrix); Q_EMIT projectionMatrixChanged(this->projectionMatrix); } -static GLenum getGlTypeForArrayClass(const gl::ArrayClass vboClass) +static constexpr GLenum getGlTypeForArrayClass(const gl::ArrayClass vboClass) { switch (vboClass) { @@ -103,7 +102,7 @@ case gl::ArrayClass::Quads: return GL_QUADS; } - throw std::runtime_error{"Bad vbo class passed to getGlTypeForVboClass"}; + throw std::runtime_error{"bad value for vboClass"}; } void PartRenderer::paintGL() @@ -117,12 +116,15 @@ { if (this->needBuild) { - this->compiler->build(this->documents, this->renderPreferences); + gl::build(&this->shaders, this->model, this->colorTable, this->documents, this->renderPreferences); + this->boundingBox = gl::boundingBoxForModel(this->model, this->documents); this->needBuild = false; } this->checkForGLErrors(); - if (this->renderPreferences.lineAntiAliasing && this->renderPreferences.style != gl::RenderStyle::PickScene) - { + if (true + and this->renderPreferences.lineAntiAliasing + and this->renderPreferences.style != gl::RenderStyle::PickScene + ) { glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); } @@ -137,27 +139,34 @@ static_cast(backgroundColor.greenF()), static_cast(backgroundColor.blueF()), 1.0f); - this->compiler->setUniform("useLighting", GL_TRUE); + gl::setShaderUniform(&this->shaders, "useLighting", GL_TRUE); } else { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - this->compiler->setUniform("useLighting", GL_FALSE); + gl::setShaderUniform(&this->shaders, "useLighting", GL_FALSE); } this->checkForGLErrors(); - this->compiler->setUniform("selectedColor", vec3FromQColor(this->renderPreferences.selectedColor)); - this->compiler->setUniform("highlighted", this->highlighted.value); + const QVector3D color = calcQVector3DFromQColor(this->renderPreferences.selectedColor); + gl::setShaderUniform(&this->shaders, "selectedColor", color); + gl::setShaderUniform(&this->shaders, "highlighted", this->highlighted.value); this->checkForGLErrors(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0f, 1.0f); glLineWidth(this->renderPreferences.lineThickness); + const auto renderAllArrays = [this](){ + // Lines need to be rendered last so that anti-aliasing does not interfere with polygon rendering. + this->renderVao(gl::ArrayClass::Triangles); + this->renderVao(gl::ArrayClass::Quads); + this->renderVao(gl::ArrayClass::Lines); + }; switch (this->renderPreferences.style) { case gl::RenderStyle::Normal: this->setFragmentStyle(gl::FragmentStyle::Normal); - this->renderAllArrays(); + renderAllArrays(); break; case gl::RenderStyle::BfcRedGreen: glEnable(GL_CULL_FACE); @@ -172,59 +181,49 @@ glDisable(GL_CULL_FACE); this->setFragmentStyle(gl::FragmentStyle::Normal); renderVao(gl::ArrayClass::Lines); + break; case gl::RenderStyle::RandomColors: this->setFragmentStyle(gl::FragmentStyle::RandomColors); - this->renderAllArrays(); + renderAllArrays(); break; case gl::RenderStyle::PickScene: glLineWidth(3.0f); this->setFragmentStyle(gl::FragmentStyle::Id); - this->renderAllArrays(); + renderAllArrays(); break; case gl::RenderStyle::VertexPickScene: glLineWidth(1.0f); this->setFragmentStyle(gl::FragmentStyle::Black); - this->renderAllArrays(); + renderAllArrays(); break; case gl::RenderStyle::Wireframe: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); this->setFragmentStyle(gl::FragmentStyle::Normal); - this->renderAllArrays(); + renderAllArrays(); break; } glDisable(GL_POLYGON_OFFSET_FILL); } -void PartRenderer::renderAllArrays() -{ - // Lines need to be rendered last so that anti-aliasing does not interfere with polygon rendering. - renderVao(gl::ArrayClass::Triangles); - renderVao(gl::ArrayClass::Quads); - renderVao(gl::ArrayClass::Lines); -} - void PartRenderer::updateViewMatrix() { // I'm not quite sure why using the exponent function on the zoom factor causes linear zoom behavior - const double z = 2 * std::exp(this->zoom) * (1 + this->compiler->modelDistance()); + const float modelDistance = longestMeasure(this->boundingBox); + const double z = 2.0 * std::exp(this->zoom) * (1 + static_cast(modelDistance)); this->viewMatrix = glm::lookAt(glm::vec3{0, 0, z}, {0, 0, 0}, {0, -1, 0}); - this->compiler->setUniformMatrix("viewMatrix", this->viewMatrix); + gl::setShaderUniformMatrix(&this->shaders, "viewMatrix", this->viewMatrix); Q_EMIT this->viewMatrixChanged(this->viewMatrix); } void PartRenderer::updateModelMatrix() { this->modelMatrix = glm::mat4_cast(this->modelQuaternion); - this->compiler->setUniformMatrix("modelMatrix", modelMatrix); + gl::setShaderUniformMatrix(&this->shaders, "modelMatrix", modelMatrix); Q_EMIT this->modelMatrixChanged(this->modelMatrix); this->update(); } -void PartRenderer::setupBackgroundColor() -{ -} - void PartRenderer::build() { this->needBuild = true; @@ -232,12 +231,12 @@ void PartRenderer::renderVao(const gl::ArrayClass arrayClass) { - this->compiler->bindVertexArray(arrayClass); - const std::size_t vertexCount = this->compiler->vertexCount(arrayClass); + gl::bindModelShaderVertexArray(&this->shaders, arrayClass); + const std::size_t vertexCount = gl::vertexCount(&this->shaders, arrayClass); this->checkForGLErrors(); glDrawArrays(getGlTypeForArrayClass(arrayClass), 0, static_cast(vertexCount)); this->checkForGLErrors(); - this->compiler->releaseVertexArray(arrayClass); + gl::releaseModelShaderVertexArray(&this->shaders, arrayClass); this->checkForGLErrors(); } @@ -365,7 +364,7 @@ this->checkForGLErrors(); this->renderPreferences.style = oldRenderStyle; this->update(); - return gl::Compiler::idFromColor(data); + return gl::idFromColor(data); } /** @@ -374,7 +373,7 @@ */ void PartRenderer::setFragmentStyle(gl::FragmentStyle newFragmentStyle) { - this->compiler->setUniform("fragmentStyle", static_cast(newFragmentStyle)); + gl::setShaderUniform(&this->shaders, "fragmentStyle", static_cast(newFragmentStyle)); } /** @@ -389,7 +388,6 @@ if (mainColorChanged or backgroundColorChanged) { this->build(); - this->setupBackgroundColor(); } Q_EMIT this->renderPreferencesChanged(); this->update(); diff -r 64ea7282611e -r 815fbaae9cb2 src/gl/partrenderer.h --- a/src/gl/partrenderer.h Tue May 24 16:11:10 2022 +0300 +++ b/src/gl/partrenderer.h Wed May 25 12:01:58 2022 +0300 @@ -11,7 +11,7 @@ #include "gl/common.h" #include "gl/compiler.h" -class PartRenderer : public QOpenGLWidget, protected QOpenGLFunctions +class PartRenderer : public QOpenGLWidget { Q_OBJECT public: @@ -33,7 +33,8 @@ Model* const model; DocumentManager* const documents; const ldraw::ColorTable& colorTable; - gl::Compiler* const compiler; + BoundingBox boundingBox; + gl::ModelShaders shaders; ldraw::id_t highlighted = ldraw::NULL_ID; std::optional screenToModelCoordinates(const QPoint& point, const geom::Plane& plane) const; QPointF modelToScreenCoordinates(const glm::vec3& point) const; @@ -53,11 +54,9 @@ void renderPreferencesChanged(); private: void setFragmentStyle(gl::FragmentStyle fragStyle); - void renderAllArrays(); void renderScene(); void updateViewMatrix(); void updateModelMatrix(); - void setupBackgroundColor(); Q_SLOT void build(); double zoom = 1.0; bool initialized = false; diff -r 64ea7282611e -r 815fbaae9cb2 src/types/boundingbox.cpp --- a/src/types/boundingbox.cpp Tue May 24 16:11:10 2022 +0300 +++ b/src/types/boundingbox.cpp Wed May 25 12:01:58 2022 +0300 @@ -18,20 +18,19 @@ #include "boundingbox.h" -BoundingBox& BoundingBox::operator<<(const glm::vec3& vertex) +/** + * @brief Resizes @c box so that @c vertex fits inside + * @param box + * @param vertex + */ +void addPointToBox(BoundingBox &box, const glm::vec3 &vertex) { - this->consider(vertex); - return *this; -} - -void BoundingBox::consider(const glm::vec3& vertex) -{ - this->minimum.x = math::min(vertex.x, this->minimum.x); - this->minimum.y = math::min(vertex.y, this->minimum.y); - this->minimum.z = math::min(vertex.z, this->minimum.z); - this->maximum.x = math::max(vertex.x, this->maximum.x); - this->maximum.y = math::max(vertex.y, this->maximum.y); - this->maximum.z = math::max(vertex.z, this->maximum.z); + box.minimum.x = math::min(vertex.x, box.minimum.x); + box.minimum.y = math::min(vertex.y, box.minimum.y); + box.minimum.z = math::min(vertex.z, box.minimum.z); + box.maximum.x = math::max(vertex.x, box.maximum.x); + box.maximum.y = math::max(vertex.y, box.maximum.y); + box.maximum.z = math::max(vertex.z, box.maximum.z); } /* diff -r 64ea7282611e -r 815fbaae9cb2 src/types/boundingbox.h --- a/src/types/boundingbox.h Tue May 24 16:11:10 2022 +0300 +++ b/src/types/boundingbox.h Wed May 25 12:01:58 2022 +0300 @@ -20,19 +20,16 @@ #include "basics.h" #include "maths.h" -class BoundingBox +struct BoundingBox { -public: - void consider(const glm::vec3& vertex); glm::vec3 minimum {math::infinity, math::infinity, math::infinity}; glm::vec3 maximum {-math::infinity, -math::infinity, -math::infinity}; - BoundingBox& operator<<(const glm::vec3& v); }; -inline const BoundingBox emptyBoundingBox = {}; +constexpr BoundingBox emptyBoundingBox = {}; glm::vec3 boxCenter(const BoundingBox& box); float longestMeasure(const BoundingBox& box); float spaceDiagonal(const BoundingBox& box); - +void addPointToBox(BoundingBox& box, const glm::vec3& vertex); bool operator==(const BoundingBox& box_1, const BoundingBox& box_2); bool operator!=(const BoundingBox& box_1, const BoundingBox& box_2); diff -r 64ea7282611e -r 815fbaae9cb2 src/ui/canvas.cpp --- a/src/ui/canvas.cpp Tue May 24 16:11:10 2022 +0300 +++ b/src/ui/canvas.cpp Wed May 25 12:01:58 2022 +0300 @@ -22,7 +22,7 @@ Q_ASSERT(not selectedIds.contains(ldraw::NULL_ID)); this->selection.subtract(deselectedIds); this->selection.unite(selectedIds); - this->compiler->setSelectedObjects(this->selection); + gl::setModelShaderSelectedObjects(&this->shaders, this->selection); this->update(); } @@ -378,7 +378,7 @@ void Canvas::clearSelection() { this->selection.clear(); - this->compiler->setSelectedObjects(this->selection); + gl::setModelShaderSelectedObjects(&this->shaders, this->selection); Q_EMIT selectionChanged(this->selection); this->update(); } @@ -390,7 +390,7 @@ void Canvas::addToSelection(ldraw::id_t id) { this->selection.insert(id); - this->compiler->setSelectedObjects(this->selection); + gl::setModelShaderSelectedObjects(&this->shaders, this->selection); Q_EMIT selectionChanged(this->selection); this->update(); }