src/gldraw.cpp

changeset 538
2f85d4d286e5
parent 534
3ed2ebcbc84f
child 539
72ad83a67165
equal deleted inserted replaced
537:1add0ee96fb3 538:2f85d4d286e5
95 { QColor (80, 192, 0), vertex (0, 10000, 0) }, 95 { QColor (80, 192, 0), vertex (0, 10000, 0) },
96 { QColor (0, 160, 192), vertex (0, 0, 10000) }, 96 { QColor (0, 160, 192), vertex (0, 0, 10000) },
97 }; 97 };
98 98
99 static bool g_glInvert = false; 99 static bool g_glInvert = false;
100 static QList<short> g_warnedColors; 100 static QList<int> g_warnedColors;
101 101
102 // ============================================================================= 102 // =============================================================================
103 // ----------------------------------------------------------------------------- 103 // -----------------------------------------------------------------------------
104 GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent) 104 GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent)
105 { m_picking = m_rangepick = false; 105 { m_picking = m_rangepick = false;
318 // not appear pitch-black. 318 // not appear pitch-black.
319 if (obj->color() != edgecolor) 319 if (obj->color() != edgecolor)
320 qcol = getMainColor(); 320 qcol = getMainColor();
321 321
322 // Warn about the unknown colors, but only once. 322 // Warn about the unknown colors, but only once.
323 for (short i : g_warnedColors) 323 for (int i : g_warnedColors)
324 if (obj->color() == i) 324 if (obj->color() == i)
325 return; 325 return;
326 326
327 log ("%1: Unknown color %2!\n", __func__, obj->color()); 327 log ("%1: Unknown color %2!\n", __func__, obj->color());
328 g_warnedColors << obj->color(); 328 g_warnedColors << obj->color();
471 471
472 vertex pos3d; 472 vertex pos3d;
473 const LDFixedCameraInfo* cam = &g_FixedCameras[m_camera]; 473 const LDFixedCameraInfo* cam = &g_FixedCameras[m_camera];
474 const Axis axisX = cam->axisX; 474 const Axis axisX = cam->axisX;
475 const Axis axisY = cam->axisY; 475 const Axis axisY = cam->axisY;
476 const short negXFac = cam->negX ? -1 : 1, 476 const int negXFac = cam->negX ? -1 : 1,
477 negYFac = cam->negY ? -1 : 1; 477 negYFac = cam->negY ? -1 : 1;
478 478
479 // Calculate cx and cy - these are the LDraw unit coords the cursor is at. 479 // Calculate cx and cy - these are the LDraw unit coords the cursor is at.
480 double cx = (-m_virtWidth + ((2 * pos2d.x() * m_virtWidth) / m_width) - pan (X)); 480 double cx = (-m_virtWidth + ((2 * pos2d.x() * m_virtWidth) / m_width) - pan (X));
481 double cy = (m_virtHeight - ((2 * pos2d.y() * m_virtHeight) / m_height) - pan (Y)); 481 double cy = (m_virtHeight - ((2 * pos2d.y() * m_virtHeight) / m_height) - pan (Y));
490 490
491 str tmp; 491 str tmp;
492 // Create the vertex from the coordinates 492 // Create the vertex from the coordinates
493 pos3d[axisX] = tmp.sprintf ("%.3f", cx).toDouble(); 493 pos3d[axisX] = tmp.sprintf ("%.3f", cx).toDouble();
494 pos3d[axisY] = tmp.sprintf ("%.3f", cy).toDouble(); 494 pos3d[axisY] = tmp.sprintf ("%.3f", cy).toDouble();
495 pos3d[3 - axisX - axisY] = depthValue(); 495 pos3d[3 - axisX - axisY] = getDepthValue();
496 return pos3d; 496 return pos3d;
497 } 497 }
498 498
499 // ============================================================================= 499 // =============================================================================
500 // ----------------------------------------------------------------------------- 500 // -----------------------------------------------------------------------------
504 QPoint GLRenderer::coordconv3_2 (const vertex& pos3d) const 504 QPoint GLRenderer::coordconv3_2 (const vertex& pos3d) const
505 { GLfloat m[16]; 505 { GLfloat m[16];
506 const LDFixedCameraInfo* cam = &g_FixedCameras[m_camera]; 506 const LDFixedCameraInfo* cam = &g_FixedCameras[m_camera];
507 const Axis axisX = cam->axisX; 507 const Axis axisX = cam->axisX;
508 const Axis axisY = cam->axisY; 508 const Axis axisY = cam->axisY;
509 const short negXFac = cam->negX ? -1 : 1, 509 const int negXFac = cam->negX ? -1 : 1,
510 negYFac = cam->negY ? -1 : 1; 510 negYFac = cam->negY ? -1 : 1;
511 511
512 glGetFloatv (GL_MODELVIEW_MATRIX, m); 512 glGetFloatv (GL_MODELVIEW_MATRIX, m);
513 513
514 const double x = pos3d.x(); 514 const double x = pos3d.x();
637 { // If we have not specified the center point of the circle yet, preview it on the screen. 637 { // If we have not specified the center point of the circle yet, preview it on the screen.
638 if (m_drawedVerts.isEmpty()) 638 if (m_drawedVerts.isEmpty())
639 drawBlip (paint, coordconv3_2 (m_hoverpos)); 639 drawBlip (paint, coordconv3_2 (m_hoverpos));
640 else 640 else
641 { QVector<vertex> verts, verts2; 641 { QVector<vertex> verts, verts2;
642 const double dist0 = circleDrawDist (0), 642 const double dist0 = getCircleDrawDist (0),
643 dist1 = (m_drawedVerts.size() >= 2) ? circleDrawDist (1) : -1; 643 dist1 = (m_drawedVerts.size() >= 2) ? getCircleDrawDist (1) : -1;
644 const int segs = lores; 644 const int segs = lores;
645 const double angleUnit = (2 * pi) / segs; 645 const double angleUnit = (2 * pi) / segs;
646 Axis relX, relY; 646 Axis relX, relY;
647 QVector<QPoint> ringpoints, circlepoints, circle2points; 647 QVector<QPoint> ringpoints, circlepoints, circle2points;
648 648
893 LDSubfile::DeepInline | 893 LDSubfile::DeepInline |
894 LDSubfile::CacheInline | 894 LDSubfile::CacheInline |
895 LDSubfile::RendererInline); 895 LDSubfile::RendererInline);
896 bool oldinvert = g_glInvert; 896 bool oldinvert = g_glInvert;
897 897
898 if (ref->transform().determinant() < 0) 898 if (ref->transform().getDeterminant() < 0)
899 g_glInvert = !g_glInvert; 899 g_glInvert = !g_glInvert;
900 900
901 LDObject* prev = ref->prev(); 901 LDObject* prev = ref->prev();
902 902
903 if (prev && prev->getType() == LDObject::BFC && static_cast<LDBFC*> (prev)->type == LDBFC::InvertNext) 903 if (prev && prev->getType() == LDObject::BFC && static_cast<LDBFC*> (prev)->type == LDBFC::InvertNext)
1198 1198
1199 drawGLScene(); 1199 drawGLScene();
1200 1200
1201 glGetIntegerv (GL_VIEWPORT, viewport); 1201 glGetIntegerv (GL_VIEWPORT, viewport);
1202 1202
1203 short x0 = mouseX, 1203 int x0 = mouseX,
1204 y0 = mouseY; 1204 y0 = mouseY;
1205 short x1, y1; 1205 int x1, y1;
1206 1206
1207 // Determine how big an area to read - with range picking, we pick by 1207 // Determine how big an area to read - with range picking, we pick by
1208 // the area given, with single pixel picking, we use an 1 x 1 area. 1208 // the area given, with single pixel picking, we use an 1 x 1 area.
1209 if (m_rangepick) 1209 if (m_rangepick)
1210 { x1 = m_rangeStart.x(); 1210 { x1 = m_rangeStart.x();
1221 1221
1222 if (y0 > y1) 1222 if (y0 > y1)
1223 dataswap (y0, y1); 1223 dataswap (y0, y1);
1224 1224
1225 // Clamp the values to ensure they're within bounds 1225 // Clamp the values to ensure they're within bounds
1226 x0 = max<short> (0, x0); 1226 x0 = max (0, x0);
1227 y0 = max<short> (0, y0); 1227 y0 = max (0, y0);
1228 x1 = min<short> (x1, m_width); 1228 x1 = min (x1, m_width);
1229 y1 = min<short> (y1, m_height); 1229 y1 = min (y1, m_height);
1230 1230
1231 const short areawidth = (x1 - x0); 1231 const int areawidth = (x1 - x0);
1232 const short areaheight = (y1 - y0); 1232 const int areaheight = (y1 - y0);
1233 const long numpixels = areawidth * areaheight; 1233 const qint32 numpixels = areawidth * areaheight;
1234 1234
1235 // Allocate space for the pixel data. 1235 // Allocate space for the pixel data.
1236 uchar* const pixeldata = new uchar[4 * numpixels]; 1236 uchar* const pixeldata = new uchar[4 * numpixels];
1237 uchar* pixelptr = &pixeldata[0]; 1237 uchar* pixelptr = &pixeldata[0];
1238 1238
1242 glReadPixels (x0, viewport[3] - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixeldata); 1242 glReadPixels (x0, viewport[3] - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixeldata);
1243 1243
1244 LDObject* removedObj = null; 1244 LDObject* removedObj = null;
1245 1245
1246 // Go through each pixel read and add them to the selection. 1246 // Go through each pixel read and add them to the selection.
1247 for (long i = 0; i < numpixels; ++i) 1247 for (qint32 i = 0; i < numpixels; ++i)
1248 { long idx = 1248 { qint32 idx =
1249 (* (pixelptr + 0) * 0x10000) + 1249 (*(pixelptr + 0) * 0x10000) +
1250 (* (pixelptr + 1) * 0x00100) + 1250 (*(pixelptr + 1) * 0x00100) +
1251 (* (pixelptr + 2) * 0x00001); 1251 (*(pixelptr + 2) * 0x00001);
1252 pixelptr += 4; 1252 pixelptr += 4;
1253 1253
1254 if (idx == 0xFFFFFF) 1254 if (idx == 0xFFFFFF)
1255 continue; // White is background; skip 1255 continue; // White is background; skip
1256 1256
1348 // ----------------------------------------------------------------------------- 1348 // -----------------------------------------------------------------------------
1349 SET_ACCESSOR (LDFile*, GLRenderer::setFile) 1349 SET_ACCESSOR (LDFile*, GLRenderer::setFile)
1350 { m_file = val; 1350 { m_file = val;
1351 1351
1352 if (val != null) 1352 if (val != null)
1353 overlaysFromObjects(); 1353 initOverlaysFromObjects();
1354 } 1354 }
1355 1355
1356 // ============================================================================= 1356 // =============================================================================
1357 // ----------------------------------------------------------------------------- 1357 // -----------------------------------------------------------------------------
1358 matrix GLRenderer::getCircleDrawMatrix (double scale) 1358 matrix GLRenderer::getCircleDrawMatrix (double scale)
1425 } 1425 }
1426 } break; 1426 } break;
1427 1427
1428 case CircleMode: 1428 case CircleMode:
1429 { const int segs = lores, divs = lores; // TODO: make customizable 1429 { const int segs = lores, divs = lores; // TODO: make customizable
1430 double dist0 = circleDrawDist (0), 1430 double dist0 = getCircleDrawDist (0),
1431 dist1 = circleDrawDist (1); 1431 dist1 = getCircleDrawDist (1);
1432 LDFile* refFile = null; 1432 LDFile* refFile = null;
1433 matrix transform; 1433 matrix transform;
1434 bool circleOrDisc = false; 1434 bool circleOrDisc = false;
1435 1435
1436 if (dist1 < dist0) 1436 if (dist1 < dist0)
1448 transform = getCircleDrawMatrix ((dist0 != 0) ? dist0 : dist1); 1448 transform = getCircleDrawMatrix ((dist0 != 0) ? dist0 : dist1);
1449 circleOrDisc = true; 1449 circleOrDisc = true;
1450 } 1450 }
1451 elif (g_RingFinder (dist0, dist1)) 1451 elif (g_RingFinder (dist0, dist1))
1452 { // The ring finder found a solution, use that. Add the component rings to the file. 1452 { // The ring finder found a solution, use that. Add the component rings to the file.
1453 for (const RingFinder::Component& cmp : g_RingFinder.bestSolution()->components()) 1453 for (const RingFinder::Component& cmp : g_RingFinder.bestSolution()->getComponents())
1454 { if ((refFile = getFile (radialFileName (::Ring, lores, lores, cmp.num))) == null) 1454 { if ((refFile = getFile (radialFileName (::Ring, lores, lores, cmp.num))) == null)
1455 { refFile = generatePrimitive (::Ring, lores, lores, cmp.num); 1455 { refFile = generatePrimitive (::Ring, lores, lores, cmp.num);
1456 refFile->setImplicit (false); 1456 refFile->setImplicit (false);
1457 } 1457 }
1458 1458
1474 y0 = m_drawedVerts[0][relY]; 1474 y0 = m_drawedVerts[0][relY];
1475 1475
1476 vertex templ; 1476 vertex templ;
1477 templ[relX] = x0; 1477 templ[relX] = x0;
1478 templ[relY] = y0; 1478 templ[relY] = y0;
1479 templ[relZ] = depthValue(); 1479 templ[relZ] = getDepthValue();
1480 1480
1481 // Calculate circle coords 1481 // Calculate circle coords
1482 makeCircle (segs, divs, dist0, c0); 1482 makeCircle (segs, divs, dist0, c0);
1483 makeCircle (segs, divs, dist1, c1); 1483 makeCircle (segs, divs, dist1, c1);
1484 1484
1537 m_rectdraw = false; 1537 m_rectdraw = false;
1538 } 1538 }
1539 1539
1540 // ============================================================================= 1540 // =============================================================================
1541 // ----------------------------------------------------------------------------- 1541 // -----------------------------------------------------------------------------
1542 double GLRenderer::circleDrawDist (int pos) const 1542 double GLRenderer::getCircleDrawDist (int pos) const
1543 { assert (m_drawedVerts.size() >= pos + 1); 1543 { assert (m_drawedVerts.size() >= pos + 1);
1544 const vertex& v1 = (m_drawedVerts.size() >= pos + 2) ? m_drawedVerts[pos + 1] : m_hoverpos; 1544 const vertex& v1 = (m_drawedVerts.size() >= pos + 2) ? m_drawedVerts[pos + 1] : m_hoverpos;
1545 Axis relX, relY; 1545 Axis relX, relY;
1546 getRelativeAxes (relX, relY); 1546 getRelativeAxes (relX, relY);
1547 1547
1605 obj->m_glinit = true; 1605 obj->m_glinit = true;
1606 } 1606 }
1607 1607
1608 // ============================================================================= 1608 // =============================================================================
1609 // ----------------------------------------------------------------------------- 1609 // -----------------------------------------------------------------------------
1610 uchar* GLRenderer::screencap (int& w, int& h) 1610 uchar* GLRenderer::getScreencap (int& w, int& h)
1611 { w = m_width; 1611 { w = m_width;
1612 h = m_height; 1612 h = m_height;
1613 uchar* cap = new uchar[4 * w * h]; 1613 uchar* cap = new uchar[4 * w * h];
1614 1614
1615 m_screencap = true; 1615 m_screencap = true;
1651 obj->m_glinit = false; 1651 obj->m_glinit = false;
1652 } 1652 }
1653 1653
1654 // ============================================================================= 1654 // =============================================================================
1655 // ----------------------------------------------------------------------------- 1655 // -----------------------------------------------------------------------------
1656 Axis GLRenderer::cameraAxis (bool y, GL::Camera camid) 1656 Axis GLRenderer::getCameraAxis (bool y, GL::Camera camid)
1657 { if (camid == (GL::Camera) - 1) 1657 { if (camid == (GL::Camera) - 1)
1658 camid = m_camera; 1658 camid = m_camera;
1659 1659
1660 const LDFixedCameraInfo* cam = &g_FixedCameras[camid]; 1660 const LDFixedCameraInfo* cam = &g_FixedCameras[camid];
1661 return (y) ? cam->axisY : cam->axisX; 1661 return (y) ? cam->axisY : cam->axisX;
1685 if (info.lw == 0) 1685 if (info.lw == 0)
1686 info.lw = (info.lh * img->width()) / img->height(); 1686 info.lw = (info.lh * img->width()) / img->height();
1687 elif (info.lh == 0) 1687 elif (info.lh == 0)
1688 info.lh = (info.lw * img->height()) / img->width(); 1688 info.lh = (info.lw * img->height()) / img->width();
1689 1689
1690 const Axis x2d = cameraAxis (false, cam), 1690 const Axis x2d = getCameraAxis (false, cam),
1691 y2d = cameraAxis (true, cam); 1691 y2d = getCameraAxis (true, cam);
1692 const double negXFac = g_FixedCameras[cam].negX ? -1 : 1, 1692 const double negXFac = g_FixedCameras[cam].negX ? -1 : 1,
1693 negYFac = g_FixedCameras[cam].negY ? -1 : 1; 1693 negYFac = g_FixedCameras[cam].negY ? -1 : 1;
1694 1694
1695 info.v0 = info.v1 = g_origin; 1695 info.v0 = info.v1 = g_origin;
1696 info.v0[x2d] = - (info.ox * info.lw * negXFac) / img->width(); 1696 info.v0[x2d] = - (info.ox * info.lw * negXFac) / img->width();
1729 m_depthValues[camera()] = depth; 1729 m_depthValues[camera()] = depth;
1730 } 1730 }
1731 1731
1732 // ============================================================================= 1732 // =============================================================================
1733 // ----------------------------------------------------------------------------- 1733 // -----------------------------------------------------------------------------
1734 double GLRenderer::depthValue() const 1734 double GLRenderer::getDepthValue() const
1735 { assert (camera() < Free); 1735 { assert (camera() < Free);
1736 return m_depthValues[camera()]; 1736 return m_depthValues[camera()];
1737 } 1737 }
1738 1738
1739 // ============================================================================= 1739 // =============================================================================
1740 // ----------------------------------------------------------------------------- 1740 // -----------------------------------------------------------------------------
1741 const char* GLRenderer::cameraName() const 1741 const char* GLRenderer::getCameraName() const
1742 { return g_CameraNames[camera()]; 1742 { return g_CameraNames[camera()];
1743 } 1743 }
1744 1744
1745 // ============================================================================= 1745 // =============================================================================
1746 // ----------------------------------------------------------------------------- 1746 // -----------------------------------------------------------------------------
1863 } 1863 }
1864 1864
1865 vertex v0 = m_drawedVerts[0], 1865 vertex v0 = m_drawedVerts[0],
1866 v1 = (m_drawedVerts.size() >= 2) ? m_drawedVerts[1] : m_hoverpos; 1866 v1 = (m_drawedVerts.size() >= 2) ? m_drawedVerts[1] : m_hoverpos;
1867 1867
1868 const Axis ax = cameraAxis (false), 1868 const Axis ax = getCameraAxis (false),
1869 ay = cameraAxis (true), 1869 ay = getCameraAxis (true),
1870 az = (Axis) (3 - ax - ay); 1870 az = (Axis) (3 - ax - ay);
1871 1871
1872 for (int i = 0; i < 4; ++i) 1872 for (int i = 0; i < 4; ++i)
1873 m_rectverts[i][az] = depthValue(); 1873 m_rectverts[i][az] = getDepthValue();
1874 1874
1875 m_rectverts[0][ax] = v0[ax]; 1875 m_rectverts[0][ax] = v0[ax];
1876 m_rectverts[0][ay] = v0[ay]; 1876 m_rectverts[0][ay] = v0[ay];
1877 m_rectverts[1][ax] = v1[ax]; 1877 m_rectverts[1][ax] = v1[ax];
1878 m_rectverts[1][ay] = v0[ay]; 1878 m_rectverts[1][ay] = v0[ay];
1917 1917
1918 // ============================================================================= 1918 // =============================================================================
1919 // ----------------------------------------------------------------------------- 1919 // -----------------------------------------------------------------------------
1920 // Read in overlays from the current file and update overlay info accordingly. 1920 // Read in overlays from the current file and update overlay info accordingly.
1921 // ----------------------------------------------------------------------------- 1921 // -----------------------------------------------------------------------------
1922 void GLRenderer::overlaysFromObjects() 1922 void GLRenderer::initOverlaysFromObjects()
1923 { for (Camera cam : g_Cameras) 1923 { for (Camera cam : g_Cameras)
1924 { if (cam == Free) 1924 { if (cam == Free)
1925 continue; 1925 continue;
1926 1926
1927 LDGLOverlay& meta = m_overlays[cam]; 1927 LDGLOverlay& meta = m_overlays[cam];
1970 // object and put an empty object after it (though don't do this if 1970 // object and put an empty object after it (though don't do this if
1971 // there was no schemantic elements at all) 1971 // there was no schemantic elements at all)
1972 int i, lastOverlay = -1; 1972 int i, lastOverlay = -1;
1973 bool found = false; 1973 bool found = false;
1974 1974
1975 for (i = 0; i < file()->numObjs(); ++i) 1975 for (i = 0; i < file()->getObjectCount(); ++i)
1976 { LDObject* obj = file()->obj (i); 1976 { LDObject* obj = file()->getObject (i);
1977 1977
1978 if (obj->isScemantic()) 1978 if (obj->isScemantic())
1979 { found = true; 1979 { found = true;
1980 break; 1980 break;
1981 } 1981 }

mercurial