stuff

Wed, 17 Feb 2021 16:49:35 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 17 Feb 2021 16:49:35 +0200
changeset 102
9f435f66bd0c
parent 101
910890292639

stuff

CMakeLists.txt file | annotate | diff | comparison | revisions
src/gl/abstractshaderprogram.cpp file | annotate | diff | comparison | revisions
src/gl/abstractshaderprogram.h file | annotate | diff | comparison | revisions
src/gl/axesprogram.cpp file | annotate | diff | comparison | revisions
src/gl/axesprogram.h file | annotate | diff | comparison | revisions
src/gl/basicshaderprogram.h file | annotate | diff | comparison | revisions
src/gl/geometrypreview.cpp file | annotate | diff | comparison | revisions
src/gl/geometrypreview.h file | annotate | diff | comparison | revisions
src/gl/gridprogram.cpp file | annotate | diff | comparison | revisions
src/gl/gridprogram.h file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h file | annotate | diff | comparison | revisions
src/tools/basetool.h file | annotate | diff | comparison | revisions
src/tools/drawtool.cpp file | annotate | diff | comparison | revisions
src/tools/drawtool.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Fri Feb 05 14:23:16 2021 +0200
+++ b/CMakeLists.txt	Wed Feb 17 16:49:35 2021 +0200
@@ -44,6 +44,7 @@
 	src/gl/axesprogram.cpp
 	src/gl/basicshaderprogram.cpp
 	src/gl/compiler.cpp
+	src/gl/geometrypreview.cpp
 	src/gl/gridprogram.cpp
 	src/gl/partrenderer.cpp
 	src/linetypes/comment.cpp
@@ -96,6 +97,7 @@
 	src/gl/basicshaderprogram.h
 	src/gl/common.h
 	src/gl/compiler.h
+	src/gl/geometrypreview.h
 	src/gl/gridprogram.h
 	src/gl/partrenderer.h
 	src/linetypes/comment.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gl/abstractshaderprogram.cpp	Wed Feb 17 16:49:35 2021 +0200
