1 /* |
1 /* |
2 * LDForge: LDraw parts authoring CAD |
2 * LDForge: LDraw parts authoring CAD |
3 * Copyright (C) 2013 Santeri Piippo |
3 * Copyright (C) 2013 Santeri Piippo |
4 * |
4 * |
5 * This program is free software: you can redistribute it and/or modify |
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 |
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 |
7 * the Free Software Foundation, either version 3 of the License, or |
8 * (at your option) any later version. |
8 * (at your option) any later version. |
9 * |
9 * |
10 * This program is distributed in the hope that it will be useful, |
10 * This program is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 * GNU General Public License for more details. |
13 * GNU General Public License for more details. |
14 * |
14 * |
15 * You should have received a copy of the GNU General Public License |
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/>. |
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 */ |
17 */ |
18 |
18 |
19 #include <QGLWidget> |
19 #include <QGLWidget> |
20 #include <QWheelEvent> |
20 #include <QWheelEvent> |
21 #include <QMouseEvent> |
21 #include <QMouseEvent> |
22 #include <QContextMenuEvent> |
22 #include <QContextMenuEvent> |
23 #include <QInputDialog> |
23 #include <QInputDialog> |
24 #include <qtooltip.h> |
24 #include <QToolTip> |
25 #include <QTimer> |
25 #include <QTimer> |
26 #include <GL/glu.h> |
26 #include <GL/glu.h> |
27 |
27 |
28 #include "common.h" |
28 #include "common.h" |
29 #include "config.h" |
29 #include "config.h" |
34 #include "misc.h" |
34 #include "misc.h" |
35 #include "history.h" |
35 #include "history.h" |
36 #include "dialogs.h" |
36 #include "dialogs.h" |
37 #include "addObjectDialog.h" |
37 #include "addObjectDialog.h" |
38 #include "messagelog.h" |
38 #include "messagelog.h" |
|
39 #include "build/moc_gldraw.cpp" |
39 |
40 |
40 static const struct staticCameraMeta { |
41 static const struct staticCameraMeta { |
41 const char glrotate[3]; |
42 const char glrotate[3]; |
42 const Axis axisX, axisY; |
43 const Axis axisX, axisY; |
43 const bool negX, negY; |
44 const bool negX, negY; |
87 } g_GLAxes[3] = { |
88 } g_GLAxes[3] = { |
88 { QColor (255, 0, 0), vertex (10000, 0, 0) }, |
89 { QColor (255, 0, 0), vertex (10000, 0, 0) }, |
89 { QColor (80, 192, 0), vertex (0, 10000, 0) }, |
90 { QColor (80, 192, 0), vertex (0, 10000, 0) }, |
90 { QColor (0, 160, 192), vertex (0, 0, 10000) }, |
91 { QColor (0, 160, 192), vertex (0, 0, 10000) }, |
91 }; |
92 }; |
92 |
93 |
93 // ============================================================================= |
94 static bool g_glInvert = false; |
94 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
95 static List<short> g_warnedColors; |
95 // ============================================================================= |
96 |
|
97 // ============================================================================= |
|
98 // ----------------------------------------------------------------------------- |
96 GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent) { |
99 GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent) { |
97 m_picking = m_rangepick = false; |
100 m_picking = m_rangepick = false; |
98 m_camera = (GL::Camera) gl_camera.value; |
101 m_camera = (GL::Camera) gl_camera.value; |
99 m_drawToolTip = false; |
102 m_drawToolTip = false; |
100 m_editMode = Select; |
103 m_editMode = Select; |
129 |
132 |
130 calcCameraIcons(); |
133 calcCameraIcons(); |
131 } |
134 } |
132 |
135 |
133 // ============================================================================= |
136 // ============================================================================= |
|
137 // ----------------------------------------------------------------------------- |
134 GLRenderer::~GLRenderer() { |
138 GLRenderer::~GLRenderer() { |
135 for (int i = 0; i < 6; ++i) |
139 for (int i = 0; i < 6; ++i) |
136 delete m_overlays[i].img; |
140 delete m_overlays[i].img; |
137 |
141 |
138 for (CameraIcon& info : m_cameraIcons) |
142 for (CameraIcon& info : m_cameraIcons) |
139 delete info.img; |
143 delete info.img; |
140 } |
144 } |
141 |
145 |
142 // ============================================================================= |
146 // ============================================================================= |
143 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
147 // ----------------------------------------------------------------------------- |
144 // ============================================================================= |
|
145 void GLRenderer::calcCameraIcons() { |
148 void GLRenderer::calcCameraIcons() { |
146 ushort i = 0; |
149 ushort i = 0; |
147 |
150 |
148 for (CameraIcon& info : m_cameraIcons) { |
151 for (CameraIcon& info : m_cameraIcons) { |
149 const long x1 = (m_width - (info.cam != Free ? 48 : 16)) + ((i % 3) * 16) - 1, |
152 const long x1 = (m_width - (info.cam != Free ? 48 : 16)) + ((i % 3) * 16) - 1, |
155 info.destRect.width() + 1, info.destRect.height() + 1); |
158 info.destRect.width() + 1, info.destRect.height() + 1); |
156 ++i; |
159 ++i; |
157 } |
160 } |
158 } |
161 } |
159 |
162 |
|
163 // ============================================================================= |
|
164 // ----------------------------------------------------------------------------- |
160 void GLRenderer::initGLData() { |
165 void GLRenderer::initGLData() { |
161 glEnable (GL_BLEND); |
166 glEnable (GL_BLEND); |
162 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
167 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
163 glEnable (GL_POLYGON_OFFSET_FILL); |
168 glEnable (GL_POLYGON_OFFSET_FILL); |
164 glPolygonOffset (1.0f, 1.0f); |
169 glPolygonOffset (1.0f, 1.0f); |
170 glEnable (GL_LINE_SMOOTH); |
175 glEnable (GL_LINE_SMOOTH); |
171 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); |
176 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); |
172 } |
177 } |
173 |
178 |
174 // ============================================================================= |
179 // ============================================================================= |
|
180 // ----------------------------------------------------------------------------- |
175 void GLRenderer::resetAngles() { |
181 void GLRenderer::resetAngles() { |
176 m_rotX = 30.0f; |
182 m_rotX = 30.0f; |
177 m_rotY = 325.f; |
183 m_rotY = 325.f; |
178 m_panX = m_panY = m_rotZ = 0.0f; |
184 m_panX = m_panY = m_rotZ = 0.0f; |
179 zoomToFit(); |
185 zoomToFit(); |
180 } |
186 } |
181 |
187 |
182 // ============================================================================= |
188 // ============================================================================= |
183 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
189 // ----------------------------------------------------------------------------- |
184 // ============================================================================= |
|
185 void GLRenderer::initializeGL() { |
190 void GLRenderer::initializeGL() { |
186 setBackground(); |
191 setBackground(); |
187 |
192 |
188 glLineWidth (gl_linethickness); |
193 glLineWidth (gl_linethickness); |
189 |
194 |
192 setFocusPolicy (Qt::WheelFocus); |
197 setFocusPolicy (Qt::WheelFocus); |
193 compileAllObjects(); |
198 compileAllObjects(); |
194 } |
199 } |
195 |
200 |
196 // ============================================================================= |
201 // ============================================================================= |
197 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
202 // ----------------------------------------------------------------------------- |
198 // ============================================================================= |
|
199 QColor GLRenderer::getMainColor() { |
203 QColor GLRenderer::getMainColor() { |
200 QColor col (gl_maincolor); |
204 QColor col (gl_maincolor); |
201 |
205 |
202 if (!col.isValid()) |
206 if (!col.isValid()) |
203 return QColor (0, 0, 0); |
207 return QColor (0, 0, 0); |
204 |
208 |
205 col.setAlpha (gl_maincolor_alpha * 255.f); |
209 col.setAlpha (gl_maincolor_alpha * 255.f); |
206 return col; |
210 return col; |
207 } |
211 } |
208 |
212 |
|
213 // ============================================================================= |
209 // ----------------------------------------------------------------------------- |
214 // ----------------------------------------------------------------------------- |
210 void GLRenderer::setBackground() { |
215 void GLRenderer::setBackground() { |
211 QColor col (gl_bgcolor); |
216 QColor col (gl_bgcolor); |
212 |
217 |
213 if (!col.isValid()) |
218 if (!col.isValid()) |
219 m_bgcolor = col; |
224 m_bgcolor = col; |
220 qglClearColor (col); |
225 qglClearColor (col); |
221 } |
226 } |
222 |
227 |
223 // ============================================================================= |
228 // ============================================================================= |
224 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
229 // ----------------------------------------------------------------------------- |
225 // ============================================================================= |
|
226 static List<short> g_warnedColors; |
|
227 void GLRenderer::setObjectColor (LDObject* obj, const ListType list) { |
230 void GLRenderer::setObjectColor (LDObject* obj, const ListType list) { |
228 QColor qcol; |
231 QColor qcol; |
229 |
232 |
230 if (!obj->isColored()) |
233 if (!obj->isColored()) |
231 return; |
234 return; |
311 ((double) b) / 255.0f, |
314 ((double) b) / 255.0f, |
312 ((double) a) / 255.0f); |
315 ((double) a) / 255.0f); |
313 } |
316 } |
314 |
317 |
315 // ============================================================================= |
318 // ============================================================================= |
316 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
319 // ----------------------------------------------------------------------------- |
317 // ============================================================================= |
|
318 void GLRenderer::refresh() { |
320 void GLRenderer::refresh() { |
319 update(); |
321 update(); |
320 swapBuffers(); |
322 swapBuffers(); |
321 } |
323 } |
322 |
324 |
323 // ============================================================================= |
325 // ============================================================================= |
|
326 // ----------------------------------------------------------------------------- |
324 void GLRenderer::hardRefresh() { |
327 void GLRenderer::hardRefresh() { |
325 compileAllObjects(); |
328 compileAllObjects(); |
326 refresh(); |
329 refresh(); |
327 |
330 |
328 glLineWidth (gl_linethickness); |
331 glLineWidth (gl_linethickness); |
329 } |
332 } |
330 |
333 |
331 // ============================================================================= |
334 // ============================================================================= |
332 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
335 // ----------------------------------------------------------------------------- |
333 // ============================================================================= |
|
334 void GLRenderer::resizeGL (int w, int h) { |
336 void GLRenderer::resizeGL (int w, int h) { |
335 m_width = w; |
337 m_width = w; |
336 m_height = h; |
338 m_height = h; |
337 |
339 |
338 calcCameraIcons(); |
340 calcCameraIcons(); |
342 glLoadIdentity(); |
344 glLoadIdentity(); |
343 gluPerspective (45.0f, (double) w / (double) h, 1.0f, 10000.0f); |
345 gluPerspective (45.0f, (double) w / (double) h, 1.0f, 10000.0f); |
344 glMatrixMode (GL_MODELVIEW); |
346 glMatrixMode (GL_MODELVIEW); |
345 } |
347 } |
346 |
348 |
|
349 // ============================================================================= |
|
350 // ----------------------------------------------------------------------------- |
347 void GLRenderer::drawGLScene() { |
351 void GLRenderer::drawGLScene() { |
348 if (file() == null) |
352 if (file() == null) |
349 return; |
353 return; |
350 |
354 |
351 if (gl_wireframe && !picking()) |
355 if (gl_wireframe && !picking()) |
416 glMatrixMode (GL_MODELVIEW); |
420 glMatrixMode (GL_MODELVIEW); |
417 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); |
421 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); |
418 } |
422 } |
419 |
423 |
420 // ============================================================================= |
424 // ============================================================================= |
|
425 // ----------------------------------------------------------------------------- |
421 // This converts a 2D point on the screen to a 3D point in the model. If 'snap' |
426 // This converts a 2D point on the screen to a 3D point in the model. If 'snap' |
422 // is true, the 3D point will snap to the current grid. |
427 // is true, the 3D point will snap to the current grid. |
423 // ============================================================================= |
428 // ----------------------------------------------------------------------------- |
424 vertex GLRenderer::coordconv2_3 (const QPoint& pos2d, bool snap) const { |
429 vertex GLRenderer::coordconv2_3 (const QPoint& pos2d, bool snap) const { |
425 assert (camera() != Free); |
430 assert (camera() != Free); |
426 |
431 |
427 vertex pos3d; |
432 vertex pos3d; |
428 const staticCameraMeta* cam = &g_staticCameras[m_camera]; |
433 const staticCameraMeta* cam = &g_staticCameras[m_camera]; |
450 pos3d[3 - axisX - axisY] = depthValue(); |
455 pos3d[3 - axisX - axisY] = depthValue(); |
451 return pos3d; |
456 return pos3d; |
452 } |
457 } |
453 |
458 |
454 // ============================================================================= |
459 // ============================================================================= |
|
460 // ----------------------------------------------------------------------------- |
455 // Inverse operation for the above - convert a 3D position to a 2D screen |
461 // Inverse operation for the above - convert a 3D position to a 2D screen |
456 // position |
462 // position |
457 // ============================================================================= |
463 // ----------------------------------------------------------------------------- |
458 QPoint GLRenderer::coordconv3_2 (const vertex& pos3d) const { |
464 QPoint GLRenderer::coordconv3_2 (const vertex& pos3d) const { |
459 GLfloat m[16]; |
465 GLfloat m[16]; |
460 const staticCameraMeta* cam = &g_staticCameras[m_camera]; |
466 const staticCameraMeta* cam = &g_staticCameras[m_camera]; |
461 const Axis axisX = cam->axisX; |
467 const Axis axisX = cam->axisX; |
462 const Axis axisY = cam->axisY; |
468 const Axis axisY = cam->axisY; |
479 |
485 |
480 return QPoint (rx, -ry); |
486 return QPoint (rx, -ry); |
481 } |
487 } |
482 |
488 |
483 // ============================================================================= |
489 // ============================================================================= |
484 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
490 // ----------------------------------------------------------------------------- |
485 // ============================================================================= |
|
486 void GLRenderer::paintEvent (QPaintEvent* ev) { |
491 void GLRenderer::paintEvent (QPaintEvent* ev) { |
487 Q_UNUSED (ev) |
492 Q_UNUSED (ev) |
488 |
493 |
489 makeCurrent(); |
494 makeCurrent(); |
490 m_virtWidth = zoom(); |
495 m_virtWidth = zoom(); |
632 if (msglog()) { |
637 if (msglog()) { |
633 int y = 0; |
638 int y = 0; |
634 const int margin = 2; |
639 const int margin = 2; |
635 QColor penColor = getTextPen(); |
640 QColor penColor = getTextPen(); |
636 |
641 |
637 for (const MessageManager::Line& line : *msglog()) { |
642 for (const MessageManager::Line& line : msglog()->getLines()) { |
638 penColor.setAlphaF (line.alpha); |
643 penColor.setAlphaF (line.alpha); |
639 paint.setPen (penColor); |
644 paint.setPen (penColor); |
640 paint.drawText (QPoint (margin, y + margin + metrics.ascent()), line.text); |
645 paint.drawText (QPoint (margin, y + margin + metrics.ascent()), line.text); |
641 y += metrics.height(); |
646 y += metrics.height(); |
642 } |
647 } |
696 |
701 |
697 setCursor (Qt::ArrowCursor); |
702 setCursor (Qt::ArrowCursor); |
698 } |
703 } |
699 |
704 |
700 // ============================================================================= |
705 // ============================================================================= |
701 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
706 // ----------------------------------------------------------------------------- |
702 // ============================================================================= |
|
703 static bool g_glInvert = false; |
|
704 |
|
705 void GLRenderer::compileSubObject (LDObject* obj, const GLenum gltype) { |
707 void GLRenderer::compileSubObject (LDObject* obj, const GLenum gltype) { |
706 glBegin (gltype); |
708 glBegin (gltype); |
707 |
709 |
708 const short numverts = (obj->getType() != LDObject::CondLine) ? obj->vertices() : 2; |
710 const short numverts = (obj->getType() != LDObject::CondLine) ? obj->vertices() : 2; |
709 |
711 |
716 |
718 |
717 glEnd(); |
719 glEnd(); |
718 } |
720 } |
719 |
721 |
720 // ============================================================================= |
722 // ============================================================================= |
721 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
723 // ----------------------------------------------------------------------------- |
722 // ============================================================================= |
|
723 void GLRenderer::compileList (LDObject* obj, const GLRenderer::ListType list) { |
724 void GLRenderer::compileList (LDObject* obj, const GLRenderer::ListType list) { |
724 setObjectColor (obj, list); |
725 setObjectColor (obj, list); |
725 |
726 |
726 switch (obj->getType()) { |
727 switch (obj->getType()) { |
727 case LDObject::Line: |
728 case LDObject::Line: |
775 break; |
776 break; |
776 } |
777 } |
777 } |
778 } |
778 |
779 |
779 // ============================================================================= |
780 // ============================================================================= |
780 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
781 // ----------------------------------------------------------------------------- |
781 // ============================================================================= |
|
782 void GLRenderer::compileVertex (const vertex& vrt) { |
782 void GLRenderer::compileVertex (const vertex& vrt) { |
783 glVertex3d (vrt[X], -vrt[Y], -vrt[Z]); |
783 glVertex3d (vrt[X], -vrt[Y], -vrt[Z]); |
784 } |
784 } |
785 |
785 |
786 // ============================================================================= |
786 // ============================================================================= |
787 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
787 // ----------------------------------------------------------------------------- |
788 // ============================================================================= |
|
789 void GLRenderer::clampAngle (double& angle) const { |
788 void GLRenderer::clampAngle (double& angle) const { |
790 while (angle < 0) |
789 while (angle < 0) |
791 angle += 360.0; |
790 angle += 360.0; |
792 while (angle > 360.0) |
791 while (angle > 360.0) |
793 angle -= 360.0; |
792 angle -= 360.0; |
794 } |
793 } |
795 |
794 |
|
795 // ============================================================================= |
|
796 // ----------------------------------------------------------------------------- |
796 void GLRenderer::addDrawnVertex (vertex pos) { |
797 void GLRenderer::addDrawnVertex (vertex pos) { |
797 // If we picked an already-existing vertex, stop drawing |
798 // If we picked an already-existing vertex, stop drawing |
798 for (vertex& vert : m_drawedVerts) { |
799 for (vertex& vert : m_drawedVerts) { |
799 if (vert == pos) { |
800 if (vert == pos) { |
800 endDraw (true); |
801 endDraw (true); |
804 |
805 |
805 m_drawedVerts << pos; |
806 m_drawedVerts << pos; |
806 } |
807 } |
807 |
808 |
808 // ============================================================================= |
809 // ============================================================================= |
809 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
810 // ----------------------------------------------------------------------------- |
810 // ============================================================================= |
|
811 void GLRenderer::mouseReleaseEvent (QMouseEvent* ev) { |
811 void GLRenderer::mouseReleaseEvent (QMouseEvent* ev) { |
812 const bool wasLeft = (m_lastButtons & Qt::LeftButton) && !(ev->buttons() & Qt::LeftButton), |
812 const bool wasLeft = (m_lastButtons & Qt::LeftButton) && !(ev->buttons() & Qt::LeftButton), |
813 wasRight = (m_lastButtons & Qt::RightButton) && !(ev->buttons() & Qt::RightButton), |
813 wasRight = (m_lastButtons & Qt::RightButton) && !(ev->buttons() & Qt::RightButton), |
814 wasMid = (m_lastButtons & Qt::MidButton) && !(ev->buttons() & Qt::MidButton); |
814 wasMid = (m_lastButtons & Qt::MidButton) && !(ev->buttons() & Qt::MidButton); |
815 |
815 |
914 update(); |
914 update(); |
915 m_totalmove = 0; |
915 m_totalmove = 0; |
916 } |
916 } |
917 |
917 |
918 // ============================================================================= |
918 // ============================================================================= |
919 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
919 // ----------------------------------------------------------------------------- |
920 // ============================================================================= |
|
921 void GLRenderer::mousePressEvent (QMouseEvent* ev) { |
920 void GLRenderer::mousePressEvent (QMouseEvent* ev) { |
922 m_totalmove = 0; |
921 m_totalmove = 0; |
923 |
922 |
924 if (ev->modifiers() & Qt::ControlModifier) { |
923 if (ev->modifiers() & Qt::ControlModifier) { |
925 m_rangepick = true; |
924 m_rangepick = true; |
972 |
971 |
973 update(); |
972 update(); |
974 } |
973 } |
975 |
974 |
976 // ============================================================================= |
975 // ============================================================================= |
977 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
976 // ----------------------------------------------------------------------------- |
978 // ============================================================================= |
|
979 void GLRenderer::keyPressEvent (QKeyEvent* ev) { |
977 void GLRenderer::keyPressEvent (QKeyEvent* ev) { |
980 m_keymods = ev->modifiers(); |
978 m_keymods = ev->modifiers(); |
981 } |
979 } |
982 |
980 |
|
981 // ============================================================================= |
|
982 // ----------------------------------------------------------------------------- |
983 void GLRenderer::keyReleaseEvent (QKeyEvent* ev) { |
983 void GLRenderer::keyReleaseEvent (QKeyEvent* ev) { |
984 m_keymods = ev->modifiers(); |
984 m_keymods = ev->modifiers(); |
985 } |
985 } |
986 |
986 |
987 // ============================================================================= |
987 // ============================================================================= |
|
988 // ----------------------------------------------------------------------------- |
988 void GLRenderer::wheelEvent (QWheelEvent* ev) { |
989 void GLRenderer::wheelEvent (QWheelEvent* ev) { |
989 makeCurrent(); |
990 makeCurrent(); |
990 |
991 |
991 zoomNotch (ev->delta() > 0); |
992 zoomNotch (ev->delta() > 0); |
992 setZoom (clamp<double> (zoom(), 0.01f, 10000.0f)); |
993 setZoom (clamp<double> (zoom(), 0.01f, 10000.0f)); |
994 update(); |
995 update(); |
995 ev->accept(); |
996 ev->accept(); |
996 } |
997 } |
997 |
998 |
998 // ============================================================================= |
999 // ============================================================================= |
|
1000 // ----------------------------------------------------------------------------- |
999 void GLRenderer::leaveEvent (QEvent* ev) { |
1001 void GLRenderer::leaveEvent (QEvent* ev) { |
1000 (void) ev; |
1002 (void) ev; |
1001 m_drawToolTip = false; |
1003 m_drawToolTip = false; |
1002 m_toolTipTimer->stop(); |
1004 m_toolTipTimer->stop(); |
1003 update(); |
1005 update(); |
1004 } |
1006 } |
1005 |
1007 |
1006 // ============================================================================= |
1008 // ============================================================================= |
|
1009 // ----------------------------------------------------------------------------- |
1007 void GLRenderer::contextMenuEvent (QContextMenuEvent* ev) { |
1010 void GLRenderer::contextMenuEvent (QContextMenuEvent* ev) { |
1008 g_win->spawnContextMenu (ev->globalPos()); |
1011 g_win->spawnContextMenu (ev->globalPos()); |
1009 } |
1012 } |
1010 |
1013 |
1011 // ============================================================================= |
1014 // ============================================================================= |
|
1015 // ----------------------------------------------------------------------------- |
1012 void GLRenderer::setCamera (const GL::Camera cam) { |
1016 void GLRenderer::setCamera (const GL::Camera cam) { |
1013 m_camera = cam; |
1017 m_camera = cam; |
1014 gl_camera = (int) cam; |
1018 gl_camera = (int) cam; |
1015 g_win->updateEditModeActions(); |
1019 g_win->updateEditModeActions(); |
1016 } |
1020 } |
1017 |
1021 |
1018 // ============================================================================= |
1022 // ============================================================================= |
1019 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1023 // ----------------------------------------------------------------------------- |
1020 // ============================================================================= |
|
1021 void GLRenderer::pick (uint mouseX, uint mouseY) { |
1024 void GLRenderer::pick (uint mouseX, uint mouseY) { |
1022 GLint viewport[4]; |
1025 GLint viewport[4]; |
1023 makeCurrent(); |
1026 makeCurrent(); |
1024 |
1027 |
1025 // Use particularly thick lines while picking ease up selecting lines. |
1028 // Use particularly thick lines while picking ease up selecting lines. |
1147 setBackground(); |
1150 setBackground(); |
1148 repaint(); |
1151 repaint(); |
1149 } |
1152 } |
1150 |
1153 |
1151 // ============================================================================= |
1154 // ============================================================================= |
|
1155 // ----------------------------------------------------------------------------- |
1152 READ_ACCESSOR (EditMode, GLRenderer::editMode) { |
1156 READ_ACCESSOR (EditMode, GLRenderer::editMode) { |
1153 return m_editMode; |
1157 return m_editMode; |
1154 } |
1158 } |
1155 |
1159 |
|
1160 // ============================================================================= |
|
1161 // ----------------------------------------------------------------------------- |
1156 SET_ACCESSOR (EditMode, GLRenderer::setEditMode) { |
1162 SET_ACCESSOR (EditMode, GLRenderer::setEditMode) { |
1157 m_editMode = val; |
1163 m_editMode = val; |
1158 |
1164 |
1159 switch (editMode()) { |
1165 switch (editMode()) { |
1160 case Select: |
1166 case Select: |
1185 |
1191 |
1186 g_win->updateEditModeActions(); |
1192 g_win->updateEditModeActions(); |
1187 update(); |
1193 update(); |
1188 } |
1194 } |
1189 |
1195 |
|
1196 // ============================================================================= |
|
1197 // ----------------------------------------------------------------------------- |
1190 READ_ACCESSOR (LDFile*, GLRenderer::file) { |
1198 READ_ACCESSOR (LDFile*, GLRenderer::file) { |
1191 return m_file; |
1199 return m_file; |
1192 } |
1200 } |
1193 |
1201 |
|
1202 // ============================================================================= |
|
1203 // ----------------------------------------------------------------------------- |
1194 SET_ACCESSOR (LDFile*, GLRenderer::setFile) { |
1204 SET_ACCESSOR (LDFile*, GLRenderer::setFile) { |
1195 m_file = val; |
1205 m_file = val; |
1196 |
1206 |
1197 if (val != null) |
1207 if (val != null) |
1198 overlaysFromObjects(); |
1208 overlaysFromObjects(); |
1199 } |
1209 } |
1200 |
1210 |
1201 // ============================================================================= |
1211 // ============================================================================= |
|
1212 // ----------------------------------------------------------------------------- |
1202 void GLRenderer::endDraw (bool accept) { |
1213 void GLRenderer::endDraw (bool accept) { |
1203 (void) accept; |
1214 (void) accept; |
1204 |
1215 |
1205 // Clean the selection and create the object |
1216 // Clean the selection and create the object |
1206 List<vertex>& verts = m_drawedVerts; |
1217 List<vertex>& verts = m_drawedVerts; |
1255 |
1266 |
1256 m_drawedVerts.clear(); |
1267 m_drawedVerts.clear(); |
1257 m_rectdraw = false; |
1268 m_rectdraw = false; |
1258 } |
1269 } |
1259 |
1270 |
|
1271 // ============================================================================= |
|
1272 // ----------------------------------------------------------------------------- |
1260 static List<vertex> getVertices (LDObject* obj) { |
1273 static List<vertex> getVertices (LDObject* obj) { |
1261 List<vertex> verts; |
1274 List<vertex> verts; |
1262 |
1275 |
1263 if (obj->vertices() >= 2) { |
1276 if (obj->vertices() >= 2) { |
1264 for (int i = 0; i < obj->vertices(); ++i) |
1277 for (int i = 0; i < obj->vertices(); ++i) |
1274 |
1287 |
1275 return verts; |
1288 return verts; |
1276 } |
1289 } |
1277 |
1290 |
1278 // ============================================================================= |
1291 // ============================================================================= |
1279 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1292 // ----------------------------------------------------------------------------- |
1280 // ============================================================================= |
|
1281 void GLRenderer::compileObject (LDObject* obj) { |
1293 void GLRenderer::compileObject (LDObject* obj) { |
1282 deleteLists (obj); |
1294 deleteLists (obj); |
1283 |
1295 |
1284 for (const GL::ListType listType : g_glListTypes) { |
1296 for (const GL::ListType listType : g_glListTypes) { |
1285 if (drawOnly() && listType != GL::NormalList) |
1297 if (drawOnly() && listType != GL::NormalList) |
1301 |
1313 |
1302 obj->m_glinit = true; |
1314 obj->m_glinit = true; |
1303 } |
1315 } |
1304 |
1316 |
1305 // ============================================================================= |
1317 // ============================================================================= |
|
1318 // ----------------------------------------------------------------------------- |
1306 uchar* GLRenderer::screencap (ushort& w, ushort& h) { |
1319 uchar* GLRenderer::screencap (ushort& w, ushort& h) { |
1307 w = m_width; |
1320 w = m_width; |
1308 h = m_height; |
1321 h = m_height; |
1309 uchar* cap = new uchar[4 * w * h]; |
1322 uchar* cap = new uchar[4 * w * h]; |
1310 |
1323 |
1317 |
1330 |
1318 return cap; |
1331 return cap; |
1319 } |
1332 } |
1320 |
1333 |
1321 // ============================================================================= |
1334 // ============================================================================= |
|
1335 // ----------------------------------------------------------------------------- |
1322 void GLRenderer::slot_toolTipTimer() { |
1336 void GLRenderer::slot_toolTipTimer() { |
1323 // We come here if the cursor has stayed in one place for longer than a |
1337 // We come here if the cursor has stayed in one place for longer than a |
1324 // a second. Check if we're holding it over a camera icon - if so, draw |
1338 // a second. Check if we're holding it over a camera icon - if so, draw |
1325 // a tooltip. |
1339 // a tooltip. |
1326 for (CameraIcon& icon : m_cameraIcons) { |
1340 for (CameraIcon& icon : m_cameraIcons) { |
1344 |
1359 |
1345 obj->m_glinit = false; |
1360 obj->m_glinit = false; |
1346 } |
1361 } |
1347 |
1362 |
1348 // ============================================================================= |
1363 // ============================================================================= |
|
1364 // ----------------------------------------------------------------------------- |
1349 Axis GLRenderer::cameraAxis (bool y, GL::Camera camid) { |
1365 Axis GLRenderer::cameraAxis (bool y, GL::Camera camid) { |
1350 if (camid == (GL::Camera) -1) |
1366 if (camid == (GL::Camera) -1) |
1351 camid = m_camera; |
1367 camid = m_camera; |
1352 |
1368 |
1353 const staticCameraMeta* cam = &g_staticCameras[camid]; |
1369 const staticCameraMeta* cam = &g_staticCameras[camid]; |
1354 return (y) ? cam->axisY : cam->axisX; |
1370 return (y) ? cam->axisY : cam->axisX; |
1355 } |
1371 } |
1356 |
1372 |
1357 // ============================================================================= |
1373 // ============================================================================= |
|
1374 // ----------------------------------------------------------------------------- |
1358 bool GLRenderer::setupOverlay (GL::Camera cam, str file, int x, int y, int w, int h) { |
1375 bool GLRenderer::setupOverlay (GL::Camera cam, str file, int x, int y, int w, int h) { |
1359 QImage* img = new QImage (file); |
1376 QImage* img = new QImage (file); |
1360 overlayMeta& info = getOverlay (cam); |
1377 overlayMeta& info = getOverlay (cam); |
1361 |
1378 |
1362 if (img->isNull()) { |
1379 if (img->isNull()) { |
1379 elif (info.lh == 0) |
1396 elif (info.lh == 0) |
1380 info.lh = (info.lw * img->height()) / img->width(); |
1397 info.lh = (info.lw * img->height()) / img->width(); |
1381 |
1398 |
1382 const Axis x2d = cameraAxis (false, cam), |
1399 const Axis x2d = cameraAxis (false, cam), |
1383 y2d = cameraAxis (true, cam); |
1400 y2d = cameraAxis (true, cam); |
1384 |
1401 |
1385 double negXFac = g_staticCameras[cam].negX ? -1 : 1, |
1402 double negXFac = g_staticCameras[cam].negX ? -1 : 1, |
1386 negYFac = g_staticCameras[cam].negY ? -1 : 1; |
1403 negYFac = g_staticCameras[cam].negY ? -1 : 1; |
1387 |
1404 |
1388 info.v0 = info.v1 = g_origin; |
1405 info.v0 = info.v1 = g_origin; |
1389 info.v0[x2d] = - (info.ox * info.lw * negXFac) / img->width(); |
1406 info.v0[x2d] = - (info.ox * info.lw * negXFac) / img->width(); |
1390 info.v0[y2d] = (info.oy * info.lh * negYFac) / img->height(); |
1407 info.v0[y2d] = (info.oy * info.lh * negYFac) / img->height(); |
1391 info.v1[x2d] = info.v0[x2d] + info.lw; |
1408 info.v1[x2d] = info.v0[x2d] + info.lw; |
1392 info.v1[y2d] = info.v0[y2d] + info.lh; |
1409 info.v1[y2d] = info.v0[y2d] + info.lh; |
1393 |
1410 |
1394 // Set alpha of all pixels to 0.5 |
1411 // Set alpha of all pixels to 0.5 |
1395 for (long i = 0; i < img->width(); ++i) |
1412 for (long i = 0; i < img->width(); ++i) |
1396 for (long j = 0; j < img->height(); ++j) { |
1413 for (long j = 0; j < img->height(); ++j) { |
1397 uint32 pixel = img->pixel (i, j); |
1414 uint32 pixel = img->pixel (i, j); |
1398 img->setPixel (i, j, 0x80000000 | (pixel & 0x00FFFFFF)); |
1415 img->setPixel (i, j, 0x80000000 | (pixel & 0x00FFFFFF)); |
1399 } |
1416 } |
1400 |
1417 |
1401 updateOverlayObjects(); |
1418 updateOverlayObjects(); |
1402 return true; |
1419 return true; |
1403 } |
1420 } |
1404 |
1421 |
|
1422 // ============================================================================= |
|
1423 // ----------------------------------------------------------------------------- |
1405 void GLRenderer::clearOverlay() { |
1424 void GLRenderer::clearOverlay() { |
1406 if (camera() == Free) |
1425 if (camera() == Free) |
1407 return; |
1426 return; |
1408 |
1427 |
1409 overlayMeta& info = m_overlays[camera()]; |
1428 overlayMeta& info = m_overlays[camera()]; |
1411 info.img = null; |
1430 info.img = null; |
1412 |
1431 |
1413 updateOverlayObjects(); |
1432 updateOverlayObjects(); |
1414 } |
1433 } |
1415 |
1434 |
|
1435 // ============================================================================= |
|
1436 // ----------------------------------------------------------------------------- |
1416 void GLRenderer::setDepthValue (double depth) { |
1437 void GLRenderer::setDepthValue (double depth) { |
1417 assert (camera() < Free); |
1438 assert (camera() < Free); |
1418 m_depthValues[camera()] = depth; |
1439 m_depthValues[camera()] = depth; |
1419 } |
1440 } |
1420 |
1441 |
|
1442 // ============================================================================= |
|
1443 // ----------------------------------------------------------------------------- |
1421 double GLRenderer::depthValue() const { |
1444 double GLRenderer::depthValue() const { |
1422 assert (camera() < Free); |
1445 assert (camera() < Free); |
1423 return m_depthValues[camera()]; |
1446 return m_depthValues[camera()]; |
1424 } |
1447 } |
1425 |
1448 |
|
1449 // ============================================================================= |
|
1450 // ----------------------------------------------------------------------------- |
1426 const char* GLRenderer::cameraName() const { |
1451 const char* GLRenderer::cameraName() const { |
1427 return g_CameraNames[camera()]; |
1452 return g_CameraNames[camera()]; |
1428 } |
1453 } |
1429 |
1454 |
|
1455 // ============================================================================= |
|
1456 // ----------------------------------------------------------------------------- |
1430 overlayMeta& GLRenderer::getOverlay (int newcam) { |
1457 overlayMeta& GLRenderer::getOverlay (int newcam) { |
1431 return m_overlays[newcam]; |
1458 return m_overlays[newcam]; |
1432 } |
1459 } |
1433 |
1460 |
|
1461 // ============================================================================= |
|
1462 // ----------------------------------------------------------------------------- |
1434 void GLRenderer::zoomNotch (bool inward) { |
1463 void GLRenderer::zoomNotch (bool inward) { |
1435 if (zoom() > 15) |
1464 if (zoom() > 15) |
1436 setZoom (zoom() * (inward ? 0.833f : 1.2f)); |
1465 setZoom (zoom() * (inward ? 0.833f : 1.2f)); |
1437 else |
1466 else |
1438 setZoom (zoom() + (inward ? -1.2f : 1.2f)); |
1467 setZoom (zoom() + (inward ? -1.2f : 1.2f)); |
1439 } |
1468 } |
1440 |
1469 |
1441 // ============================================================================= |
1470 // ============================================================================= |
|
1471 // ----------------------------------------------------------------------------- |
1442 void GLRenderer::zoomToFit() { |
1472 void GLRenderer::zoomToFit() { |
1443 if (file() == null) { |
1473 if (file() == null) { |
1444 setZoom (30.0f); |
1474 setZoom (30.0f); |
1445 return; |
1475 return; |
1446 } |
1476 } |
1546 m_rectverts[2][ay] = v1[ay]; |
1577 m_rectverts[2][ay] = v1[ay]; |
1547 m_rectverts[3][ax] = v0[ax]; |
1578 m_rectverts[3][ax] = v0[ax]; |
1548 m_rectverts[3][ay] = v1[ay]; |
1579 m_rectverts[3][ay] = v1[ay]; |
1549 } |
1580 } |
1550 |
1581 |
|
1582 // ============================================================================= |
|
1583 // ----------------------------------------------------------------------------- |
1551 void GLRenderer::mouseDoubleClickEvent (QMouseEvent* ev) { |
1584 void GLRenderer::mouseDoubleClickEvent (QMouseEvent* ev) { |
1552 if (!(ev->buttons() & Qt::LeftButton) || editMode() != Select) |
1585 if (!(ev->buttons() & Qt::LeftButton) || editMode() != Select) |
1553 return; |
1586 return; |
1554 |
1587 |
1555 pick (ev->x(), ev->y()); |
1588 pick (ev->x(), ev->y()); |
1562 AddObjectDialog::staticDialog (obj->getType(), obj); |
1595 AddObjectDialog::staticDialog (obj->getType(), obj); |
1563 g_win->endAction(); |
1596 g_win->endAction(); |
1564 ev->accept(); |
1597 ev->accept(); |
1565 } |
1598 } |
1566 |
1599 |
|
1600 // ============================================================================= |
|
1601 // ----------------------------------------------------------------------------- |
1567 LDOverlayObject* GLRenderer::findOverlayObject (GLRenderer::Camera cam) { |
1602 LDOverlayObject* GLRenderer::findOverlayObject (GLRenderer::Camera cam) { |
1568 LDOverlayObject* ovlobj = null; |
1603 LDOverlayObject* ovlobj = null; |
1569 |
1604 |
1570 for (LDObject * obj : *file()) { |
1605 for (LDObject * obj : *file()) { |
1571 if (obj->getType() == LDObject::Overlay && static_cast<LDOverlayObject*> (obj)->camera() == cam) { |
1606 if (obj->getType() == LDObject::Overlay && static_cast<LDOverlayObject*> (obj)->camera() == cam) { |
1578 } |
1613 } |
1579 |
1614 |
1580 // ============================================================================= |
1615 // ============================================================================= |
1581 // ----------------------------------------------------------------------------- |
1616 // ----------------------------------------------------------------------------- |
1582 // Read in overlays from the current file and update overlay info accordingly. |
1617 // Read in overlays from the current file and update overlay info accordingly. |
1583 // ============================================================================= |
1618 // ----------------------------------------------------------------------------- |
1584 void GLRenderer::overlaysFromObjects() { |
1619 void GLRenderer::overlaysFromObjects() { |
1585 for (Camera cam : g_Cameras) { |
1620 for (Camera cam : g_Cameras) { |
1586 if (cam == Free) |
1621 if (cam == Free) |
1587 continue; |
1622 continue; |
1588 |
1623 |
1596 setupOverlay (cam, ovlobj->filename(), ovlobj->x(), ovlobj->y(), ovlobj->width(), ovlobj->height()); |
1631 setupOverlay (cam, ovlobj->filename(), ovlobj->x(), ovlobj->y(), ovlobj->width(), ovlobj->height()); |
1597 } |
1632 } |
1598 } |
1633 } |
1599 |
1634 |
1600 // ============================================================================= |
1635 // ============================================================================= |
|
1636 // ----------------------------------------------------------------------------- |
1601 void GLRenderer::updateOverlayObjects() { |
1637 void GLRenderer::updateOverlayObjects() { |
1602 for (Camera cam : g_Cameras) { |
1638 for (Camera cam : g_Cameras) { |
1603 if (cam == Free) |
1639 if (cam == Free) |
1604 continue; |
1640 continue; |
1605 |
1641 |