gldraw.cpp

changeset 104
6e29bb0e83c5
parent 103
b0a345196435
child 105
53f95a6e351d
equal deleted inserted replaced
103:b0a345196435 104:6e29bb0e83c5
1 /* 1 /*
2 * LDForge: LDraw parts authoring CAD 2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013 Santeri `arezey` Piippo 3 * Copyright (C) 2013 Santeri Piippo
4 * 4 *
5 * This program is free software: you can redistribute it and/or modify 5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or 7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version. 8 * (at your option) any later version.
23 #include "config.h" 23 #include "config.h"
24 #include "file.h" 24 #include "file.h"
25 #include "gldraw.h" 25 #include "gldraw.h"
26 #include "bbox.h" 26 #include "bbox.h"
27 #include "colors.h" 27 #include "colors.h"
28 #include "gui.h"
28 29
29 static double g_faObjectOffset[3]; 30 static double g_faObjectOffset[3];
30 static double g_StoredBBoxSize; 31 static double g_StoredBBoxSize;
32 static bool g_bPicking = false;
31 33
32 cfg (str, gl_bgcolor, "#CCCCD9"); 34 cfg (str, gl_bgcolor, "#CCCCD9");
33 cfg (str, gl_maincolor, "#707078"); 35 cfg (str, gl_maincolor, "#707078");
34 cfg (float, gl_maincolor_alpha, 1.0); 36 cfg (float, gl_maincolor_alpha, 1.0);
35 cfg (int, gl_linethickness, 2); 37 cfg (int, gl_linethickness, 2);
36 cfg (bool, gl_colorbfc, true); 38 cfg (bool, gl_colorbfc, true);
37 39
38 // ============================================================================= 40 // ========================================================================= //
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 // ============================================================================= 42 // ========================================================================= //
41 renderer::renderer (QWidget* parent) { 43 renderer::renderer (QWidget* parent) {
42 parent = parent; // shhh, GCC 44 parent = parent; // shhh, GCC
43 fRotX = fRotY = fRotZ = 0.0f; 45 fRotX = fRotY = fRotZ = 0.0f;
44 fZoom = 1.0f; 46 fZoom = 1.0f;
45 } 47 }
46 48
47 // ============================================================================= 49 // ========================================================================= //
48 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 50 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
49 // ============================================================================= 51 // ========================================================================= //
50 void renderer::initializeGL () { 52 void renderer::initializeGL () {
51 glLoadIdentity(); 53 glLoadIdentity();
52 glMatrixMode (GL_MODELVIEW); 54 glMatrixMode (GL_MODELVIEW);
53 55
54 setBackground (); 56 setBackground ();
71 setMouseTracking (true); 73 setMouseTracking (true);
72 74
73 compileObjects (); 75 compileObjects ();
74 } 76 }
75 77
76 // ============================================================================= 78 // ========================================================================= //
77 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 79 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
78 // ============================================================================= 80 // ========================================================================= //
79 void renderer::setMainColor () { 81 void renderer::setMainColor () {
80 QColor col (gl_maincolor.value.chars()); 82 QColor col (gl_maincolor.value.chars());
81 83
82 if (!col.isValid ()) 84 if (!col.isValid ())
83 return; 85 return;
87 ((double)col.green()) / 255.0f, 89 ((double)col.green()) / 255.0f,
88 ((double)col.blue()) / 255.0f, 90 ((double)col.blue()) / 255.0f,
89 gl_maincolor_alpha); 91 gl_maincolor_alpha);
90 } 92 }
91 93
92 // ----------------------------------------------------------------------------- 94 // ------------------------------------------------------------------------- //
93 void renderer::setBackground () { 95 void renderer::setBackground () {
94 QColor col (gl_bgcolor.value.chars()); 96 QColor col (gl_bgcolor.value.chars());
95 97
96 if (!col.isValid ()) 98 if (!col.isValid ())
97 return; 99 return;
101 ((double)col.green()) / 255.0f, 103 ((double)col.green()) / 255.0f,
102 ((double)col.blue()) / 255.0f, 104 ((double)col.blue()) / 255.0f,
103 1.0f); 105 1.0f);
104 } 106 }
105 107
106 // ============================================================================= 108 // ========================================================================= //
107 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 109 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
108 // ============================================================================= 110 // ========================================================================= //
109 static vector<short> g_daWarnedColors; 111 static vector<short> g_daWarnedColors;
110 void renderer::setObjectColor (LDObject* obj, bool bBackSide) { 112 void renderer::setObjectColor (LDObject* obj) {
113 if (g_bPicking) {
114 // Make the color by the object's index color if we're picking, so we can
115 // make the index from the color we get from the picking results.
116 long i = obj->getIndex (g_CurrentFile);
117
118 // If we couldn't find the index, this object must not be from this file,
119 // therefore it must be an object inlined from another file through a
120 // subfile reference. Use the reference's index.
121 if (i == -1)
122 i = obj->topLevelParent ()->getIndex (g_CurrentFile);
123
124 // We should have the index now.
125 assert (i != -1);
126
127 // Calculate a color based from this index. This method caters for
128 // 16777216 objects. I don't think that'll be exceeded anytime soon. :)
129 // ATM biggest is 53588.dat with 12600 lines.
130 double r = i % 256;
131 double g = (i / 256) % 256;
132 double b = (i / (256 * 256)) % 256;
133
134 glColor3f (r / 255.f, g / 255.f, b / 255.f);
135 return;
136 }
137
111 if (obj->dColor == -1) 138 if (obj->dColor == -1)
112 return; 139 return;
113 140
141 #if 0
114 if (gl_colorbfc && 142 if (gl_colorbfc &&
115 obj->getType () != OBJ_Line && 143 obj->getType () != OBJ_Line &&
116 obj->getType () != OBJ_CondLine) 144 obj->getType () != OBJ_CondLine)
117 { 145 {
118 if (bBackSide) 146 if (bBackSide)
119 glColor4f (0.9f, 0.0f, 0.0f, 1.0f); 147 glColor4f (0.9f, 0.0f, 0.0f, 1.0f);
120 else 148 else
121 glColor4f (0.0f, 0.8f, 0.0f, 1.0f); 149 glColor4f (0.0f, 0.8f, 0.0f, 1.0f);
122 return; 150 return;
123 } 151 }
152 #endif
124 153
125 if (obj->dColor == dMainColor) { 154 if (obj->dColor == dMainColor) {
126 setMainColor (); 155 setMainColor ();
127 return; 156 return;
128 } 157 }
137 // Warn about the unknown colors, but only once. 166 // Warn about the unknown colors, but only once.
138 for (short i : g_daWarnedColors) 167 for (short i : g_daWarnedColors)
139 if (obj->dColor == i) 168 if (obj->dColor == i)
140 return; 169 return;
141 170
142 printf ("setObjectColor Unknown color %d!\n", obj->dColor); 171 printf ("%s: Unknown color %d!\n", __func__, obj->dColor);
143 g_daWarnedColors.push_back (obj->dColor); 172 g_daWarnedColors.push_back (obj->dColor);
144 return; 173 return;
145 } 174 }
146 175
147 glColor4f ( 176 glColor4f (
149 ((double)col->qColor.green()) / 255.0f, 178 ((double)col->qColor.green()) / 255.0f,
150 ((double)col->qColor.blue()) / 255.0f, 179 ((double)col->qColor.blue()) / 255.0f,
151 ((double)col->qColor.alpha()) / 255.0f); 180 ((double)col->qColor.alpha()) / 255.0f);
152 } 181 }
153 182
154 // ============================================================================= 183 // ========================================================================= //
155 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 184 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
156 // ============================================================================= 185 // ========================================================================= //
157 void renderer::hardRefresh () { 186 void renderer::hardRefresh () {
158 compileObjects (); 187 compileObjects ();
159 paintGL (); 188 paintGL ();
160 swapBuffers (); 189 swapBuffers ();
161 190
162 glLineWidth (gl_linethickness); 191 glLineWidth (gl_linethickness);
163 } 192 }
164 193
165 // ============================================================================= 194 // ========================================================================= //
166 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 195 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
167 // ============================================================================= 196 // ========================================================================= //
168 void renderer::resizeGL (int w, int h) { 197 void renderer::resizeGL (int w, int h) {
169 glViewport (0, 0, w, h); 198 glViewport (0, 0, w, h);
170 glLoadIdentity (); 199 glLoadIdentity ();
171 glMatrixMode (GL_PROJECTION); 200 glMatrixMode (GL_PROJECTION);
172 gluPerspective (45.0f, (double)w / (double)h, 0.1f, 100.0f); 201 gluPerspective (45.0f, (double)w / (double)h, 0.1f, 100.0f);
173 } 202 }
174 203
175 // ============================================================================= 204 // ========================================================================= //
176 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 205 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
177 // ============================================================================= 206 // ========================================================================= //
178 void renderer::paintGL () { 207 void renderer::paintGL () {
179 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 208 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
180 glMatrixMode (GL_MODELVIEW); 209 glMatrixMode (GL_MODELVIEW);
181 210
182 glPushMatrix (); 211 glPushMatrix ();
187 216
188 glRotatef (fRotX, 1.0f, 0.0f, 0.0f); 217 glRotatef (fRotX, 1.0f, 0.0f, 0.0f);
189 glRotatef (fRotY, 0.0f, 1.0f, 0.0f); 218 glRotatef (fRotY, 0.0f, 1.0f, 0.0f);
190 glRotatef (fRotZ, 0.0f, 0.0f, 1.0f); 219 glRotatef (fRotZ, 0.0f, 0.0f, 1.0f);
191 220
192 if (gl_colorbfc) { 221 for (GLuint uList : uaObjLists)
193 glEnable (GL_CULL_FACE); 222 glCallList (uList);
194
195 glCullFace (GL_FRONT);
196 glCallList (uObjList);
197
198 glCullFace (GL_BACK);
199 glCallList (uObjListBack);
200
201 glDisable (GL_CULL_FACE);
202 } else
203 glCallList (uObjList);
204 glPopMatrix (); 223 glPopMatrix ();
205 } 224 }
206 225
207 // ============================================================================= 226 // ========================================================================= //
208 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 227 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
209 // ============================================================================= 228 // ========================================================================= //
210 void renderer::compileObjects () { 229 void renderer::compileObjects () {
230 uaObjLists.clear ();
231
211 g_faObjectOffset[0] = -(g_BBox.v0.x + g_BBox.v1.x) / 2; 232 g_faObjectOffset[0] = -(g_BBox.v0.x + g_BBox.v1.x) / 2;
212 g_faObjectOffset[1] = -(g_BBox.v0.y + g_BBox.v1.y) / 2; 233 g_faObjectOffset[1] = -(g_BBox.v0.y + g_BBox.v1.y) / 2;
213 g_faObjectOffset[2] = -(g_BBox.v0.z + g_BBox.v1.z) / 2; 234 g_faObjectOffset[2] = -(g_BBox.v0.z + g_BBox.v1.z) / 2;
214 g_StoredBBoxSize = g_BBox.calcSize (); 235 g_StoredBBoxSize = g_BBox.calcSize ();
215 printf ("bbox size is %f\n", g_StoredBBoxSize); 236 printf ("bbox size is %f\n", g_StoredBBoxSize);
217 if (!g_CurrentFile) { 238 if (!g_CurrentFile) {
218 printf ("renderer: no files loaded, cannot compile anything\n"); 239 printf ("renderer: no files loaded, cannot compile anything\n");
219 return; 240 return;
220 } 241 }
221 242
222 GLuint* upaLists[2] = { 243 for (LDObject* obj : g_CurrentFile->objects)
223 &uObjList, 244 compileOneObject (obj);
224 &uObjListBack, 245 }
225 }; 246
226 247 // ========================================================================= //
227 for (uchar i = 0; i < 2; ++i) { 248 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
228 if (i && !gl_colorbfc) 249 // ========================================================================= //
229 continue;
230
231 *upaLists[i] = glGenLists (1);
232 glNewList (*upaLists[i], GL_COMPILE);
233
234 for (LDObject* obj : g_CurrentFile->objects)
235 compileOneObject (obj, i);
236
237 glEndList ();
238 }
239 }
240
241 // =============================================================================
242 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
243 // =============================================================================
244 template<class T> void renderer::compileSubObject (LDObject* obj, 250 template<class T> void renderer::compileSubObject (LDObject* obj,
245 const bool bBackSide, const GLenum eGLType, const short dVerts) 251 const GLenum eGLType, const short dVerts)
246 { 252 {
247 setObjectColor (obj, bBackSide); 253 setObjectColor (obj);
248 T* newobj = static_cast<T*> (obj); 254 T* newobj = static_cast<T*> (obj);
249 glBegin (eGLType); 255 glBegin (eGLType);
250 256
251 for (short i = 0; i < dVerts; ++i) 257 for (short i = 0; i < dVerts; ++i)
252 compileVertex (newobj->vaCoords[i]); 258 compileVertex (newobj->vaCoords[i]);
253 259
254 glEnd (); 260 glEnd ();
255 } 261 }
256 262
257 // ============================================================================= 263 // ========================================================================= //
258 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 264 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
259 // ============================================================================= 265 // ========================================================================= //
260 void renderer::compileOneObject (LDObject* obj, bool bBackSide) { 266 void renderer::compileOneObject (LDObject* obj) {
261 if (!obj) 267 GLuint uList = glGenLists (1);
262 return; 268 glNewList (uList, GL_COMPILE);
263 269
264 switch (obj->getType ()) { 270 switch (obj->getType ()) {
265 case OBJ_Line: 271 case OBJ_Line:
266 compileSubObject<LDLine> (obj, bBackSide, GL_LINES, 2); 272 compileSubObject<LDLine> (obj, GL_LINES, 2);
267 break; 273 break;
268 274
269 case OBJ_CondLine: 275 case OBJ_CondLine:
270 glLineStipple (1, 0x6666); 276 glLineStipple (1, 0x6666);
271 glEnable (GL_LINE_STIPPLE); 277 glEnable (GL_LINE_STIPPLE);
272 278
273 compileSubObject<LDCondLine> (obj, bBackSide, GL_LINES, 2); 279 compileSubObject<LDCondLine> (obj, GL_LINES, 2);
274 280
275 glDisable (GL_LINE_STIPPLE); 281 glDisable (GL_LINE_STIPPLE);
276 break; 282 break;
277 283
278 case OBJ_Triangle: 284 case OBJ_Triangle:
279 compileSubObject<LDTriangle> (obj, bBackSide, GL_TRIANGLES, 3); 285 compileSubObject<LDTriangle> (obj, GL_TRIANGLES, 3);
280 break; 286 break;
281 287
282 case OBJ_Quad: 288 case OBJ_Quad:
283 compileSubObject<LDQuad> (obj, bBackSide, GL_QUADS, 4); 289 compileSubObject<LDQuad> (obj, GL_QUADS, 4);
284 break; 290 break;
285 291
286 case OBJ_Subfile: 292 case OBJ_Subfile:
287 { 293 {
288 LDSubfile* ref = static_cast<LDSubfile*> (obj); 294 LDSubfile* ref = static_cast<LDSubfile*> (obj);
289 295
290 vector<LDObject*> objs = ref->inlineContents (true, true); 296 vector<LDObject*> objs = ref->inlineContents (true, true);
291 297
292 for (LDObject* obj : objs) { 298 for (LDObject* obj : objs) {
293 compileOneObject (obj, bBackSide); 299 compileOneObject (obj);
294 delete obj; 300 delete obj;
295 } 301 }
296 } 302 }
297 break; 303 break;
298 304
331 #endif // 0 337 #endif // 0
332 338
333 default: 339 default:
334 break; 340 break;
335 } 341 }
336 } 342
337 343 glEndList ();
338 // ============================================================================= 344 uaObjLists.push_back (uList);
339 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 345 obj->uGLList = uList;
340 // ============================================================================= 346 }
347
348 // ========================================================================= //
349 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
350 // ========================================================================= //
341 void renderer::compileVertex (vertex& vrt) { 351 void renderer::compileVertex (vertex& vrt) {
342 glVertex3d ( 352 glVertex3d (
343 (vrt.x + g_faObjectOffset[0]) / g_StoredBBoxSize, 353 (vrt.x + g_faObjectOffset[0]) / g_StoredBBoxSize,
344 -(vrt.y + g_faObjectOffset[1]) / g_StoredBBoxSize, 354 -(vrt.y + g_faObjectOffset[1]) / g_StoredBBoxSize,
345 -(vrt.z + g_faObjectOffset[2]) / g_StoredBBoxSize); 355 -(vrt.z + g_faObjectOffset[2]) / g_StoredBBoxSize);
346 } 356 }
347 357
348 // ============================================================================= 358 // ========================================================================= //
349 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 359 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
350 // ============================================================================= 360 // ========================================================================= //
351 void renderer::clampAngle (double& fAngle) { 361 void renderer::clampAngle (double& fAngle) {
352 while (fAngle < 0) 362 while (fAngle < 0)
353 fAngle += 360.0; 363 fAngle += 360.0;
354 while (fAngle > 360.0) 364 while (fAngle > 360.0)
355 fAngle -= 360.0; 365 fAngle -= 360.0;
356 } 366 }
357 367
358 // ============================================================================= 368 // ========================================================================= //
359 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 369 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
360 // ============================================================================= 370 // ========================================================================= //
371 void renderer::mouseReleaseEvent (QMouseEvent* event) {
372 if ((qMouseButtons & Qt::LeftButton) && !(event->buttons() & Qt::LeftButton)) {
373 if (ulTotalMouseMove < 10)
374 pick (event->x(), event->y());
375
376 ulTotalMouseMove = 0;
377 }
378 }
379
380 void renderer::mousePressEvent (QMouseEvent* event) {
381 qMouseButtons = event->buttons();
382 if (event->buttons() & Qt::LeftButton)
383 ulTotalMouseMove = 0;
384 }
385
386 // ========================================================================= //
387 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
388 // ========================================================================= //
361 void renderer::mouseMoveEvent (QMouseEvent *event) { 389 void renderer::mouseMoveEvent (QMouseEvent *event) {
362 int dx = event->x () - lastPos.x (); 390 int dx = event->x () - lastPos.x ();
363 int dy = event->y () - lastPos.y (); 391 int dy = event->y () - lastPos.y ();
392 ulTotalMouseMove += abs (dx) + abs (dy);
364 393
365 if (event->buttons () & Qt::LeftButton) { 394 if (event->buttons () & Qt::LeftButton) {
366 fRotX = fRotX + (dy); 395 fRotX = fRotX + (dy);
367 fRotY = fRotY + (dx); 396 fRotY = fRotY + (dx);
368 clampAngle (fRotX); 397 clampAngle (fRotX);
382 } 411 }
383 412
384 lastPos = event->pos(); 413 lastPos = event->pos();
385 updateGL (); 414 updateGL ();
386 } 415 }
416
417 // ========================================================================= //
418 void renderer::pick (uint mx, uint my) {
419 glDisable (GL_DITHER);
420 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
421
422 g_bPicking = true;
423
424 compileObjects ();
425 paintGL ();
426
427 GLubyte pixel[3];
428 GLint viewport[4];
429 glGetIntegerv (GL_VIEWPORT, viewport);
430 glReadPixels (mx, viewport[3] - my, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*> (pixel));
431
432 if (pixel[0] != 255 || pixel[1] != 255 || pixel[2] != 255) {
433 ulong idx = pixel[0] + (pixel[1] * 256) + (pixel[2] * 256 * 256);
434 printf ("idx: %lu\n", idx);
435
436 LDObject* obj = g_CurrentFile->object (idx);
437
438 g_ForgeWindow->paSelection.clear ();
439 g_ForgeWindow->paSelection.push_back (obj);
440 }
441
442 g_bPicking = false;
443 glEnable (GL_DITHER);
444
445 setBackground ();
446 compileObjects ();
447 paintGL ();
448
449 g_ForgeWindow->updateSelection ();
450 }

mercurial