@@ -0,0 +1,113 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2020 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/>.
+ */
+
+#include "abstractshaderprogram.h"
+
+AbstractShaderProgram::AbstractBasicShaderProgram(const QVector<ArraySpecification>& arraySpecifications, QObject* parent) :
+	QObject{parent},
+	buffer{QOpenGLBuffer::VertexBuffer},
+	vertexShader{QOpenGLShader::Vertex},
+	fragmentShader{QOpenGLShader::Fragment}
+{
+	this->arrays.reserve(arraySpecifications.size());
+	for (const ArraySpecification& arraySpecification : arraySpecifications)
+	{
+		this->arrays.emplace_back({arraySpecification});
+	}
+}
+
+void AbstractShaderProgram::initialize()
+{
+	if (not this->isInitialized)
+	{
+		this->initializeOpenGLFunctions();
+		this->isInitialized = true;
+		this->program.emplace(this);
+		gl::buildShaders(&*this->program, this->vertexShaderSource(), this->fragmentShaderSource());
+		this->program->bind();
+		for (auto& array : this->arrays)
+		{
+			array.buffer.create();
+			array.buffer.bind();
+			array.buffer.setUsagePattern(array.specification.bufferUsagePattern);
+			array.vertexArrayObject.create();
+			array.vertexArrayObject.bind();
+		}
+		this->setupVertexArrays();
+		this->vertexArrayObject.release();
+		this->releaseBuffers();
+		this->buffer.release();
+		this->program->release();
+		this->checkForGLErrors();
+	}
+}
+
+void AbstractShaderProgram::setViewMatrix(const glm::mat4& newViewMatrix)
+{
+	this->setMatrix("view", newViewMatrix);
+}
+
+void AbstractShaderProgram::setProjectionMatrix(const glm::mat4& newProjectionMatrix)
+{
+	this->setMatrix("projection", newProjectionMatrix);
+}
+
+void AbstractShaderProgram::setModelMatrix(const glm::mat4& newModelMatrix)
+{
+	this->setMatrix("model", newModelMatrix);
+}
+
+void AbstractShaderProgram::setMatrix(const char* name, const glm::mat4& matrix)
+{
+	Q_ASSERT(this->isInitialized);
+	this->program->bind();
+	this->program->setUniformMatrix(name, matrix);
+	this->program->release();
+	this->checkForGLErrors();
+}
+
+void AbstractShaderProgram::draw()
+{
+	this->program->bind();
+	for (Array& array : this->arrays)
+	{
+		array.vertexArrayObject.bind();
+		glDrawArrays(array.specification.drawMode, 0, array.count);
+		this->vertexArrayObject.release();
+	}
+	this->program->release();
+	this->checkForGLErrors();
+}
+
+void AbstractShaderProgram::teardown()
+{
+	this->vertexArrayObject.destroy();
+	this->buffer.destroy();
+	this->program.reset();
+}
+
+void AbstractShaderProgram::checkForGLErrors()
+{
+	gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent()));
+}
+
+void AbstractShaderProgram::upload(Array* array, const void* data, int count)
+{
+	array->count = count;
+	array->buffer->buffer.allocate(data, count * array->specification.vertexSize);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gl/abstractshaderprogram.h	Wed Feb 17 16:49:35 2021 +0200
@@ -0,0 +1,48 @@
+#pragma once
+#include "common.h"
+
+/**
+ * @brief Base class for shader programs
+ */
+class AbstractShaderProgram : public QObject, protected QOpenGLFunctions
+{
+	Q_OBJECT
+public:
+	struct ArraySpecification
+	{
+		GLenum drawMode;
+		std::size_t vertexSize;
+		QOpenGLBuffer::UsagePattern bufferUsagePattern = QOpenGLBuffer::StaticDraw;
+	};
+	struct Array
+	{
+		const ArraySpecification specification;
+		QOpenGLBuffer buffer;
+		QOpenGLVertexArrayObject vertexArrayObject;
+		int count;
+	};
+	AbstractShaderProgram(const QVector<ArraySpecification>& arraySpecifications, QObject* parent = nullptr);
+	~AbstractShaderProgram() = default;
+	void initialize();
+	Q_SLOT void setViewMatrix(const glm::mat4& newViewMatrix);
+	Q_SLOT void setProjectionMatrix(const glm::mat4& newProjectionMatrix);
+	Q_SLOT void setModelMatrix(const glm::mat4& newModelMatrix);
+	void draw();
+	void teardown();
+protected:
+	void setMatrix(const char* name, const glm::mat4& matrix);
+	void upload(Array* array, const void* data, int count);
+	void checkForGLErrors();
+	/// \returns the source code of the vertex shader
+	virtual const char* vertexShaderSource() const = 0;
+	/// \returns the source code of the fragment shader
+	virtual const char* fragmentShaderSource() const = 0;
+	/// Called during initialization to set up the VAO. Set up your vertex array attributes here.
+	virtual void setupVertexArrays() = 0;
+
+	bool isInitialized = false;
+	QOpenGLShader vertexShader;
+	QOpenGLShader fragmentShader;
+	std::optional<gl::ShaderProgram> program{std::nullopt};
+	QVector<Array> arrays;
+};
--- a/src/gl/axesprogram.cpp	Fri Feb 05 14:23:16 2021 +0200
+++ b/src/gl/axesprogram.cpp	Wed Feb 17 16:49:35 2021 +0200
@@ -72,6 +72,11 @@
 	AxesVertex{{0, 0, 0}, {0, 0, 0.5}},
 };
 
+constexpr std::size_t vertexSize = sizeof data[0];
+
+AxesProgram::AxesProgram(QObject* parent) :
+	AbstractShaderProgram{{{GL_LINES, ::vertexSize}}, parent} {}
+
 const char* AxesProgram::vertexShaderSource() const
 {
 	return ::vertexShaderSource;
@@ -87,28 +92,13 @@
 	return ::data;
 }
 
