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 "moc_gldraw.cpp" |
39 #include "moc_gldraw.cpp" |
40 |
40 |
41 static const struct staticCameraMeta |
41 static const LDFixedCameraInfo g_FixedCameras[6] = |
42 { const char glrotate[3]; |
|
43 const Axis axisX, axisY; |
|
44 const bool negX, negY; |
|
45 } g_staticCameras[6] = |
|
46 { {{ 1, 0, 0 }, X, Z, false, false }, |
42 { {{ 1, 0, 0 }, X, Z, false, false }, |
47 {{ 0, 0, 0 }, X, Y, false, true }, |
43 {{ 0, 0, 0 }, X, Y, false, true }, |
48 {{ 0, 1, 0 }, Z, Y, true, true }, |
44 {{ 0, 1, 0 }, Z, Y, true, true }, |
49 {{ -1, 0, 0 }, X, Z, false, true }, |
45 {{ -1, 0, 0 }, X, Z, false, true }, |
50 {{ 0, 0, 0 }, X, Y, true, true }, |
46 {{ 0, 0, 0 }, X, Y, true, true }, |
87 GL::Back, |
83 GL::Back, |
88 GL::Right, |
84 GL::Right, |
89 GL::Free |
85 GL::Free |
90 }; |
86 }; |
91 |
87 |
92 const struct GLAxis |
88 const struct LDGLAxis |
93 { const QColor col; |
89 { const QColor col; |
94 const vertex vert; |
90 const vertex vert; |
95 } g_GLAxes[3] = |
91 } g_GLAxes[3] = |
96 { { QColor (255, 0, 0), vertex (10000, 0, 0) }, |
92 { { QColor (255, 0, 0), vertex (10000, 0, 0) }, |
97 { QColor (80, 192, 0), vertex (0, 10000, 0) }, |
93 { QColor (80, 192, 0), vertex (0, 10000, 0) }, |
98 { QColor (0, 160, 192), vertex (0, 0, 10000) }, |
94 { QColor (0, 160, 192), vertex (0, 0, 10000) }, |
99 }; |
95 }; |
100 |
96 |
101 static bool g_glInvert = false; |
97 static bool g_glInvert = false; |
102 static List<short> g_warnedColors; |
98 static List<short> g_warnedColors; |
122 m_thickBorderPen = QPen (QColor (0, 0, 0, 208), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); |
118 m_thickBorderPen = QPen (QColor (0, 0, 0, 208), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); |
123 m_thinBorderPen = m_thickBorderPen; |
119 m_thinBorderPen = m_thickBorderPen; |
124 m_thinBorderPen.setWidth (1); |
120 m_thinBorderPen.setWidth (1); |
125 |
121 |
126 // Init camera icons |
122 // Init camera icons |
127 for (const GL::Camera cam : g_Cameras) |
123 for (const GL::Camera cam : g_Cameras) |
128 { str iconname = fmt ("camera-%1", tr (g_CameraNames[cam]).toLower()); |
124 { str iconname = fmt ("camera-%1", tr (g_CameraNames[cam]).toLower()); |
129 |
125 |
130 CameraIcon* info = &m_cameraIcons[cam]; |
126 CameraIcon* info = &m_cameraIcons[cam]; |
131 info->img = new QPixmap (getIcon (iconname)); |
127 info->img = new QPixmap (getIcon (iconname)); |
132 info->cam = cam; |
128 info->cam = cam; |
144 // ----------------------------------------------------------------------------- |
140 // ----------------------------------------------------------------------------- |
145 GLRenderer::~GLRenderer() |
141 GLRenderer::~GLRenderer() |
146 { for (int i = 0; i < 6; ++i) |
142 { for (int i = 0; i < 6; ++i) |
147 delete m_overlays[i].img; |
143 delete m_overlays[i].img; |
148 |
144 |
149 for (CameraIcon & info : m_cameraIcons) |
145 for (CameraIcon& info : m_cameraIcons) |
150 delete info.img; |
146 delete info.img; |
151 } |
147 } |
152 |
148 |
153 // ============================================================================= |
149 // ============================================================================= |
|
150 // Calculates the "hitboxes" of the camera icons so that we can tell when the |
|
151 // cursor is pointing at the camera icon. |
154 // ----------------------------------------------------------------------------- |
152 // ----------------------------------------------------------------------------- |
155 void GLRenderer::calcCameraIcons() |
153 void GLRenderer::calcCameraIcons() |
156 { ushort i = 0; |
154 { int i = 0; |
157 |
155 |
158 for (CameraIcon & info : m_cameraIcons) |
156 for (CameraIcon& info : m_cameraIcons) |
159 { const long x1 = (m_width - (info.cam != Free ? 48 : 16)) + ( (i % 3) * 16) - 1, |
157 { // MATH |
160 y1 = ( (i / 3) * 16) + 1; |
158 const long x1 = (m_width - (info.cam != Free ? 48 : 16)) + ((i % 3) * 16) - 1, |
|
159 y1 = ((i / 3) * 16) + 1; |
161 |
160 |
162 info.srcRect = QRect (0, 0, 16, 16); |
161 info.srcRect = QRect (0, 0, 16, 16); |
163 info.destRect = QRect (x1, y1, 16, 16); |
162 info.destRect = QRect (x1, y1, 16, 16); |
164 info.selRect = QRect (info.destRect.x(), info.destRect.y(), |
163 info.selRect = QRect ( |
165 info.destRect.width() + 1, info.destRect.height() + 1); |
164 info.destRect.x(), |
|
165 info.destRect.y(), |
|
166 info.destRect.width() + 1, |
|
167 info.destRect.height() + 1 |
|
168 ); |
|
169 |
166 ++i; |
170 ++i; |
167 } |
171 } |
168 } |
172 } |
169 |
173 |
170 // ============================================================================= |
174 // ============================================================================= |
291 // not appear pitch-black. |
295 // not appear pitch-black. |
292 if (obj->color() != edgecolor) |
296 if (obj->color() != edgecolor) |
293 qcol = getMainColor(); |
297 qcol = getMainColor(); |
294 |
298 |
295 // Warn about the unknown colors, but only once. |
299 // Warn about the unknown colors, but only once. |
296 for (short i : g_warnedColors) |
300 for (short i : g_warnedColors) |
297 if (obj->color() == i) |
301 if (obj->color() == i) |
298 return; |
302 return; |
299 |
303 |
300 printf ("%s: Unknown color %d!\n", __func__, obj->color()); |
304 print ("%1: Unknown color %2!\n", __func__, obj->color()); |
301 g_warnedColors << obj->color(); |
305 g_warnedColors << obj->color(); |
302 return; |
306 return; |
303 } |
307 } |
304 } |
308 } |
305 |
309 |
316 g = min (g + add, 255l); |
320 g = min (g + add, 255l); |
317 b = min (b + add, 255l); |
321 b = min (b + add, 255l); |
318 } |
322 } |
319 |
323 |
320 glColor4f ( |
324 glColor4f ( |
321 ( (double) r) / 255.0f, |
325 ((double) r) / 255.0f, |
322 ( (double) g) / 255.0f, |
326 ((double) g) / 255.0f, |
323 ( (double) b) / 255.0f, |
327 ((double) b) / 255.0f, |
324 ( (double) a) / 255.0f); |
328 ((double) a) / 255.0f); |
325 } |
329 } |
326 |
330 |
327 // ============================================================================= |
331 // ============================================================================= |
328 // ----------------------------------------------------------------------------- |
332 // ----------------------------------------------------------------------------- |
329 void GLRenderer::refresh() |
333 void GLRenderer::refresh() |
374 glLoadIdentity(); |
378 glLoadIdentity(); |
375 glOrtho (-m_virtWidth, m_virtWidth, -m_virtHeight, m_virtHeight, -100.0f, 100.0f); |
379 glOrtho (-m_virtWidth, m_virtWidth, -m_virtHeight, m_virtHeight, -100.0f, 100.0f); |
376 glTranslatef (m_panX, m_panY, 0.0f); |
380 glTranslatef (m_panX, m_panY, 0.0f); |
377 |
381 |
378 if (m_camera != Front && m_camera != Back) |
382 if (m_camera != Front && m_camera != Back) |
379 { glRotatef (90.0f, g_staticCameras[m_camera].glrotate[0], |
383 { glRotatef (90.0f, g_FixedCameras[m_camera].glrotate[0], |
380 g_staticCameras[m_camera].glrotate[1], |
384 g_FixedCameras[m_camera].glrotate[1], |
381 g_staticCameras[m_camera].glrotate[2]); |
385 g_FixedCameras[m_camera].glrotate[2]); |
382 } |
386 } |
383 |
387 |
384 // Back camera needs to be handled differently |
388 // Back camera needs to be handled differently |
385 if (m_camera == GLRenderer::Back) |
389 if (m_camera == GLRenderer::Back) |
386 { glRotatef (180.0f, 1.0f, 0.0f, 0.0f); |
390 { glRotatef (180.0f, 1.0f, 0.0f, 0.0f); |
402 const GL::ListType list = (!drawOnly() && m_picking) ? PickList : NormalList; |
406 const GL::ListType list = (!drawOnly() && m_picking) ? PickList : NormalList; |
403 |
407 |
404 if (gl_colorbfc && !m_picking && !drawOnly()) |
408 if (gl_colorbfc && !m_picking && !drawOnly()) |
405 { glEnable (GL_CULL_FACE); |
409 { glEnable (GL_CULL_FACE); |
406 |
410 |
407 for (LDObject * obj : file()->objects()) |
411 for (LDObject* obj : file()->objects()) |
408 { if (obj->hidden()) |
412 { if (obj->hidden()) |
409 continue; |
413 continue; |
410 |
414 |
411 glCullFace (GL_BACK); |
415 glCullFace (GL_BACK); |
412 glCallList (obj->glLists[BFCFrontList]); |
416 glCallList (obj->glLists[BFCFrontList]); |
441 // ----------------------------------------------------------------------------- |
445 // ----------------------------------------------------------------------------- |
442 vertex GLRenderer::coordconv2_3 (const QPoint& pos2d, bool snap) const |
446 vertex GLRenderer::coordconv2_3 (const QPoint& pos2d, bool snap) const |
443 { assert (camera() != Free); |
447 { assert (camera() != Free); |
444 |
448 |
445 vertex pos3d; |
449 vertex pos3d; |
446 const staticCameraMeta* cam = &g_staticCameras[m_camera]; |
450 const LDFixedCameraInfo* cam = &g_FixedCameras[m_camera]; |
447 const Axis axisX = cam->axisX; |
451 const Axis axisX = cam->axisX; |
448 const Axis axisY = cam->axisY; |
452 const Axis axisY = cam->axisY; |
449 const short negXFac = cam->negX ? -1 : 1, |
453 const short negXFac = cam->negX ? -1 : 1, |
450 negYFac = cam->negY ? -1 : 1; |
454 negYFac = cam->negY ? -1 : 1; |
451 |
455 |
474 // Inverse operation for the above - convert a 3D position to a 2D screen |
478 // Inverse operation for the above - convert a 3D position to a 2D screen |
475 // position |
479 // position |
476 // ----------------------------------------------------------------------------- |
480 // ----------------------------------------------------------------------------- |
477 QPoint GLRenderer::coordconv3_2 (const vertex& pos3d) const |
481 QPoint GLRenderer::coordconv3_2 (const vertex& pos3d) const |
478 { GLfloat m[16]; |
482 { GLfloat m[16]; |
479 const staticCameraMeta* cam = &g_staticCameras[m_camera]; |
483 const LDFixedCameraInfo* cam = &g_FixedCameras[m_camera]; |
480 const Axis axisX = cam->axisX; |
484 const Axis axisX = cam->axisX; |
481 const Axis axisY = cam->axisY; |
485 const Axis axisY = cam->axisY; |
482 const short negXFac = cam->negX ? -1 : 1, |
486 const short negXFac = cam->negX ? -1 : 1, |
483 negYFac = cam->negY ? -1 : 1; |
487 negYFac = cam->negY ? -1 : 1; |
484 |
488 |
520 if (drawOnly()) |
524 if (drawOnly()) |
521 return; |
525 return; |
522 |
526 |
523 if (m_camera != Free && !picking()) |
527 if (m_camera != Free && !picking()) |
524 { // Paint the overlay image if we have one |
528 { // Paint the overlay image if we have one |
525 const overlayMeta& overlay = m_overlays[m_camera]; |
529 const LDGLOverlay& overlay = m_overlays[m_camera]; |
526 |
530 |
527 if (overlay.img != null) |
531 if (overlay.img != null) |
528 { QPoint v0 = coordconv3_2 (m_overlays[m_camera].v0), |
532 { QPoint v0 = coordconv3_2 (m_overlays[m_camera].v0), |
529 v1 = coordconv3_2 (m_overlays[m_camera].v1); |
533 v1 = coordconv3_2 (m_overlays[m_camera].v1); |
530 |
534 |
750 glDeleteLists (m_axeslist, 1); |
754 glDeleteLists (m_axeslist, 1); |
751 m_axeslist = glGenLists (1); |
755 m_axeslist = glGenLists (1); |
752 glNewList (m_axeslist, GL_COMPILE); |
756 glNewList (m_axeslist, GL_COMPILE); |
753 glBegin (GL_LINES); |
757 glBegin (GL_LINES); |
754 |
758 |
755 for (const GLAxis & ax : g_GLAxes) |
759 for (const LDGLAxis & ax : g_GLAxes) |
756 { qglColor (ax.col); |
760 { qglColor (ax.col); |
757 compileVertex (ax.vert); |
761 compileVertex (ax.vert); |
758 compileVertex (-ax.vert); |
762 compileVertex (-ax.vert); |
759 } |
763 } |
760 |
764 |
1398 } |
1402 } |
1399 |
1403 |
1400 // ============================================================================= |
1404 // ============================================================================= |
1401 // ----------------------------------------------------------------------------- |
1405 // ----------------------------------------------------------------------------- |
1402 void GLRenderer::getRelativeAxes (Axis& relX, Axis& relY) const |
1406 void GLRenderer::getRelativeAxes (Axis& relX, Axis& relY) const |
1403 { const staticCameraMeta* cam = &g_staticCameras[m_camera]; |
1407 { const LDFixedCameraInfo* cam = &g_FixedCameras[m_camera]; |
1404 relX = cam->axisX; |
1408 relX = cam->axisX; |
1405 relY = cam->axisY; |
1409 relY = cam->axisY; |
1406 } |
1410 } |
1407 |
1411 |
1408 // ============================================================================= |
1412 // ============================================================================= |
1503 // ----------------------------------------------------------------------------- |
1507 // ----------------------------------------------------------------------------- |
1504 Axis GLRenderer::cameraAxis (bool y, GL::Camera camid) |
1508 Axis GLRenderer::cameraAxis (bool y, GL::Camera camid) |
1505 { if (camid == (GL::Camera) - 1) |
1509 { if (camid == (GL::Camera) - 1) |
1506 camid = m_camera; |
1510 camid = m_camera; |
1507 |
1511 |
1508 const staticCameraMeta* cam = &g_staticCameras[camid]; |
1512 const LDFixedCameraInfo* cam = &g_FixedCameras[camid]; |
1509 return (y) ? cam->axisY : cam->axisX; |
1513 return (y) ? cam->axisY : cam->axisX; |
1510 } |
1514 } |
1511 |
1515 |
1512 // ============================================================================= |
1516 // ============================================================================= |
1513 // ----------------------------------------------------------------------------- |
1517 // ----------------------------------------------------------------------------- |
1514 bool GLRenderer::setupOverlay (GL::Camera cam, str file, int x, int y, int w, int h) |
1518 bool GLRenderer::setupOverlay (GL::Camera cam, str file, int x, int y, int w, int h) |
1515 { QImage* img = new QImage (file); |
1519 { QImage* img = new QImage (file); |
1516 overlayMeta& info = getOverlay (cam); |
1520 LDGLOverlay& info = getOverlay (cam); |
1517 |
1521 |
1518 if (img->isNull()) |
1522 if (img->isNull()) |
1519 { critical (tr ("Failed to load overlay image!")); |
1523 { critical (tr ("Failed to load overlay image!")); |
1520 delete img; |
1524 delete img; |
1521 return false; |
1525 return false; |
1537 info.lh = (info.lw * img->height()) / img->width(); |
1541 info.lh = (info.lw * img->height()) / img->width(); |
1538 |
1542 |
1539 const Axis x2d = cameraAxis (false, cam), |
1543 const Axis x2d = cameraAxis (false, cam), |
1540 y2d = cameraAxis (true, cam); |
1544 y2d = cameraAxis (true, cam); |
1541 |
1545 |
1542 double negXFac = g_staticCameras[cam].negX ? -1 : 1, |
1546 double negXFac = g_FixedCameras[cam].negX ? -1 : 1, |
1543 negYFac = g_staticCameras[cam].negY ? -1 : 1; |
1547 negYFac = g_FixedCameras[cam].negY ? -1 : 1; |
1544 |
1548 |
1545 info.v0 = info.v1 = g_origin; |
1549 info.v0 = info.v1 = g_origin; |
1546 info.v0[x2d] = - (info.ox * info.lw * negXFac) / img->width(); |
1550 info.v0[x2d] = - (info.ox * info.lw * negXFac) / img->width(); |
1547 info.v0[y2d] = (info.oy * info.lh * negYFac) / img->height(); |
1551 info.v0[y2d] = (info.oy * info.lh * negYFac) / img->height(); |
1548 info.v1[x2d] = info.v0[x2d] + info.lw; |
1552 info.v1[x2d] = info.v0[x2d] + info.lw; |
1592 { return g_CameraNames[camera()]; |
1596 { return g_CameraNames[camera()]; |
1593 } |
1597 } |
1594 |
1598 |
1595 // ============================================================================= |
1599 // ============================================================================= |
1596 // ----------------------------------------------------------------------------- |
1600 // ----------------------------------------------------------------------------- |
1597 overlayMeta& GLRenderer::getOverlay (int newcam) |
1601 LDGLOverlay& GLRenderer::getOverlay (int newcam) |
1598 { return m_overlays[newcam]; |
1602 { return m_overlays[newcam]; |
1599 } |
1603 } |
1600 |
1604 |
1601 // ============================================================================= |
1605 // ============================================================================= |
1602 // ----------------------------------------------------------------------------- |
1606 // ----------------------------------------------------------------------------- |
1617 |
1621 |
1618 bool lastfilled = false; |
1622 bool lastfilled = false; |
1619 bool firstrun = true; |
1623 bool firstrun = true; |
1620 const uint32 white = 0xFFFFFFFF; |
1624 const uint32 white = 0xFFFFFFFF; |
1621 bool inward = true; |
1625 bool inward = true; |
1622 ulong run = 0; |
1626 int run = 0; |
1623 const ushort w = m_width, h = m_height; |
1627 const int w = m_width, h = m_height; |
1624 |
1628 |
1625 glClearColor (1.0, 1.0, 1.0, 1.0); |
1629 glClearColor (1.0, 1.0, 1.0, 1.0); |
1626 glDisable (GL_DITHER); |
1630 glDisable (GL_DITHER); |
1627 |
1631 |
1628 // Use the pick list while drawing the scene, this way we can tell whether borders |
1632 // Use the pick list while drawing the scene, this way we can tell whether borders |
1779 void GLRenderer::updateOverlayObjects() |
1783 void GLRenderer::updateOverlayObjects() |
1780 { for (Camera cam : g_Cameras) |
1784 { for (Camera cam : g_Cameras) |
1781 { if (cam == Free) |
1785 { if (cam == Free) |
1782 continue; |
1786 continue; |
1783 |
1787 |
1784 overlayMeta& meta = m_overlays[cam]; |
1788 LDGLOverlay& meta = m_overlays[cam]; |
1785 LDOverlay* ovlobj = findOverlayObject (cam); |
1789 LDOverlay* ovlobj = findOverlayObject (cam); |
1786 |
1790 |
1787 if (!meta.img && ovlobj) |
1791 if (!meta.img && ovlobj) |
1788 { // If this is the last overlay image, we need to remove the empty space after it as well. |
1792 { // If this is the last overlay image, we need to remove the empty space after it as well. |
1789 LDObject* nextobj = ovlobj->next(); |
1793 LDObject* nextobj = ovlobj->next(); |