src/gl/partrenderer.cpp

changeset 376
3cef3b016330
parent 360
41b38b9e05a2
child 382
94d5587bb0c4
equal deleted inserted replaced
375:21a5ecbe34e4 376:3cef3b016330
31 #include "src/gl/partrenderer.h" 31 #include "src/gl/partrenderer.h"
32 #include "src/gl/compiler.h" 32 #include "src/gl/compiler.h"
33 33
34 static constexpr double MIN_ZOOM = -3.0; 34 static constexpr double MIN_ZOOM = -3.0;
35 static constexpr double MAX_ZOOM = 3.0; 35 static constexpr double MAX_ZOOM = 3.0;
36 const gl::RenderPreferences PartRenderer::default_render_preferences{};
37 const gl::build_preferences PartRenderer::default_build_preferences{};
36 38
37 PartRenderer::PartRenderer( 39 PartRenderer::PartRenderer(
38 QTextDocument* model, 40 QTextDocument* model,
39 DocumentManager* documents, 41 DocumentManager* documents,
40 const ColorTable& colorTable, 42 const ColorTable& colorTable,
118 120
119 void PartRenderer::renderScene() 121 void PartRenderer::renderScene()
120 { 122 {
121 if (this->needBuild) 123 if (this->needBuild)
122 { 124 {
123 gl::build(&this->shaders, this->model, this->colorTable, this->documents, this->renderPreferences); 125 gl::build(&this->shaders, this->model, this->colorTable, this->documents, this->build_preferences);
124 this->boundingBox = gl::boundingBoxForModel(this->model, this->documents); 126 this->boundingBox = gl::boundingBoxForModel(this->model, this->documents);
125 this->needBuild = false; 127 this->needBuild = false;
126 } 128 }
127 this->checkForGLErrors(); 129 this->checkForGLErrors();
128 if (true 130 if (this->render_preferences->lineAntiAliasing)
129 and this->renderPreferences.lineAntiAliasing 131 {
130 and this->renderPreferences.style != gl::RenderStyle::PickScene
131 ) {
132 glEnable(GL_LINE_SMOOTH); 132 glEnable(GL_LINE_SMOOTH);
133 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 133 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
134 } 134 }
135 else { 135 else {
136 glDisable(GL_LINE_SMOOTH); 136 glDisable(GL_LINE_SMOOTH);
137 } 137 }
138 if (this->renderPreferences.style != gl::RenderStyle::PickScene) 138 if (this->render_preferences->style != gl::RenderStyle::PickScene)
139 { 139 {
140 const QColor& backgroundColor = this->renderPreferences.backgroundColor; 140 const QColor& backgroundColor = this->build_preferences->backgroundColor;
141 glClearColor( 141 glClearColor(
142 static_cast<float>(backgroundColor.redF()), 142 static_cast<float>(backgroundColor.redF()),
143 static_cast<float>(backgroundColor.greenF()), 143 static_cast<float>(backgroundColor.greenF()),
144 static_cast<float>(backgroundColor.blueF()), 144 static_cast<float>(backgroundColor.blueF()),
145 1.0f); 145 1.0f);
149 { 149 {
150 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 150 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
151 gl::setShaderUniform(&this->shaders, "useLighting", GL_FALSE); 151 gl::setShaderUniform(&this->shaders, "useLighting", GL_FALSE);
152 } 152 }
153 this->checkForGLErrors(); 153 this->checkForGLErrors();
154 const QColor qs = this->renderPreferences.selectedColor; 154 const QColor qs = this->render_preferences->selectedColor;
155 const glm::vec4 selectedColor{qs.redF(), qs.greenF(), qs.blueF(), 1.0f}; 155 const glm::vec4 selectedColor{qs.redF(), qs.greenF(), qs.blueF(), 1.0f};
156 gl::setShaderUniformVector(&this->shaders, "selectedColor", selectedColor); 156 gl::setShaderUniformVector(&this->shaders, "selectedColor", selectedColor);
157 gl::setShaderUniform(&this->shaders, "highlighted", this->highlighted.value); 157 gl::setShaderUniform(&this->shaders, "highlighted", this->highlighted.value);
158 this->checkForGLErrors(); 158 this->checkForGLErrors();
159 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 159 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
160 glEnable(GL_DEPTH_TEST); 160 glEnable(GL_DEPTH_TEST);
161 glEnable(GL_POLYGON_OFFSET_FILL); 161 glEnable(GL_POLYGON_OFFSET_FILL);
162 glPolygonOffset(1.0f, 1.0f); 162 glPolygonOffset(1.0f, 1.0f);
163 glLineWidth(this->renderPreferences.lineThickness); 163 glLineWidth(this->render_preferences->lineThickness);
164 const auto renderAllArrays = [this](){ 164 const auto renderAllArrays = [this](){
165 // Lines need to be rendered last so that anti-aliasing does not interfere with polygon rendering. 165 // Lines need to be rendered last so that anti-aliasing does not interfere with polygon rendering.
166 this->renderVao<gl::ArrayClass::Triangles>(); 166 this->renderVao<gl::ArrayClass::Triangles>();
167 this->renderVao<gl::ArrayClass::Quads>(); 167 this->renderVao<gl::ArrayClass::Quads>();
168 this->renderVao<gl::ArrayClass::Lines>(); 168 this->renderVao<gl::ArrayClass::Lines>();
169 }; 169 };
170 if (this->renderPreferences.wireframe and this->renderPreferences.style != gl::RenderStyle::PickScene) { 170 if (this->render_preferences->wireframe)
171 {
171 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 172 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
172 } 173 }
173 switch (this->renderPreferences.style) 174 switch (this->render_preferences->style)
174 { 175 {
175 case gl::RenderStyle::Normal: 176 case gl::RenderStyle::Normal:
176 this->setFragmentStyle(gl::FragmentStyle::Normal); 177 this->setFragmentStyle(gl::FragmentStyle::Normal);
177 renderAllArrays(); 178 renderAllArrays();
178 break; 179 break;
193 case gl::RenderStyle::RandomColors: 194 case gl::RenderStyle::RandomColors:
194 this->setFragmentStyle(gl::FragmentStyle::RandomColors); 195 this->setFragmentStyle(gl::FragmentStyle::RandomColors);
195 renderAllArrays(); 196 renderAllArrays();
196 break; 197 break;
197 case gl::RenderStyle::PickScene: 198 case gl::RenderStyle::PickScene:
198 glLineWidth(3.0f);
199 this->setFragmentStyle(gl::FragmentStyle::Id); 199 this->setFragmentStyle(gl::FragmentStyle::Id);
200 renderAllArrays(); 200 renderAllArrays();
201 break; 201 break;
202 case gl::RenderStyle::VertexPickScene: 202 case gl::RenderStyle::VertexPickScene:
203 glLineWidth(1.0f); 203 glLineWidth(1.0f);
393 return toQPointF(glm::vec2{projected.x, static_cast<float>(this->height()) - projected.y}); 393 return toQPointF(glm::vec2{projected.x, static_cast<float>(this->height()) - projected.y});
394 } 394 }
395 395
396 bool PartRenderer::isDark() const 396 bool PartRenderer::isDark() const
397 { 397 {
398 return luma(this->renderPreferences.backgroundColor) < 0.25; 398 return luma(this->build_preferences->backgroundColor) < 0.25;
399 } 399 }
400 400
401 Line<3> PartRenderer::cameraLine(const QPointF& point) const 401 Line<3> PartRenderer::cameraLine(const QPointF& point) const
402 { 402 {
403 const glm::vec3 p1 = this->unproject({point.x(), point.y(), 0}); 403 const glm::vec3 p1 = this->unproject({point.x(), point.y(), 0});
431 where.setY(this->height() - where.y()); 431 where.setY(this->height() - where.y());
432 // Since we are dealing with pixel data right from the framebuffer, its size 432 // Since we are dealing with pixel data right from the framebuffer, its size
433 // will be affected by High DPI scaling. We need to take this into account 433 // will be affected by High DPI scaling. We need to take this into account
434 // and multiply the pixel positions by the screen pixel scaling factor. 434 // and multiply the pixel positions by the screen pixel scaling factor.
435 where *= this->devicePixelRatioF(); 435 where *= this->devicePixelRatioF();
436 const gl::RenderStyle oldRenderStyle = this->renderPreferences.style; 436 static const gl::RenderPreferences pick_scene_preferences {
437 this->renderPreferences.style = gl::RenderStyle::PickScene; 437 .style = gl::RenderStyle::PickScene,
438 .selectedColor = {},
439 .lineThickness = 3.0f,
440 .lineAntiAliasing = false,
441 .drawAxes = false,
442 .wireframe = false,
443 };
444 const gl::RenderPreferences* old_render_preferences = this->render_preferences;
445 this->render_preferences = &pick_scene_preferences;
438 this->makeCurrent(); 446 this->makeCurrent();
439 QOpenGLFramebufferObject fbo{this->width(), this->height(), QOpenGLFramebufferObject::CombinedDepthStencil}; 447 QOpenGLFramebufferObject fbo{this->width(), this->height(), QOpenGLFramebufferObject::CombinedDepthStencil};
440 fbo.bind(); 448 fbo.bind();
441 this->renderScene(); 449 this->renderScene();
442 std::array<GLubyte, 3> data; 450 std::array<GLubyte, 3> data;
443 this->checkForGLErrors(); 451 this->checkForGLErrors();
444 glReadPixels(where.x(), where.y(), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &data[0]); 452 glReadPixels(where.x(), where.y(), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &data[0]);
445 this->checkForGLErrors(); 453 this->checkForGLErrors();
446 fbo.release(); 454 fbo.release();
447 this->renderPreferences.style = oldRenderStyle; 455 this->render_preferences = old_render_preferences;
448 return gl::idFromUcharColor(data); 456 return gl::idFromUcharColor(data);
449 } 457 }
450 458
451 /** 459 /**
452 * @brief Changes the color of rendered fragments 460 * @brief Changes the color of rendered fragments
453 * @param newFragmentStyle new fragment style to use 461 * @param newFragmentStyle new fragment style to use
454 */ 462 */
455 void PartRenderer::setFragmentStyle(gl::FragmentStyle newFragmentStyle) 463 void PartRenderer::setFragmentStyle(gl::FragmentStyle newFragmentStyle)
456 { 464 {
457 gl::setShaderUniform(&this->shaders, "fragmentStyle", static_cast<int>(newFragmentStyle)); 465 gl::setShaderUniform(&this->shaders, "fragmentStyle", static_cast<int>(newFragmentStyle));
458 }
459
460 /**
461 * @brief Changes the way the scene is rendered
462 * @param newStyle new render style to use
463 */
464 void PartRenderer::setRenderPreferences(const gl::RenderPreferences& newPreferences)
465 {
466 bool mainColorChanged = this->renderPreferences.mainColor != newPreferences.mainColor;
467 bool backgroundColorChanged = this->renderPreferences.backgroundColor != newPreferences.backgroundColor;
468 this->renderPreferences = newPreferences;
469 if (mainColorChanged or backgroundColorChanged)
470 {
471 this->build();
472 }
473 Q_EMIT this->renderPreferencesChanged();
474 this->update();
475 } 466 }
476 467
477 /** 468 /**
478 * @return the currently highlighted object 469 * @return the currently highlighted object
479 */ 470 */

mercurial