-GLenum AxesProgram::drawMode() const
-{
-	return GL_LINES;
-}
-
-int AxesProgram::vertexSize() const
-{
-	return sizeof data[0];
-}
-
-int AxesProgram::vertexCount() const
-{
-	return countof(data);
-}
-
 void AxesProgram::setupVertexArrays()
 {
 	for (int i : {0, 1})
 	{
 		this->program->enableAttributeArray(i);
 	}
-	const int stride = this->vertexSize();
-	this->program->setAttributeBuffer(0, GL_FLOAT, offsetof(AxesVertex, position), 3, stride);
-	this->program->setAttributeBuffer(1, GL_FLOAT, offsetof(AxesVertex, color), 3, stride);
+	this->program->setAttributeBuffer(0, GL_FLOAT, offsetof(AxesVertex, position), 3, ::vertexSize);
+	this->program->setAttributeBuffer(1, GL_FLOAT, offsetof(AxesVertex, color), 3, ::vertexSize);
+	this->upload(&this->arrays[0], ::data, countof(data));
 }
--- a/src/gl/axesprogram.h	Fri Feb 05 14:23:16 2021 +0200
+++ b/src/gl/axesprogram.h	Wed Feb 17 16:49:35 2021 +0200
@@ -1,18 +1,14 @@
 #pragma once
 #include "gl/common.h"
-#include "gl/basicshaderprogram.h"
+#include "gl/abstractshaderprogram.h"
 
-class AxesProgram : public AbstractBasicShaderProgram
+class AxesProgram : public AbstractShaderProgram
 {
 	Q_OBJECT
 public:
-	using AbstractBasicShaderProgram::AbstractBasicShaderProgram;
+	AxesProgram(QObject* parent = nullptr);
 protected:
 	const char* vertexShaderSource() const override;
 	const char* fragmentShaderSource() const override;
-	const void* vertexData() const override;
-	GLenum drawMode() const override;
-	int vertexSize() const override;
-	int vertexCount() const override;
 	void setupVertexArrays() override;
 };
--- a/src/gl/basicshaderprogram.h	Fri Feb 05 14:23:16 2021 +0200
+++ b/src/gl/basicshaderprogram.h	Wed Feb 17 16:49:35 2021 +0200
@@ -1,5 +1,5 @@
 #pragma once
-#include "common.h"
+#include "abstractshaderprogram.h"
 
 /**
  * @brief Base class for basic shader programs
@@ -8,7 +8,7 @@
  * a vertex shader and a fragment shader. This program deals with these
  * components, leaving the program-specific details to the subclasses.
  */
-class AbstractBasicShaderProgram : public QObject, protected QOpenGLFunctions
+class AbstractBasicShaderProgram : public AbstractShaderProgram
 {
 	Q_OBJECT
 public:
--- /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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gl/geometrypreview.h	Wed Feb 17 16:49:35 2021 +0200
@@ -0,0 +1,30 @@
+#pragma once
+#include "abstractshaderprogram.h"
+
+class GeometryPreview : public AbstractShaderProgram
+{
+public:
+	struct Vertex
+	{
+		glm::vec3 point;
+		glm::vec4 color;
+	};
+	GeometryPreview(QObject* parent = nullptr);
+	~GeometryPreview();
+	QVector<Vertex>& modifyLinesBuffer();
+	QVector<Vertex>& modifyTrianglesBuffer();
+private:
+	QVector<Vertex> lines;
+	QVector<Vertex> triangles;
+	QOpenGLBuffer linesBuffer;
+	QOpenGLBuffer trianglesBuffer;
+	QOpenGLShader vertexShader;
+	QOpenGLShader fragmentShader;
+	std::optional<gl::ShaderProgram> program{std::nullopt};
+	QOpenGLVertexArrayObject vertexArrayObject;
+	bool isInitialized = false;
+	bool needRebuild = false;
+	void initialize();
+	void rebuildIfNecessary();
+	void checkForGLErrors();
+};
--- a/src/gl/gridprogram.cpp	Fri Feb 05 14:23:16 2021 +0200
+++ b/src/gl/gridprogram.cpp	Wed Feb 17 16:49:35 2021 +0200
@@ -63,6 +63,10 @@
 )";
 
 static const glm::vec2 data[] = {{-1, -1}, {-1, 1}, {1, 1}, {1, -1}};
