src/glCompiler.cpp

changeset 1231
ce0c9f2e6b9c
parent 1224
5a31b6d4bf81
child 1232
7eb8b59577d0
equal deleted inserted replaced
1230:29dc03eceb5f 1231:ce0c9f2e6b9c
23 #include "ldObject.h" 23 #include "ldObject.h"
24 #include "colors.h" 24 #include "colors.h"
25 #include "ldDocument.h" 25 #include "ldDocument.h"
26 #include "miscallenous.h" 26 #include "miscallenous.h"
27 #include "glRenderer.h" 27 #include "glRenderer.h"
28 #include "dialogs.h"
29 #include "guiutilities.h" 28 #include "guiutilities.h"
30 #include "documentmanager.h" 29 #include "documentmanager.h"
30
31 static const QColor bfcFrontColor {64, 192, 80};
32 static const QColor bfcBackColor {208, 64, 64};
31 33
32 struct GLErrorInfo 34 struct GLErrorInfo
33 { 35 {
34 GLenum value; 36 GLenum value;
35 QString text; 37 QString text;
47 { GL_STACK_OVERFLOW, "The operation would have caused an overflow" }, 49 { GL_STACK_OVERFLOW, "The operation would have caused an overflow" },
48 }; 50 };
49 51
50 ConfigOption(QString SelectColorBlend = "#0080FF") 52 ConfigOption(QString SelectColorBlend = "#0080FF")
51 53
52 // static QMap<LDObject*, String> g_objectOrigins;
53
54 void CheckGLErrorImpl(const char* file, int line) 54 void CheckGLErrorImpl(const char* file, int line)
55 { 55 {
56 QString errmsg; 56 QString errmsg;
57 GLenum errnum = glGetError(); 57 GLenum errnum = glGetError();
58 58
70 70
71 print("OpenGL ERROR: at %1:%2: %3", Basename(QString(file)), line, errmsg); 71 print("OpenGL ERROR: at %1:%2: %3", Basename(QString(file)), line, errmsg);
72 } 72 }
73 73
74 74
75 GLCompiler::GLCompiler(GLRenderer* renderer) : 75 GLCompiler::GLCompiler(LDDocument* document, GLRenderer* renderer) :
76 HierarchyElement(renderer), 76 document {document},
77 m_renderer(renderer) 77 renderer {renderer} {}
78 {
79 needMerge();
80 memset(m_vboSizes, 0, sizeof m_vboSizes);
81 }
82 78
83 79
84 void GLCompiler::initialize() 80 void GLCompiler::initialize()
85 { 81 {
86 initializeOpenGLFunctions(); 82 initializeOpenGLFunctions();
87 glGenBuffers(NumVbos, &m_vbo[0]); 83 glGenBuffers(NumVbos, &vboIndices[0]);
88 CHECK_GL_ERROR(); 84 CHECK_GL_ERROR();
89 } 85 }
90 86
91 87
92 GLCompiler::~GLCompiler() 88 GLCompiler::~GLCompiler()
93 { 89 {
94 glDeleteBuffers(NumVbos, &m_vbo[0]); 90 glDeleteBuffers(NumVbos, &vboIndices[0]);
95 CHECK_GL_ERROR(); 91 CHECK_GL_ERROR();
96 } 92 }
97 93
98 94 /*
95 * Returns a color that represents this object index. There are 256³ possible
96 * colors, so that many indices can be bijectively addressed with colorss.
97 */
99 QColor GLCompiler::indexColorForID(int id) const 98 QColor GLCompiler::indexColorForID(int id) const
100 { 99 {
101 // Calculate a color based from this index. This method caters for 100 int red = (id / 0x10000) % 0x100;
102 // 16777216 objects. I don't think that will be exceeded anytime soon. :) 101 int green = (id / 0x100) % 0x100;
103 int r = (id / 0x10000) % 0x100, 102 int blue = id % 0x100;
104 g = (id / 0x100) % 0x100, 103
105 b = id % 0x100; 104 return {red, green, blue};
106 105 }
107 return QColor(r, g, b); 106
107
108 QColor blend(QColor baseColor, QColor blendColor, double intensity)
109 {
110 double red = baseColor.redF();
111 red += blendColor.redF() * intensity;
112 red /= (intensity + 1.0);
113 double green = baseColor.greenF();
114 green += blendColor.greenF() * intensity;
115 green /= (intensity + 1.0);
116 double blue = baseColor.blueF();
117 blue += blendColor.blueF() * intensity;
118 blue /= (intensity + 1.0);
119 return {int(round(red)), int(round(green)), int(round(blue))};
108 } 120 }
109 121
110 122
111 QColor GLCompiler::getColorForPolygon(LDPolygon& poly, LDObject* topobj, ComplementVboType complement) const 123 QColor GLCompiler::getColorForPolygon(LDPolygon& poly, LDObject* topobj, ComplementVboType complement) const
112 { 124 {
113 QColor qcol; 125 QColor color;
114 static const QColor bfcFrontColor(64, 192, 80);
115 static const QColor bfcBackColor(208, 64, 64);
116 126
117 switch(complement) 127 switch(complement)
118 { 128 {
119 case SurfacesVboComplement: 129 case SurfacesVboComplement:
120 case NumVboComplements: 130 case NumVboComplements:
121 return QColor(); 131 return {};
122 132
123 case BfcFrontColorsVboComplement: 133 case BfcFrontColorsVboComplement:
124 qcol = bfcFrontColor; 134 color = bfcFrontColor;
125 break; 135 break;
126 136
127 case BfcBackColorsVboComplement: 137 case BfcBackColorsVboComplement:
128 qcol = bfcBackColor; 138 color = bfcBackColor;
129 break; 139 break;
130 140
131 case PickColorsVboComplement: 141 case PickColorsVboComplement:
132 return indexColorForID(topobj->id()); 142 return indexColorForID(topobj->id());
133 143
134 case RandomColorsVboComplement: 144 case RandomColorsVboComplement:
135 qcol = topobj->randomColor(); 145 color = topobj->randomColor();
136 break; 146 break;
137 147
138 case NormalColorsVboComplement: 148 case NormalColorsVboComplement:
139 if (poly.color == MainColor) 149 if (poly.color == MainColor)
140 { 150 {
141 if (topobj->color() == MainColor) 151 if (topobj->color() == MainColor)
142 qcol = guiUtilities()->mainColorRepresentation(); 152 color = mainColorRepresentation();
143 else 153 else
144 qcol = topobj->color().faceColor(); 154 color = topobj->color().faceColor();
145 } 155 }
146 else if (poly.color == EdgeColor) 156 else if (poly.color == EdgeColor)
147 { 157 {
148 qcol = luma(QColor(config->backgroundColor())) > 40 ? Qt::black : Qt::white; 158 if (luma(config->backgroundColor()) > 40)
159 color = Qt::black;
160 else
161 color = Qt::white;
149 } 162 }
150 else 163 else
151 { 164 {
152 LDColor col = poly.color; 165 LDColor colorInfo = poly.color;
153 166
154 if (col.isValid()) 167 if (colorInfo.isValid())
155 qcol = col.faceColor(); 168 color = colorInfo.faceColor();
156 } 169 }
157 break; 170 break;
158 } 171 }
159 172
160 if (not qcol.isValid()) 173 if (not color.isValid())
161 { 174 {
162 // The color was unknown. Use main color to make the polygon at least 175 // The color was unknown. Use main color to make the polygon at least
163 // not appear pitch-black. 176 // not appear pitch-black.
164 if (poly.num != 2 and poly.num != 5) 177 if (poly.num != 2 and poly.num != 5)
165 qcol = guiUtilities()->mainColorRepresentation(); 178 color = mainColorRepresentation();
166 else 179 else
167 qcol = Qt::black; 180 color = Qt::black;
168 181
169 // Warn about the unknown color, but only once. 182 // Warn about the unknown color, but only once.
170 static QList<int> warnedColors; 183 static QSet<int> warnedColors;
171 if (not warnedColors.contains(poly.color)) 184 if (not warnedColors.contains(poly.color))
172 { 185 {
173 print("Unknown color %1!\n", poly.color); 186 print("Unknown color %1!\n", poly.color);
174 warnedColors << poly.color; 187 warnedColors.insert(poly.color);
175 } 188 }
176 189
177 return qcol; 190 return color;
178 } 191 }
179 192
180 double blendAlpha = 0.0; 193 double blendAlpha = 0.0;
181 194
182 if (topobj->isSelected()) 195 if (topobj->isSelected())
183 blendAlpha = 1.0; 196 blendAlpha = 1.0;
184 else if (topobj == m_renderer->objectAtCursor()) 197 else if (topobj == renderer->objectAtCursor())
185 blendAlpha = 0.5; 198 blendAlpha = 0.5;
186 199
187 if (blendAlpha != 0.0) 200 color = blend(color, config->selectColorBlend(), blendAlpha);
188 { 201 return color;
189 QColor selcolor(config->selectColorBlend());
190 double denom = blendAlpha + 1.0;
191 qcol.setRed((qcol.red() +(selcolor.red() * blendAlpha)) / denom);
192 qcol.setGreen((qcol.green() +(selcolor.green() * blendAlpha)) / denom);
193 qcol.setBlue((qcol.blue() +(selcolor.blue() * blendAlpha)) / denom);
194 }
195
196 return qcol;
197 } 202 }
198 203
199 204
200 void GLCompiler::needMerge() 205 void GLCompiler::needMerge()
201 { 206 {
202 for (int i = 0; i < countof(m_vboChanged); ++i) 207 for (bool& changed_flag : this->vboChanged)
203 m_vboChanged[i] = true; 208 changed_flag = true;
204 } 209 }
205 210
206 211
207 void GLCompiler::stageForCompilation(LDObject* obj) 212 void GLCompiler::stageForCompilation(LDObject* obj)
208 { 213 {
209 /* 214 stagedObjects << obj;
210 g_objectOrigins[obj] = format("%1:%2(%3)",
211 obj->document()->getDisplayName(), obj->lineNumber(), obj->typeName());
212 */
213
214 m_staged << obj;
215 } 215 }
216 216
217 217
218 void GLCompiler::unstage(LDObject* obj) 218 void GLCompiler::unstage(LDObject* obj)
219 { 219 {
220 m_staged.remove(obj); 220 stagedObjects.remove(obj);
221 } 221 }
222 222
223 223
224 void GLCompiler::compileDocument(LDDocument* doc) 224 void GLCompiler::compileDocument(LDDocument* document)
225 { 225 {
226 if (doc) 226 if (document)
227 { 227 {
228 for (LDObject* obj : doc->objects()) 228 for (LDObject* obj : document->objects())
229 compileObject(obj); 229 compileObject(obj);
230 } 230 }
231 } 231 }
232 232
233 233
234 void GLCompiler::compileStaged() 234 void GLCompiler::compileStaged()
235 { 235 {
236 for (QSetIterator<LDObject*> it(m_staged); it.hasNext();) 236 for (QSetIterator<LDObject*> it(stagedObjects); it.hasNext();)
237 compileObject(it.next()); 237 compileObject(it.next());
238 238
239 m_staged.clear(); 239 stagedObjects.clear();
240 } 240 }
241 241
242 242
243 void GLCompiler::prepareVBO(int vbonum) 243 void GLCompiler::prepareVBO(int vbonum)
244 { 244 {
245 // Compile anything that still awaits it 245 // Compile anything that still awaits it
246 compileStaged(); 246 compileStaged();
247 247
248 if (not m_vboChanged[vbonum]) 248 if (not vboChanged[vbonum])
249 return; 249 {
250 250 print("Merging %1", vbonum);
251 QVector<GLfloat> vbodata; 251 QVector<GLfloat> vbodata;
252 252
253 for (auto it = m_objectInfo.begin(); it != m_objectInfo.end();) 253 for (auto it = objectInfo.begin(); it != objectInfo.end();)
254 { 254 {
255 if (it.key() == nullptr) 255 if (it.key() == nullptr)
256 { 256 {
257 it = m_objectInfo.erase(it); 257 it = objectInfo.erase(it);
258 continue; 258 }
259 } 259 else
260 260 {
261 if (it.key()->document() == currentDocument() and not it.key()->isHidden()) 261 if (not it.key()->isHidden())
262 vbodata += it->data[vbonum]; 262 vbodata += it->data[vbonum];
263 263
264 ++it; 264 ++it;
265 } 265 }
266 266 }
267 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[vbonum]); 267
268 glBufferData(GL_ARRAY_BUFFER, vbodata.size() * sizeof(GLfloat), vbodata.constData(), GL_STATIC_DRAW); 268 glBindBuffer(GL_ARRAY_BUFFER, vboIndices[vbonum]);
269 glBindBuffer(GL_ARRAY_BUFFER, 0); 269 glBufferData(
270 CHECK_GL_ERROR(); 270 GL_ARRAY_BUFFER,
271 m_vboChanged[vbonum] = false; 271 vbodata.size() * sizeof(GLfloat),
272 m_vboSizes[vbonum] = vbodata.size(); 272 vbodata.constData(),
273 GL_STATIC_DRAW);
274 glBindBuffer(GL_ARRAY_BUFFER, 0);
275 CHECK_GL_ERROR();
276 vboChanged[vbonum] = false;
277 vboSizes[vbonum] = vbodata.size();
278 }
273 } 279 }
274 280
275 281
276 void GLCompiler::dropObjectInfo(LDObject* obj) 282 void GLCompiler::dropObjectInfo(LDObject* obj)
277 { 283 {
278 if (m_objectInfo.contains(obj)) 284 if (objectInfo.contains(obj))
279 { 285 {
280 m_objectInfo.remove(obj); 286 objectInfo.remove(obj);
281 needMerge(); 287 needMerge();
282 } 288 }
283 } 289 }
284 290
285 291
334 340
335 default: 341 default:
336 break; 342 break;
337 } 343 }
338 344
339 m_objectInfo[obj] = info; 345 objectInfo[obj] = info;
340 needMerge(); 346 needMerge();
341 } 347 }
342 348
343 349
344 void GLCompiler::compilePolygon(LDPolygon& poly, LDObject* topobj, ObjectVBOInfo* objinfo) 350 void GLCompiler::compilePolygon(LDPolygon& poly, LDObject* topobj, ObjectVBOInfo* objinfo)
379 } 385 }
380 } 386 }
381 } 387 }
382 } 388 }
383 389
384
385 void GLCompiler::setRenderer(GLRenderer* renderer)
386 {
387 m_renderer = renderer;
388 }
389
390
391 int GLCompiler::vboNumber(SurfaceVboType surface, ComplementVboType complement) 390 int GLCompiler::vboNumber(SurfaceVboType surface, ComplementVboType complement)
392 { 391 {
393 return (surface * NumVboComplements) + complement; 392 return (surface * NumVboComplements) + complement;
394 } 393 }
395 394
396 395
397 GLuint GLCompiler::vbo(int vbonum) const 396 GLuint GLCompiler::vbo(int vbonum) const
398 { 397 {
399 return m_vbo[vbonum]; 398 return vboIndices[vbonum];
400 } 399 }
401 400
402 401
403 int GLCompiler::vboSize(int vbonum) const 402 int GLCompiler::vboSize(int vbonum) const
404 { 403 {
405 return m_vboSizes[vbonum]; 404 return vboSizes[vbonum];
406 } 405 }

mercurial