src/gl/gridprogram.cpp

changeset 53
3af627f7a40f
child 54
a4055f67b9c7
equal deleted inserted replaced
52:eee644f88e93 53:3af627f7a40f
1 /*
2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2020 Teemu Piippo
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "gridprogram.h"
20
21 // Based on https://stackoverflow.com/q/30842755
22 const char vertexShaderSource[] = R"(
23 #version 330 core
24
25 layout (location = 0) in vec2 in_position;
26 uniform mat4 view;
27 uniform mat4 projection;
28 uniform mat4 model;
29 smooth out vec2 ex_uv;
30 const mat4 stretch = mat4(vec4(10000, 0, 0, 0), vec4(0, 10000, 0, 0), vec4(0, 0, 10000, 0), vec4(0, 0, 0, 1));
31
32 void main()
33 {
34 gl_Position = projection * view * model * stretch * vec4(in_position, 0.0, 1.0);
35 ex_uv = in_position;
36 }
37 )";
38
39 const char fragmentShaderSource[] = R"(
40 #version 330 core
41
42 out vec4 color;
43 smooth in vec2 ex_uv;
44 const vec4 lineColor = vec4(1.0, 1.0, 1.0, 0.75);
45
46 void main(void)
47 {
48 if(fract(ex_uv.x / 0.001f) < 0.01f || fract(ex_uv.y / 0.001f) < 0.01f)
49 color = lineColor;
50 else
51 color = vec4(0);
52 }
53 )";
54
55 static const glm::vec2 data[] = {{-1, -1}, {-1, 1}, {1, 1}, {1, -1}};
56
57 GridProgram::GridProgram(QObject* parent) :
58 QObject{parent},
59 buffer{QOpenGLBuffer::VertexBuffer},
60 vertexShader{QOpenGLShader::Vertex},
61 fragmentShader{QOpenGLShader::Fragment}
62 {
63 }
64
65 void GridProgram::initialize()
66 {
67 if (not isInitialized)
68 {
69 this->initializeOpenGLFunctions();
70 this->isInitialized = true;
71 this->program.emplace(this);
72 gl::buildShaders(&*this->program, ::vertexShaderSource, ::fragmentShaderSource);
73 this->program->bind();
74 this->buffer.create();
75 this->buffer.bind();
76 this->buffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
77 this->buffer.allocate(data, countof(data) * sizeof data[0]);
78 this->vertexArrayObject.create();
79 this->vertexArrayObject.bind();
80 this->program->enableAttributeArray(0);
81 this->program->setAttributeBuffer(0, GL_FLOAT, 0, 2, 0);
82 this->vertexArrayObject.release();
83 this->buffer.release();
84 this->program->release();
85 this->checkForGLErrors();
86 }
87 }
88
89 void GridProgram::setViewMatrix(const glm::mat4& newViewMatrix)
90 {
91 Q_ASSERT(this->isInitialized);
92 this->program->bind();
93 this->program->setUniformMatrix("view", newViewMatrix);
94 this->program->release();
95 this->checkForGLErrors();
96 }
97
98 void GridProgram::setProjectionMatrix(const glm::mat4& newProjectionMatrix)
99 {
100 Q_ASSERT(this->isInitialized);
101 this->program->bind();
102 this->program->setUniformMatrix("projection", newProjectionMatrix);
103 this->program->release();
104 this->checkForGLErrors();
105 }
106
107 void GridProgram::setModelMatrix(const glm::mat4& newModelMatrix)
108 {
109 Q_ASSERT(this->isInitialized);
110 this->program->bind();
111 this->program->setUniformMatrix("model", newModelMatrix);
112 this->program->release();
113 this->checkForGLErrors();
114 }
115
116 void GridProgram::draw()
117 {
118 this->program->bind();
119 this->vertexArrayObject.bind();
120 glDrawArrays(GL_QUADS, 0, countof(data));
121 this->vertexArrayObject.release();
122 this->program->release();
123 this->checkForGLErrors();
124 }
125
126 void GridProgram::teardown()
127 {
128 this->vertexArrayObject.destroy();
129 this->buffer.destroy();
130 this->program.reset();
131 }
132
133 void GridProgram::checkForGLErrors()
134 {
135 gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent()));
136 }

mercurial