+constexpr std::size_t vertexSize = sizeof data[0];
+
+GridProgram::GridProgram(QObject* parent) :
+	AbstractShaderProgram{{{GL_QUADS, vertexSize}}, parent}
 
 void GridProgram::setGridMatrix(const glm::mat4& newGridMatrix)
 {
@@ -95,29 +99,11 @@
 	return ::fragmentShaderSource;
 }
 
-const void* GridProgram::vertexData() const
-{
-	return ::data;
-}
-
-int GridProgram::vertexSize() const
-{
-	return sizeof data[0];
-}
-
-int GridProgram::vertexCount() const
-{
-	return glm::countof(data);
-}
-
 void GridProgram::setupVertexArrays()
 {
 	this->program->enableAttributeArray(0);
 	this->program->setAttributeBuffer(0, GL_FLOAT, 0, 2, 0);
 	this->program->setUniformVector("gridColor", this->gridColor);
+	this->upload(&this->arrays[0], ::data, countof(data));
 }
 
-GLenum GridProgram::drawMode() const
-{
-	return GL_QUADS;
-}
--- a/src/gl/gridprogram.h	Fri Feb 05 14:23:16 2021 +0200
+++ b/src/gl/gridprogram.h	Wed Feb 17 16:49:35 2021 +0200
@@ -17,14 +17,14 @@
  */
 
 #pragma once
-#include "basicshaderprogram.h"
+#include "abstractshaderprogram.h"
 #include "common.h"
 
-class GridProgram : public AbstractBasicShaderProgram
+class GridProgram : public AbstractShaderProgram
 {
 	Q_OBJECT
 public:
-	using AbstractBasicShaderProgram::AbstractBasicShaderProgram;
+	GridProgram(QObject* parent = nullptr);
 	void setGridMatrix(const glm::mat4& newGridMatrix);
 	void setGridColor(const QColor& newGridColor);
 protected:
--- a/src/mainwindow.cpp	Fri Feb 05 14:23:16 2021 +0200
+++ b/src/mainwindow.cpp	Wed Feb 17 16:49:35 2021 +0200
@@ -405,3 +405,11 @@
 		}
 	}
 }
+
+void MainWindow::pointInCanvasClicked(const glm::vec3& point)
+{
+	if (this->selectedTool != nullptr)
+	{
+		this->selectedTool->pointInCanvasClicked(point);
+	}
+}
--- a/src/mainwindow.h	Fri Feb 05 14:23:16 2021 +0200
+++ b/src/mainwindow.h	Wed Feb 17 16:49:35 2021 +0200
@@ -41,6 +41,7 @@
 	void updateRecentlyOpenedDocumentsMenu();
 	void openRecentFile();
 	void setRenderStyle(gl::RenderStyle renderStyle);
+	void pointInCanvasClicked(const glm::vec3& point);
 protected:
 	void changeEvent(QEvent* event) override;
 	void closeEvent(QCloseEvent* event) override;
--- a/src/tools/basetool.h	Fri Feb 05 14:23:16 2021 +0200
+++ b/src/tools/basetool.h	Wed Feb 17 16:49:35 2021 +0200
@@ -24,4 +24,5 @@
 	virtual bool mouseDoubleClicked(QMouseEvent*) { return false; }
 	virtual bool mouseMoved(QMouseEvent*) { return false; }
 	virtual bool keyReleased(QKeyEvent*) { return false; }
+	virtual void pointInCanvasClicked(const glm::vec3&) {}
 };
--- a/src/tools/drawtool.cpp	Fri Feb 05 14:23:16 2021 +0200
+++ b/src/tools/drawtool.cpp	Wed Feb 17 16:49:35 2021 +0200
@@ -14,3 +14,8 @@
 	static const QString result = tr("Draw new elements into the model.");
 	return result;
 }
+
+void DrawTool::pointInCanvasClicked(const glm::vec3& point)
+{
+
+}
--- a/src/tools/drawtool.h	Fri Feb 05 14:23:16 2021 +0200
+++ b/src/tools/drawtool.h	Wed Feb 17 16:49:35 2021 +0200
@@ -10,4 +10,6 @@
 
 	QString name() const;
 	QString toolTip() const;
+
+	void pointInCanvasClicked(const glm::vec3& point) override;
 };

mercurial