src/gldata.cpp

changeset 441
a958f6925088
child 442
4852e815df29
equal deleted inserted replaced
440:ce2009d50c61 441:a958f6925088
1 #include "gldata.h"
2 #include "ldtypes.h"
3 #include "colors.h"
4 #include "file.h"
5 #include "misc.h"
6 #include "gldraw.h"
7
8 cfg (bool, gl_blackedges, true);
9
10 // =============================================================================
11 // -----------------------------------------------------------------------------
12 VertexCompiler::Array::Array() :
13 m_data (null)
14 {
15 clear();
16 }
17
18 // =============================================================================
19 // -----------------------------------------------------------------------------
20 VertexCompiler::Array::~Array() {
21 delete[] m_data;
22 }
23
24 // =============================================================================
25 // -----------------------------------------------------------------------------
26 void VertexCompiler::Array::clear() {
27 delete[] m_data;
28
29 m_data = new DataType[64];
30 m_size = 64;
31 m_ptr = &m_data[0];
32 }
33
34 // =============================================================================
35 // -----------------------------------------------------------------------------
36 void VertexCompiler::Array::resizeToFit (
37 VertexCompiler::Array::SizeType newSize
38 ) {
39 if (allocatedSize() >= newSize)
40 return;
41
42 int32 cachedWriteSize = writtenSize();
43
44 // Add some lee-way space to reduce the amount of resizing.
45 newSize += 256;
46
47 const SizeType oldSize = allocatedSize();
48
49 // We need to back up the data first
50 DataType* copy = new DataType[oldSize];
51 memcpy (copy, m_data, oldSize);
52
53 // Re-create the buffer
54 delete[] m_data;
55 m_data = new DataType[newSize];
56 m_size = newSize;
57 m_ptr = &m_data[cachedWriteSize / sizeof (DataType)];
58
59 // Copy the data back
60 memcpy (m_data, copy, oldSize);
61 delete[] copy;
62 }
63
64 // =============================================================================
65 // -----------------------------------------------------------------------------
66 const VertexCompiler::Array::DataType* VertexCompiler::Array::data() const {
67 return m_data;
68 }
69
70 // =============================================================================
71 // -----------------------------------------------------------------------------
72 const VertexCompiler::Array::SizeType& VertexCompiler::Array::allocatedSize() const {
73 return m_size;
74 }
75
76 // =============================================================================
77 // -----------------------------------------------------------------------------
78 VertexCompiler::Array::SizeType VertexCompiler::Array::writtenSize() const {
79 return (m_ptr - m_data) * sizeof (DataType);
80 }
81
82 // =============================================================================
83 // -----------------------------------------------------------------------------
84 void VertexCompiler::Array::write (
85 VertexCompiler::Array::DataType f
86 ) {
87 // Ensure there's enoughspace for the new float
88 resizeToFit (writtenSize() + sizeof f);
89
90 // Write the float in
91 *m_ptr++ = f;
92 }
93
94 // =============================================================================
95 // -----------------------------------------------------------------------------
96 void VertexCompiler::Array::merge (
97 Array* other
98 ) {
99 // Ensure there's room for both buffers
100 resizeToFit (writtenSize() + other->writtenSize());
101
102 memcpy (m_ptr, other->data(), other->writtenSize());
103 m_ptr += other->writtenSize() / sizeof (DataType);
104 }
105
106 // =============================================================================
107 // -----------------------------------------------------------------------------
108 VertexCompiler::VertexCompiler() :
109 m_file (null)
110 {
111 for (int i = 0; i < NumArrays; ++i) {
112 m_mainArrays[i] = new Array;
113 m_changed[i] = false;
114 }
115 }
116
117 // =============================================================================
118 // -----------------------------------------------------------------------------
119 VertexCompiler::~VertexCompiler() {
120 for (Array* array : m_mainArrays)
121 delete array;
122 }
123
124 // =============================================================================
125 // -----------------------------------------------------------------------------
126 void VertexCompiler::compileVertex (
127 vertex v,
128 QColor col,
129 Array* array
130 ) {
131 VertexCompiler::Vertex glvertex;
132 glvertex.x = v.x();
133 glvertex.y = v.y();
134 glvertex.z = v.z();
135 glvertex.color =
136 (col.red() & 0xFF) << 0x00 |
137 (col.green() & 0xFF) << 0x08 |
138 (col.blue() & 0xFF) << 0x10 |
139 (col.alpha() & 0xFF) << 0x18;
140
141 array->write (glvertex);
142 }
143
144 // =============================================================================
145 // -----------------------------------------------------------------------------
146 void VertexCompiler::compilePolygon (
147 LDObject* obj,
148 VertexCompiler::Array** arrays
149 ) {
150 LDObject::Type objtype = obj->getType();
151 bool isline = (objtype == LDObject::Line || objtype == LDObject::CondLine);
152 int verts = isline ? 2 : obj->vertices();
153
154 for (int i = 0; i < verts; ++i) {
155 compileVertex (obj->getVertex (i), getObjectColor (obj, Normal),
156 arrays[isline ? EdgeArray : MainArray]);
157 }
158
159 // For non-lines, compile BFC data
160 if (!isline) {
161 QColor col = getObjectColor (obj, BFCFront);
162 for (int i = 0; i < verts; ++i)
163 compileVertex (obj->getVertex(i), col, arrays[BFCArray]);
164
165 col = getObjectColor (obj, BFCBack);
166 for (int i = verts - 1; i >= 0; --i)
167 compileVertex (obj->getVertex(i), col, arrays[BFCArray]);
168 }
169 }
170
171 // =============================================================================
172 // -----------------------------------------------------------------------------
173 void VertexCompiler::compileObject (
174 LDObject* obj
175 ) {
176 if (m_objArrays.find (obj) == m_objArrays.end()) {
177 m_objArrays[obj] = new Array*[NumArrays];
178
179 for (int i = 0; i < NumArrays; ++i)
180 m_objArrays[obj][i] = new Array;
181 } else {
182 for (int i = 0; i < NumArrays; ++i)
183 m_objArrays[obj][i]->clear();
184 }
185
186 switch (obj->getType()) {
187 case LDObject::Triangle:
188 compilePolygon (obj, m_objArrays[obj]);
189 m_changed[MainArray] = true;
190 break;
191
192 case LDObject::Quad:
193 for (LDTriangleObject* triangle : static_cast<LDQuadObject*> (obj)->splitToTriangles())
194 compilePolygon (triangle, m_objArrays[obj]);
195 m_changed[MainArray] = true;
196 break;
197
198 case LDObject::Line:
199 compilePolygon (obj, m_objArrays[obj]);
200 break;
201
202 default:
203 break;
204 }
205 }
206
207 // =============================================================================
208 // -----------------------------------------------------------------------------
209 void VertexCompiler::compileFile() {
210 for (LDObject* obj : *m_file)
211 compileObject (obj);
212 }
213
214 // =============================================================================
215 // -----------------------------------------------------------------------------
216 void VertexCompiler::forgetObject (
217 LDObject* obj
218 ) {
219 for (int i = 0; i < NumArrays; ++i)
220 delete m_objArrays[obj][i];
221
222 delete m_objArrays[obj];
223 m_objArrays.remove (obj);
224 }
225
226 // =============================================================================
227 // -----------------------------------------------------------------------------
228 void VertexCompiler::setFile (
229 LDFile* file
230 ) {
231 m_file = file;
232 }
233
234 // =============================================================================
235 // -----------------------------------------------------------------------------
236 VertexCompiler::Array* VertexCompiler::getMergedBuffer (
237 VertexCompiler::MergedArrayType type
238 ) {
239 assert (type < NumArrays);
240
241 if (m_changed) {
242 m_changed[type] = false;
243 m_mainArrays[type]->clear();
244
245 for (LDObject* obj : *m_file) {
246 auto it = m_objArrays.find (obj);
247
248 if (it != m_objArrays.end())
249 m_mainArrays[type]->merge ((*it)[type]);
250 }
251 }
252
253 return m_mainArrays[type];
254 }
255
256 // =============================================================================
257 // -----------------------------------------------------------------------------
258 static List<short> g_warnedColors;
259 QColor VertexCompiler::getObjectColor (
260 LDObject* obj,
261 ColorType colotype
262 ) const {
263 QColor qcol;
264
265 if (!obj->isColored())
266 return QColor();
267
268 /*
269 if (list == GL::PickList) {
270 // Make the color by the object's ID if we're picking, so we can make the
271 // ID again from the color we get from the picking results. Be sure to use
272 // the top level parent's index since we want a subfile's children point
273 // to the subfile itself.
274 long i = obj->topLevelParent()->id();
275
276 // Calculate a color based from this index. This method caters for
277 // 16777216 objects. I don't think that'll be exceeded anytime soon. :)
278 // ATM biggest is 53588.dat with 12600 lines.
279 double r = (i / (256 * 256)) % 256,
280 g = (i / 256) % 256,
281 b = i % 256;
282
283 qglColor (QColor (r, g, b));
284 return;
285 }
286 */
287
288 if ((colotype == BFCFront || colotype == BFCBack) &&
289 obj->getType() != LDObject::Line &&
290 obj->getType() != LDObject::CondLine) {
291
292 if (colotype == BFCFront)
293 qcol = QColor (40, 192, 0);
294 else
295 qcol = QColor (224, 0, 0);
296 } else {
297 if (obj->color() == maincolor)
298 qcol = GL::getMainColor();
299 else {
300 LDColor* col = getColor (obj->color());
301
302 if (col)
303 qcol = col->faceColor;
304 }
305
306 if (obj->color() == edgecolor) {
307 qcol = QColor (32, 32, 32); // luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black;
308 LDColor* col;
309
310 if (!gl_blackedges && obj->parent() && (col = getColor (obj->parent()->color())))
311 qcol = col->edgeColor;
312 }
313
314 if (qcol.isValid() == false) {
315 // The color was unknown. Use main color to make the object at least
316 // not appear pitch-black.
317 if (obj->color() != edgecolor)
318 qcol = GL::getMainColor();
319
320 // Warn about the unknown colors, but only once.
321 for (short i : g_warnedColors)
322 if (obj->color() == i)
323 return Qt::black;
324
325 print ("%1: Unknown color %2!\n", __func__, obj->color());
326 g_warnedColors << obj->color();
327 return Qt::black;
328 }
329 }
330
331 if (obj->topLevelParent()->selected()) {
332 // Brighten it up for the select list.
333 const uchar add = 51;
334
335 qcol.setRed (min (qcol.red() + add, 255));
336 qcol.setGreen (min (qcol.green() + add, 255));
337 qcol.setBlue (min (qcol.blue() + add, 255));
338 }
339
340 return qcol;
341 }

mercurial