src/ui/canvas.cpp

changeset 70
f21b800b02a4
parent 68
ddb07bb6840c
child 71
198d25fe4e21
equal deleted inserted replaced
69:a36913fc552a 70:f21b800b02a4
5 Canvas::Canvas( 5 Canvas::Canvas(
6 Model* model, 6 Model* model,
7 DocumentManager* documents, 7 DocumentManager* documents,
8 const ldraw::ColorTable& colorTable, 8 const ldraw::ColorTable& colorTable,
9 QWidget* parent) : 9 QWidget* parent) :
10 PartRenderer{model, documents, colorTable, parent}, 10 PartRenderer{model, documents, colorTable, parent}
11 gridProgram{this}
12 { 11 {
13 this->setMouseTracking(true); 12 this->setMouseTracking(true);
14 } 13 }
15 14
16 void Canvas::handleSelectionChange(const QSet<ldraw::Id>& selectedIds, const QSet<ldraw::Id>& deselectedIds) 15 void Canvas::handleSelectionChange(const QSet<ldraw::Id>& selectedIds, const QSet<ldraw::Id>& deselectedIds)
68 const float angle_x = std::abs(glm::dot(vector_x, cameraDirection)); 67 const float angle_x = std::abs(glm::dot(vector_x, cameraDirection));
69 const float angle_y = std::abs(glm::dot(vector_y, cameraDirection)); 68 const float angle_y = std::abs(glm::dot(vector_y, cameraDirection));
70 if (angle_x < angle_y) 69 if (angle_x < angle_y)
71 { 70 {
72 this->newStatusText("rotate by X axis"); 71 this->newStatusText("rotate by X axis");
73 this->gridMatrix = glm::rotate(this->gridMatrix, float{M_PI} / 2, glm::vec3{1, 0, 0}); 72 this->gridMatrix = glm::rotate(this->gridMatrix, PIf / 2, glm::vec3{1, 0, 0});
74 } 73 }
75 else 74 else
76 { 75 {
77 this->newStatusText("rotate by Y axis"); 76 this->newStatusText("rotate by Y axis");
78 this->gridMatrix = glm::rotate(this->gridMatrix, float{M_PI} / 2, glm::vec3{0, 1, 0}); 77 this->gridMatrix = glm::rotate(this->gridMatrix, PIf / 2, glm::vec3{0, 1, 0});
79 } 78 }
80 this->updateGridMatrix(); 79 this->updateGridMatrix();
81 this->update(); 80 this->update();
82 } 81 }
83 else 82 else
117 { 116 {
118 // We first create the grid program and connect everything and only then call the part renderer's initialization 117 // We first create the grid program and connect everything and only then call the part renderer's initialization
119 // functions so that when initialization sets up, the signals also set up the matrices on our side. 118 // functions so that when initialization sets up, the signals also set up the matrices on our side.
120 this->gridProgram.emplace(this); 119 this->gridProgram.emplace(this);
121 this->gridProgram->initialize(); 120 this->gridProgram->initialize();
122 connect(this, &PartRenderer::projectionMatrixChanged, [&]() 121 this->axesProgram.emplace(this);
123 { 122 this->axesProgram->initialize();
124 this->gridProgram->setProjectionMatrix(this->projectionMatrix); 123 for (AbstractBasicShaderProgram* program : {
125 }); 124 static_cast<AbstractBasicShaderProgram*>(&*this->gridProgram),
126 connect(this, &PartRenderer::modelMatrixChanged, [&]() 125 static_cast<AbstractBasicShaderProgram*>(&*this->axesProgram),
127 { 126 })
128 this->gridProgram->setModelMatrix(this->modelMatrix); 127 {
129 }); 128 connect(this, &PartRenderer::projectionMatrixChanged,
130 connect(this, &PartRenderer::viewMatrixChanged, [&]() 129 program, &AbstractBasicShaderProgram::setProjectionMatrix);
131 { 130 connect(this, &PartRenderer::modelMatrixChanged,
132 this->gridProgram->setViewMatrix(this->viewMatrix); 131 program, &AbstractBasicShaderProgram::setModelMatrix);
133 }); 132 connect(this, &PartRenderer::viewMatrixChanged,
133 program, &AbstractBasicShaderProgram::setViewMatrix);
134 }
134 connect(this, &PartRenderer::renderPreferencesChanged, [&]() 135 connect(this, &PartRenderer::renderPreferencesChanged, [&]()
135 { 136 {
136 if (this->gridProgram.has_value()) 137 if (this->gridProgram.has_value())
137 { 138 {
138 const bool isDark = luma(this->renderPreferences.backgroundColor) < 0.25; 139 const bool isDark = luma(this->renderPreferences.backgroundColor) < 0.25;
139 this->gridProgram->setGridColor(isDark ? Qt::white : Qt::black); 140 this->gridProgram->setGridColor(isDark ? Qt::white : Qt::black);
140 } 141 }
141 }); 142 });
142 PartRenderer::initializeGL(); 143 PartRenderer::initializeGL();
143 /* 144 // Set up XZ grid matrix
144 this->gridMatrix = glm::mat4{
145 {-4, 0, 0, 0},
146 {0, 6.9266, -3.6955, 0},
147 {0, -16.7222, -1.5307, 0},
148 {0, -13.273, -9.255, 1},
149 };
150 */
151 this->gridMatrix = glm::mat4{ 145 this->gridMatrix = glm::mat4{
152 {1, 0, 0, 0}, 146 {1, 0, 0, 0},
153 {0, 0, 1, 0}, 147 {0, 0, 1, 0},
154 {0, 1, 0, 0}, 148 {0, 1, 0, 0},
155 {0, 0, 0, 1} 149 {0, 0, 0, 1}
158 } 152 }
159 153
160 void Canvas::paintGL() 154 void Canvas::paintGL()
161 { 155 {
162 PartRenderer::paintGL(); 156 PartRenderer::paintGL();
163 glEnable(GL_BLEND); 157 // Render axes
164 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 158 {
165 this->gridProgram->draw(); 159 glLineWidth(5);
166 glDisable(GL_BLEND); 160 glEnable(GL_LINE_SMOOTH);
161 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
162 this->axesProgram->draw();
163 glDisable(GL_LINE_SMOOTH);
164 }
165 // Render grid
166 {
167 glEnable(GL_BLEND);
168 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
169 this->gridProgram->draw();
170 glDisable(GL_BLEND);
171 }
167 if (this->worldPosition.has_value()) 172 if (this->worldPosition.has_value())
168 { 173 {
169 QPainter painter{this}; 174 QPainter painter{this};
170 painter.setRenderHint(QPainter::Antialiasing); 175 painter.setRenderHint(QPainter::Antialiasing);
171 painter.setPen(Qt::black); 176 painter.setPen(Qt::black);
172 painter.setBrush(Qt::green); 177 painter.setBrush(Qt::green);
173 const QPointF pos = this->modelToScreenCoordinates(*this->worldPosition); 178 const QPointF pos = this->modelToScreenCoordinates(*this->worldPosition);
174 painter.drawEllipse(pos, 5, 5); 179 painter.drawEllipse(pos, 5, 5);
175 painter.setPen(Qt::white); 180 painter.setPen(Qt::white);
176 painter.drawText(pos + QPointF{5, 5}, vectorToString(*this->worldPosition)); 181 painter.drawText(pos + QPointF{5, 5}, vectorToString(*this->worldPosition));
177 }
178 {
179 QPainter axisPainter{this};
180 axisPainter.setRenderHint(QPainter::Antialiasing);
181 axisPainter.setPen(Qt::red);
182 axisPainter.drawLine(
183 this->modelToScreenCoordinates({10, 0, 0}),
184 this->modelToScreenCoordinates({-10, 0, 0}));
185 axisPainter.setPen(Qt::green);
186 axisPainter.drawLine(
187 this->modelToScreenCoordinates({0, 10, 0}),
188 this->modelToScreenCoordinates({0, -10, 0}));
189 axisPainter.setPen(Qt::blue);
190 axisPainter.drawLine(
191 this->modelToScreenCoordinates({0, 0, 10}),
192 this->modelToScreenCoordinates({0, 0, -10}));
193 } 182 }
194 } 183 }
195 184
196 void Canvas::updateGridMatrix() 185 void Canvas::updateGridMatrix()
197 { 186 {

mercurial