--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gl/geometrypreview.cpp Wed Feb 17 16:49:35 2021 +0200 @@ -0,0 +1,108 @@ +#include "geometrypreview.h" + +const char vertexShaderSource[] = R"( +#version 330 core + +layout (location = 0) in vec3 in_position; +layout (location = 1) in vec3 in_color; +uniform mat4 view; +uniform mat4 projection; +uniform mat4 model; +smooth out vec3 ex_color; + +void main() +{ + gl_Position = projection * view * model * vec4(in_position, 1.0); + ex_color = in_color; +} +)"; + +const char fragmentShaderSource[] = R"( +#version 330 core + +out vec4 color; +smooth in vec3 ex_color; + +void main(void) +{ + color = vec4(ex_color, 1); +} +)"; + +constexpr std::size_t vertexSize = sizeof(GeometryPreview::Vertex); + +GeometryPreview::GeometryPreview(QObject *parent) : + AbstractShaderProgram{{ + {GL_LINES, vertexSize, QOpenGLBuffer::DynamicDraw}, + {GL_TRIANGLES, vertexSize, QOpenGLBuffer::DynamicDraw} + }, parent} +{ +} + +GeometryPreview::~GeometryPreview() +{ +} + +QVector<GeometryPreview::Vertex>& GeometryPreview::modifyLinesBuffer() +{ + this->needRebuild = true; + return this->lines; +} + +QVector<GeometryPreview::Vertex>& GeometryPreview::modifyTrianglesBuffer() +{ + this->needRebuild = true; + return this->triangles; +} + +void GeometryPreview::initialize() +{ + if (not this->isInitialized) + { + this->isInitialized = true; + this->program.emplace(this); + gl::buildShaders(&*this->program, ::vertexShaderSource, ::fragmentShaderSource); + this->program->bind(); + for (QOpenGLBuffer* buffer : {&this->linesBuffer, &this->trianglesBuffer}) + { + buffer->create(); + buffer->bind(); + buffer->setUsagePattern(QOpenGLBuffer::DynamicDraw); + } + this->vertexArrayObject.create(); + this->vertexArrayObject.bind(); + this->setupVertexArrays(); + this->vertexArrayObject.release(); + for (auto& buffer : {this->linesBuffer, this->trianglesBuffer}) + { + buffer->release(); + } + this->program->release(); + this->checkForGLErrors(); + } +} + +void GeometryPreview::rebuildIfNecessary() +{ + if (this->needRebuild) + { + this->buffer.allocate(this->vertexData(), this->vertexCount() * this->vertexSize()); + this->needRebuild = false; + } +} + +void GeometryPreview::checkForGLErrors() +{ + gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent())); +} + +void GeometryPreview::setupVertexArrays() +{ + for (int i : {0, 1}) + { + this->program->enableAttributeArray(i); + } + const int stride = this->vertexSize(); + this->program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride); + this->program->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, color), 4, stride); +}