src/gldraw.cpp

changeset 493
16766ac1bbd9
parent 492
e964085e6913
child 494
bd005c78a089
equal deleted inserted replaced
492:e964085e6913 493:16766ac1bbd9
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 39 #include "moc_gldraw.cpp"
40 static const struct staticCameraMeta { 40
41 const char glrotate[3]; 41 static const struct staticCameraMeta
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;
44 } g_staticCameras[6] = { 45 } g_staticCameras[6] =
45 {{ 1, 0, 0 }, X, Z, false, false }, 46 { {{ 1, 0, 0 }, X, Z, false, false },
46 {{ 0, 0, 0 }, X, Y, false, true }, 47 {{ 0, 0, 0 }, X, Y, false, true },
47 {{ 0, 1, 0 }, Z, Y, true, true }, 48 {{ 0, 1, 0 }, Z, Y, true, true },
48 {{ -1, 0, 0 }, X, Z, false, true }, 49 {{ -1, 0, 0 }, X, Z, false, true },
49 {{ 0, 0, 0 }, X, Y, true, true }, 50 {{ 0, 0, 0 }, X, Y, true, true },
50 {{ 0, -1, 0 }, Z, Y, false, true }, 51 {{ 0, -1, 0 }, Z, Y, false, true },
51 }; 52 };
52 53
53 static const matrix g_circleDrawTransforms[3] = { 54 static const matrix g_circleDrawTransforms[3] =
54 { 2, 0, 0, 0, 1, 0, 0, 0, 2 }, 55 { { 2, 0, 0, 0, 1, 0, 0, 0, 2 },
55 { 2, 0, 0, 0, 0, 2, 0, 1, 0 }, 56 { 2, 0, 0, 0, 0, 2, 0, 1, 0 },
56 { 0, 1, 0, 2, 0, 0, 0, 0, 2 }, 57 { 0, 1, 0, 2, 0, 0, 0, 0, 2 },
57 }; 58 };
58 59
59 cfg (String, gl_bgcolor, "#CCCCD9"); 60 cfg (String, gl_bgcolor, "#CCCCD9");
66 cfg (Bool, gl_axes, false); 67 cfg (Bool, gl_axes, false);
67 cfg (Bool, gl_wireframe, false); 68 cfg (Bool, gl_wireframe, false);
68 cfg (Bool, gl_logostuds, false); 69 cfg (Bool, gl_logostuds, false);
69 70
70 // argh 71 // argh
71 const char* g_CameraNames[7] = { 72 const char* g_CameraNames[7] =
72 QT_TRANSLATE_NOOP ("GLRenderer", "Top"), 73 { QT_TRANSLATE_NOOP ("GLRenderer", "Top"),
73 QT_TRANSLATE_NOOP ("GLRenderer", "Front"), 74 QT_TRANSLATE_NOOP ("GLRenderer", "Front"),
74 QT_TRANSLATE_NOOP ("GLRenderer", "Left"), 75 QT_TRANSLATE_NOOP ("GLRenderer", "Left"),
75 QT_TRANSLATE_NOOP ("GLRenderer", "Bottom"), 76 QT_TRANSLATE_NOOP ("GLRenderer", "Bottom"),
76 QT_TRANSLATE_NOOP ("GLRenderer", "Back"), 77 QT_TRANSLATE_NOOP ("GLRenderer", "Back"),
77 QT_TRANSLATE_NOOP ("GLRenderer", "Right"), 78 QT_TRANSLATE_NOOP ("GLRenderer", "Right"),
78 QT_TRANSLATE_NOOP ("GLRenderer", "Free") 79 QT_TRANSLATE_NOOP ("GLRenderer", "Free")
79 }; 80 };
80 81
81 const GL::Camera g_Cameras[7] = { 82 const GL::Camera g_Cameras[7] =
82 GL::Top, 83 { GL::Top,
83 GL::Front, 84 GL::Front,
84 GL::Left, 85 GL::Left,
85 GL::Bottom, 86 GL::Bottom,
86 GL::Back, 87 GL::Back,
87 GL::Right, 88 GL::Right,
88 GL::Free 89 GL::Free
89 }; 90 };
90 91
91 const struct GLAxis { 92 const struct GLAxis
92 const QColor col; 93 { const QColor col;
93 const vertex vert; 94 const vertex vert;
94 } g_GLAxes[3] = { 95 } g_GLAxes[3] =
95 { QColor (255, 0, 0), vertex (10000, 0, 0) }, 96 { { QColor (255, 0, 0), vertex (10000, 0, 0) },
96 { QColor (80, 192, 0), vertex (0, 10000, 0) }, 97 { QColor (80, 192, 0), vertex (0, 10000, 0) },
97 { QColor (0, 160, 192), vertex (0, 0, 10000) }, 98 { QColor (0, 160, 192), vertex (0, 0, 10000) },
98 }; 99 };
99 100
100 static bool g_glInvert = false; 101 static bool g_glInvert = false;
101 static List<short> g_warnedColors; 102 static List<short> g_warnedColors;
102 103
103 // ============================================================================= 104 // =============================================================================
104 // ----------------------------------------------------------------------------- 105 // -----------------------------------------------------------------------------
105 GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent) { 106 GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent)
106 m_picking = m_rangepick = false; 107 { m_picking = m_rangepick = false;
107 m_camera = (GL::Camera) gl_camera.value; 108 m_camera = (GL::Camera) gl_camera.value;
108 m_drawToolTip = false; 109 m_drawToolTip = false;
109 m_editMode = Select; 110 m_editMode = Select;
110 m_rectdraw = false; 111 m_rectdraw = false;
111 m_panning = false; 112 m_panning = false;
112 setFile (null); 113 setFile (null);
113 setDrawOnly (false); 114 setDrawOnly (false);
114 resetAngles(); 115 resetAngles();
115 setMessageLog (null); 116 setMessageLog (null);
116 117
117 m_toolTipTimer = new QTimer (this); 118 m_toolTipTimer = new QTimer (this);
118 m_toolTipTimer->setSingleShot (true); 119 m_toolTipTimer->setSingleShot (true);
119 connect (m_toolTipTimer, SIGNAL (timeout()), this, SLOT (slot_toolTipTimer())); 120 connect (m_toolTipTimer, SIGNAL (timeout()), this, SLOT (slot_toolTipTimer()));
120 121
121 m_thickBorderPen = QPen (QColor (0, 0, 0, 208), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); 122 m_thickBorderPen = QPen (QColor (0, 0, 0, 208), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
122 m_thinBorderPen = m_thickBorderPen; 123 m_thinBorderPen = m_thickBorderPen;
123 m_thinBorderPen.setWidth (1); 124 m_thinBorderPen.setWidth (1);
124 125
125 // Init camera icons 126 // Init camera icons
126 for (const GL::Camera cam : g_Cameras) { 127 for (const GL::Camera cam : g_Cameras)
127 str iconname = fmt ("camera-%1", tr (g_CameraNames[cam]).toLower()); 128 { str iconname = fmt ("camera-%1", tr (g_CameraNames[cam]).toLower());
128 129
129 CameraIcon* info = &m_cameraIcons[cam]; 130 CameraIcon* info = &m_cameraIcons[cam];
130 info->img = new QPixmap (getIcon (iconname)); 131 info->img = new QPixmap (getIcon (iconname));
131 info->cam = cam; 132 info->cam = cam;
132 } 133 }
133 134
134 for (int i = 0; i < 6; ++i) { 135 for (int i = 0; i < 6; ++i)
135 m_overlays[i].img = null; 136 { m_overlays[i].img = null;
136 m_depthValues[i] = 0.0f; 137 m_depthValues[i] = 0.0f;
137 } 138 }
138 139
139 calcCameraIcons(); 140 calcCameraIcons();
140 } 141 }
141 142
142 // ============================================================================= 143 // =============================================================================
143 // ----------------------------------------------------------------------------- 144 // -----------------------------------------------------------------------------
144 GLRenderer::~GLRenderer() { 145 GLRenderer::~GLRenderer()
145 for (int i = 0; i < 6; ++i) 146 { for (int i = 0; i < 6; ++i)
146 delete m_overlays[i].img; 147 delete m_overlays[i].img;
147 148
148 for (CameraIcon& info : m_cameraIcons) 149 for (CameraIcon & info : m_cameraIcons)
149 delete info.img; 150 delete info.img;
150 } 151 }
151 152
152 // ============================================================================= 153 // =============================================================================
153 // ----------------------------------------------------------------------------- 154 // -----------------------------------------------------------------------------
154 void GLRenderer::calcCameraIcons() { 155 void GLRenderer::calcCameraIcons()
155 ushort i = 0; 156 { ushort i = 0;
156 157
157 for (CameraIcon& info : m_cameraIcons) { 158 for (CameraIcon & info : m_cameraIcons)
158 const long x1 = (m_width - (info.cam != Free ? 48 : 16)) + ((i % 3) * 16) - 1, 159 { const long x1 = (m_width - (info.cam != Free ? 48 : 16)) + ( (i % 3) * 16) - 1,
159 y1 = ((i / 3) * 16) + 1; 160 y1 = ( (i / 3) * 16) + 1;
160 161
161 info.srcRect = QRect (0, 0, 16, 16); 162 info.srcRect = QRect (0, 0, 16, 16);
162 info.destRect = QRect (x1, y1, 16, 16); 163 info.destRect = QRect (x1, y1, 16, 16);
163 info.selRect = QRect (info.destRect.x(), info.destRect.y(), 164 info.selRect = QRect (info.destRect.x(), info.destRect.y(),
164 info.destRect.width() + 1, info.destRect.height() + 1); 165 info.destRect.width() + 1, info.destRect.height() + 1);
165 ++i; 166 ++i;
166 } 167 }
167 } 168 }
168 169
169 // ============================================================================= 170 // =============================================================================
170 // ----------------------------------------------------------------------------- 171 // -----------------------------------------------------------------------------
171 void GLRenderer::initGLData() { 172 void GLRenderer::initGLData()
172 glEnable (GL_BLEND); 173 { glEnable (GL_BLEND);
173 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 174 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
174 glEnable (GL_POLYGON_OFFSET_FILL); 175 glEnable (GL_POLYGON_OFFSET_FILL);
175 glPolygonOffset (1.0f, 1.0f); 176 glPolygonOffset (1.0f, 1.0f);
176 177
177 glEnable (GL_DEPTH_TEST); 178 glEnable (GL_DEPTH_TEST);
178 glShadeModel (GL_SMOOTH); 179 glShadeModel (GL_SMOOTH);
179 glEnable (GL_MULTISAMPLE); 180 glEnable (GL_MULTISAMPLE);
180 181
181 glEnable (GL_LINE_SMOOTH); 182 glEnable (GL_LINE_SMOOTH);
182 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); 183 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
183 } 184 }
184 185
185 // ============================================================================= 186 // =============================================================================
186 // ----------------------------------------------------------------------------- 187 // -----------------------------------------------------------------------------
187 void GLRenderer::resetAngles() { 188 void GLRenderer::resetAngles()
188 m_rotX = 30.0f; 189 { m_rotX = 30.0f;
189 m_rotY = 325.f; 190 m_rotY = 325.f;
190 m_panX = m_panY = m_rotZ = 0.0f; 191 m_panX = m_panY = m_rotZ = 0.0f;
191 zoomToFit(); 192 zoomToFit();
192 } 193 }
193 194
194 // ============================================================================= 195 // =============================================================================
195 // ----------------------------------------------------------------------------- 196 // -----------------------------------------------------------------------------
196 void GLRenderer::initializeGL() { 197 void GLRenderer::initializeGL()
197 setBackground(); 198 { setBackground();
198 199
199 glLineWidth (gl_linethickness); 200 glLineWidth (gl_linethickness);
200 201
201 setAutoFillBackground (false); 202 setAutoFillBackground (false);
202 setMouseTracking (true); 203 setMouseTracking (true);
203 setFocusPolicy (Qt::WheelFocus); 204 setFocusPolicy (Qt::WheelFocus);
204 compileAllObjects(); 205 compileAllObjects();
205 } 206 }
206 207
207 // ============================================================================= 208 // =============================================================================
208 // ----------------------------------------------------------------------------- 209 // -----------------------------------------------------------------------------
209 QColor GLRenderer::getMainColor() { 210 QColor GLRenderer::getMainColor()
210 QColor col (gl_maincolor); 211 { QColor col (gl_maincolor);
211 212
212 if (!col.isValid()) 213 if (!col.isValid())
213 return QColor (0, 0, 0); 214 return QColor (0, 0, 0);
214 215
215 col.setAlpha (gl_maincolor_alpha * 255.f); 216 col.setAlpha (gl_maincolor_alpha * 255.f);
216 return col; 217 return col;
217 } 218 }
218 219
219 // ============================================================================= 220 // =============================================================================
220 // ----------------------------------------------------------------------------- 221 // -----------------------------------------------------------------------------
221 void GLRenderer::setBackground() { 222 void GLRenderer::setBackground()
222 QColor col (gl_bgcolor); 223 { QColor col (gl_bgcolor);
223 224
224 if (!col.isValid()) 225 if (!col.isValid())
225 return; 226 return;
226 227
227 col.setAlpha (255); 228 col.setAlpha (255);
228 229
229 m_darkbg = luma (col) < 80; 230 m_darkbg = luma (col) < 80;
230 m_bgcolor = col; 231 m_bgcolor = col;
231 qglClearColor (col); 232 qglClearColor (col);
232 } 233 }
233 234
234 // ============================================================================= 235 // =============================================================================
235 // ----------------------------------------------------------------------------- 236 // -----------------------------------------------------------------------------
236 void GLRenderer::setObjectColor (LDObject* obj, const ListType list) { 237 void GLRenderer::setObjectColor (LDObject* obj, const ListType list)
237 QColor qcol; 238 { QColor qcol;
238 239
239 if (!obj->isColored()) 240 if (!obj->isColored())
240 return; 241 return;
241 242
242 if (list == GL::PickList) { 243 if (list == GL::PickList)
243 // Make the color by the object's ID if we're picking, so we can make the 244 { // Make the color by the object's ID if we're picking, so we can make the
244 // ID again from the color we get from the picking results. Be sure to use 245 // ID again from the color we get from the picking results. Be sure to use
245 // the top level parent's index since we want a subfile's children point 246 // the top level parent's index since we want a subfile's children point
246 // to the subfile itself. 247 // to the subfile itself.
247 long i = obj->topLevelParent()->id(); 248 long i = obj->topLevelParent()->id();
248 249
249 // Calculate a color based from this index. This method caters for 250 // Calculate a color based from this index. This method caters for
250 // 16777216 objects. I don't think that'll be exceeded anytime soon. :) 251 // 16777216 objects. I don't think that'll be exceeded anytime soon. :)
251 // ATM biggest is 53588.dat with 12600 lines. 252 // ATM biggest is 53588.dat with 12600 lines.
252 double r = (i / (256 * 256)) % 256, 253 double r = (i / (256 * 256)) % 256,
253 g = (i / 256) % 256, 254 g = (i / 256) % 256,
254 b = i % 256; 255 b = i % 256;
255 256
256 qglColor (QColor (r, g, b)); 257 qglColor (QColor (r, g, b));
257 return; 258 return;
258 } 259 }
259 260
260 if ((list == BFCFrontList || list == BFCBackList) && 261 if ( (list == BFCFrontList || list == BFCBackList) &&
261 obj->getType() != LDObject::Line && 262 obj->getType() != LDObject::Line &&
262 obj->getType() != LDObject::CndLine) { 263 obj->getType() != LDObject::CndLine)
263 264 {
265
264 if (list == GL::BFCFrontList) 266 if (list == GL::BFCFrontList)
265 qcol = QColor (40, 192, 0); 267 qcol = QColor (40, 192, 0);
266 else 268 else
267 qcol = QColor (224, 0, 0); 269 qcol = QColor (224, 0, 0);
268 } else { 270 }
269 if (obj->color() == maincolor) 271 else
272 { if (obj->color() == maincolor)
270 qcol = getMainColor(); 273 qcol = getMainColor();
271 else { 274 else
272 LDColor* col = getColor (obj->color()); 275 { LDColor* col = getColor (obj->color());
273 276
274 if (col) 277 if (col)
275 qcol = col->faceColor; 278 qcol = col->faceColor;
276 } 279 }
277 280
278 if (obj->color() == edgecolor) { 281 if (obj->color() == edgecolor)
279 qcol = luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black; 282 { qcol = luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black;
280 LDColor* col; 283 LDColor* col;
281 284
282 if (!gl_blackedges && obj->parent() && (col = getColor (obj->parent()->color()))) 285 if (!gl_blackedges && obj->parent() && (col = getColor (obj->parent()->color())))
283 qcol = col->edgeColor; 286 qcol = col->edgeColor;
284 } 287 }
285 288
286 if (qcol.isValid() == false) { 289 if (qcol.isValid() == false)
287 // The color was unknown. Use main color to make the object at least 290 { // The color was unknown. Use main color to make the object at least
288 // not appear pitch-black. 291 // not appear pitch-black.
289 if (obj->color() != edgecolor) 292 if (obj->color() != edgecolor)
290 qcol = getMainColor(); 293 qcol = getMainColor();
291 294
292 // Warn about the unknown colors, but only once. 295 // Warn about the unknown colors, but only once.
293 for (short i : g_warnedColors) 296 for (short i : g_warnedColors)
294 if (obj->color() == i) 297 if (obj->color() == i)
295 return; 298 return;
296 299
297 printf ("%s: Unknown color %d!\n", __func__, obj->color()); 300 printf ("%s: Unknown color %d!\n", __func__, obj->color());
298 g_warnedColors << obj->color(); 301 g_warnedColors << obj->color();
299 return; 302 return;
300 } 303 }
301 } 304 }
302 305
303 long r = qcol.red(), 306 long r = qcol.red(),
304 g = qcol.green(), 307 g = qcol.green(),
305 b = qcol.blue(), 308 b = qcol.blue(),
306 a = qcol.alpha(); 309 a = qcol.alpha();
307 310
308 if (obj->topLevelParent()->selected()) { 311 if (obj->topLevelParent()->selected())
309 // Brighten it up for the select list. 312 { // Brighten it up for the select list.
310 const uchar add = 51; 313 const uchar add = 51;
311 314
312 r = min (r + add, 255l); 315 r = min (r + add, 255l);
313 g = min (g + add, 255l); 316 g = min (g + add, 255l);
314 b = min (b + add, 255l); 317 b = min (b + add, 255l);
315 } 318 }
316 319
317 glColor4f ( 320 glColor4f (
318 ((double) r) / 255.0f, 321 ( (double) r) / 255.0f,
319 ((double) g) / 255.0f, 322 ( (double) g) / 255.0f,
320 ((double) b) / 255.0f, 323 ( (double) b) / 255.0f,
321 ((double) a) / 255.0f); 324 ( (double) a) / 255.0f);
322 } 325 }
323 326
324 // ============================================================================= 327 // =============================================================================
325 // ----------------------------------------------------------------------------- 328 // -----------------------------------------------------------------------------
326 void GLRenderer::refresh() { 329 void GLRenderer::refresh()
327 update(); 330 { update();
328 swapBuffers(); 331 swapBuffers();
329 } 332 }
330 333
331 // ============================================================================= 334 // =============================================================================
332 // ----------------------------------------------------------------------------- 335 // -----------------------------------------------------------------------------
333 void GLRenderer::hardRefresh() { 336 void GLRenderer::hardRefresh()
334 compileAllObjects(); 337 { compileAllObjects();
335 refresh(); 338 refresh();
336 339
337 glLineWidth (gl_linethickness); 340 glLineWidth (gl_linethickness);
338 } 341 }
339 342
340 // ============================================================================= 343 // =============================================================================
341 // ----------------------------------------------------------------------------- 344 // -----------------------------------------------------------------------------
342 void GLRenderer::resizeGL (int w, int h) { 345 void GLRenderer::resizeGL (int w, int h)
343 m_width = w; 346 { m_width = w;
344 m_height = h; 347 m_height = h;
345 348
346 calcCameraIcons(); 349 calcCameraIcons();
347 350
348 glViewport (0, 0, w, h); 351 glViewport (0, 0, w, h);
349 glMatrixMode (GL_PROJECTION); 352 glMatrixMode (GL_PROJECTION);
350 glLoadIdentity(); 353 glLoadIdentity();
351 gluPerspective (45.0f, (double) w / (double) h, 1.0f, 10000.0f); 354 gluPerspective (45.0f, (double) w / (double) h, 1.0f, 10000.0f);
352 glMatrixMode (GL_MODELVIEW); 355 glMatrixMode (GL_MODELVIEW);
353 } 356 }
354 357
355 // ============================================================================= 358 // =============================================================================
356 // ----------------------------------------------------------------------------- 359 // -----------------------------------------------------------------------------
357 void GLRenderer::drawGLScene() { 360 void GLRenderer::drawGLScene()
358 if (file() == null) 361 { if (file() == null)
359 return; 362 return;
360 363
361 if (gl_wireframe && !picking()) 364 if (gl_wireframe && !picking())
362 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 365 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
363 366
364 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 367 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
365 glEnable (GL_DEPTH_TEST); 368 glEnable (GL_DEPTH_TEST);
366 369
367 if (m_camera != Free) { 370 if (m_camera != Free)
368 glMatrixMode (GL_PROJECTION); 371 { glMatrixMode (GL_PROJECTION);
369 glPushMatrix(); 372 glPushMatrix();
370 373
371 glLoadIdentity(); 374 glLoadIdentity();
372 glOrtho (-m_virtWidth, m_virtWidth, -m_virtHeight, m_virtHeight, -100.0f, 100.0f); 375 glOrtho (-m_virtWidth, m_virtWidth, -m_virtHeight, m_virtHeight, -100.0f, 100.0f);
373 glTranslatef (m_panX, m_panY, 0.0f); 376 glTranslatef (m_panX, m_panY, 0.0f);
374 377
375 if (m_camera != Front && m_camera != Back) { 378 if (m_camera != Front && m_camera != Back)
376 glRotatef (90.0f, g_staticCameras[m_camera].glrotate[0], 379 { glRotatef (90.0f, g_staticCameras[m_camera].glrotate[0],
377 g_staticCameras[m_camera].glrotate[1], 380 g_staticCameras[m_camera].glrotate[1],
378 g_staticCameras[m_camera].glrotate[2]); 381 g_staticCameras[m_camera].glrotate[2]);
379 } 382 }
380 383
381 // Back camera needs to be handled differently 384 // Back camera needs to be handled differently
382 if (m_camera == GLRenderer::Back) { 385 if (m_camera == GLRenderer::Back)
383 glRotatef (180.0f, 1.0f, 0.0f, 0.0f); 386 { glRotatef (180.0f, 1.0f, 0.0f, 0.0f);
384 glRotatef (180.0f, 0.0f, 0.0f, 1.0f); 387 glRotatef (180.0f, 0.0f, 0.0f, 1.0f);
385 } 388 }
386 } else { 389 }
387 glMatrixMode (GL_MODELVIEW); 390 else
391 { glMatrixMode (GL_MODELVIEW);
388 glPushMatrix(); 392 glPushMatrix();
389 glLoadIdentity(); 393 glLoadIdentity();
390 394
391 glTranslatef (0.0f, 0.0f, -2.0f); 395 glTranslatef (0.0f, 0.0f, -2.0f);
392 glTranslatef (m_panX, m_panY, -zoom()); 396 glTranslatef (m_panX, m_panY, -zoom());
393 glRotatef (m_rotX, 1.0f, 0.0f, 0.0f); 397 glRotatef (m_rotX, 1.0f, 0.0f, 0.0f);
394 glRotatef (m_rotY, 0.0f, 1.0f, 0.0f); 398 glRotatef (m_rotY, 0.0f, 1.0f, 0.0f);
395 glRotatef (m_rotZ, 0.0f, 0.0f, 1.0f); 399 glRotatef (m_rotZ, 0.0f, 0.0f, 1.0f);
396 } 400 }
397 401
398 const GL::ListType list = (!drawOnly() && m_picking) ? PickList : NormalList; 402 const GL::ListType list = (!drawOnly() && m_picking) ? PickList : NormalList;
399 403
400 if (gl_colorbfc && !m_picking && !drawOnly()) { 404 if (gl_colorbfc && !m_picking && !drawOnly())
401 glEnable (GL_CULL_FACE); 405 { glEnable (GL_CULL_FACE);
402 406
403 for (LDObject* obj : file()->objects()) { 407 for (LDObject * obj : file()->objects())
404 if (obj->hidden()) 408 { if (obj->hidden())
405 continue; 409 continue;
406 410
407 glCullFace (GL_BACK); 411 glCullFace (GL_BACK);
408 glCallList (obj->glLists[BFCFrontList]); 412 glCallList (obj->glLists[BFCFrontList]);
409 413
410 glCullFace (GL_FRONT); 414 glCullFace (GL_FRONT);
411 glCallList (obj->glLists[BFCBackList]); 415 glCallList (obj->glLists[BFCBackList]);
412 } 416 }
413 417
414 glDisable (GL_CULL_FACE); 418 glDisable (GL_CULL_FACE);
415 } else { 419 }
416 for (LDObject* obj : file()->objects()) { 420 else
417 if (obj->hidden()) 421 { for (LDObject * obj : file()->objects())
422 { if (obj->hidden())
418 continue; 423 continue;
419 424
420 glCallList (obj->glLists[list]); 425 glCallList (obj->glLists[list]);
421 } 426 }
422 } 427 }
423 428
424 if (gl_axes && !m_picking && !drawOnly()) 429 if (gl_axes && !m_picking && !drawOnly())
425 glCallList (m_axeslist); 430 glCallList (m_axeslist);
426 431
427 glPopMatrix(); 432 glPopMatrix();
428 glMatrixMode (GL_MODELVIEW); 433 glMatrixMode (GL_MODELVIEW);
429 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 434 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
430 } 435 }
431 436
432 // ============================================================================= 437 // =============================================================================
433 // ----------------------------------------------------------------------------- 438 // -----------------------------------------------------------------------------
434 // This converts a 2D point on the screen to a 3D point in the model. If 'snap' 439 // This converts a 2D point on the screen to a 3D point in the model. If 'snap'
435 // is true, the 3D point will snap to the current grid. 440 // is true, the 3D point will snap to the current grid.
436 // ----------------------------------------------------------------------------- 441 // -----------------------------------------------------------------------------
437 vertex GLRenderer::coordconv2_3 (const QPoint& pos2d, bool snap) const { 442 vertex GLRenderer::coordconv2_3 (const QPoint& pos2d, bool snap) const
438 assert (camera() != Free); 443 { assert (camera() != Free);
439 444
440 vertex pos3d; 445 vertex pos3d;
441 const staticCameraMeta* cam = &g_staticCameras[m_camera]; 446 const staticCameraMeta* cam = &g_staticCameras[m_camera];
442 const Axis axisX = cam->axisX; 447 const Axis axisX = cam->axisX;
443 const Axis axisY = cam->axisY; 448 const Axis axisY = cam->axisY;
444 const short negXFac = cam->negX ? -1 : 1, 449 const short negXFac = cam->negX ? -1 : 1,
445 negYFac = cam->negY ? -1 : 1; 450 negYFac = cam->negY ? -1 : 1;
446 451
447 // Calculate cx and cy - these are the LDraw unit coords the cursor is at. 452 // Calculate cx and cy - these are the LDraw unit coords the cursor is at.
448 double cx = (-m_virtWidth + ((2 * pos2d.x() * m_virtWidth) / m_width) - m_panX); 453 double cx = (-m_virtWidth + ( (2 * pos2d.x() * m_virtWidth) / m_width) - m_panX);
449 double cy = (m_virtHeight - ((2 * pos2d.y() * m_virtHeight) / m_height) - m_panY); 454 double cy = (m_virtHeight - ( (2 * pos2d.y() * m_virtHeight) / m_height) - m_panY);
450 455
451 if (snap) { 456 if (snap)
452 cx = Grid::snap (cx, (Grid::Config) axisX); 457 { cx = Grid::snap (cx, (Grid::Config) axisX);
453 cy = Grid::snap (cy, (Grid::Config) axisY); 458 cy = Grid::snap (cy, (Grid::Config) axisY);
454 } 459 }
455 460
456 cx *= negXFac; 461 cx *= negXFac;
457 cy *= negYFac; 462 cy *= negYFac;
458 463
459 str tmp; 464 str tmp;
460 // Create the vertex from the coordinates 465 // Create the vertex from the coordinates
461 pos3d[axisX] = tmp.sprintf ("%.3f", cx).toDouble(); 466 pos3d[axisX] = tmp.sprintf ("%.3f", cx).toDouble();
462 pos3d[axisY] = tmp.sprintf ("%.3f", cy).toDouble(); 467 pos3d[axisY] = tmp.sprintf ("%.3f", cy).toDouble();
463 pos3d[3 - axisX - axisY] = depthValue(); 468 pos3d[3 - axisX - axisY] = depthValue();
467 // ============================================================================= 472 // =============================================================================
468 // ----------------------------------------------------------------------------- 473 // -----------------------------------------------------------------------------
469 // Inverse operation for the above - convert a 3D position to a 2D screen 474 // Inverse operation for the above - convert a 3D position to a 2D screen
470 // position 475 // position
471 // ----------------------------------------------------------------------------- 476 // -----------------------------------------------------------------------------
472 QPoint GLRenderer::coordconv3_2 (const vertex& pos3d) const { 477 QPoint GLRenderer::coordconv3_2 (const vertex& pos3d) const
473 GLfloat m[16]; 478 { GLfloat m[16];
474 const staticCameraMeta* cam = &g_staticCameras[m_camera]; 479 const staticCameraMeta* cam = &g_staticCameras[m_camera];
475 const Axis axisX = cam->axisX; 480 const Axis axisX = cam->axisX;
476 const Axis axisY = cam->axisY; 481 const Axis axisY = cam->axisY;
477 const short negXFac = cam->negX ? -1 : 1, 482 const short negXFac = cam->negX ? -1 : 1,
478 negYFac = cam->negY ? -1 : 1; 483 negYFac = cam->negY ? -1 : 1;
479 484
480 glGetFloatv (GL_MODELVIEW_MATRIX, m); 485 glGetFloatv (GL_MODELVIEW_MATRIX, m);
481 486
482 const double x = pos3d.x(); 487 const double x = pos3d.x();
483 const double y = pos3d.y(); 488 const double y = pos3d.y();
484 const double z = pos3d.z(); 489 const double z = pos3d.z();
485 490
486 vertex transformed; 491 vertex transformed;
487 transformed[X] = (m[0] * x) + (m[1] * y) + (m[2] * z) + m[3]; 492 transformed[X] = (m[0] * x) + (m[1] * y) + (m[2] * z) + m[3];
488 transformed[Y] = (m[4] * x) + (m[5] * y) + (m[6] * z) + m[7]; 493 transformed[Y] = (m[4] * x) + (m[5] * y) + (m[6] * z) + m[7];
489 transformed[Z] = (m[8] * x) + (m[9] * y) + (m[10] * z) + m[11]; 494 transformed[Z] = (m[8] * x) + (m[9] * y) + (m[10] * z) + m[11];
490 495
491 double rx = (((transformed[axisX] * negXFac) + m_virtWidth + m_panX) * m_width) / (2 * m_virtWidth); 496 double rx = ( ( (transformed[axisX] * negXFac) + m_virtWidth + m_panX) * m_width) / (2 * m_virtWidth);
492 double ry = (((transformed[axisY] * negYFac) - m_virtHeight + m_panY) * m_height) / (2 * m_virtHeight); 497 double ry = ( ( (transformed[axisY] * negYFac) - m_virtHeight + m_panY) * m_height) / (2 * m_virtHeight);
493 498
494 return QPoint (rx, -ry); 499 return QPoint (rx, -ry);
495 } 500 }
496 501
497 // ============================================================================= 502 // =============================================================================
498 // ----------------------------------------------------------------------------- 503 // -----------------------------------------------------------------------------
499 void GLRenderer::paintEvent (QPaintEvent* ev) { 504 void GLRenderer::paintEvent (QPaintEvent* ev)
500 Q_UNUSED (ev) 505 { Q_UNUSED (ev)
501 506
502 makeCurrent(); 507 makeCurrent();
503 m_virtWidth = zoom(); 508 m_virtWidth = zoom();
504 m_virtHeight = (m_height * m_virtWidth) / m_width; 509 m_virtHeight = (m_height * m_virtWidth) / m_width;
505 510
506 initGLData(); 511 initGLData();
507 drawGLScene(); 512 drawGLScene();
508 513
509 QPainter paint (this); 514 QPainter paint (this);
510 QFontMetrics metrics = QFontMetrics (QFont()); 515 QFontMetrics metrics = QFontMetrics (QFont());
511 paint.setRenderHint (QPainter::HighQualityAntialiasing); 516 paint.setRenderHint (QPainter::HighQualityAntialiasing);
512 517
513 // If we wish to only draw the brick, stop here 518 // If we wish to only draw the brick, stop here
514 if (drawOnly()) 519 if (drawOnly())
515 return; 520 return;
516 521
517 if (m_camera != Free && !picking()) { 522 if (m_camera != Free && !picking())
518 // Paint the overlay image if we have one 523 { // Paint the overlay image if we have one
519 const overlayMeta& overlay = m_overlays[m_camera]; 524 const overlayMeta& overlay = m_overlays[m_camera];
520 if (overlay.img != null) { 525
521 QPoint v0 = coordconv3_2 (m_overlays[m_camera].v0), 526 if (overlay.img != null)
522 v1 = coordconv3_2 (m_overlays[m_camera].v1); 527 { QPoint v0 = coordconv3_2 (m_overlays[m_camera].v0),
523 528 v1 = coordconv3_2 (m_overlays[m_camera].v1);
529
524 QRect targRect (v0.x(), v0.y(), abs (v1.x() - v0.x()), abs (v1.y() - v0.y())), 530 QRect targRect (v0.x(), v0.y(), abs (v1.x() - v0.x()), abs (v1.y() - v0.y())),
525 srcRect (0, 0, overlay.img->width(), overlay.img->height()); 531 srcRect (0, 0, overlay.img->width(), overlay.img->height());
526 paint.drawImage (targRect, *overlay.img, srcRect); 532 paint.drawImage (targRect, *overlay.img, srcRect);
527 } 533 }
528 534
529 // Paint the coordinates onto the screen. 535 // Paint the coordinates onto the screen.
530 str text = fmt (tr ("X: %1, Y: %2, Z: %3"), m_hoverpos[X], m_hoverpos[Y], m_hoverpos[Z]); 536 str text = fmt (tr ("X: %1, Y: %2, Z: %3"), m_hoverpos[X], m_hoverpos[Y], m_hoverpos[Z]);
531 537
532 QFontMetrics metrics = QFontMetrics (font()); 538 QFontMetrics metrics = QFontMetrics (font());
533 QRect textSize = metrics.boundingRect (0, 0, m_width, m_height, Qt::AlignCenter, text); 539 QRect textSize = metrics.boundingRect (0, 0, m_width, m_height, Qt::AlignCenter, text);
534 540
535 paint.setPen (getTextPen()); 541 paint.setPen (getTextPen());
536 paint.drawText (m_width - textSize.width(), m_height - 16, textSize.width(), 542 paint.drawText (m_width - textSize.width(), m_height - 16, textSize.width(),
537 textSize.height(), Qt::AlignCenter, text); 543 textSize.height(), Qt::AlignCenter, text);
538 544
539 // If we're drawing, draw the vertices onto the screen. 545 // If we're drawing, draw the vertices onto the screen.
540 if (editMode() == Draw) { 546 if (editMode() == Draw)
541 int numverts = 4; 547 { int numverts = 4;
542 548
543 if (!m_rectdraw) 549 if (!m_rectdraw)
544 numverts = m_drawedVerts.size() + 1; 550 numverts = m_drawedVerts.size() + 1;
545 551
546 if (numverts > 0) { 552 if (numverts > 0)
547 QPoint poly[4]; 553 { QPoint poly[4];
548 vertex polyverts[4]; 554 vertex polyverts[4];
549 555
550 if (!m_rectdraw) { 556 if (!m_rectdraw)
551 uchar i = 0; 557 { uchar i = 0;
552 for (vertex& vert : m_drawedVerts) { 558
553 poly[i] = coordconv3_2 (vert); 559 for (vertex & vert : m_drawedVerts)
560 { poly[i] = coordconv3_2 (vert);
554 polyverts[i] = vert; 561 polyverts[i] = vert;
555 ++i; 562 ++i;
556 } 563 }
557 564
558 // Draw the cursor vertex as the last one in the list. 565 // Draw the cursor vertex as the last one in the list.
559 if (numverts <= 4) { 566 if (numverts <= 4)
560 poly[i] = coordconv3_2 (m_hoverpos); 567 { poly[i] = coordconv3_2 (m_hoverpos);
561 polyverts[i] = m_hoverpos; 568 polyverts[i] = m_hoverpos;
562 } else {
563 numverts = 4;
564 } 569 }
565 } else { 570 else
566 if (m_drawedVerts.size() > 0) { 571 { numverts = 4;
567 // Get vertex information from m_rectverts 572 }
568 for (int i = 0; i < numverts; ++i) { 573 }
569 polyverts[i] = m_rectverts[i]; 574 else
575 { if (m_drawedVerts.size() > 0)
576 { // Get vertex information from m_rectverts
577 for (int i = 0; i < numverts; ++i)
578 { polyverts[i] = m_rectverts[i];
570 poly[i] = coordconv3_2 (polyverts[i]); 579 poly[i] = coordconv3_2 (polyverts[i]);
571 } 580 }
572 } else { 581 }
573 poly[0] = coordconv3_2 (m_hoverpos); 582 else
583 { poly[0] = coordconv3_2 (m_hoverpos);
574 polyverts[0] = m_hoverpos; 584 polyverts[0] = m_hoverpos;
575 } 585 }
576 } 586 }
577 587
578 // Draw the polygon-to-be 588 // Draw the polygon-to-be
579 QPen pen = m_thinBorderPen; 589 QPen pen = m_thinBorderPen;
580 pen.setWidth (2); 590 pen.setWidth (2);
581 pen.setColor (luma (m_bgcolor) < 40 ? Qt::white : Qt::black); 591 pen.setColor (luma (m_bgcolor) < 40 ? Qt::white : Qt::black);
582 paint.setPen (pen); 592 paint.setPen (pen);
583 paint.setBrush (QColor (64, 192, 0, 128)); 593 paint.setBrush (QColor (64, 192, 0, 128));
584 paint.drawPolygon (poly, numverts); 594 paint.drawPolygon (poly, numverts);
585 595
586 // Draw vertex blips 596 // Draw vertex blips
587 for (int i = 0; i < numverts; ++i) { 597 for (int i = 0; i < numverts; ++i)
588 QPoint& blip = poly[i]; 598 { QPoint& blip = poly[i];
589 drawBlip (paint, blip); 599 drawBlip (paint, blip);
590 600
591 // Draw their coordinates 601 // Draw their coordinates
592 paint.drawText (blip.x(), blip.y() - 8, polyverts[i].stringRep (true)); 602 paint.drawText (blip.x(), blip.y() - 8, polyverts[i].stringRep (true));
593 } 603 }
594 } 604 }
595 } 605 }
606
596 elif (editMode() == CircleMode) 607 elif (editMode() == CircleMode)
597 { // If we have not specified the center point of the circle yet, preview it on the screen. 608 { // If we have not specified the center point of the circle yet, preview it on the screen.
598 if (m_drawedVerts.size() == 0) 609 if (m_drawedVerts.size() == 0)
599 drawBlip (paint, coordconv3_2 (m_hoverpos)); 610 drawBlip (paint, coordconv3_2 (m_hoverpos));
600 else 611 else
611 v[relY] = m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist); 622 v[relY] = m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist);
612 verts << v; 623 verts << v;
613 } 624 }
614 625
615 QVector<QPoint> points; 626 QVector<QPoint> points;
616 for (const vertex& v : verts) 627
628 for (const vertex & v : verts)
617 { QPoint point = coordconv3_2 (v); 629 { QPoint point = coordconv3_2 (v);
618 drawBlip (paint, point); 630 drawBlip (paint, point);
619 points << point; 631 points << point;
620 } 632 }
621 633
626 paint.setBrush (Qt::NoBrush); 638 paint.setBrush (Qt::NoBrush);
627 paint.drawPolygon (QPolygon (points)); 639 paint.drawPolygon (QPolygon (points));
628 } 640 }
629 } 641 }
630 } 642 }
631 643
632 // Camera icons 644 // Camera icons
633 if (!m_picking) { 645 if (!m_picking)
634 // Draw a background for the selected camera 646 { // Draw a background for the selected camera
635 paint.setPen (m_thinBorderPen); 647 paint.setPen (m_thinBorderPen);
636 paint.setBrush (QBrush (QColor (0, 128, 160, 128))); 648 paint.setBrush (QBrush (QColor (0, 128, 160, 128)));
637 paint.drawRect (m_cameraIcons[camera()].selRect); 649 paint.drawRect (m_cameraIcons[camera()].selRect);
638 650
639 // Draw the actual icons 651 // Draw the actual icons
640 for (CameraIcon& info : m_cameraIcons) { 652 for (CameraIcon & info : m_cameraIcons)
641 // Don't draw the free camera icon when in draw mode 653 { // Don't draw the free camera icon when in draw mode
642 if (&info == &m_cameraIcons[GL::Free] && editMode() != Select) 654 if (&info == &m_cameraIcons[GL::Free] && editMode() != Select)
643 continue; 655 continue;
644 656
645 paint.drawPixmap (info.destRect, *info.img, info.srcRect); 657 paint.drawPixmap (info.destRect, *info.img, info.srcRect);
646 } 658 }
647 659
648 str fmtstr = tr ("%1 Camera"); 660 str fmtstr = tr ("%1 Camera");
649 661
650 // Draw a label for the current camera in the bottom left corner 662 // Draw a label for the current camera in the bottom left corner
651 { 663 { const ushort margin = 4;
652 const ushort margin = 4; 664
653
654 str label; 665 str label;
655 label = fmt (fmtstr, tr (g_CameraNames[camera()])); 666 label = fmt (fmtstr, tr (g_CameraNames[camera()]));
656 paint.setPen (getTextPen()); 667 paint.setPen (getTextPen());
657 paint.drawText (QPoint (margin, height() - (margin + metrics.descent())), label); 668 paint.drawText (QPoint (margin, height() - (margin + metrics.descent())), label);
658 } 669 }
659 670
660 // Tool tips 671 // Tool tips
661 if (m_drawToolTip) { 672 if (m_drawToolTip)
662 if (m_cameraIcons[m_toolTipCamera].destRect.contains (m_pos) == false) 673 { if (m_cameraIcons[m_toolTipCamera].destRect.contains (m_pos) == false)
663 m_drawToolTip = false; 674 m_drawToolTip = false;
664 else { 675 else
665 str label = fmt (fmtstr, tr (g_CameraNames[m_toolTipCamera])); 676 { str label = fmt (fmtstr, tr (g_CameraNames[m_toolTipCamera]));
666 QToolTip::showText (m_globalpos, label); 677 QToolTip::showText (m_globalpos, label);
667 } 678 }
668 } 679 }
669 } 680 }
670 681
671 // Message log 682 // Message log
672 if (msglog()) { 683 if (msglog())
673 int y = 0; 684 { int y = 0;
674 const int margin = 2; 685 const int margin = 2;
675 QColor penColor = getTextPen(); 686 QColor penColor = getTextPen();
676 687
677 for (const MessageManager::Line& line : msglog()->getLines()) { 688 for (const MessageManager::Line & line : msglog()->getLines())
678 penColor.setAlphaF (line.alpha); 689 { penColor.setAlphaF (line.alpha);
679 paint.setPen (penColor); 690 paint.setPen (penColor);
680 paint.drawText (QPoint (margin, y + margin + metrics.ascent()), line.text); 691 paint.drawText (QPoint (margin, y + margin + metrics.ascent()), line.text);
681 y += metrics.height(); 692 y += metrics.height();
682 } 693 }
683 } 694 }
684 695
685 // If we're range-picking, draw a rectangle encompassing the selection area. 696 // If we're range-picking, draw a rectangle encompassing the selection area.
686 if (m_rangepick && !m_picking && m_totalmove >= 10) { 697 if (m_rangepick && !m_picking && m_totalmove >= 10)
687 const short x0 = m_rangeStart.x(), 698 { const short x0 = m_rangeStart.x(),
688 y0 = m_rangeStart.y(), 699 y0 = m_rangeStart.y(),
689 x1 = m_pos.x(), 700 x1 = m_pos.x(),
690 y1 = m_pos.y(); 701 y1 = m_pos.y();
691 702
692 QRect rect (x0, y0, x1 - x0, y1 - y0); 703 QRect rect (x0, y0, x1 - x0, y1 - y0);
693 QColor fillColor = (m_addpick ? "#40FF00" : "#00CCFF"); 704 QColor fillColor = (m_addpick ? "#40FF00" : "#00CCFF");
694 fillColor.setAlphaF (0.2f); 705 fillColor.setAlphaF (0.2f);
695 706
696 paint.setPen (m_thickBorderPen); 707 paint.setPen (m_thickBorderPen);
697 paint.setBrush (QBrush (fillColor)); 708 paint.setBrush (QBrush (fillColor));
698 paint.drawRect (rect); 709 paint.drawRect (rect);
699 } 710 }
700 } 711 }
710 paint.drawEllipse (pos.x() - blipsize / 2, pos.y() - blipsize / 2, blipsize, blipsize); 721 paint.drawEllipse (pos.x() - blipsize / 2, pos.y() - blipsize / 2, blipsize, blipsize);
711 } 722 }
712 723
713 // ============================================================================= 724 // =============================================================================
714 // ----------------------------------------------------------------------------- 725 // -----------------------------------------------------------------------------
715 QColor GLRenderer::getTextPen () const { 726 QColor GLRenderer::getTextPen () const
716 return m_darkbg ? Qt::white : Qt::black; 727 { return m_darkbg ? Qt::white : Qt::black;
717 } 728 }
718 729
719 // ============================================================================= 730 // =============================================================================
720 // ----------------------------------------------------------------------------- 731 // -----------------------------------------------------------------------------
721 void GLRenderer::compileAllObjects() { 732 void GLRenderer::compileAllObjects()
722 if (!file()) 733 { if (!file())
723 return; 734 return;
724 735
725 // Compiling all is a big job, use a busy cursor 736 // Compiling all is a big job, use a busy cursor
726 setCursor (Qt::BusyCursor); 737 setCursor (Qt::BusyCursor);
727 738
728 m_knownVerts.clear(); 739 m_knownVerts.clear();
729 740
730 for (LDObject* obj : file()->objects()) 741 for (LDObject * obj : file()->objects())
731 compileObject (obj); 742 compileObject (obj);
732 743
733 // Compile axes 744 // Compile axes
734 glDeleteLists (m_axeslist, 1); 745 glDeleteLists (m_axeslist, 1);
735 m_axeslist = glGenLists (1); 746 m_axeslist = glGenLists (1);
736 glNewList (m_axeslist, GL_COMPILE); 747 glNewList (m_axeslist, GL_COMPILE);
737 glBegin (GL_LINES); 748 glBegin (GL_LINES);
738 749
739 for (const GLAxis& ax : g_GLAxes) { 750 for (const GLAxis & ax : g_GLAxes)
740 qglColor (ax.col); 751 { qglColor (ax.col);
741 compileVertex (ax.vert); 752 compileVertex (ax.vert);
742 compileVertex (-ax.vert); 753 compileVertex (-ax.vert);
743 } 754 }
744 755
745 glEnd(); 756 glEnd();
746 glEndList(); 757 glEndList();
747 758
748 setCursor (Qt::ArrowCursor); 759 setCursor (Qt::ArrowCursor);
749 } 760 }
750 761
751 // ============================================================================= 762 // =============================================================================
752 // ----------------------------------------------------------------------------- 763 // -----------------------------------------------------------------------------
753 void GLRenderer::compileSubObject (LDObject* obj, const GLenum gltype) { 764 void GLRenderer::compileSubObject (LDObject* obj, const GLenum gltype)
754 glBegin (gltype); 765 { glBegin (gltype);
755 766
756 const short numverts = (obj->getType() != LDObject::CndLine) ? obj->vertices() : 2; 767 const short numverts = (obj->getType() != LDObject::CndLine) ? obj->vertices() : 2;
757 768
758 if (g_glInvert == false) 769 if (g_glInvert == false)
759 for (short i = 0; i < numverts; ++i) 770 for (short i = 0; i < numverts; ++i)
760 compileVertex (obj->m_coords[i]); 771 compileVertex (obj->m_coords[i]);
761 else 772 else
762 for (short i = numverts - 1; i >= 0; --i) 773 for (short i = numverts - 1; i >= 0; --i)
763 compileVertex (obj->m_coords[i]); 774 compileVertex (obj->m_coords[i]);
764 775
765 glEnd(); 776 glEnd();
766 } 777 }
767 778
768 // ============================================================================= 779 // =============================================================================
769 // ----------------------------------------------------------------------------- 780 // -----------------------------------------------------------------------------
770 void GLRenderer::compileList (LDObject* obj, const GLRenderer::ListType list) { 781 void GLRenderer::compileList (LDObject* obj, const GLRenderer::ListType list)
771 setObjectColor (obj, list); 782 { setObjectColor (obj, list);
772 783
773 switch (obj->getType()) { 784 switch (obj->getType())
774 case LDObject::Line: 785 { case LDObject::Line:
775 compileSubObject (obj, GL_LINES); 786 compileSubObject (obj, GL_LINES);
776 break; 787 break;
777 788
778 case LDObject::CndLine: 789 case LDObject::CndLine:
779 // Draw conditional lines with a dash pattern - however, use a full 790
780 // line when drawing a pick list to make selecting them easier. 791 // Draw conditional lines with a dash pattern - however, use a full
781 if (list != GL::PickList) { 792 // line when drawing a pick list to make selecting them easier.
782 glLineStipple (1, 0x6666); 793 if (list != GL::PickList)
783 glEnable (GL_LINE_STIPPLE); 794 { glLineStipple (1, 0x6666);
784 } 795 glEnable (GL_LINE_STIPPLE);
785 796 }
786 compileSubObject (obj, GL_LINES); 797
787 798 compileSubObject (obj, GL_LINES);
788 glDisable (GL_LINE_STIPPLE); 799
789 break; 800 glDisable (GL_LINE_STIPPLE);
790 801 break;
791 case LDObject::Triangle: 802
792 compileSubObject (obj, GL_TRIANGLES); 803 case LDObject::Triangle:
793 break; 804 compileSubObject (obj, GL_TRIANGLES);
794 805 break;
795 case LDObject::Quad: 806
796 compileSubObject (obj, GL_QUADS); 807 case LDObject::Quad:
797 break; 808 compileSubObject (obj, GL_QUADS);
798 809 break;
799 case LDObject::Subfile: { 810
800 LDSubfile* ref = static_cast<LDSubfile*> (obj); 811 case LDObject::Subfile:
812 { LDSubfile* ref = static_cast<LDSubfile*> (obj);
801 List<LDObject*> objs; 813 List<LDObject*> objs;
802 814
803 objs = ref->inlineContents ( 815 objs = ref->inlineContents (
804 LDSubfile::DeepInline | 816 LDSubfile::DeepInline |
805 LDSubfile::CacheInline | 817 LDSubfile::CacheInline |
806 LDSubfile::RendererInline); 818 LDSubfile::RendererInline);
807 bool oldinvert = g_glInvert; 819 bool oldinvert = g_glInvert;
808 820
809 if (ref->transform().determinant() < 0) 821 if (ref->transform().determinant() < 0)
810 g_glInvert = !g_glInvert; 822 g_glInvert = !g_glInvert;
811 823
812 LDObject* prev = ref->prev(); 824 LDObject* prev = ref->prev();
825
813 if (prev && prev->getType() == LDObject::BFC && static_cast<LDBFC*> (prev)->type == LDBFC::InvertNext) 826 if (prev && prev->getType() == LDObject::BFC && static_cast<LDBFC*> (prev)->type == LDBFC::InvertNext)
814 g_glInvert = !g_glInvert; 827 g_glInvert = !g_glInvert;
815 828
816 for (LDObject* obj : objs) { 829 for (LDObject * obj : objs)
817 compileList (obj, list); 830 { compileList (obj, list);
818 delete obj; 831 delete obj;
819 } 832 }
820 833
821 g_glInvert = oldinvert; 834 g_glInvert = oldinvert;
822 } 835 }
823 break; 836 break;
824 837
825 default: 838 default:
826 break; 839 break;
827 } 840 }
828 } 841 }
829 842
830 // ============================================================================= 843 // =============================================================================
831 // ----------------------------------------------------------------------------- 844 // -----------------------------------------------------------------------------
832 void GLRenderer::compileVertex (const vertex& vrt) { 845 void GLRenderer::compileVertex (const vertex& vrt)
833 glVertex3d (vrt[X], -vrt[Y], -vrt[Z]); 846 { glVertex3d (vrt[X], -vrt[Y], -vrt[Z]);
834 } 847 }
835 848
836 // ============================================================================= 849 // =============================================================================
837 // ----------------------------------------------------------------------------- 850 // -----------------------------------------------------------------------------
838 void GLRenderer::clampAngle (double& angle) const { 851 void GLRenderer::clampAngle (double& angle) const
839 while (angle < 0) 852 { while (angle < 0)
840 angle += 360.0; 853 angle += 360.0;
854
841 while (angle > 360.0) 855 while (angle > 360.0)
842 angle -= 360.0; 856 angle -= 360.0;
843 } 857 }
844 858
845 // ============================================================================= 859 // =============================================================================
846 // ----------------------------------------------------------------------------- 860 // -----------------------------------------------------------------------------
847 void GLRenderer::addDrawnVertex (vertex pos) { 861 void GLRenderer::addDrawnVertex (vertex pos)
848 // If we picked an already-existing vertex, stop drawing 862 { // If we picked an already-existing vertex, stop drawing
849 for (vertex& vert : m_drawedVerts) { 863 for (vertex & vert : m_drawedVerts)
850 if (vert == pos) { 864 { if (vert == pos)
851 endDraw (true); 865 { endDraw (true);
852 return; 866 return;
853 } 867 }
854 } 868 }
855 869
856 m_drawedVerts << pos; 870 m_drawedVerts << pos;
857 } 871 }
858 872
859 // ============================================================================= 873 // =============================================================================
860 // ----------------------------------------------------------------------------- 874 // -----------------------------------------------------------------------------
861 void GLRenderer::mouseReleaseEvent (QMouseEvent* ev) { 875 void GLRenderer::mouseReleaseEvent (QMouseEvent* ev)
862 const bool wasLeft = (m_lastButtons & Qt::LeftButton) && !(ev->buttons() & Qt::LeftButton), 876 { const bool wasLeft = (m_lastButtons & Qt::LeftButton) && ! (ev->buttons() & Qt::LeftButton),
863 wasRight = (m_lastButtons & Qt::RightButton) && !(ev->buttons() & Qt::RightButton), 877 wasRight = (m_lastButtons & Qt::RightButton) && ! (ev->buttons() & Qt::RightButton),
864 wasMid = (m_lastButtons & Qt::MidButton) && !(ev->buttons() & Qt::MidButton); 878 wasMid = (m_lastButtons & Qt::MidButton) && ! (ev->buttons() & Qt::MidButton);
865 879
866 if (m_panning) 880 if (m_panning)
867 m_panning = false; 881 m_panning = false;
868 882
869 if (wasLeft) { 883 if (wasLeft)
870 // Check if we selected a camera icon 884 { // Check if we selected a camera icon
871 if (!m_rangepick) { 885 if (!m_rangepick)
872 for (CameraIcon& info : m_cameraIcons) { 886 { for (CameraIcon & info : m_cameraIcons)
873 if (info.destRect.contains (ev->pos())) { 887 { if (info.destRect.contains (ev->pos()))
874 setCamera (info.cam); 888 { setCamera (info.cam);
875 goto end; 889 goto end;
876 } 890 }
877 } 891 }
878 } 892 }
879 893
880 switch (editMode()) { 894 switch (editMode())
881 case Draw: 895 { case Draw:
882 if (m_rectdraw) { 896
883 if (m_drawedVerts.size() == 2) { 897 if (m_rectdraw)
884 endDraw (true); 898 { if (m_drawedVerts.size() == 2)
899 { endDraw (true);
900 return;
901 }
902 }
903 else
904 { // If we have 4 verts, stop drawing.
905 if (m_drawedVerts.size() >= 4)
906 { endDraw (true);
907 return;
908 }
909
910 if (m_drawedVerts.size() == 0 && ev->modifiers() & Qt::ShiftModifier)
911 { m_rectdraw = true;
912 updateRectVerts();
913 }
914 }
915
916 addDrawnVertex (m_hoverpos);
917 break;
918
919 case CircleMode:
920
921 if (m_drawedVerts.size() == 2)
922 { endDraw (true);
885 return; 923 return;
886 } 924 }
887 } else { 925
888 // If we have 4 verts, stop drawing. 926 addDrawnVertex (m_hoverpos);
889 if (m_drawedVerts.size() >= 4) { 927 break;
890 endDraw (true); 928
891 return; 929 case Select:
930
931 if (!drawOnly())
932 { if (m_totalmove < 10)
933 m_rangepick = false;
934
935 if (!m_rangepick)
936 m_addpick = (m_keymods & Qt::ControlModifier);
937
938 if (m_totalmove < 10 || m_rangepick)
939 pick (ev->x(), ev->y());
892 } 940 }
893 941
894 if (m_drawedVerts.size() == 0 && ev->modifiers() & Qt::ShiftModifier) { 942 break;
895 m_rectdraw = true; 943 }
896 updateRectVerts(); 944
897 }
898 }
899
900 addDrawnVertex (m_hoverpos);
901 break;
902
903 case CircleMode:
904 if (m_drawedVerts.size() == 2)
905 { endDraw (true);
906 return;
907 }
908
909 addDrawnVertex (m_hoverpos);
910 break;
911
912 case Select:
913 if (!drawOnly()) {
914 if (m_totalmove < 10)
915 m_rangepick = false;
916
917 if (!m_rangepick)
918 m_addpick = (m_keymods & Qt::ControlModifier);
919
920 if (m_totalmove < 10 || m_rangepick)
921 pick (ev->x(), ev->y());
922 }
923
924 break;
925 }
926
927 m_rangepick = false; 945 m_rangepick = false;
928 } 946 }
929 947
930 if (wasMid && editMode() == Draw && m_drawedVerts.size() < 4 && m_totalmove < 10) { 948 if (wasMid && editMode() != Select && m_drawedVerts.size() < 4 && m_totalmove < 10)
931 // Find the closest vertex to our cursor 949 { // Find the closest vertex to our cursor
932 double mindist = 1024.0f; 950 double mindist = 1024.0f;
933 vertex closest; 951 vertex closest;
934 bool valid = false; 952 bool valid = false;
935 953
936 QPoint curspos = coordconv3_2 (m_hoverpos); 954 QPoint curspos = coordconv3_2 (m_hoverpos);
937 955
938 for (const vertex& pos3d: m_knownVerts) { 956 for (const vertex & pos3d: m_knownVerts)
939 QPoint pos2d = coordconv3_2 (pos3d); 957 { QPoint pos2d = coordconv3_2 (pos3d);
940 958
941 // Measure squared distance 959 // Measure squared distance
942 const double dx = abs (pos2d.x() - curspos.x()), 960 const double dx = abs (pos2d.x() - curspos.x()),
943 dy = abs (pos2d.y() - curspos.y()), 961 dy = abs (pos2d.y() - curspos.y()),
944 distsq = (dx * dx) + (dy * dy); 962 distsq = (dx * dx) + (dy * dy);
945 963
946 if (distsq >= 1024.0f) // 32.0f ** 2 964 if (distsq >= 1024.0f) // 32.0f ** 2
947 continue; // too far away 965 continue; // too far away
948 966
949 if (distsq < mindist) { 967 if (distsq < mindist)
950 mindist = distsq; 968 { mindist = distsq;
951 closest = pos3d; 969 closest = pos3d;
952 valid = true; 970 valid = true;
953 971
954 // If it's only 4 pixels away, I think we found our vertex now. 972 // If it's only 4 pixels away, I think we found our vertex now.
955 if (distsq <= 16.0f) // 4.0f ** 2 973 if (distsq <= 16.0f) // 4.0f ** 2
956 break; 974 break;
957 } 975 }
958 } 976 }
959 977
960 if (valid) 978 if (valid)
961 addDrawnVertex (closest); 979 addDrawnVertex (closest);
962 } 980 }
963 981
964 if (wasRight && m_drawedVerts.size() > 0) { 982 if (wasRight && m_drawedVerts.size() > 0)
965 // Remove the last vertex 983 { // Remove the last vertex
966 m_drawedVerts.erase (m_drawedVerts.size() - 1); 984 m_drawedVerts.erase (m_drawedVerts.size() - 1);
967 985
968 if (m_drawedVerts.size() == 0) 986 if (m_drawedVerts.size() == 0)
969 m_rectdraw = false; 987 m_rectdraw = false;
970 } 988 }
971 989
972 end: 990 end:
973 update(); 991 update();
974 m_totalmove = 0; 992 m_totalmove = 0;
975 } 993 }
976 994
977 // ============================================================================= 995 // =============================================================================
978 // ----------------------------------------------------------------------------- 996 // -----------------------------------------------------------------------------
979 void GLRenderer::mousePressEvent (QMouseEvent* ev) { 997 void GLRenderer::mousePressEvent (QMouseEvent* ev)
980 m_totalmove = 0; 998 { m_totalmove = 0;
981 999
982 if (ev->modifiers() & Qt::ControlModifier) { 1000 if (ev->modifiers() & Qt::ControlModifier)
983 m_rangepick = true; 1001 { m_rangepick = true;
984 m_rangeStart.setX (ev->x()); 1002 m_rangeStart.setX (ev->x());
985 m_rangeStart.setY (ev->y()); 1003 m_rangeStart.setY (ev->y());
986 m_addpick = (m_keymods & Qt::AltModifier); 1004 m_addpick = (m_keymods & Qt::AltModifier);
987 ev->accept(); 1005 ev->accept();
988 } 1006 }
989 1007
990 m_lastButtons = ev->buttons(); 1008 m_lastButtons = ev->buttons();
991 } 1009 }
992 1010
993 // ============================================================================= 1011 // =============================================================================
994 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 1012 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
995 // ============================================================================= 1013 // =============================================================================
996 void GLRenderer::mouseMoveEvent (QMouseEvent* ev) { 1014 void GLRenderer::mouseMoveEvent (QMouseEvent* ev)
997 int dx = ev->x() - m_pos.x(); 1015 { int dx = ev->x() - m_pos.x();
998 int dy = ev->y() - m_pos.y(); 1016 int dy = ev->y() - m_pos.y();
999 m_totalmove += abs (dx) + abs (dy); 1017 m_totalmove += abs (dx) + abs (dy);
1000 1018
1001 const bool left = ev->buttons() & Qt::LeftButton, 1019 const bool left = ev->buttons() & Qt::LeftButton,
1002 mid = ev->buttons() & Qt::MidButton, 1020 mid = ev->buttons() & Qt::MidButton,
1003 shift = ev->modifiers() & Qt::ShiftModifier; 1021 shift = ev->modifiers() & Qt::ShiftModifier;
1004 1022
1005 if (mid || (left && shift)) { 1023 if (mid || (left && shift))
1006 m_panX += 0.03f * dx * (zoom() / 7.5f); 1024 { m_panX += 0.03f * dx * (zoom() / 7.5f);
1007 m_panY -= 0.03f * dy * (zoom() / 7.5f); 1025 m_panY -= 0.03f * dy * (zoom() / 7.5f);
1008 m_panning = true; 1026 m_panning = true;
1009 } elif (left && !m_rangepick && camera() == Free) { 1027 } elif (left && !m_rangepick && camera() == Free)
1010 m_rotX = m_rotX + (dy); 1028
1029 { m_rotX = m_rotX + (dy);
1011 m_rotY = m_rotY + (dx); 1030 m_rotY = m_rotY + (dx);
1012 1031
1013 clampAngle (m_rotX); 1032 clampAngle (m_rotX);
1014 clampAngle (m_rotY); 1033 clampAngle (m_rotY);
1015 } 1034 }
1016 1035
1017 // Start the tool tip timer 1036 // Start the tool tip timer
1018 if (!m_drawToolTip) 1037 if (!m_drawToolTip)
1019 m_toolTipTimer->start (500); 1038 m_toolTipTimer->start (500);
1020 1039
1021 // Update 2d position 1040 // Update 2d position
1022 m_pos = ev->pos(); 1041 m_pos = ev->pos();
1023 m_globalpos = ev->globalPos(); 1042 m_globalpos = ev->globalPos();
1024 1043
1025 // Calculate 3d position of the cursor 1044 // Calculate 3d position of the cursor
1026 m_hoverpos = (camera() != Free) ? coordconv2_3 (m_pos, true) : g_origin; 1045 m_hoverpos = (camera() != Free) ? coordconv2_3 (m_pos, true) : g_origin;
1027 1046
1028 // Update rect vertices since m_hoverpos may have changed 1047 // Update rect vertices since m_hoverpos may have changed
1029 updateRectVerts(); 1048 updateRectVerts();
1030 1049
1031 update(); 1050 update();
1032 } 1051 }
1033 1052
1034 // ============================================================================= 1053 // =============================================================================
1035 // ----------------------------------------------------------------------------- 1054 // -----------------------------------------------------------------------------
1036 void GLRenderer::keyPressEvent (QKeyEvent* ev) { 1055 void GLRenderer::keyPressEvent (QKeyEvent* ev)
1037 m_keymods = ev->modifiers(); 1056 { m_keymods = ev->modifiers();
1038 } 1057 }
1039 1058
1040 // ============================================================================= 1059 // =============================================================================
1041 // ----------------------------------------------------------------------------- 1060 // -----------------------------------------------------------------------------
1042 void GLRenderer::keyReleaseEvent (QKeyEvent* ev) { 1061 void GLRenderer::keyReleaseEvent (QKeyEvent* ev)
1043 m_keymods = ev->modifiers(); 1062 { m_keymods = ev->modifiers();
1044 } 1063 }
1045 1064
1046 // ============================================================================= 1065 // =============================================================================
1047 // ----------------------------------------------------------------------------- 1066 // -----------------------------------------------------------------------------
1048 void GLRenderer::wheelEvent (QWheelEvent* ev) { 1067 void GLRenderer::wheelEvent (QWheelEvent* ev)
1049 makeCurrent(); 1068 { makeCurrent();
1050 1069
1051 zoomNotch (ev->delta() > 0); 1070 zoomNotch (ev->delta() > 0);
1052 setZoom (clamp<double> (zoom(), 0.01f, 10000.0f)); 1071 setZoom (clamp<double> (zoom(), 0.01f, 10000.0f));
1053 1072
1054 update(); 1073 update();
1055 ev->accept(); 1074 ev->accept();
1056 } 1075 }
1057 1076
1058 // ============================================================================= 1077 // =============================================================================
1059 // ----------------------------------------------------------------------------- 1078 // -----------------------------------------------------------------------------
1060 void GLRenderer::leaveEvent (QEvent* ev) { 1079 void GLRenderer::leaveEvent (QEvent* ev)
1061 (void) ev; 1080 { (void) ev;
1062 m_drawToolTip = false; 1081 m_drawToolTip = false;
1063 m_toolTipTimer->stop(); 1082 m_toolTipTimer->stop();
1064 update(); 1083 update();
1065 } 1084 }
1066 1085
1067 // ============================================================================= 1086 // =============================================================================
1068 // ----------------------------------------------------------------------------- 1087 // -----------------------------------------------------------------------------
1069 void GLRenderer::contextMenuEvent (QContextMenuEvent* ev) { 1088 void GLRenderer::contextMenuEvent (QContextMenuEvent* ev)
1070 g_win->spawnContextMenu (ev->globalPos()); 1089 { g_win->spawnContextMenu (ev->globalPos());
1071 } 1090 }
1072 1091
1073 // ============================================================================= 1092 // =============================================================================
1074 // ----------------------------------------------------------------------------- 1093 // -----------------------------------------------------------------------------
1075 void GLRenderer::setCamera (const GL::Camera cam) { 1094 void GLRenderer::setCamera (const GL::Camera cam)
1076 m_camera = cam; 1095 { m_camera = cam;
1077 gl_camera = (int) cam; 1096 gl_camera = (int) cam;
1078 g_win->updateEditModeActions(); 1097 g_win->updateEditModeActions();
1079 } 1098 }
1080 1099
1081 // ============================================================================= 1100 // =============================================================================
1082 // ----------------------------------------------------------------------------- 1101 // -----------------------------------------------------------------------------
1083 void GLRenderer::pick (uint mouseX, uint mouseY) { 1102 void GLRenderer::pick (uint mouseX, uint mouseY)
1084 GLint viewport[4]; 1103 { GLint viewport[4];
1085 makeCurrent(); 1104 makeCurrent();
1086 1105
1087 // Use particularly thick lines while picking ease up selecting lines. 1106 // Use particularly thick lines while picking ease up selecting lines.
1088 glLineWidth (max<double> (gl_linethickness, 6.5f)); 1107 glLineWidth (max<double> (gl_linethickness, 6.5f));
1089 1108
1090 // Clear the selection if we do not wish to add to it. 1109 // Clear the selection if we do not wish to add to it.
1091 if (!m_addpick) { 1110 if (!m_addpick)
1092 List<LDObject*> oldsel = g_win->sel(); 1111 { List<LDObject*> oldsel = g_win->sel();
1093 g_win->sel().clear(); 1112 g_win->sel().clear();
1094 1113
1095 for (LDObject* obj : oldsel) { 1114 for (LDObject * obj : oldsel)
1096 obj->setSelected (false); 1115 { obj->setSelected (false);
1097 compileObject (obj); 1116 compileObject (obj);
1098 } 1117 }
1099 } 1118 }
1100 1119
1101 m_picking = true; 1120 m_picking = true;
1102 1121
1103 // Paint the picking scene 1122 // Paint the picking scene
1104 glDisable (GL_DITHER); 1123 glDisable (GL_DITHER);
1105 glClearColor (1.0f, 1.0f, 1.0f, 1.0f); 1124 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
1106 1125
1107 drawGLScene(); 1126 drawGLScene();
1108 1127
1109 glGetIntegerv (GL_VIEWPORT, viewport); 1128 glGetIntegerv (GL_VIEWPORT, viewport);
1110 1129
1111 short x0 = mouseX, 1130 short x0 = mouseX,
1112 y0 = mouseY; 1131 y0 = mouseY;
1113 short x1, y1; 1132 short x1, y1;
1114 1133
1115 // Determine how big an area to read - with range picking, we pick by 1134 // Determine how big an area to read - with range picking, we pick by
1116 // the area given, with single pixel picking, we use an 1 x 1 area. 1135 // the area given, with single pixel picking, we use an 1 x 1 area.
1117 if (m_rangepick) { 1136 if (m_rangepick)
1118 x1 = m_rangeStart.x(); 1137 { x1 = m_rangeStart.x();
1119 y1 = m_rangeStart.y(); 1138 y1 = m_rangeStart.y();
1120 } else { 1139 }
1121 x1 = x0 + 1; 1140 else
1141 { x1 = x0 + 1;
1122 y1 = y0 + 1; 1142 y1 = y0 + 1;
1123 } 1143 }
1124 1144
1125 // x0 and y0 must be less than x1 and y1, respectively. 1145 // x0 and y0 must be less than x1 and y1, respectively.
1126 if (x0 > x1) 1146 if (x0 > x1)
1127 dataswap (x0, x1); 1147 dataswap (x0, x1);
1128 1148
1129 if (y0 > y1) 1149 if (y0 > y1)
1130 dataswap (y0, y1); 1150 dataswap (y0, y1);
1131 1151
1132 // Clamp the values to ensure they're within bounds 1152 // Clamp the values to ensure they're within bounds
1133 x0 = max<short> (0, x0); 1153 x0 = max<short> (0, x0);
1134 y0 = max<short> (0, y0); 1154 y0 = max<short> (0, y0);
1135 x1 = min<short> (x1, m_width); 1155 x1 = min<short> (x1, m_width);
1136 y1 = min<short> (y1, m_height); 1156 y1 = min<short> (y1, m_height);
1137 1157
1138 const short areawidth = (x1 - x0); 1158 const short areawidth = (x1 - x0);
1139 const short areaheight = (y1 - y0); 1159 const short areaheight = (y1 - y0);
1140 const long numpixels = areawidth * areaheight; 1160 const long numpixels = areawidth * areaheight;
1141 1161
1142 // Allocate space for the pixel data. 1162 // Allocate space for the pixel data.
1143 uchar* const pixeldata = new uchar[4 * numpixels]; 1163 uchar* const pixeldata = new uchar[4 * numpixels];
1144 uchar* pixelptr = &pixeldata[0]; 1164 uchar* pixelptr = &pixeldata[0];
1145 1165
1146 assert (viewport[3] == m_height); 1166 assert (viewport[3] == m_height);
1147 1167
1148 // Read pixels from the color buffer. 1168 // Read pixels from the color buffer.
1149 glReadPixels (x0, viewport[3] - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixeldata); 1169 glReadPixels (x0, viewport[3] - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixeldata);
1150 1170
1151 LDObject* removedObj = null; 1171 LDObject* removedObj = null;
1152 1172
1153 // Go through each pixel read and add them to the selection. 1173 // Go through each pixel read and add them to the selection.
1154 for (long i = 0; i < numpixels; ++i) { 1174 for (long i = 0; i < numpixels; ++i)
1155 long idx = 1175 { long idx =
1156 (*(pixelptr + 0) * 0x10000) + 1176 (* (pixelptr + 0) * 0x10000) +
1157 (*(pixelptr + 1) * 0x00100) + 1177 (* (pixelptr + 1) * 0x00100) +
1158 (*(pixelptr + 2) * 0x00001); 1178 (* (pixelptr + 2) * 0x00001);
1159 pixelptr += 4; 1179 pixelptr += 4;
1160 1180
1161 if (idx == 0xFFFFFF) 1181 if (idx == 0xFFFFFF)
1162 continue; // White is background; skip 1182 continue; // White is background; skip
1163 1183
1164 LDObject* obj = LDObject::fromID (idx); 1184 LDObject* obj = LDObject::fromID (idx);
1165 1185
1166 // If this is an additive single pick and the object is currently selected, 1186 // If this is an additive single pick and the object is currently selected,
1167 // we remove it from selection instead. 1187 // we remove it from selection instead.
1168 if (!m_rangepick && m_addpick) { 1188 if (!m_rangepick && m_addpick)
1169 bool removed = false; 1189 { bool removed = false;
1170 1190
1171 for (ulong i = 0; i < g_win->sel().size(); ++i) { 1191 for (ulong i = 0; i < g_win->sel().size(); ++i)
1172 if (g_win->sel()[i] == obj) { 1192 { if (g_win->sel() [i] == obj)
1173 g_win->sel().erase (i); 1193 { g_win->sel().erase (i);
1174 obj->setSelected (false); 1194 obj->setSelected (false);
1175 removed = true; 1195 removed = true;
1176 removedObj = obj; 1196 removedObj = obj;
1177 } 1197 }
1178 } 1198 }
1179 1199
1180 if (removed) 1200 if (removed)
1181 break; 1201 break;
1182 } 1202 }
1183 1203
1184 g_win->sel() << obj; 1204 g_win->sel() << obj;
1185 } 1205 }
1186 1206
1187 delete[] pixeldata; 1207 delete[] pixeldata;
1188 1208
1189 // Remove duplicated entries 1209 // Remove duplicated entries
1190 g_win->sel().makeUnique(); 1210 g_win->sel().makeUnique();
1191 1211
1192 // Update everything now. 1212 // Update everything now.
1193 g_win->updateSelection(); 1213 g_win->updateSelection();
1194 1214
1195 // Recompile the objects now to update their color 1215 // Recompile the objects now to update their color
1196 for (LDObject* obj : g_win->sel()) 1216 for (LDObject * obj : g_win->sel())
1197 compileObject (obj); 1217 compileObject (obj);
1198 1218
1199 if (removedObj) 1219 if (removedObj)
1200 compileObject (removedObj); 1220 compileObject (removedObj);
1201 1221
1202 // Restore line thickness 1222 // Restore line thickness
1203 glLineWidth (gl_linethickness); 1223 glLineWidth (gl_linethickness);
1204 1224
1205 m_picking = false; 1225 m_picking = false;
1206 m_rangepick = false; 1226 m_rangepick = false;
1207 glEnable (GL_DITHER); 1227 glEnable (GL_DITHER);
1208 1228
1209 setBackground(); 1229 setBackground();
1210 repaint(); 1230 repaint();
1211 } 1231 }
1212 1232
1213 // ============================================================================= 1233 // =============================================================================
1214 // ----------------------------------------------------------------------------- 1234 // -----------------------------------------------------------------------------
1215 READ_ACCESSOR (EditMode, GLRenderer::editMode) { 1235 READ_ACCESSOR (EditMode, GLRenderer::editMode)
1216 return m_editMode; 1236 { return m_editMode;
1217 } 1237 }
1218 1238
1219 // ============================================================================= 1239 // =============================================================================
1220 // ----------------------------------------------------------------------------- 1240 // -----------------------------------------------------------------------------
1221 SET_ACCESSOR (EditMode, GLRenderer::setEditMode) { 1241 SET_ACCESSOR (EditMode, GLRenderer::setEditMode)
1222 m_editMode = val; 1242 { m_editMode = val;
1223 1243
1224 switch (editMode()) { 1244 switch (editMode())
1225 case Select: 1245 { case Select:
1226 unsetCursor(); 1246 unsetCursor();
1227 setContextMenuPolicy (Qt::DefaultContextMenu); 1247 setContextMenuPolicy (Qt::DefaultContextMenu);
1228 break; 1248 break;
1229 1249
1230 case Draw: 1250 case Draw:
1231 case CircleMode: 1251 case CircleMode:
1232 // Cannot draw into the free camera - use top instead. 1252
1233 if (m_camera == Free) 1253 // Cannot draw into the free camera - use top instead.
1234 setCamera (Top); 1254 if (m_camera == Free)
1235 1255 setCamera (Top);
1236 // Disable the context menu - we need the right mouse button 1256
1237 // for removing vertices. 1257 // Disable the context menu - we need the right mouse button
1238 setContextMenuPolicy (Qt::NoContextMenu); 1258 // for removing vertices.
1239 1259 setContextMenuPolicy (Qt::NoContextMenu);
1240 // Use the crosshair cursor when drawing. 1260
1241 setCursor (Qt::CrossCursor); 1261 // Use the crosshair cursor when drawing.
1242 1262 setCursor (Qt::CrossCursor);
1243 // Clear the selection when beginning to draw. 1263
1244 // FIXME: make the selection clearing stuff in ::pick a method and use it 1264 // Clear the selection when beginning to draw.
1245 // here! This code doesn't update the GL lists. 1265 // FIXME: make the selection clearing stuff in ::pick a method and use it
1246 g_win->sel().clear(); 1266 // here! This code doesn't update the GL lists.
1247 g_win->updateSelection(); 1267 g_win->sel().clear();
1248 m_drawedVerts.clear(); 1268 g_win->updateSelection();
1249 break; 1269 m_drawedVerts.clear();
1250 } 1270 break;
1251 1271 }
1272
1252 g_win->updateEditModeActions(); 1273 g_win->updateEditModeActions();
1253 update(); 1274 update();
1254 } 1275 }
1255 1276
1256 // ============================================================================= 1277 // =============================================================================
1257 // ----------------------------------------------------------------------------- 1278 // -----------------------------------------------------------------------------
1258 READ_ACCESSOR (LDFile*, GLRenderer::file) { 1279 READ_ACCESSOR (LDFile*, GLRenderer::file)
1259 return m_file; 1280 { return m_file;
1260 } 1281 }
1261 1282
1262 // ============================================================================= 1283 // =============================================================================
1263 // ----------------------------------------------------------------------------- 1284 // -----------------------------------------------------------------------------
1264 SET_ACCESSOR (LDFile*, GLRenderer::setFile) { 1285 SET_ACCESSOR (LDFile*, GLRenderer::setFile)
1265 m_file = val; 1286 { m_file = val;
1266 1287
1267 if (val != null) 1288 if (val != null)
1268 overlaysFromObjects(); 1289 overlaysFromObjects();
1269 } 1290 }
1270 1291
1271 // ============================================================================= 1292 // =============================================================================
1272 // ----------------------------------------------------------------------------- 1293 // -----------------------------------------------------------------------------
1273 void GLRenderer::endDraw (bool accept) { 1294 void GLRenderer::endDraw (bool accept)
1274 (void) accept; 1295 { (void) accept;
1275 1296
1276 // Clean the selection and create the object 1297 // Clean the selection and create the object
1277 List<vertex>& verts = m_drawedVerts; 1298 List<vertex>& verts = m_drawedVerts;
1278 LDObject* obj = null; 1299 LDObject* obj = null;
1279 1300
1280 switch (editMode()) 1301 switch (editMode())
1281 { case Draw: 1302 { case Draw:
1282 if (m_rectdraw) { 1303
1283 LDQuad* quad = new LDQuad; 1304 if (m_rectdraw)
1284 1305 { LDQuad* quad = new LDQuad;
1285 // Copy the vertices from m_rectverts 1306
1286 updateRectVerts(); 1307 // Copy the vertices from m_rectverts
1287 1308 updateRectVerts();
1288 for (int i = 0; i < quad->vertices(); ++i) 1309
1289 quad->setVertex (i, m_rectverts[i]); 1310 for (int i = 0; i < quad->vertices(); ++i)
1290 1311 quad->setVertex (i, m_rectverts[i]);
1291 quad->setColor (maincolor); 1312
1292 obj = quad; 1313 quad->setColor (maincolor);
1293 } else { 1314 obj = quad;
1294 switch (verts.size()) {
1295 case 1:
1296 // 1 vertex - add a vertex object
1297 obj = new LDVertex;
1298 static_cast<LDVertex*> (obj)->pos = verts[0];
1299 obj->setColor (maincolor);
1300 break;
1301
1302 case 2:
1303 // 2 verts - make a line
1304 obj = new LDLine (verts[0], verts[1]);
1305 obj->setColor (edgecolor);
1306 break;
1307
1308 case 3:
1309 case 4:
1310 obj = (verts.size() == 3) ?
1311 static_cast<LDObject*> (new LDTriangle) :
1312 static_cast<LDObject*> (new LDQuad);
1313
1314 obj->setColor (maincolor);
1315 for (ushort i = 0; i < obj->vertices(); ++i)
1316 obj->setVertex (i, verts[i]);
1317 break;
1318 } 1315 }
1319 } 1316 else
1320 break; 1317 { switch (verts.size())
1318 { case 1:
1319 // 1 vertex - add a vertex object
1320 obj = new LDVertex;
1321 static_cast<LDVertex*> (obj)->pos = verts[0];
1322 obj->setColor (maincolor);
1323 break;
1324
1325 case 2:
1326 // 2 verts - make a line
1327 obj = new LDLine (verts[0], verts[1]);
1328 obj->setColor (edgecolor);
1329 break;
1330
1331 case 3:
1332 case 4:
1333 obj = (verts.size() == 3) ?
1334 static_cast<LDObject*> (new LDTriangle) :
1335 static_cast<LDObject*> (new LDQuad);
1336
1337 obj->setColor (maincolor);
1338
1339 for (ushort i = 0; i < obj->vertices(); ++i)
1340 obj->setVertex (i, verts[i]);
1341
1342 break;
1343 }
1344 }
1345
1346 break;
1321 1347
1322 case CircleMode: 1348 case CircleMode:
1323 { const staticCameraMeta* cam = &g_staticCameras[m_camera]; 1349 { const staticCameraMeta* cam = &g_staticCameras[m_camera];
1324 const double dist = circleDrawDist(); 1350 const double dist = circleDrawDist();
1325 1351
1326 matrix transform = g_circleDrawTransforms[camera() % 3]; 1352 matrix transform = g_circleDrawTransforms[camera() % 3];
1353
1327 for (int i = 0; i < 9; ++i) 1354 for (int i = 0; i < 9; ++i)
1328 { if (transform[i] == 2) 1355 { if (transform[i] == 2)
1329 transform[i] = dist; 1356 transform[i] = dist;
1357
1330 elif (transform[i] == 1 && camera() >= 3) 1358 elif (transform[i] == 1 && camera() >= 3)
1331 transform[i] = -1; 1359 transform[i] = -1;
1332 } 1360 }
1333 1361
1334 LDSubfile* ref = new LDSubfile; 1362 LDSubfile* ref = new LDSubfile;
1335 ref->setFileInfo (findLoadedFile ("4-4edge.dat")); 1363 ref->setFileInfo (findLoadedFile ("4-4edge.dat"));
1336 ref->setTransform (transform); 1364 ref->setTransform (transform);
1339 obj = ref; 1367 obj = ref;
1340 } 1368 }
1341 break; 1369 break;
1342 1370
1343 case Select: 1371 case Select:
1344 assert (false); 1372 assert (false);
1345 return; 1373 return;
1346 } 1374 }
1347 1375
1348 if (obj) { 1376 if (obj)
1349 g_win->beginAction (null); 1377 { g_win->beginAction (null);
1350 file()->addObject (obj); 1378 file()->addObject (obj);
1351 compileObject (obj); 1379 compileObject (obj);
1352 g_win->fullRefresh(); 1380 g_win->fullRefresh();
1353 g_win->endAction(); 1381 g_win->endAction();
1354 } 1382 }
1355 1383
1356 m_drawedVerts.clear(); 1384 m_drawedVerts.clear();
1357 m_rectdraw = false; 1385 m_rectdraw = false;
1358 } 1386 }
1359 1387
1360 // ============================================================================= 1388 // =============================================================================
1365 Axis relX, relY; 1393 Axis relX, relY;
1366 getRelativeAxes (relX, relY); 1394 getRelativeAxes (relX, relY);
1367 1395
1368 const double dx = m_drawedVerts[0][relX] - v1[relX]; 1396 const double dx = m_drawedVerts[0][relX] - v1[relX];
1369 const double dy = m_drawedVerts[0][relY] - v1[relY]; 1397 const double dy = m_drawedVerts[0][relY] - v1[relY];
1370 return sqrt ((dx * dx) + (dy * dy)); 1398 return sqrt ( (dx * dx) + (dy * dy));
1371 } 1399 }
1372 1400
1373 // ============================================================================= 1401 // =============================================================================
1374 // ----------------------------------------------------------------------------- 1402 // -----------------------------------------------------------------------------
1375 void GLRenderer::getRelativeAxes (Axis& relX, Axis& relY) const 1403 void GLRenderer::getRelativeAxes (Axis& relX, Axis& relY) const
1378 relY = cam->axisY; 1406 relY = cam->axisY;
1379 } 1407 }
1380 1408
1381 // ============================================================================= 1409 // =============================================================================
1382 // ----------------------------------------------------------------------------- 1410 // -----------------------------------------------------------------------------
1383 static List<vertex> getVertices (LDObject* obj) { 1411 static List<vertex> getVertices (LDObject* obj)
1384 List<vertex> verts; 1412 { List<vertex> verts;
1385 1413
1386 if (obj->vertices() >= 2) { 1414 if (obj->vertices() >= 2)
1387 for (int i = 0; i < obj->vertices(); ++i) 1415 { for (int i = 0; i < obj->vertices(); ++i)
1388 verts << obj->getVertex (i); 1416 verts << obj->getVertex (i);
1389 } elif (obj->getType() == LDObject::Subfile) { 1417 } elif (obj->getType() == LDObject::Subfile)
1390 LDSubfile* ref = static_cast<LDSubfile*> (obj); 1418
1419 { LDSubfile* ref = static_cast<LDSubfile*> (obj);
1391 List<LDObject*> objs = ref->inlineContents (LDSubfile::DeepCacheInline); 1420 List<LDObject*> objs = ref->inlineContents (LDSubfile::DeepCacheInline);
1392 1421
1393 for(LDObject* obj : objs) { 1422 for (LDObject * obj : objs)
1394 verts << getVertices (obj); 1423 { verts << getVertices (obj);
1395 delete obj; 1424 delete obj;
1396 } 1425 }
1397 } 1426 }
1398 1427
1399 return verts; 1428 return verts;
1400 } 1429 }
1401 1430
1402 // ============================================================================= 1431 // =============================================================================
1403 // ----------------------------------------------------------------------------- 1432 // -----------------------------------------------------------------------------
1404 void GLRenderer::compileObject (LDObject* obj) { 1433 void GLRenderer::compileObject (LDObject* obj)
1405 deleteLists (obj); 1434 { deleteLists (obj);
1406 1435
1407 for (const GL::ListType listType : g_glListTypes) { 1436 for (const GL::ListType listType : g_glListTypes)
1408 if (drawOnly() && listType != GL::NormalList) 1437 { if (drawOnly() && listType != GL::NormalList)
1409 continue; 1438 continue;
1410 1439
1411 GLuint list = glGenLists (1); 1440 GLuint list = glGenLists (1);
1412 glNewList (list, GL_COMPILE); 1441 glNewList (list, GL_COMPILE);
1413 1442
1414 obj->glLists[listType] = list; 1443 obj->glLists[listType] = list;
1415 compileList (obj, listType); 1444 compileList (obj, listType);
1416 1445
1417 glEndList(); 1446 glEndList();
1418 } 1447 }
1419 1448
1420 // Mark in known vertices of this object 1449 // Mark in known vertices of this object
1421 List<vertex> verts = getVertices (obj); 1450 List<vertex> verts = getVertices (obj);
1422 m_knownVerts << verts; 1451 m_knownVerts << verts;
1423 m_knownVerts.makeUnique(); 1452 m_knownVerts.makeUnique();
1424 1453
1425 obj->m_glinit = true; 1454 obj->m_glinit = true;
1426 } 1455 }
1427 1456
1428 // ============================================================================= 1457 // =============================================================================
1429 // ----------------------------------------------------------------------------- 1458 // -----------------------------------------------------------------------------
1430 uchar* GLRenderer::screencap (ushort& w, ushort& h) { 1459 uchar* GLRenderer::screencap (ushort& w, ushort& h)
1431 w = m_width; 1460 { w = m_width;
1432 h = m_height; 1461 h = m_height;
1433 uchar* cap = new uchar[4 * w * h]; 1462 uchar* cap = new uchar[4 * w * h];
1434 1463
1435 m_screencap = true; 1464 m_screencap = true;
1436 update(); 1465 update();
1437 m_screencap = false; 1466 m_screencap = false;
1438 1467
1439 // Capture the pixels 1468 // Capture the pixels
1440 glReadPixels (0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, cap); 1469 glReadPixels (0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, cap);
1441 1470
1442 return cap; 1471 return cap;
1443 } 1472 }
1444 1473
1445 // ============================================================================= 1474 // =============================================================================
1446 // ----------------------------------------------------------------------------- 1475 // -----------------------------------------------------------------------------
1447 void GLRenderer::slot_toolTipTimer() { 1476 void GLRenderer::slot_toolTipTimer()
1448 // We come here if the cursor has stayed in one place for longer than a 1477 { // We come here if the cursor has stayed in one place for longer than a
1449 // a second. Check if we're holding it over a camera icon - if so, draw 1478 // a second. Check if we're holding it over a camera icon - if so, draw
1450 // a tooltip. 1479 // a tooltip.
1451 for (CameraIcon& icon : m_cameraIcons) { 1480 for (CameraIcon & icon : m_cameraIcons)
1452 if (icon.destRect.contains (m_pos)) { 1481 { if (icon.destRect.contains (m_pos))
1453 m_toolTipCamera = icon.cam; 1482 { m_toolTipCamera = icon.cam;
1454 m_drawToolTip = true; 1483 m_drawToolTip = true;
1455 update(); 1484 update();
1456 break; 1485 break;
1457 } 1486 }
1458 } 1487 }
1459 } 1488 }
1460 1489
1461 // ============================================================================= 1490 // =============================================================================
1462 // ----------------------------------------------------------------------------- 1491 // -----------------------------------------------------------------------------
1463 void GLRenderer::deleteLists (LDObject* obj) { 1492 void GLRenderer::deleteLists (LDObject* obj)
1464 // Delete the lists but only if they have been initialized 1493 { // Delete the lists but only if they have been initialized
1465 if (!obj->m_glinit) 1494 if (!obj->m_glinit)
1466 return; 1495 return;
1467 1496
1468 for (const GL::ListType listType : g_glListTypes) 1497 for (const GL::ListType listType : g_glListTypes)
1469 glDeleteLists (obj->glLists[listType], 1); 1498 glDeleteLists (obj->glLists[listType], 1);
1470 1499
1471 obj->m_glinit = false; 1500 obj->m_glinit = false;
1472 } 1501 }
1473 1502
1474 // ============================================================================= 1503 // =============================================================================
1475 // ----------------------------------------------------------------------------- 1504 // -----------------------------------------------------------------------------
1476 Axis GLRenderer::cameraAxis (bool y, GL::Camera camid) { 1505 Axis GLRenderer::cameraAxis (bool y, GL::Camera camid)
1477 if (camid == (GL::Camera) -1) 1506 { if (camid == (GL::Camera) - 1)
1478 camid = m_camera; 1507 camid = m_camera;
1479 1508
1480 const staticCameraMeta* cam = &g_staticCameras[camid]; 1509 const staticCameraMeta* cam = &g_staticCameras[camid];
1481 return (y) ? cam->axisY : cam->axisX; 1510 return (y) ? cam->axisY : cam->axisX;
1482 } 1511 }
1483 1512
1484 // ============================================================================= 1513 // =============================================================================
1485 // ----------------------------------------------------------------------------- 1514 // -----------------------------------------------------------------------------
1486 bool GLRenderer::setupOverlay (GL::Camera cam, str file, int x, int y, int w, int h) { 1515 bool GLRenderer::setupOverlay (GL::Camera cam, str file, int x, int y, int w, int h)
1487 QImage* img = new QImage (file); 1516 { QImage* img = new QImage (file);
1488 overlayMeta& info = getOverlay (cam); 1517 overlayMeta& info = getOverlay (cam);
1489 1518
1490 if (img->isNull()) { 1519 if (img->isNull())
1491 critical (tr ("Failed to load overlay image!")); 1520 { critical (tr ("Failed to load overlay image!"));
1492 delete img; 1521 delete img;
1493 return false; 1522 return false;
1494 } 1523 }
1495 1524
1496 delete info.img; // delete the old image 1525 delete info.img; // delete the old image
1497 1526
1498 info.fname = file; 1527 info.fname = file;
1499 info.lw = w; 1528 info.lw = w;
1500 info.lh = h; 1529 info.lh = h;
1501 info.ox = x; 1530 info.ox = x;
1502 info.oy = y; 1531 info.oy = y;
1503 info.img = img; 1532 info.img = img;
1504 1533
1505 if (info.lw == 0) 1534 if (info.lw == 0)
1506 info.lw = (info.lh * img->width()) / img->height(); 1535 info.lw = (info.lh * img->width()) / img->height();
1536
1507 elif (info.lh == 0) 1537 elif (info.lh == 0)
1508 info.lh = (info.lw * img->height()) / img->width(); 1538 info.lh = (info.lw * img->height()) / img->width();
1509 1539
1510 const Axis x2d = cameraAxis (false, cam), 1540 const Axis x2d = cameraAxis (false, cam),
1511 y2d = cameraAxis (true, cam); 1541 y2d = cameraAxis (true, cam);
1512 1542
1513 double negXFac = g_staticCameras[cam].negX ? -1 : 1, 1543 double negXFac = g_staticCameras[cam].negX ? -1 : 1,
1514 negYFac = g_staticCameras[cam].negY ? -1 : 1; 1544 negYFac = g_staticCameras[cam].negY ? -1 : 1;
1515 1545
1516 info.v0 = info.v1 = g_origin; 1546 info.v0 = info.v1 = g_origin;
1517 info.v0[x2d] = - (info.ox * info.lw * negXFac) / img->width(); 1547 info.v0[x2d] = - (info.ox * info.lw * negXFac) / img->width();
1518 info.v0[y2d] = (info.oy * info.lh * negYFac) / img->height(); 1548 info.v0[y2d] = (info.oy * info.lh * negYFac) / img->height();
1519 info.v1[x2d] = info.v0[x2d] + info.lw; 1549 info.v1[x2d] = info.v0[x2d] + info.lw;
1520 info.v1[y2d] = info.v0[y2d] + info.lh; 1550 info.v1[y2d] = info.v0[y2d] + info.lh;
1521 1551
1522 // Set alpha of all pixels to 0.5 1552 // Set alpha of all pixels to 0.5
1523 for (long i = 0; i < img->width(); ++i) 1553 for (long i = 0; i < img->width(); ++i)
1524 for (long j = 0; j < img->height(); ++j) { 1554 for (long j = 0; j < img->height(); ++j)
1525 uint32 pixel = img->pixel (i, j); 1555 { uint32 pixel = img->pixel (i, j);
1526 img->setPixel (i, j, 0x80000000 | (pixel & 0x00FFFFFF)); 1556 img->setPixel (i, j, 0x80000000 | (pixel & 0x00FFFFFF));
1527 } 1557 }
1528 1558
1529 updateOverlayObjects(); 1559 updateOverlayObjects();
1530 return true; 1560 return true;
1531 } 1561 }
1532 1562
1533 // ============================================================================= 1563 // =============================================================================
1534 // ----------------------------------------------------------------------------- 1564 // -----------------------------------------------------------------------------
1535 void GLRenderer::clearOverlay() { 1565 void GLRenderer::clearOverlay()
1536 if (camera() == Free) 1566 { if (camera() == Free)
1537 return; 1567 return;
1538 1568
1539 overlayMeta& info = m_overlays[camera()]; 1569 overlayMeta& info = m_overlays[camera()];
1540 delete info.img; 1570 delete info.img;
1541 info.img = null; 1571 info.img = null;
1542 1572
1543 updateOverlayObjects(); 1573 updateOverlayObjects();
1544 } 1574 }
1545 1575
1546 // ============================================================================= 1576 // =============================================================================
1547 // ----------------------------------------------------------------------------- 1577 // -----------------------------------------------------------------------------
1548 void GLRenderer::setDepthValue (double depth) { 1578 void GLRenderer::setDepthValue (double depth)
1549 assert (camera() < Free); 1579 { assert (camera() < Free);
1550 m_depthValues[camera()] = depth; 1580 m_depthValues[camera()] = depth;
1551 } 1581 }
1552 1582
1553 // ============================================================================= 1583 // =============================================================================
1554 // ----------------------------------------------------------------------------- 1584 // -----------------------------------------------------------------------------
1555 double GLRenderer::depthValue() const { 1585 double GLRenderer::depthValue() const
1556 assert (camera() < Free); 1586 { assert (camera() < Free);
1557 return m_depthValues[camera()]; 1587 return m_depthValues[camera()];
1558 } 1588 }
1559 1589
1560 // ============================================================================= 1590 // =============================================================================
1561 // ----------------------------------------------------------------------------- 1591 // -----------------------------------------------------------------------------
1562 const char* GLRenderer::cameraName() const { 1592 const char* GLRenderer::cameraName() const
1563 return g_CameraNames[camera()]; 1593 { return g_CameraNames[camera()];
1564 } 1594 }
1565 1595
1566 // ============================================================================= 1596 // =============================================================================
1567 // ----------------------------------------------------------------------------- 1597 // -----------------------------------------------------------------------------
1568 overlayMeta& GLRenderer::getOverlay (int newcam) { 1598 overlayMeta& GLRenderer::getOverlay (int newcam)
1569 return m_overlays[newcam]; 1599 { return m_overlays[newcam];
1570 } 1600 }
1571 1601
1572 // ============================================================================= 1602 // =============================================================================
1573 // ----------------------------------------------------------------------------- 1603 // -----------------------------------------------------------------------------
1574 void GLRenderer::zoomNotch (bool inward) { 1604 void GLRenderer::zoomNotch (bool inward)
1575 if (zoom() > 15) 1605 { if (zoom() > 15)
1576 setZoom (zoom() * (inward ? 0.833f : 1.2f)); 1606 setZoom (zoom() * (inward ? 0.833f : 1.2f));
1577 else 1607 else
1578 setZoom (zoom() + (inward ? -1.2f : 1.2f)); 1608 setZoom (zoom() + (inward ? -1.2f : 1.2f));
1579 } 1609 }
1580 1610
1581 // ============================================================================= 1611 // =============================================================================
1582 // ----------------------------------------------------------------------------- 1612 // -----------------------------------------------------------------------------
1583 void GLRenderer::zoomToFit() { 1613 void GLRenderer::zoomToFit()
1584 if (file() == null) { 1614 { if (file() == null)
1585 setZoom (30.0f); 1615 { setZoom (30.0f);
1586 return; 1616 return;
1587 } 1617 }
1588 1618
1589 bool lastfilled = false; 1619 bool lastfilled = false;
1590 bool firstrun = true; 1620 bool firstrun = true;
1591 const uint32 white = 0xFFFFFFFF; 1621 const uint32 white = 0xFFFFFFFF;
1592 bool inward = true; 1622 bool inward = true;
1593 ulong run = 0; 1623 ulong run = 0;
1594 const ushort w = m_width, h = m_height; 1624 const ushort w = m_width, h = m_height;
1595 1625
1596 glClearColor (1.0, 1.0, 1.0, 1.0); 1626 glClearColor (1.0, 1.0, 1.0, 1.0);
1597 glDisable (GL_DITHER); 1627 glDisable (GL_DITHER);
1598 1628
1599 // Use the pick list while drawing the scene, this way we can tell whether borders 1629 // Use the pick list while drawing the scene, this way we can tell whether borders
1600 // are background or not. 1630 // are background or not.
1601 m_picking = true; 1631 m_picking = true;
1602 1632
1603 for (;;) { 1633 for (;;)
1604 if (zoom() > 10000.0f || zoom() < 0.0f) { 1634 { if (zoom() > 10000.0f || zoom() < 0.0f)
1605 // Obviously, there's nothing to draw if we get here. 1635 { // Obviously, there's nothing to draw if we get here.
1606 // Default to 30.0f and break out. 1636 // Default to 30.0f and break out.
1607 setZoom (30.0f); 1637 setZoom (30.0f);
1608 break; 1638 break;
1609 } 1639 }
1610 1640
1611 zoomNotch (inward); 1641 zoomNotch (inward);
1612 1642
1613 uchar* cap = new uchar[4 * w * h]; 1643 uchar* cap = new uchar[4 * w * h];
1614 drawGLScene(); 1644 drawGLScene();
1615 glReadPixels (0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, cap); 1645 glReadPixels (0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, cap);
1616 uint32* imgdata = reinterpret_cast<uint32*> (cap); 1646 uint32* imgdata = reinterpret_cast<uint32*> (cap);
1617 bool filled = false; 1647 bool filled = false;
1618 1648
1619 // Check the top and bottom rows 1649 // Check the top and bottom rows
1620 for (ushort i = 0; i < w && !filled; ++i) 1650 for (ushort i = 0; i < w && !filled; ++i)
1621 if (imgdata[i] != white || imgdata[((h - 1) * w) + i] != white) 1651 if (imgdata[i] != white || imgdata[ ( (h - 1) * w) + i] != white)
1622 filled = true; 1652 filled = true;
1623 1653
1624 // Left and right edges 1654 // Left and right edges
1625 for (ushort i = 0; i < h && !filled; ++i) 1655 for (ushort i = 0; i < h && !filled; ++i)
1626 if (imgdata[i * w] != white || imgdata[(i * w) + (w - 1)] != white) 1656 if (imgdata[i * w] != white || imgdata[ (i * w) + (w - 1)] != white)
1627 filled = true; 1657 filled = true;
1628 1658
1629 if (firstrun) { 1659 if (firstrun)
1630 // If this is the first run, we don't know enough to determine 1660 { // If this is the first run, we don't know enough to determine
1631 // whether the zoom was to fit, so we mark in our knowledge so 1661 // whether the zoom was to fit, so we mark in our knowledge so
1632 // far and start over. 1662 // far and start over.
1633 inward = !filled; 1663 inward = !filled;
1634 firstrun = false; 1664 firstrun = false;
1635 } else { 1665 }
1636 // If this run filled the screen and the last one did not, the 1666 else
1667 { // If this run filled the screen and the last one did not, the
1637 // last run had ideal zoom - zoom a bit back and we should reach it. 1668 // last run had ideal zoom - zoom a bit back and we should reach it.
1638 if (filled && !lastfilled) { 1669 if (filled && !lastfilled)
1639 zoomNotch (false); 1670 { zoomNotch (false);
1640 break; 1671 break;
1641 } 1672 }
1642 1673
1643 // If this run did not fill the screen and the last one did, we've 1674 // If this run did not fill the screen and the last one did, we've
1644 // now reached ideal zoom so we're done here. 1675 // now reached ideal zoom so we're done here.
1645 if (!filled && lastfilled) 1676 if (!filled && lastfilled)
1646 break; 1677 break;
1647 1678
1648 inward = !filled; 1679 inward = !filled;
1649 } 1680 }
1650 1681
1651 delete[] cap; 1682 delete[] cap;
1652 lastfilled = filled; 1683 lastfilled = filled;
1653 ++run; 1684 ++run;
1654 } 1685 }
1655 1686
1656 setBackground(); 1687 setBackground();
1657 m_picking = false; 1688 m_picking = false;
1658 } 1689 }
1659 1690
1660 // ============================================================================= 1691 // =============================================================================
1661 // ----------------------------------------------------------------------------- 1692 // -----------------------------------------------------------------------------
1662 void GLRenderer::updateRectVerts() { 1693 void GLRenderer::updateRectVerts()
1663 if (!m_rectdraw) 1694 { if (!m_rectdraw)
1664 return; 1695 return;
1665 1696
1666 if (m_drawedVerts.size() == 0) { 1697 if (m_drawedVerts.size() == 0)
1667 for (int i = 0; i < 4; ++i) 1698 { for (int i = 0; i < 4; ++i)
1668 m_rectverts[i] = m_hoverpos; 1699 m_rectverts[i] = m_hoverpos;
1669 1700
1670 return; 1701 return;
1671 } 1702 }
1672 1703
1673 vertex v0 = m_drawedVerts[0], 1704 vertex v0 = m_drawedVerts[0],
1674 v1 = (m_drawedVerts.size() >= 2) ? m_drawedVerts[1] : m_hoverpos; 1705 v1 = (m_drawedVerts.size() >= 2) ? m_drawedVerts[1] : m_hoverpos;
1675 1706
1676 const Axis ax = cameraAxis (false), 1707 const Axis ax = cameraAxis (false),
1677 ay = cameraAxis (true), 1708 ay = cameraAxis (true),
1678 az = (Axis) (3 - ax - ay); 1709 az = (Axis) (3 - ax - ay);
1679 1710
1680 for (int i = 0; i < 4; ++i) 1711 for (int i = 0; i < 4; ++i)
1681 m_rectverts[i][az] = depthValue(); 1712 m_rectverts[i][az] = depthValue();
1682 1713
1683 m_rectverts[0][ax] = v0[ax]; 1714 m_rectverts[0][ax] = v0[ax];
1684 m_rectverts[0][ay] = v0[ay]; 1715 m_rectverts[0][ay] = v0[ay];
1685 m_rectverts[1][ax] = v1[ax]; 1716 m_rectverts[1][ax] = v1[ax];
1686 m_rectverts[1][ay] = v0[ay]; 1717 m_rectverts[1][ay] = v0[ay];
1687 m_rectverts[2][ax] = v1[ax]; 1718 m_rectverts[2][ax] = v1[ax];
1690 m_rectverts[3][ay] = v1[ay]; 1721 m_rectverts[3][ay] = v1[ay];
1691 } 1722 }
1692 1723
1693 // ============================================================================= 1724 // =============================================================================
1694 // ----------------------------------------------------------------------------- 1725 // -----------------------------------------------------------------------------
1695 void GLRenderer::mouseDoubleClickEvent (QMouseEvent* ev) { 1726 void GLRenderer::mouseDoubleClickEvent (QMouseEvent* ev)
1696 if (!(ev->buttons() & Qt::LeftButton) || editMode() != Select) 1727 { if (! (ev->buttons() & Qt::LeftButton) || editMode() != Select)
1697 return; 1728 return;
1698 1729
1699 pick (ev->x(), ev->y()); 1730 pick (ev->x(), ev->y());
1700 1731
1701 if (g_win->sel().size() == 0) 1732 if (g_win->sel().size() == 0)
1702 return; 1733 return;
1703 1734
1704 g_win->beginAction (null); 1735 g_win->beginAction (null);
1705 LDObject* obj = g_win->sel()[0]; 1736 LDObject* obj = g_win->sel() [0];
1706 AddObjectDialog::staticDialog (obj->getType(), obj); 1737 AddObjectDialog::staticDialog (obj->getType(), obj);
1707 g_win->endAction(); 1738 g_win->endAction();
1708 ev->accept(); 1739 ev->accept();
1709 } 1740 }
1710 1741
1711 // ============================================================================= 1742 // =============================================================================
1712 // ----------------------------------------------------------------------------- 1743 // -----------------------------------------------------------------------------
1713 LDOverlay* GLRenderer::findOverlayObject (GLRenderer::Camera cam) { 1744 LDOverlay* GLRenderer::findOverlayObject (GLRenderer::Camera cam)
1714 LDOverlay* ovlobj = null; 1745 { LDOverlay* ovlobj = null;
1715 1746
1716 for (LDObject * obj : file()->objects()) { 1747 for (LDObject * obj : file()->objects())
1717 if (obj->getType() == LDObject::Overlay && static_cast<LDOverlay*> (obj)->camera() == cam) { 1748 { if (obj->getType() == LDObject::Overlay && static_cast<LDOverlay*> (obj)->camera() == cam)
1718 ovlobj = static_cast<LDOverlay*> (obj); 1749 { ovlobj = static_cast<LDOverlay*> (obj);
1719 break; 1750 break;
1720 } 1751 }
1721 } 1752 }
1722 1753
1723 return ovlobj; 1754 return ovlobj;
1724 } 1755 }
1725 1756
1726 // ============================================================================= 1757 // =============================================================================
1727 // ----------------------------------------------------------------------------- 1758 // -----------------------------------------------------------------------------
1728 // Read in overlays from the current file and update overlay info accordingly. 1759 // Read in overlays from the current file and update overlay info accordingly.
1729 // ----------------------------------------------------------------------------- 1760 // -----------------------------------------------------------------------------
1730 void GLRenderer::overlaysFromObjects() { 1761 void GLRenderer::overlaysFromObjects()
1731 for (Camera cam : g_Cameras) { 1762 { for (Camera cam : g_Cameras)
1732 if (cam == Free) 1763 { if (cam == Free)
1733 continue; 1764 continue;
1734 1765
1735 overlayMeta& meta = m_overlays[cam]; 1766 overlayMeta& meta = m_overlays[cam];
1736 LDOverlay* ovlobj = findOverlayObject (cam); 1767 LDOverlay* ovlobj = findOverlayObject (cam);
1737 1768
1738 if (!ovlobj && meta.img) { 1769 if (!ovlobj && meta.img)
1739 delete meta.img; 1770 { delete meta.img;
1740 meta.img = null; 1771 meta.img = null;
1741 } elif (ovlobj && (!meta.img || meta.fname != ovlobj->filename())) 1772 } elif (ovlobj && (!meta.img || meta.fname != ovlobj->filename()))
1742 setupOverlay (cam, ovlobj->filename(), ovlobj->x(), ovlobj->y(), ovlobj->width(), ovlobj->height()); 1773
1743 } 1774 setupOverlay (cam, ovlobj->filename(), ovlobj->x(), ovlobj->y(), ovlobj->width(), ovlobj->height());
1744 } 1775 }
1745 1776 }
1746 // ============================================================================= 1777
1747 // ----------------------------------------------------------------------------- 1778 // =============================================================================
1748 void GLRenderer::updateOverlayObjects() { 1779 // -----------------------------------------------------------------------------
1749 for (Camera cam : g_Cameras) { 1780 void GLRenderer::updateOverlayObjects()
1750 if (cam == Free) 1781 { for (Camera cam : g_Cameras)
1782 { if (cam == Free)
1751 continue; 1783 continue;
1752 1784
1753 overlayMeta& meta = m_overlays[cam]; 1785 overlayMeta& meta = m_overlays[cam];
1754 LDOverlay* ovlobj = findOverlayObject (cam); 1786 LDOverlay* ovlobj = findOverlayObject (cam);
1755 1787
1756 if (!meta.img && ovlobj) { 1788 if (!meta.img && ovlobj)
1757 // If this is the last overlay image, we need to remove the empty space after it as well. 1789 { // If this is the last overlay image, we need to remove the empty space after it as well.
1758 LDObject* nextobj = ovlobj->next(); 1790 LDObject* nextobj = ovlobj->next();
1759 1791
1760 if (nextobj && nextobj->getType() == LDObject::Empty) { 1792 if (nextobj && nextobj->getType() == LDObject::Empty)
1761 m_file->forgetObject (nextobj); 1793 { m_file->forgetObject (nextobj);
1762 delete nextobj; 1794 delete nextobj;
1763 } 1795 }
1764 1796
1765 // If the overlay object was there and the overlay itself is 1797 // If the overlay object was there and the overlay itself is
1766 // not, remove the object. 1798 // not, remove the object.
1767 m_file->forgetObject (ovlobj); 1799 m_file->forgetObject (ovlobj);
1768 delete ovlobj; 1800 delete ovlobj;
1769 } elif (meta.img && !ovlobj) { 1801 } elif (meta.img && !ovlobj)
1770 // Inverse case: image is there but the overlay object is 1802
1803 { // Inverse case: image is there but the overlay object is
1771 // not, thus create the object. 1804 // not, thus create the object.
1772 ovlobj = new LDOverlay; 1805 ovlobj = new LDOverlay;
1773 1806
1774 // Find a suitable position to place this object. We want to place 1807 // Find a suitable position to place this object. We want to place
1775 // this into the header, which is everything up to the first scemantic 1808 // this into the header, which is everything up to the first scemantic
1776 // object. If we find another overlay object, place this object after 1809 // object. If we find another overlay object, place this object after
1777 // the last one found. Otherwise, place it before the first schemantic 1810 // the last one found. Otherwise, place it before the first schemantic
1778 // object and put an empty object after it (though don't do this if 1811 // object and put an empty object after it (though don't do this if
1779 // there was no schemantic elements at all) 1812 // there was no schemantic elements at all)
1780 ulong i, lastOverlay = -1u; 1813 ulong i, lastOverlay = -1u;
1781 bool found = false; 1814 bool found = false;
1782 1815
1783 for (i = 0; i < file()->numObjs(); ++i) { 1816 for (i = 0; i < file()->numObjs(); ++i)
1784 LDObject* obj = file()->obj (i); 1817 { LDObject* obj = file()->obj (i);
1785 1818
1786 if (obj->isScemantic()) { 1819 if (obj->isScemantic())
1787 found = true; 1820 { found = true;
1788 break; 1821 break;
1789 } 1822 }
1790 1823
1791 if (obj->getType() == LDObject::Overlay) 1824 if (obj->getType() == LDObject::Overlay)
1792 lastOverlay = i; 1825 lastOverlay = i;
1793 } 1826 }
1794 1827
1795 if (lastOverlay != -1u) 1828 if (lastOverlay != -1u)
1796 file()->insertObj (lastOverlay + 1, ovlobj); 1829 file()->insertObj (lastOverlay + 1, ovlobj);
1797 else { 1830 else
1798 file()->insertObj (i, ovlobj); 1831 { file()->insertObj (i, ovlobj);
1799 1832
1800 if (found) 1833 if (found)
1801 file()->insertObj (i + 1, new LDEmpty); 1834 file()->insertObj (i + 1, new LDEmpty);
1802 } 1835 }
1803 } 1836 }
1804 1837
1805 if (meta.img && ovlobj) { 1838 if (meta.img && ovlobj)
1806 ovlobj->setCamera (cam); 1839 { ovlobj->setCamera (cam);
1807 ovlobj->setFilename (meta.fname); 1840 ovlobj->setFilename (meta.fname);
1808 ovlobj->setX (meta.ox); 1841 ovlobj->setX (meta.ox);
1809 ovlobj->setY (meta.oy); 1842 ovlobj->setY (meta.oy);
1810 ovlobj->setWidth (meta.lw); 1843 ovlobj->setWidth (meta.lw);
1811 ovlobj->setHeight (meta.lh); 1844 ovlobj->setHeight (meta.lh);
1812 } 1845 }
1813 } 1846 }
1814 1847
1815 if (g_win->R() == this) 1848 if (g_win->R() == this)
1816 g_win->refresh(); 1849 g_win->refresh();
1817 } 1850 }
1818 #include "moc_gldraw.cpp"

mercurial