Fri, 06 Mar 2020 16:08:53 +0200
begin work on axes program
69 | 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 vec3 in_position; | |
26 | layout (location = 1) in vec3 in_color; | |
27 | uniform mat4 view; | |
28 | uniform mat4 projection; | |
29 | uniform mat4 model; | |
30 | smooth out vec3 ex_color; | |
31 | ||
32 | void main() | |
33 | { | |
34 | gl_Position = projection * view * model * vec4(in_position, 0.0, 1.0); | |
35 | ex_uv = ex_color; | |
36 | } | |
37 | )"; | |
38 | ||
39 | const char fragmentShaderSource[] = R"( | |
40 | #version 330 core | |
41 | ||
42 | out vec4 color; | |
43 | smooth in vec3 ex_color; | |
44 | ||
45 | void main(void) | |
46 | { | |
47 | color = vec4(ex_color, 1) | |
48 | } | |
49 | )"; | |
50 | ||
51 | namespace | |
52 | { | |
53 | struct AxesVertex | |
54 | { | |
55 | glm::vec3 position; | |
56 | glm::vec3 color; | |
57 | }; | |
58 | } | |
59 | ||
60 | static AxesVertex data[] = | |
61 | { | |
62 | AxesVertex{{-10000, 0, 0}, {1, 0, 0}}, | |
63 | AxesVertex{{10000, 0, 0}, {1, 0, 0}}, | |
64 | AxesVertex{{0, -10000, 0}, {0, 1, 0}}, | |
65 | AxesVertex{{0, 10000, 0}, {0, 1, 0}}, | |
66 | AxesVertex{{0, 0, -10000}, {0, 0, 1}}, | |
67 | AxesVertex{{0, 0, 10000}, {0, 0, 1}}, | |
68 | }; | |
69 | ||
70 | AxesProgram::AxesProgram(QObject* parent) : | |
71 | QObject{parent}, | |
72 | buffer{QOpenGLBuffer::VertexBuffer}, | |
73 | vertexShader{QOpenGLShader::Vertex}, | |
74 | fragmentShader{QOpenGLShader::Fragment} | |
75 | { | |
76 | } | |
77 | ||
78 | void AxesProgram::initialize() | |
79 | { | |
80 | if (not isInitialized) | |
81 | { | |
82 | this->initializeOpenGLFunctions(); | |
83 | this->isInitialized = true; | |
84 | this->program.emplace(this); | |
85 | gl::buildShaders(&*this->program, ::vertexShaderSource, ::fragmentShaderSource); | |
86 | this->program->bind(); | |
87 | this->buffer.create(); | |
88 | this->buffer.bind(); | |
89 | this->buffer.setUsagePattern(QOpenGLBuffer::StaticDraw); | |
90 | this->buffer.allocate(data, countof(data) * sizeof data[0]); | |
91 | this->vertexArrayObject.create(); | |
92 | this->vertexArrayObject.bind(); | |
93 | this->program->enableAttributeArray(0); | |
94 | this->program->setAttributeBuffer(0, GL_FLOAT, 0, 2, 0); | |
95 | this->program->setUniformVector("gridColor", this->gridColor); | |
96 | this->vertexArrayObject.release(); | |
97 | this->buffer.release(); | |
98 | this->program->release(); | |
99 | this->checkForGLErrors(); | |
100 | } | |
101 | } | |
102 | ||
103 | void AxesProgram::setViewMatrix(const glm::mat4& newViewMatrix) | |
104 | { | |
105 | this->setMatrix("view", newViewMatrix); | |
106 | } | |
107 | ||
108 | void AxesProgram::setProjectionMatrix(const glm::mat4& newProjectionMatrix) | |
109 | { | |
110 | this->setMatrix("projection", newProjectionMatrix); | |
111 | } | |
112 | ||
113 | void AxesProgram::setModelMatrix(const glm::mat4& newModelMatrix) | |
114 | { | |
115 | this->setMatrix("model", newModelMatrix); | |
116 | } | |
117 | ||
118 | void AxesProgram::setGridMatrix(const glm::mat4& newGridMatrix) | |
119 | { | |
120 | this->setMatrix("grid", newGridMatrix); | |
121 | } | |
122 | ||
123 | void AxesProgram::setMatrix(const char* name, const glm::mat4& matrix) | |
124 | { | |
125 | Q_ASSERT(this->isInitialized); | |
126 | this->program->bind(); | |
127 | this->program->setUniformMatrix(name, matrix); | |
128 | this->program->release(); | |
129 | this->checkForGLErrors(); | |
130 | } | |
131 | ||
132 | void GridProgram::setGridColor(const QColor& newGridColor) | |
133 | { | |
134 | const glm::vec4 vec = gl::colorToVector4(newGridColor); | |
135 | if (this->isInitialized) | |
136 | { | |
137 | this->program->bind(); | |
138 | this->program->setUniformVector("gridColor", vec); | |
139 | this->program->release(); | |
140 | this->checkForGLErrors(); | |
141 | } | |
142 | else | |
143 | { | |
144 | this->gridColor = vec; | |
145 | } | |
146 | } | |
147 | ||
148 | void GridProgram::draw() | |
149 | { | |
150 | this->program->bind(); | |
151 | this->vertexArrayObject.bind(); | |
152 | glDrawArrays(GL_QUADS, 0, countof(data)); | |
153 | this->vertexArrayObject.release(); | |
154 | this->program->release(); | |
155 | this->checkForGLErrors(); | |
156 | } | |
157 | ||
158 | void GridProgram::teardown() | |
159 | { | |
160 | this->vertexArrayObject.destroy(); | |
161 | this->buffer.destroy(); | |
162 | this->program.reset(); | |
163 | } | |
164 | ||
165 | void GridProgram::checkForGLErrors() | |
166 | { | |
167 | gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent())); | |
168 | } |