src/gldraw.cpp

changeset 253
0737c217a54d
parent 252
3f9067022d74
child 254
434c9844e45d
equal deleted inserted replaced
252:3f9067022d74 253:0737c217a54d
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 <QTimer>
24 #include <GL/glu.h> 25 #include <GL/glu.h>
25 26
26 #include "common.h" 27 #include "common.h"
27 #include "config.h" 28 #include "config.h"
28 #include "file.h" 29 #include "file.h"
95 m_picking = m_rangepick = false; 96 m_picking = m_rangepick = false;
96 m_camera = (GL::Camera) gl_camera.value; 97 m_camera = (GL::Camera) gl_camera.value;
97 m_drawToolTip = false; 98 m_drawToolTip = false;
98 m_editMode = Select; 99 m_editMode = Select;
99 m_rectdraw = false; 100 m_rectdraw = false;
101 setFile (null);
102 setDrawOnly (false);
100 103
101 m_toolTipTimer = new QTimer (this); 104 m_toolTipTimer = new QTimer (this);
102 m_toolTipTimer->setSingleShot (true); 105 m_toolTipTimer->setSingleShot (true);
103 connect (m_toolTipTimer, SIGNAL (timeout ()), this, SLOT (slot_toolTipTimer ())); 106 connect (m_toolTipTimer, SIGNAL (timeout ()), this, SLOT (slot_toolTipTimer ()));
104 107
171 m_rotY = 325.f; 174 m_rotY = 325.f;
172 m_panX = m_panY = m_rotZ = 0.0f; 175 m_panX = m_panY = m_rotZ = 0.0f;
173 176
174 // Set the default zoom based on the bounding box 177 // Set the default zoom based on the bounding box
175 if (g_BBox.empty () == false) 178 if (g_BBox.empty () == false)
176 m_zoom = g_BBox.size () * 6; 179 setZoom (g_BBox.size () * 6);
177 else 180 else
178 m_zoom = 30.0f; 181 setZoom (30.0f);
179 } 182 }
180 183
181 // ============================================================================= 184 // =============================================================================
182 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 185 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
183 // ============================================================================= 186 // =============================================================================
231 234
232 if (list == GL::PickList) { 235 if (list == GL::PickList) {
233 // Make the color by the object's index color if we're picking, so we can 236 // Make the color by the object's index color if we're picking, so we can
234 // make the index from the color we get from the picking results. Be sure 237 // make the index from the color we get from the picking results. Be sure
235 // to use the top level parent's index since inlinees don't have an index. 238 // to use the top level parent's index since inlinees don't have an index.
236 long i = obj->topLevelParent ()->getIndex (g_curfile); 239 long i = obj->topLevelParent ()->getIndex (file ());
237 240
238 // We should have the index now. 241 // We should have the index now.
239 assert (i != -1); 242 assert (i != -1);
240 243
241 // Calculate a color based from this index. This method caters for 244 // Calculate a color based from this index. This method caters for
341 glLoadIdentity (); 344 glLoadIdentity ();
342 gluPerspective (45.0f, (double) w / (double) h, 1.0f, 10000.0f); 345 gluPerspective (45.0f, (double) w / (double) h, 1.0f, 10000.0f);
343 glMatrixMode (GL_MODELVIEW); 346 glMatrixMode (GL_MODELVIEW);
344 } 347 }
345 348
346 void GLRenderer::drawGLScene () const { 349 void GLRenderer::drawGLScene () {
347 if (g_curfile == null) 350 if (file () == null)
348 return; 351 return;
349 352
350 if (gl_wireframe && !picking ()) 353 if (gl_wireframe && !picking ())
351 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 354 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
352 355
373 glMatrixMode (GL_MODELVIEW); 376 glMatrixMode (GL_MODELVIEW);
374 glPushMatrix (); 377 glPushMatrix ();
375 glLoadIdentity (); 378 glLoadIdentity ();
376 379
377 glTranslatef (0.0f, 0.0f, -2.0f); 380 glTranslatef (0.0f, 0.0f, -2.0f);
378 glTranslatef (m_panX, m_panY, -m_zoom); 381 glTranslatef (m_panX, m_panY, -zoom ());
379 glRotatef (m_rotX, 1.0f, 0.0f, 0.0f); 382 glRotatef (m_rotX, 1.0f, 0.0f, 0.0f);
380 glRotatef (m_rotY, 0.0f, 1.0f, 0.0f); 383 glRotatef (m_rotY, 0.0f, 1.0f, 0.0f);
381 glRotatef (m_rotZ, 0.0f, 0.0f, 1.0f); 384 glRotatef (m_rotZ, 0.0f, 0.0f, 1.0f);
382 } 385 }
383 386
384 if (gl_colorbfc && !m_picking) { 387 const GL::ListType list = (!drawOnly () && m_picking) ? PickList : NormalList;
388
389 if (gl_colorbfc && !m_picking && !drawOnly ()) {
385 glEnable (GL_CULL_FACE); 390 glEnable (GL_CULL_FACE);
386 391
387 for (LDObject* obj : g_curfile->objs ()) { 392 for (LDObject* obj : file ()->objs ()) {
388 if (obj->hidden ()) 393 if (obj->hidden ())
389 continue; 394 continue;
390 395
391 glCullFace (GL_BACK); 396 glCullFace (GL_BACK);
392 glCallList (obj->glLists[BFCFrontList]); 397 glCallList (obj->glLists[BFCFrontList]);
395 glCallList (obj->glLists[BFCBackList]); 400 glCallList (obj->glLists[BFCBackList]);
396 } 401 }
397 402
398 glDisable (GL_CULL_FACE); 403 glDisable (GL_CULL_FACE);
399 } else { 404 } else {
400 for (LDObject* obj : g_curfile->objs ()) { 405 for (LDObject* obj : file ()->objs ()) {
401 if (obj->hidden ()) 406 if (obj->hidden ())
402 continue; 407 continue;
403 408
404 glCallList (obj->glLists[(m_picking) ? PickList : NormalList]); 409 glCallList (obj->glLists[list]);
405 } 410 }
406 } 411 }
407 412
408 if (gl_axes && !m_picking) 413 if (gl_axes && !m_picking && !drawOnly ())
409 glCallList (m_axeslist); 414 glCallList (m_axeslist);
410 415
411 glPopMatrix (); 416 glPopMatrix ();
412 glMatrixMode (GL_MODELVIEW); 417 glMatrixMode (GL_MODELVIEW);
413 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 418 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
472 // ============================================================================= 477 // =============================================================================
473 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 478 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
474 // ============================================================================= 479 // =============================================================================
475 void GLRenderer::paintEvent (QPaintEvent* ev) { 480 void GLRenderer::paintEvent (QPaintEvent* ev) {
476 Q_UNUSED (ev) 481 Q_UNUSED (ev)
477 m_virtWidth = m_zoom; 482
483 makeCurrent ();
484 m_virtWidth = zoom ();
478 m_virtHeight = (m_height * m_virtWidth) / m_width; 485 m_virtHeight = (m_height * m_virtWidth) / m_width;
479 486
480 initGLData (); 487 initGLData ();
481 drawGLScene (); 488 drawGLScene ();
482 489
483 m_hoverpos = g_origin; 490 m_hoverpos = g_origin;
484 491
485 QPainter paint (this); 492 QPainter paint (this);
486 QFontMetrics metrics = QFontMetrics (QFont ()); 493 QFontMetrics metrics = QFontMetrics (QFont ());
487 paint.setRenderHint (QPainter::HighQualityAntialiasing); 494 paint.setRenderHint (QPainter::HighQualityAntialiasing);
495
496 // If we wish to only draw the brick, stop here
497 if (drawOnly ())
498 return;
488 499
489 if (m_camera != Free) { 500 if (m_camera != Free) {
490 // Paint the overlay image if we have one 501 // Paint the overlay image if we have one
491 const overlayMeta& overlay = m_overlays[m_camera]; 502 const overlayMeta& overlay = m_overlays[m_camera];
492 if (overlay.img != null) { 503 if (overlay.img != null) {
658 669
659 // ============================================================================= 670 // =============================================================================
660 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 671 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
661 // ============================================================================= 672 // =============================================================================
662 void GLRenderer::compileAllObjects () { 673 void GLRenderer::compileAllObjects () {
663 if (!g_curfile) { 674 if (!file ())
664 printf ("renderer: no files loaded, cannot compile anything\n");
665 return; 675 return;
666 } 676
667 677 for (LDObject* obj : file ()->objs ())
668 for (LDObject* obj : g_curfile->objs ())
669 compileObject (obj); 678 compileObject (obj);
670 679
671 // Compile axes 680 // Compile axes
672 glDeleteLists (m_axeslist, 1); 681 glDeleteLists (m_axeslist, 1);
673 m_axeslist = glGenLists (1); 682 m_axeslist = glGenLists (1);
881 m_drawedVerts << m_hoverpos; 890 m_drawedVerts << m_hoverpos;
882 update (); 891 update ();
883 break; 892 break;
884 893
885 case Select: 894 case Select:
886 if (!m_rangepick) 895 if (!drawOnly ()) {
887 m_addpick = (m_keymods & Qt::ControlModifier); 896 if (!m_rangepick)
888 897 m_addpick = (m_keymods & Qt::ControlModifier);
889 if (m_totalmove < 10 || m_rangepick) 898
890 pick (ev->x (), ev->y ()); 899 if (m_totalmove < 10 || m_rangepick)
900 pick (ev->x (), ev->y ());
901 }
891 break; 902 break;
892 } 903 }
893 904
894 m_rangepick = false; 905 m_rangepick = false;
895 m_totalmove = 0; 906 m_totalmove = 0;
939 clampAngle (m_rotX); 950 clampAngle (m_rotX);
940 clampAngle (m_rotY); 951 clampAngle (m_rotY);
941 } 952 }
942 953
943 if (ev->buttons () & Qt::MidButton) { 954 if (ev->buttons () & Qt::MidButton) {
944 m_panX += 0.03f * dx * (m_zoom / 7.5f); 955 m_panX += 0.03f * dx * (zoom () / 7.5f);
945 m_panY -= 0.03f * dy * (m_zoom / 7.5f); 956 m_panY -= 0.03f * dy * (zoom () / 7.5f);
946 } 957 }
947 958
948 // Start the tool tip timer 959 // Start the tool tip timer
949 if (!m_drawToolTip) 960 if (!m_drawToolTip)
950 m_toolTipTimer->start (1000); 961 m_toolTipTimer->start (1000);
964 m_keymods = ev->modifiers (); 975 m_keymods = ev->modifiers ();
965 } 976 }
966 977
967 // ============================================================================= 978 // =============================================================================
968 void GLRenderer::wheelEvent (QWheelEvent* ev) { 979 void GLRenderer::wheelEvent (QWheelEvent* ev) {
969 if (m_zoom > 15) 980 makeCurrent ();
970 m_zoom *= (ev->delta () < 0) ? 1.2f : (1.0f / 1.2f); 981
982 if (zoom () > 15)
983 setZoom (zoom () * (ev->delta () < 0 ? 1.2f : 0.833f));
971 else 984 else
972 m_zoom += (double) ev->delta () / -100.0f; 985 setZoom (zoom () + ((double) ev->delta () / -100.0f));
973 986
974 m_zoom = clamp<double> (m_zoom, 0.01f, 10000.0f); 987 setZoom (clamp<double> (zoom (), 0.01f, 10000.0f));
975 988
976 update (); 989 update ();
977 ev->accept (); 990 ev->accept ();
978 } 991 }
979 992
1000 // ============================================================================= 1013 // =============================================================================
1001 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 1014 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1002 // ============================================================================= 1015 // =============================================================================
1003 void GLRenderer::pick (uint mouseX, uint mouseY) { 1016 void GLRenderer::pick (uint mouseX, uint mouseY) {
1004 GLint viewport[4]; 1017 GLint viewport[4];
1018 makeCurrent ();
1005 1019
1006 // Use particularly thick lines while picking ease up selecting lines. 1020 // Use particularly thick lines while picking ease up selecting lines.
1007 glLineWidth (max<double> (gl_linethickness, 6.5f)); 1021 glLineWidth (max<double> (gl_linethickness, 6.5f));
1008 1022
1009 // Clear the selection if we do not wish to add to it. 1023 // Clear the selection if we do not wish to add to it.
1078 pixelptr += 4; 1092 pixelptr += 4;
1079 1093
1080 if (idx == 0xFFFFFF) 1094 if (idx == 0xFFFFFF)
1081 continue; // White is background; skip 1095 continue; // White is background; skip
1082 1096
1083 LDObject* obj = g_curfile->obj (idx); 1097 LDObject* obj = file ()->obj (idx);
1084 1098
1085 // If this is an additive single pick and the object is currently selected, 1099 // If this is an additive single pick and the object is currently selected,
1086 // we remove it from selection instead. 1100 // we remove it from selection instead.
1087 if (!m_rangepick && m_addpick) { 1101 if (!m_rangepick && m_addpick) {
1088 bool removed = false; 1102 bool removed = false;
1219 break; 1233 break;
1220 } 1234 }
1221 } 1235 }
1222 1236
1223 if (obj) { 1237 if (obj) {
1224 g_curfile->addObject (obj); 1238 file ()->addObject (obj);
1225 compileObject (obj); 1239 compileObject (obj);
1226 g_win->fullRefresh (); 1240 g_win->fullRefresh ();
1227 1241
1228 History::addEntry (new AddHistory ({(ulong) obj->getIndex (g_curfile)}, {obj->clone ()})); 1242 History::addEntry (new AddHistory ({(ulong) obj->getIndex (file ())}, {obj->clone ()}));
1229 } 1243 }
1230 1244
1231 m_drawedVerts.clear (); 1245 m_drawedVerts.clear ();
1232 m_rectdraw = false; 1246 m_rectdraw = false;
1233 } 1247 }
1237 // ============================================================================= 1251 // =============================================================================
1238 void GLRenderer::compileObject (LDObject* obj) { 1252 void GLRenderer::compileObject (LDObject* obj) {
1239 deleteLists (obj); 1253 deleteLists (obj);
1240 1254
1241 for (const GL::ListType listType : g_glListTypes) { 1255 for (const GL::ListType listType : g_glListTypes) {
1256 if (drawOnly () && listType != GL::NormalList)
1257 continue;
1258
1242 GLuint list = glGenLists (1); 1259 GLuint list = glGenLists (1);
1243 glNewList (list, GL_COMPILE); 1260 glNewList (list, GL_COMPILE);
1244 1261
1245 obj->glLists[listType] = list; 1262 obj->glLists[listType] = list;
1246 compileList (obj, listType); 1263 compileList (obj, listType);

mercurial