src/layers/gridlayer.cpp

changeset 263
59b6027b9843
parent 250
2837b549e616
child 264
76a025db4948
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/layers/gridlayer.cpp	Sun Jun 26 21:00:06 2022 +0300
@@ -0,0 +1,129 @@
+/*
+ *  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 "../gl/partrenderer.h"
+#include "gridlayer.h"
+
+constexpr char vertexShaderSource[] = R"(
+#version 330 core
+
+layout (location = 0) in vec2 in_position;
+uniform mat4 mvp;
+smooth out vec2 ex_uv;
+uniform mat4 grid;
+
+void main()
+{
+	gl_Position = mvp * grid * vec4(in_position, 0.0, 1.0);
+	ex_uv = in_position;
+}
+)";
+
+constexpr char fragmentShaderSource[] = R"(
+#version 330 core
+
+out vec4 color;
+smooth in vec2 ex_uv;
+uniform vec4 gridColor;
+
+void main(void)
+{
+	float dx = fract(ex_uv.y);
+	float dy = fract(ex_uv.x);
+	/* fade the grid towards extreme co-ordinates */
+	float d = (1.0f - 0.015 * max(abs(ex_uv.x), abs(ex_uv.y)));
+	color = vec4(gridColor.xyz, gridColor.w * d);
+}
+)";
+
+template<int extent>
+constexpr auto calcGridData()
+{
+	std::array<glm::vec2, 8 * extent + 4> result;
+	std::size_t ix = 0;
+	for (int i = -extent; i <= extent; i += 1) {
+		result[ix++] = {i, -extent};
+		result[ix++] = {i, extent};
+	}
+	for (int i = -extent; i <= extent; i += 1) {
+		result[ix++] = {-extent, i};
+		result[ix++] = {extent, i};
+	}
+	return result;
+}
+
+void GridLayer::setGridMatrix(const glm::mat4& newGridMatrix)
+{
+	this->gridMatrix = newGridMatrix;
+	if (this->isInitialized) {
+		this->shader.setUniformMatrix("grid", newGridMatrix);
+	}
+}
+
+void GridLayer::setGridColor(const QColor& newGridColor)
+{
+	this->gridColor = gl::colorToVector4(newGridColor);
+	if (this->isInitialized) {
+		this->shader.setUniformVector("gridColor", this->gridColor);
+	}
+}
+
+void GridLayer::settingsChanged()
+{
+	this->setGridColor(this->renderer->isDark() ? Qt::white : Qt::black);
+}
+
+void GridLayer::initializeGL()
+{
+	this->shader.initialize(
+		::vertexShaderSource,
+		::fragmentShaderSource,
+		QOpenGLBuffer::StaticDraw,
+		{
+			GLAttributeSpec{
+				.type = GL_FLOAT,
+				.offset = 0,
+				.tuplesize = 2,
+				.stride = 0,
+			},
+		}
+	);
+	this->isInitialized = true;
+	constexpr auto data = calcGridData<50>();
+	this->shader.setUniformVector("gridColor", this->gridColor);
+	this->setGridMatrix(this->gridMatrix);
+	this->settingsChanged();
+	this->shader.bufferData(data.data(), data.size(), sizeof data[0]);
+}
+
+void GridLayer::paintGL()
+{
+	glLineWidth(1);
+	glEnable(GL_BLEND);
+	glLineStipple(1, 0x8888);
+	glEnable(GL_LINE_STIPPLE);
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	this->shader.draw(GL_LINES);
+	glDisable(GL_BLEND);
+	glDisable(GL_LINE_STIPPLE);
+}
+
+void GridLayer::mvpMatrixChanged(const glm::mat4& mvpMatrix)
+{
+	this->shader.setMvpMatrix(mvpMatrix);
+}

mercurial