Wed, 25 May 2022 20:36:34 +0300
Fix pick() picking from weird places on the screen with high DPI scaling
glReadPixels reads data from the frame buffer, which contains data after
high DPI scaling, so any reads to that need to take this scaling into account
24 | 1 | /* |
2 | * LDForge: LDraw parts authoring CAD | |
3 | * Copyright (C) 2013 - 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 | ||
28 | 19 | #include <glm/ext/matrix_transform.hpp> |
20 | #include <glm/ext/matrix_clip_space.hpp> | |
100 | 21 | #include <GL/glu.h> |
17 | 22 | #include <QMouseEvent> |
26 | 23 | #include <QMessageBox> |
47 | 24 | #include <QAbstractButton> |
55 | 25 | #include "geometry.h" |
17 | 26 | #include "partrenderer.h" |
77
028798a72591
added some meta stuff, simplified quadrilateral splitting and tested it
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
27 | #include "model.h" |
17 | 28 | |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
29 | static constexpr double MIN_ZOOM = -3.0; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
30 | static constexpr double MAX_ZOOM = 3.0; |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
31 | QOpenGLFunctions glfunc; |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
32 | |
35
98906a94732f
renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents:
34
diff
changeset
|
33 | PartRenderer::PartRenderer( |
98906a94732f
renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents:
34
diff
changeset
|
34 | Model* model, |
98906a94732f
renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents:
34
diff
changeset
|
35 | DocumentManager* documents, |
98906a94732f
renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents:
34
diff
changeset
|
36 | const ldraw::ColorTable& colorTable, |
98906a94732f
renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents:
34
diff
changeset
|
37 | QWidget* parent) : |
21 | 38 | QOpenGLWidget{parent}, |
39 | model{model}, | |
40 | documents{documents}, | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
41 | colorTable{colorTable} |
17 | 42 | { |
43 | this->setMouseTracking(true); | |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
107
diff
changeset
|
44 | connect(model, &Model::rowsInserted, [&]{ |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
107
diff
changeset
|
45 | this->needBuild = true; |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
107
diff
changeset
|
46 | }); |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
107
diff
changeset
|
47 | connect(model, &Model::rowsRemoved, [&]{ this->needBuild = true; }); |
17 | 48 | } |
49 | ||
26 | 50 | PartRenderer::~PartRenderer() |
51 | { | |
52 | } | |
53 | ||
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
54 | static QVector3D calcQVector3DFromQColor(const QColor& color) |
53 | 55 | { |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
60
diff
changeset
|
56 | return { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
60
diff
changeset
|
57 | toFloat(color.redF()), |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
60
diff
changeset
|
58 | toFloat(color.greenF()), |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
60
diff
changeset
|
59 | toFloat(color.blueF()), |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
60
diff
changeset
|
60 | }; |
53 | 61 | } |
62 | ||
17 | 63 | void PartRenderer::initializeGL() |
64 | { | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
65 | ::glfunc.initializeOpenGLFunctions(); |
22
6da867fa5429
commit work on GL rendering
Teemu Piippo <teemu@hecknology.net>
parents:
21
diff
changeset
|
66 | if (glGetError() != GL_NO_ERROR) |
17 | 67 | { |
68 | abort(); | |
69 | } | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
70 | gl::initializeModelShaders(&this->shaders); |
86
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
71 | connect(this->model, &Model::dataChanged, this, &PartRenderer::build); |
17 | 72 | this->initialized = true; |
32 | 73 | this->modelQuaternion = glm::angleAxis(glm::radians(30.0f), glm::vec3{-1, 0, 0}); |
74 | this->modelQuaternion *= glm::angleAxis(glm::radians(225.0f), glm::vec3{-0, 1, 0}); | |
55 | 75 | this->updateModelMatrix(); |
31
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
76 | this->updateViewMatrix(); |
30 | 77 | this->update(); |
17 | 78 | } |
79 | ||
80 | void PartRenderer::resizeGL(int width, int height) | |
81 | { | |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
82 | this->viewportVector = {0, 0, width, height}; |
28 | 83 | glViewport(0, 0, width, height); |
84 | this->projectionMatrix = glm::perspective( | |
31
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
85 | glm::radians(45.0f), |
28 | 86 | static_cast<float>(width) / static_cast<float>(height), |
87 | 0.1f, | |
31
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
88 | 10000.f); |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
89 | gl::setShaderUniformMatrix(&this->shaders, "projectionMatrix", this->projectionMatrix); |
112 | 90 | Q_EMIT projectionMatrixChanged(this->projectionMatrix); |
17 | 91 | } |
92 | ||
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
93 | static constexpr GLenum getGlTypeForArrayClass(const gl::ArrayClass vboClass) |
21 | 94 | { |
95 | switch (vboClass) | |
96 | { | |
26 | 97 | case gl::ArrayClass::Lines: |
98 | case gl::ArrayClass::ConditionalLines: | |
21 | 99 | return GL_LINES; |
26 | 100 | case gl::ArrayClass::Triangles: |
21 | 101 | return GL_TRIANGLES; |
26 | 102 | case gl::ArrayClass::Quads: |
21 | 103 | return GL_QUADS; |
104 | } | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
105 | throw std::runtime_error{"bad value for vboClass"}; |
21 | 106 | } |
107 | ||
17 | 108 | void PartRenderer::paintGL() |
109 | { | |
47 | 110 | glEnable(GL_DEPTH_TEST); |
111 | glShadeModel(GL_SMOOTH); | |
112 | this->renderScene(); | |
113 | } | |
114 | ||
115 | void PartRenderer::renderScene() | |
116 | { | |
86
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
117 | if (this->needBuild) |
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
118 | { |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
119 | gl::build(&this->shaders, this->model, this->colorTable, this->documents, this->renderPreferences); |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
120 | this->boundingBox = gl::boundingBoxForModel(this->model, this->documents); |
86
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
121 | this->needBuild = false; |
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
122 | } |
53 | 123 | this->checkForGLErrors(); |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
124 | if (true |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
125 | and this->renderPreferences.lineAntiAliasing |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
126 | and this->renderPreferences.style != gl::RenderStyle::PickScene |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
127 | ) { |
45
272c84c7c87e
added configurable line anti-aliasing
Teemu Piippo <teemu@hecknology.net>
parents:
44
diff
changeset
|
128 | glEnable(GL_LINE_SMOOTH); |
272c84c7c87e
added configurable line anti-aliasing
Teemu Piippo <teemu@hecknology.net>
parents:
44
diff
changeset
|
129 | glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); |
272c84c7c87e
added configurable line anti-aliasing
Teemu Piippo <teemu@hecknology.net>
parents:
44
diff
changeset
|
130 | } |
272c84c7c87e
added configurable line anti-aliasing
Teemu Piippo <teemu@hecknology.net>
parents:
44
diff
changeset
|
131 | else { |
272c84c7c87e
added configurable line anti-aliasing
Teemu Piippo <teemu@hecknology.net>
parents:
44
diff
changeset
|
132 | glDisable(GL_LINE_SMOOTH); |
272c84c7c87e
added configurable line anti-aliasing
Teemu Piippo <teemu@hecknology.net>
parents:
44
diff
changeset
|
133 | } |
46 | 134 | if (this->renderPreferences.style != gl::RenderStyle::PickScene) |
135 | { | |
47 | 136 | const QColor& backgroundColor = this->renderPreferences.backgroundColor; |
46 | 137 | glClearColor( |
138 | static_cast<float>(backgroundColor.redF()), | |
139 | static_cast<float>(backgroundColor.greenF()), | |
140 | static_cast<float>(backgroundColor.blueF()), | |
141 | 1.0f); | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
142 | gl::setShaderUniform(&this->shaders, "useLighting", GL_TRUE); |
46 | 143 | } |
144 | else | |
145 | { | |
146 | glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
147 | gl::setShaderUniform(&this->shaders, "useLighting", GL_FALSE); |
46 | 148 | } |
53 | 149 | this->checkForGLErrors(); |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
150 | const QVector3D color = calcQVector3DFromQColor(this->renderPreferences.selectedColor); |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
151 | gl::setShaderUniform(&this->shaders, "selectedColor", color); |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
152 | gl::setShaderUniform(&this->shaders, "highlighted", this->highlighted.value); |
51 | 153 | this->checkForGLErrors(); |
26 | 154 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
155 | glEnable(GL_DEPTH_TEST); | |
156 | glEnable(GL_POLYGON_OFFSET_FILL); | |
157 | glPolygonOffset(1.0f, 1.0f); | |
44
c6114b3af3a6
added configurable line thickness
Teemu Piippo <teemu@hecknology.net>
parents:
40
diff
changeset
|
158 | glLineWidth(this->renderPreferences.lineThickness); |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
159 | const auto renderAllArrays = [this](){ |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
160 | // Lines need to be rendered last so that anti-aliasing does not interfere with polygon rendering. |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
161 | this->renderVao(gl::ArrayClass::Triangles); |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
162 | this->renderVao(gl::ArrayClass::Quads); |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
163 | this->renderVao(gl::ArrayClass::Lines); |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
164 | }; |
39
caac957e9834
Main color is now configurable
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
165 | switch (this->renderPreferences.style) |
18 | 166 | { |
167 | case gl::RenderStyle::Normal: | |
37 | 168 | this->setFragmentStyle(gl::FragmentStyle::Normal); |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
169 | renderAllArrays(); |
37 | 170 | break; |
18 | 171 | case gl::RenderStyle::BfcRedGreen: |
37 | 172 | glEnable(GL_CULL_FACE); |
173 | glCullFace(GL_BACK); | |
174 | this->setFragmentStyle(gl::FragmentStyle::BfcGreen); | |
175 | renderVao(gl::ArrayClass::Triangles); | |
176 | renderVao(gl::ArrayClass::Quads); | |
177 | glCullFace(GL_FRONT); | |
178 | this->setFragmentStyle(gl::FragmentStyle::BfcRed); | |
179 | renderVao(gl::ArrayClass::Triangles); | |
180 | renderVao(gl::ArrayClass::Quads); | |
181 | glDisable(GL_CULL_FACE); | |
182 | this->setFragmentStyle(gl::FragmentStyle::Normal); | |
183 | renderVao(gl::ArrayClass::Lines); | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
184 | break; |
18 | 185 | case gl::RenderStyle::RandomColors: |
37 | 186 | this->setFragmentStyle(gl::FragmentStyle::RandomColors); |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
187 | renderAllArrays(); |
18 | 188 | break; |
46 | 189 | case gl::RenderStyle::PickScene: |
190 | glLineWidth(3.0f); | |
191 | this->setFragmentStyle(gl::FragmentStyle::Id); | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
192 | renderAllArrays(); |
46 | 193 | break; |
119 | 194 | case gl::RenderStyle::VertexPickScene: |
195 | glLineWidth(1.0f); | |
196 | this->setFragmentStyle(gl::FragmentStyle::Black); | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
197 | renderAllArrays(); |
119 | 198 | break; |
18 | 199 | case gl::RenderStyle::Wireframe: |
200 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | |
37 | 201 | this->setFragmentStyle(gl::FragmentStyle::Normal); |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
202 | renderAllArrays(); |
18 | 203 | break; |
204 | } | |
37 | 205 | glDisable(GL_POLYGON_OFFSET_FILL); |
206 | } | |
207 | ||
208 | ||
31
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
209 | void PartRenderer::updateViewMatrix() |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
210 | { |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
211 | // I'm not quite sure why using the exponent function on the zoom factor causes linear zoom behavior |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
212 | const float modelDistance = longestMeasure(this->boundingBox); |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
213 | const double z = 2.0 * std::exp(this->zoom) * (1 + static_cast<double>(modelDistance)); |
31
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
214 | this->viewMatrix = glm::lookAt(glm::vec3{0, 0, z}, {0, 0, 0}, {0, -1, 0}); |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
215 | gl::setShaderUniformMatrix(&this->shaders, "viewMatrix", this->viewMatrix); |
112 | 216 | Q_EMIT this->viewMatrixChanged(this->viewMatrix); |
31
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
217 | } |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
218 | |
55 | 219 | void PartRenderer::updateModelMatrix() |
220 | { | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
60
diff
changeset
|
221 | this->modelMatrix = glm::mat4_cast(this->modelQuaternion); |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
222 | gl::setShaderUniformMatrix(&this->shaders, "modelMatrix", modelMatrix); |
112 | 223 | Q_EMIT this->modelMatrixChanged(this->modelMatrix); |
55 | 224 | this->update(); |
225 | } | |
226 | ||
86
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
227 | void PartRenderer::build() |
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
228 | { |
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
229 | this->needBuild = true; |
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
230 | } |
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
231 | |
27
c57fb7a5ffa3
commit work done on plugging vao to the gl renderer, renders nonsense for now
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
232 | void PartRenderer::renderVao(const gl::ArrayClass arrayClass) |
26 | 233 | { |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
234 | gl::bindModelShaderVertexArray(&this->shaders, arrayClass); |
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
235 | const std::size_t vertexCount = gl::vertexCount(&this->shaders, arrayClass); |
51 | 236 | this->checkForGLErrors(); |
26 | 237 | glDrawArrays(getGlTypeForArrayClass(arrayClass), 0, static_cast<GLsizei>(vertexCount)); |
51 | 238 | this->checkForGLErrors(); |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
239 | gl::releaseModelShaderVertexArray(&this->shaders, arrayClass); |
26 | 240 | this->checkForGLErrors(); |
241 | } | |
242 | ||
243 | void PartRenderer::checkForGLErrors() | |
244 | { | |
53 | 245 | gl::checkForGLErrors(this); |
246 | } | |
247 | ||
248 | void gl::checkForGLErrors(QWidget* parent) | |
249 | { | |
26 | 250 | GLenum glError; |
251 | QStringList errors; | |
252 | while ((glError = glGetError()) != GL_NO_ERROR) | |
21 | 253 | { |
100 | 254 | const QString glErrorString = QString::fromLatin1(reinterpret_cast<const char*>(gluErrorString(glError))); |
26 | 255 | errors.append(glErrorString); |
256 | } | |
257 | if (not errors.isEmpty()) | |
258 | { | |
53 | 259 | QMessageBox box{parent}; |
47 | 260 | box.setIcon(QMessageBox::Critical); |
53 | 261 | box.setText(QObject::tr("OpenGL error: %1").arg(errors.join("\n"))); |
262 | box.setWindowTitle(QObject::tr("OpenGL error")); | |
47 | 263 | box.setStandardButtons(QMessageBox::Close); |
53 | 264 | box.button(QMessageBox::Close)->setText(QObject::tr("Damn it")); |
47 | 265 | box.exec(); |
21 | 266 | } |
17 | 267 | } |
268 | ||
269 | void PartRenderer::mouseMoveEvent(QMouseEvent* event) | |
270 | { | |
271 | const bool left = event->buttons() & Qt::LeftButton; | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
60
diff
changeset
|
272 | const QPoint move = event->pos() - this->lastMousePosition; |
17 | 273 | if (left and not move.isNull()) |
274 | { | |
31
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
275 | // q_x is the rotation of the brick along the vertical y-axis, because turning the |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
276 | // vertical axis causes horizontal (=x) rotation. Likewise q_y is the rotation of the |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
277 | // brick along the horizontal x-axis, which causes vertical rotation. |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
278 | const auto scalar = 0.006f; |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
279 | const float move_x = static_cast<float>(move.x()); |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
280 | const float move_y = static_cast<float>(move.y()); |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
281 | const glm::quat q_x = glm::angleAxis(scalar * move_x, glm::vec3{0, -1, 0}); |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
282 | const glm::quat q_y = glm::angleAxis(scalar * move_y, glm::vec3{-1, 0, 0}); |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
283 | this->modelQuaternion = q_x * q_y * this->modelQuaternion; |
55 | 284 | this->updateModelMatrix(); |
17 | 285 | } |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
60
diff
changeset
|
286 | this->lastMousePosition = event->pos(); |
17 | 287 | } |
18 | 288 | |
31
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
289 | void PartRenderer::wheelEvent(QWheelEvent* event) |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
290 | { |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
291 | static constexpr double WHEEL_STEP = 1 / 1000.0; |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
292 | const double move = (-event->angleDelta().y()) * WHEEL_STEP; |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
293 | this->zoom = std::clamp(this->zoom + move, MIN_ZOOM, MAX_ZOOM); |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
294 | this->updateViewMatrix(); |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
295 | this->update(); |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
296 | } |
b6df269a2c6b
fix remaining rendering control issues
Teemu Piippo <teemu@hecknology.net>
parents:
30
diff
changeset
|
297 | |
58
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
298 | /** |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
299 | * @brief Converts the specified on the screen into the 3D world. The point is unprojected twice into 3D and the |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
300 | * intersection of the resulting line with the specified plane is returned. If the intersection point lies behind |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
301 | * the camera, no value is returned. |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
302 | * @param point 2D window co-ordinates to convert. |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
303 | * @param plane Plane to raycast against |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
304 | * @return world co-ordinates, or no value if the point is behind the camera. |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
305 | */ |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
306 | std::optional<glm::vec3> PartRenderer::screenToModelCoordinates(const QPoint& point, const geom::Plane& plane) const |
55 | 307 | { |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
308 | const geom::Line line = this->cameraLine(point); |
58
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
309 | std::optional<glm::vec3> result; |
59
60650929dc82
fixed testing of whether screenToModelCoordinates's result value is behind the camera
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
310 | result = geom::linePlaneIntersection(line, plane, 0.01f); |
60650929dc82
fixed testing of whether screenToModelCoordinates's result value is behind the camera
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
311 | // If the point lies behind the camera, do not return a result. |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
312 | if (result.has_value() and glm::dot(line.direction, *result - line.anchor) < 0) |
58
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
313 | { |
59
60650929dc82
fixed testing of whether screenToModelCoordinates's result value is behind the camera
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
314 | result.reset(); |
58
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
315 | } |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
316 | return result; |
55 | 317 | } |
318 | ||
58
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
319 | /** |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
320 | * @brief Converts the specified point to 2D window coordinates, with Y-coordinate inverted for Qt |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
321 | * @param point Point to unproject |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
322 | * @return screen coordinates |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
323 | */ |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
324 | QPointF PartRenderer::modelToScreenCoordinates(const glm::vec3& point) const |
55 | 325 | { |
58
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
326 | const glm::vec3 projected = glm::project( |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
327 | point, |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
328 | this->viewMatrix * glm::mat4_cast(this->modelQuaternion), |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
329 | this->projectionMatrix, |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
330 | this->viewportVector); |
60 | 331 | return toQPointF(glm::vec2{projected.x, this->height() - projected.y}); |
55 | 332 | } |
333 | ||
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
334 | geom::Line<3> PartRenderer::cameraLine(const QPoint& point) const |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
335 | { |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
336 | const glm::vec3 p1 = this->unproject({point.x(), point.y(), 0}); |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
337 | const glm::vec3 p2 = this->unproject({point.x(), point.y(), 1}); |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
338 | return geom::lineFromPoints(p1, p2); |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
339 | } |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
340 | |
58
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
341 | /** |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
342 | * @brief Unprojects the specified window coordinates to model coordinates |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
343 | * @param win Window coordinates to project. Z-coordinate indicates depth |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
344 | * @return model coordinates |
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
57
diff
changeset
|
345 | */ |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
346 | glm::vec3 PartRenderer::unproject(const glm::vec3& win) const |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
347 | { |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
348 | return glm::unProject( |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
349 | glm::vec3{win.x, this->height() - win.y, win.z}, |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
350 | this->viewMatrix * glm::mat4_cast(this->modelQuaternion), |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
351 | this->projectionMatrix, |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
352 | viewportVector); |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
353 | } |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
354 | |
199
6988973515d2
Fix pick() picking from weird places on the screen with high DPI scaling
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
355 | ldraw::id_t PartRenderer::pick(QPoint where) |
47 | 356 | { |
199
6988973515d2
Fix pick() picking from weird places on the screen with high DPI scaling
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
357 | // y is flipped, take that into account |
6988973515d2
Fix pick() picking from weird places on the screen with high DPI scaling
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
358 | where.setY(this->height() - where.y()); |
6988973515d2
Fix pick() picking from weird places on the screen with high DPI scaling
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
359 | // Since we are dealing with pixel data right from the framebuffer, its size |
6988973515d2
Fix pick() picking from weird places on the screen with high DPI scaling
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
360 | // will be affected by High DPI scaling. We need to take this into account |
6988973515d2
Fix pick() picking from weird places on the screen with high DPI scaling
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
361 | // and multiply the pixel positions by the screen pixel scaling factor. |
6988973515d2
Fix pick() picking from weird places on the screen with high DPI scaling
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
362 | where *= this->devicePixelRatioF(); |
47 | 363 | const gl::RenderStyle oldRenderStyle = this->renderPreferences.style; |
364 | this->renderPreferences.style = gl::RenderStyle::PickScene; | |
365 | this->makeCurrent(); | |
366 | this->renderScene(); | |
78
97c3ce5aa498
fixed signed vs unsigned nonsense in gl::Compiler::idFromColor
Teemu Piippo <teemu@hecknology.net>
parents:
77
diff
changeset
|
367 | std::array<GLubyte, 3> data; |
51 | 368 | this->checkForGLErrors(); |
199
6988973515d2
Fix pick() picking from weird places on the screen with high DPI scaling
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
369 | glfunc.glReadPixels(where.x(), where.y(), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &data[0]); |
51 | 370 | this->checkForGLErrors(); |
47 | 371 | this->renderPreferences.style = oldRenderStyle; |
372 | this->update(); | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
373 | return gl::idFromColor(data); |
47 | 374 | } |
375 | ||
37 | 376 | /** |
377 | * @brief Changes the color of rendered fragments | |
378 | * @param newFragmentStyle new fragment style to use | |
379 | */ | |
380 | void PartRenderer::setFragmentStyle(gl::FragmentStyle newFragmentStyle) | |
381 | { | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
150
diff
changeset
|
382 | gl::setShaderUniform(&this->shaders, "fragmentStyle", static_cast<int>(newFragmentStyle)); |
37 | 383 | } |
384 | ||
385 | /** | |
386 | * @brief Changes the way the scene is rendered | |
387 | * @param newStyle new render style to use | |
388 | */ | |
39
caac957e9834
Main color is now configurable
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
389 | void PartRenderer::setRenderPreferences(const gl::RenderPreferences& newPreferences) |
18 | 390 | { |
39
caac957e9834
Main color is now configurable
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
391 | bool mainColorChanged = this->renderPreferences.mainColor != newPreferences.mainColor; |
44
c6114b3af3a6
added configurable line thickness
Teemu Piippo <teemu@hecknology.net>
parents:
40
diff
changeset
|
392 | bool backgroundColorChanged = this->renderPreferences.backgroundColor != newPreferences.backgroundColor; |
39
caac957e9834
Main color is now configurable
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
393 | this->renderPreferences = newPreferences; |
44
c6114b3af3a6
added configurable line thickness
Teemu Piippo <teemu@hecknology.net>
parents:
40
diff
changeset
|
394 | if (mainColorChanged or backgroundColorChanged) |
39
caac957e9834
Main color is now configurable
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
395 | { |
86
4bec0525ef1b
PolygonObjectEditor can now modify the object properly
Teemu Piippo <teemu@hecknology.net>
parents:
78
diff
changeset
|
396 | this->build(); |
39
caac957e9834
Main color is now configurable
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
397 | } |
112 | 398 | Q_EMIT this->renderPreferencesChanged(); |
18 | 399 | this->update(); |
400 | } | |
107
02f142b399b1
Move selection logic into select tool
Teemu Piippo <teemu@hecknology.net>
parents:
100
diff
changeset
|
401 | |
02f142b399b1
Move selection logic into select tool
Teemu Piippo <teemu@hecknology.net>
parents:
100
diff
changeset
|
402 | /** |
02f142b399b1
Move selection logic into select tool
Teemu Piippo <teemu@hecknology.net>
parents:
100
diff
changeset
|
403 | * @return the currently highlighted object |
02f142b399b1
Move selection logic into select tool
Teemu Piippo <teemu@hecknology.net>
parents:
100
diff
changeset
|
404 | */ |
02f142b399b1
Move selection logic into select tool
Teemu Piippo <teemu@hecknology.net>
parents:
100
diff
changeset
|
405 | ldraw::id_t PartRenderer::getHighlightedObject() const |
02f142b399b1
Move selection logic into select tool
Teemu Piippo <teemu@hecknology.net>
parents:
100
diff
changeset
|
406 | { |
02f142b399b1
Move selection logic into select tool
Teemu Piippo <teemu@hecknology.net>
parents:
100
diff
changeset
|
407 | return this->highlighted; |
02f142b399b1
Move selection logic into select tool
Teemu Piippo <teemu@hecknology.net>
parents:
100
diff
changeset
|
408 | } |