src/gl/geometrypreview.cpp

changeset 102
9f435f66bd0c
--- /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);
+}

mercurial