History

Instancing work, second pass

Bradley Austin Davis committed 11 years ago

Commit e024d231 parent ba5109c33 files · +935 −877Browse files

Showing the changes to libraries/render-utils/src/GeometryCache.cpp (1 of 33 files). Show all

Unified · Split

libraries/render-utils/src/GeometryCache.cpp+463−470
@@ -33,278 +33,508 @@ · 32 unmodified lines
3333
3434 const int GeometryCache::UNKNOWN_ID = -1;
3535
36−GeometryCache::GeometryCache() :
37− _nextID(0)
38−{
39− const qint64 GEOMETRY_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE;
40− setUnusedResourceCacheSize(GEOMETRY_DEFAULT_UNUSED_MAX_SIZE);
36+static const uint FLOATS_PER_VERTEX = 3;
37+static const uint VERTICES_PER_TRIANGLE = 3;
38+static const uint TRIANGLES_PER_QUAD = 2;
39+static const uint CUBE_FACES = 6;
40+static const uint CUBE_VERTICES_PER_FACE = 4;
41+static const uint CUBE_VERTICES = CUBE_FACES * CUBE_VERTICES_PER_FACE;
42+static const uint CUBE_VERTEX_POINTS = CUBE_VERTICES * FLOATS_PER_VERTEX;
43+static const uint CUBE_INDICES = CUBE_FACES * TRIANGLES_PER_QUAD * VERTICES_PER_TRIANGLE;
44+static const uint SPHERE_LATITUDES = 24;
45+static const uint SPHERE_MERIDIANS = SPHERE_LATITUDES * 2;
46+static const uint SPHERE_INDICES = SPHERE_MERIDIANS * (SPHERE_LATITUDES - 1) * TRIANGLES_PER_QUAD * VERTICES_PER_TRIANGLE;
47+
48+static const gpu::Element POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
49+static const gpu::Element NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
50+static const gpu::Element COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA };
51+static const gpu::Element TRANSFORM_ELEMENT{ gpu::MAT4, gpu::FLOAT, gpu::XYZW };
52+
53+static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT;
54+static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT;
55+
56+static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals
57+static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3);
58+
59+
60+void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const VVertex& vertices) {
61+ vertexBuffer->append(vertices);
62+
63+ _positionView = gpu::BufferView(vertexBuffer, 0,
64+ vertexBuffer->getSize(), SHAPE_VERTEX_STRIDE, POSITION_ELEMENT);
65+ _normalView = gpu::BufferView(vertexBuffer, SHAPE_NORMALS_OFFSET,
66+ vertexBuffer->getSize(), SHAPE_VERTEX_STRIDE, NORMAL_ELEMENT);
4167 }
4268
43−GeometryCache::~GeometryCache() {
44− #ifdef WANT_DEBUG
45− qCDebug(renderutils) << "GeometryCache::~GeometryCache()... ";
46− qCDebug(renderutils) << " _registeredLine3DVBOs.size():" << _registeredLine3DVBOs.size();
47− qCDebug(renderutils) << " _line3DVBOs.size():" << _line3DVBOs.size();
48− qCDebug(renderutils) << " BatchItemDetails... population:" << GeometryCache::BatchItemDetails::population;
49− #endif //def WANT_DEBUG
50−}
69+void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, const VIndex& indices, const VIndex& wireIndices) {
70+ _indices = indexBuffer;
71+ if (!indices.empty()) {
72+ _indexOffset = indexBuffer->getSize();
73+ _indexCount = indices.size();
74+ indexBuffer->append(indices);
75+ }
5176
52−QSharedPointer<Resource> GeometryCache::createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
53− bool delayLoad, const void* extra) {
54− // NetworkGeometry is no longer a subclass of Resource, but requires this method because, it is pure virtual.
55− assert(false);
56− return QSharedPointer<Resource>();
77+ if (!wireIndices.empty()) {
78+ _wireIndexOffset = indexBuffer->getSize();
79+ _wireIndexCount = wireIndices.size();
80+ indexBuffer->append(wireIndices);
81+ }
5782 }
5883
59−const int NUM_VERTICES_PER_TRIANGLE = 3;
60−const int NUM_TRIANGLES_PER_QUAD = 2;
61−const int NUM_VERTICES_PER_TRIANGULATED_QUAD = NUM_VERTICES_PER_TRIANGLE * NUM_TRIANGLES_PER_QUAD;
62−const int NUM_COORDS_PER_VERTEX = 3;
84+void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const {
85+ batch.setInputBuffer(gpu::Stream::POSITION, _positionView);
86+ batch.setInputBuffer(gpu::Stream::NORMAL, _normalView);
87+}
6388
64−void GeometryCache::renderSphere(gpu::Batch& batch, float radius, int slices, int stacks, const glm::vec4& color, bool solid, int id) {
65− bool registered = (id != UNKNOWN_ID);
89+void GeometryCache::ShapeData::draw(gpu::Batch& batch) const {
90+ if (_indexCount) {
91+ setupBatch(batch);
92+ batch.setIndexBuffer(gpu::UINT16, _indices, _indexOffset);
93+ batch.drawIndexed(gpu::TRIANGLES, _indexCount);
94+ }
95+}
6696
67− Vec2Pair radiusKey(glm::vec2(radius, slices), glm::vec2(stacks, 0));
68− IntPair slicesStacksKey(slices, stacks);
69− Vec3Pair colorKey(glm::vec3(color.x, color.y, slices), glm::vec3(color.z, color.w, stacks));
97+void GeometryCache::ShapeData::drawWire(gpu::Batch& batch) const {
98+ if (_wireIndexCount) {
99+ setupBatch(batch);
100+ batch.setIndexBuffer(gpu::UINT16, _indices, _wireIndexOffset);
101+ batch.drawIndexed(gpu::LINES, _wireIndexCount);
102+ }
103+}
70104
71− int vertices = slices * (stacks - 1) + 2;
72− int indices = slices * (stacks - 1) * NUM_VERTICES_PER_TRIANGULATED_QUAD;
105+void GeometryCache::ShapeData::drawInstances(gpu::Batch& batch, size_t count) const {
106+ if (_indexCount) {
107+ setupBatch(batch);
108+ batch.setIndexBuffer(gpu::UINT16, _indices, _indexOffset);
109+ batch.drawIndexedInstanced(count, gpu::TRIANGLES, _indexCount);
110+ }
111+}
73112
74− if ((registered && (!_registeredSphereVertices.contains(id) || _lastRegisteredSphereVertices[id] != radiusKey))
75− || (!registered && !_sphereVertices.contains(radiusKey))) {
113+void GeometryCache::ShapeData::drawWireInstances(gpu::Batch& batch, size_t count) const {
114+ if (_wireIndexCount) {
115+ setupBatch(batch);
116+ batch.setIndexBuffer(gpu::UINT16, _indices, _wireIndexOffset);
117+ batch.drawIndexedInstanced(count, gpu::LINES, _wireIndexCount);
118+ }
119+}
76120
77− if (registered && _registeredSphereVertices.contains(id)) {
78− _registeredSphereVertices[id].reset();
79− #ifdef WANT_DEBUG
80− qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED VERTICES BUFFER";
81− #endif
82− }
121+const VVertex& icosahedronVertices() {
122+ static const float phi = (1.0 + sqrt(5.0)) / 2.0;
123+ static const float a = 0.5;
124+ static const float b = 1.0 / (2.0 * phi);
125+
126+ static const VVertex vertices{ //
127+ vec3(0, b, -a), vec3(-b, a, 0), vec3(b, a, 0), //
128+ vec3(0, b, a), vec3(b, a, 0), vec3(-b, a, 0), //
129+ vec3(0, b, a), vec3(-a, 0, b), vec3(0, -b, a), //
130+ vec3(0, b, a), vec3(0, -b, a), vec3(a, 0, b), //
131+ vec3(0, b, -a), vec3(a, 0, -b), vec3(0, -b, -a),//
132+ vec3(0, b, -a), vec3(0, -b, -a), vec3(-a, 0, -b), //
133+ vec3(0, -b, a), vec3(-b, -a, 0), vec3(b, -a, 0), //
134+ vec3(0, -b, -a), vec3(b, -a, 0), vec3(-b, -a, 0), //
135+ vec3(-b, a, 0), vec3(-a, 0, -b), vec3(-a, 0, b), //
136+ vec3(-b, -a, 0), vec3(-a, 0, b), vec3(-a, 0, -b), //
137+ vec3(b, a, 0), vec3(a, 0, b), vec3(a, 0, -b), //
138+ vec3(b, -a, 0), vec3(a, 0, -b), vec3(a, 0, b), //
139+ vec3(0, b, a), vec3(-b, a, 0), vec3(-a, 0, b), //
140+ vec3(0, b, a), vec3(a, 0, b), vec3(b, a, 0), //
141+ vec3(0, b, -a), vec3(-a, 0, -b), vec3(-b, a, 0), //
142+ vec3(0, b, -a), vec3(b, a, 0), vec3(a, 0, -b), //
143+ vec3(0, -b, -a), vec3(-b, -a, 0), vec3(-a, 0, -b), //
144+ vec3(0, -b, -a), vec3(a, 0, -b), vec3(b, -a, 0), //
145+ vec3(0, -b, a), vec3(-a, 0, b), vec3(-b, -a, 0), //
146+ vec3(0, -b, a), vec3(b, -a, 0), vec3(a, 0, b)
147+ }; //
148+ return vertices;
149+}
83150
84− auto verticesBuffer = std::make_shared<gpu::Buffer>();
85− if (registered) {
86− _registeredSphereVertices[id] = verticesBuffer;
87− _lastRegisteredSphereVertices[id] = radiusKey;
88− } else {
89− _sphereVertices[radiusKey] = verticesBuffer;
90− }
151+const VVertex& tetrahedronVertices() {
152+ static const float a = 1.0f / sqrt(2.0f);
153+ static const auto A = vec3(0, 1, a);
154+ static const auto B = vec3(0, -1, a);
155+ static const auto C = vec3(1, 0, -a);
156+ static const auto D = vec3(-1, 0, -a);
157+ static const VVertex vertices{
158+ A, B, C,
159+ D, B, A,
160+ C, D, A,
161+ C, B, D,
162+ };
163+ return vertices;
164+}
91165
92− GLfloat* vertexData = new GLfloat[vertices * NUM_COORDS_PER_VERTEX];
93− GLfloat* vertex = vertexData;
166+VVertex tesselate(const VVertex& startingTriangles, int count) {
167+ VVertex triangles = startingTriangles;
168+ if (0 != (triangles.size() % 3)) {
169+ throw std::runtime_error("Bad number of vertices for tesselation");
170+ }
94171
95− // south pole
96− *(vertex++) = 0.0f;
97− *(vertex++) = 0.0f;
98− *(vertex++) = -1.0f * radius;
172+ for (size_t i = 0; i < triangles.size(); ++i) {
173+ triangles[i] = glm::normalize(triangles[i]);
174+ }
99175
100− //add stacks vertices climbing up Y axis
101− for (int i = 1; i < stacks; i++) {
102− float phi = PI * (float)i / (float)(stacks) - PI_OVER_TWO;
103− float z = sinf(phi) * radius;
104− float stackRadius = cosf(phi) * radius;
105−
106− for (int j = 0; j < slices; j++) {
107− float theta = TWO_PI * (float)j / (float)slices;
176+ VVertex newTriangles;
177+ while (count) {
178+ newTriangles.clear();
179+ newTriangles.reserve(triangles.size() * 4);
180+ for (size_t i = 0; i < triangles.size(); i += 3) {
181+ const vec3& a = triangles[i];
182+ const vec3& b = triangles[i + 1];
183+ const vec3& c = triangles[i + 2];
184+ vec3 ab = glm::normalize(a + b);
185+ vec3 bc = glm::normalize(b + c);
186+ vec3 ca = glm::normalize(c + a);
187+
188+ newTriangles.push_back(a);
189+ newTriangles.push_back(ab);
190+ newTriangles.push_back(ca);
191+
192+ newTriangles.push_back(b);
193+ newTriangles.push_back(bc);
194+ newTriangles.push_back(ab);
195+
196+ newTriangles.push_back(c);
197+ newTriangles.push_back(ca);
198+ newTriangles.push_back(bc);
199+
200+ newTriangles.push_back(ab);
201+ newTriangles.push_back(bc);
202+ newTriangles.push_back(ca);
203+ }
204+ triangles.swap(newTriangles);
205+ --count;
206+ }
207+ return triangles;
208+}
108209
109− *(vertex++) = sinf(theta) * stackRadius;
110− *(vertex++) = cosf(theta) * stackRadius;
111− *(vertex++) = z;
210+// FIXME solids need per-face vertices, but smooth shaded
211+// components do not. Find a way to support using draw elements
212+// or draw arrays as appropriate
213+// Maybe special case cone and cylinder since they combine flat
214+// and smooth shading
215+void GeometryCache::buildShapes() {
216+ auto vertexBuffer = std::make_shared<gpu::Buffer>();
217+ auto indexBuffer = std::make_shared<gpu::Buffer>();
218+ uint16_t startingIndex = 0;
219+
220+ // Cube
221+ startingIndex = _shapeVertices->getSize() / SHAPE_VERTEX_STRIDE;
222+ {
223+ ShapeData& shapeData = _shapes[Cube];
224+ VVertex vertices;
225+ // front
226+ vertices.push_back(vec3(1, 1, 1));
227+ vertices.push_back(vec3(0, 0, 1));
228+ vertices.push_back(vec3(-1, 1, 1));
229+ vertices.push_back(vec3(0, 0, 1));
230+ vertices.push_back(vec3(-1, -1, 1));
231+ vertices.push_back(vec3(0, 0, 1));
232+ vertices.push_back(vec3(1, -1, 1));
233+ vertices.push_back(vec3(0, 0, 1));
234+
235+ // right
236+ vertices.push_back(vec3(1, 1, 1));
237+ vertices.push_back(vec3(1, 0, 0));
238+ vertices.push_back(vec3(1, -1, 1));
239+ vertices.push_back(vec3(1, 0, 0));
240+ vertices.push_back(vec3(1, -1, -1));
241+ vertices.push_back(vec3(1, 0, 0));
242+ vertices.push_back(vec3(1, 1, -1));
243+ vertices.push_back(vec3(1, 0, 0));
244+
245+ // top
246+ vertices.push_back(vec3(1, 1, 1));
247+ vertices.push_back(vec3(0, 1, 0));
248+ vertices.push_back(vec3(1, 1, -1));
249+ vertices.push_back(vec3(0, 1, 0));
250+ vertices.push_back(vec3(-1, 1, -1));
251+ vertices.push_back(vec3(0, 1, 0));
252+ vertices.push_back(vec3(-1, 1, 1));
253+ vertices.push_back(vec3(0, 1, 0));
254+
255+ // left
256+ vertices.push_back(vec3(-1, 1, 1));
257+ vertices.push_back(vec3(-1, 0, 0));
258+ vertices.push_back(vec3(-1, 1, -1));
259+ vertices.push_back(vec3(-1, 0, 0));
260+ vertices.push_back(vec3(-1, -1, -1));
261+ vertices.push_back(vec3(-1, 0, 0));
262+ vertices.push_back(vec3(-1, -1, 1));
263+ vertices.push_back(vec3(-1, 0, 0));
264+
265+ // bottom
266+ vertices.push_back(vec3(-1, -1, -1));
267+ vertices.push_back(vec3(0, -1, 0));
268+ vertices.push_back(vec3(1, -1, -1));
269+ vertices.push_back(vec3(0, -1, 0));
270+ vertices.push_back(vec3(1, -1, 1));
271+ vertices.push_back(vec3(0, -1, 0));
272+ vertices.push_back(vec3(-1, -1, 1));
273+ vertices.push_back(vec3(0, -1, 0));
274+
275+ // back
276+ vertices.push_back(vec3(1, -1, -1));
277+ vertices.push_back(vec3(0, 0, -1));
278+ vertices.push_back(vec3(-1, -1, -1));
279+ vertices.push_back(vec3(0, 0, -1));
280+ vertices.push_back(vec3(-1, 1, -1));
281+ vertices.push_back(vec3(0, 0, -1));
282+ vertices.push_back(vec3(1, 1, -1));
283+ vertices.push_back(vec3(0, 0, -1));
284+
285+ for (size_t i = 0; i < vertices.size(); ++i) {
286+ if (0 == i % 2) {
287+ vertices[i] *= 0.5f;
112288 }
113289 }
290+ shapeData.setupVertices(_shapeVertices, vertices);
291+
292+ VIndex indices{
293+ 0, 1, 2, 2, 3, 0, // front
294+ 4, 5, 6, 6, 7, 4, // right
295+ 8, 9, 10, 10, 11, 8, // top
296+ 12, 13, 14, 14, 15, 12, // left
297+ 16, 17, 18, 18, 19, 16, // bottom
298+ 20, 21, 22, 22, 23, 20 // back
299+ };
300+ for (int i = 0; i < indices.size(); ++i) {
301+ indices[i] += startingIndex;
302+ }
114303
115− // north pole
116− *(vertex++) = 0.0f;
117− *(vertex++) = 0.0f;
118− *(vertex++) = 1.0f * radius;
119−
120− verticesBuffer->append(sizeof(GLfloat) * vertices * NUM_COORDS_PER_VERTEX, (gpu::Byte*) vertexData);
121− delete[] vertexData;
122−
123− #ifdef WANT_DEBUG
124− qCDebug(renderutils) << "GeometryCache::renderSphere()... --- CREATING VERTICES BUFFER";
125− qCDebug(renderutils) << " radius:" << radius;
126− qCDebug(renderutils) << " slices:" << slices;
127− qCDebug(renderutils) << " stacks:" << stacks;
304+ VIndex wireIndices{
305+ 0, 1, 1, 2, 2, 3, 3, 0, // front
306+ 20, 21, 21, 22, 22, 23, 23, 20, // back
307+ 0, 23, 1, 22, 2, 21, 3, 20 // sides
308+ };
309+ for (int i = 0; i < wireIndices.size(); ++i) {
310+ indices[i] += startingIndex;
311+ }
128312
129− qCDebug(renderutils) << " _sphereVertices.size():" << _sphereVertices.size();
130− #endif
313+ shapeData.setupIndices(_shapeIndices, indices, wireIndices);
131314 }
132− #ifdef WANT_DEBUG
133− else if (registered) {
134− qCDebug(renderutils) << "renderSphere()... REUSING PREVIOUSLY REGISTERED VERTICES BUFFER";
135− }
136− #endif
137−
138− if ((registered && (!_registeredSphereIndices.contains(id) || _lastRegisteredSphereIndices[id] != slicesStacksKey))
139− || (!registered && !_sphereIndices.contains(slicesStacksKey))) {
140315
141− if (registered && _registeredSphereIndices.contains(id)) {
142− _registeredSphereIndices[id].reset();
143− #ifdef WANT_DEBUG
144− qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED INDICES BUFFER";
145− #endif
316+ // Tetrahedron
317+ startingIndex = _shapeVertices->getSize() / SHAPE_VERTEX_STRIDE;
318+ {
319+ ShapeData& shapeData = _shapes[Tetrahedron];
320+ size_t vertexCount = 4;
321+ VVertex vertices;
322+ {
323+ VVertex originalVertices = tetrahedronVertices();
324+ vertexCount = originalVertices.size();
325+ vertices.reserve(originalVertices.size() * 2);
326+ for (size_t i = 0; i < originalVertices.size(); i += 3) {
327+ vec3 faceNormal;
328+ for (size_t j = 0; j < 3; ++j) {
329+ faceNormal += originalVertices[i + j];
330+ }
331+ faceNormal = glm::normalize(faceNormal);
332+ for (size_t j = 0; j < 3; ++j) {
333+ vertices.push_back(glm::normalize(originalVertices[i + j]) * 0.5f);
334+ vertices.push_back(faceNormal);
335+ }
336+ }
146337 }
338+ shapeData.setupVertices(_shapeVertices, vertices);
147339
148− auto indicesBuffer = std::make_shared<gpu::Buffer>();
149− if (registered) {
150− _registeredSphereIndices[id] = indicesBuffer;
151− _lastRegisteredSphereIndices[id] = slicesStacksKey;
152− } else {
153− _sphereIndices[slicesStacksKey] = indicesBuffer;
340+ VIndex indices;
341+ for (size_t i = 0; i < vertexCount; i += 3) {
342+ for (size_t j = 0; j < 3; ++j) {
343+ indices.push_back(i + j + startingIndex);
344+ }
154345 }
155346
156− GLushort* indexData = new GLushort[indices];
157− GLushort* index = indexData;
158−
159− int indexCount = 0;
160−
161− // South cap
162− GLushort bottom = 0;
163− GLushort top = 1;
164− for (int i = 0; i < slices; i++) {
165− *(index++) = bottom;
166− *(index++) = top + i;
167− *(index++) = top + (i + 1) % slices;
168−
169− indexCount += 3;
347+ VIndex wireIndices{
348+ 0, 1, 1, 2, 2, 0,
349+ 0, 3, 1, 3, 2, 3,
350+ };
351+
352+ for (int i = 0; i < wireIndices.size(); ++i) {
353+ wireIndices[i] += startingIndex;
170354 }
171355
172− // (stacks - 2) ribbons
173− for (int i = 0; i < stacks - 2; i++) {
174− bottom = i * slices + 1;
175− top = bottom + slices;
176− for (int j = 0; j < slices; j++) {
177− int next = (j + 1) % slices;
178−
179− *(index++) = top + next;
180− *(index++) = bottom + j;
181− *(index++) = top + j;
182−
183− indexCount += 3;
184−
185− *(index++) = bottom + next;
186− *(index++) = bottom + j;
187− *(index++) = top + next;
188−
189− indexCount += 3;
356+ shapeData.setupIndices(_shapeIndices, indices, wireIndices);
357+ }
190358
359+ // Sphere
360+ // FIXME this uses way more vertices than required. Should find a way to calculate the indices
361+ // using shared vertices for better vertex caching
362+ startingIndex = _shapeVertices->getSize() / SHAPE_VERTEX_STRIDE;
363+ {
364+ ShapeData& shapeData = _shapes[Sphere];
365+ VVertex vertices;
366+ VIndex indices;
367+ {
368+ VVertex originalVertices = tesselate(icosahedronVertices(), 3);
369+ vertices.reserve(originalVertices.size() * 2);
370+ for (size_t i = 0; i < originalVertices.size(); i += 3) {
371+ for (int j = 0; j < 3; ++j) {
372+ vertices.push_back(originalVertices[i + j] * 0.5f);
373+ vertices.push_back(originalVertices[i + j]);
374+ indices.push_back(i + j + startingIndex);
375+ }
191376 }
192377 }
193378
194− // north cap
195− bottom = (stacks - 2) * slices + 1;
196− top = bottom + slices;
197− for (int i = 0; i < slices; i++) {
198− *(index++) = bottom + (i + 1) % slices;
199− *(index++) = bottom + i;
200− *(index++) = top;
201−
202− indexCount += 3;
379+ shapeData.setupVertices(_shapeVertices, vertices);
380+ // FIXME don't use solid indices for wire drawing.
381+ shapeData.setupIndices(_shapeIndices, indices, indices);
382+ }
203383
384+ // Icosahedron
385+ startingIndex = _shapeVertices->getSize() / SHAPE_VERTEX_STRIDE;
386+ {
387+ ShapeData& shapeData = _shapes[Icosahedron];
388+
389+ VVertex vertices;
390+ VIndex indices;
391+ {
392+ const VVertex& originalVertices = icosahedronVertices();
393+ vertices.reserve(originalVertices.size() * 2);
394+ for (size_t i = 0; i < originalVertices.size(); i += 3) {
395+ vec3 faceNormal;
396+ for (size_t j = 0; j < 3; ++j) {
397+ faceNormal += originalVertices[i + j];
398+ }
399+ faceNormal = glm::normalize(faceNormal);
400+ for (int j = 0; j < 3; ++j) {
401+ vertices.push_back(glm::normalize(originalVertices[i + j]) * 0.5f);
402+ vertices.push_back(faceNormal);
403+ indices.push_back(i + j + startingIndex);
404+ }
405+ }
204406 }
205− indicesBuffer->append(sizeof(GLushort) * indices, (gpu::Byte*) indexData);
206− delete[] indexData;
207−
208− #ifdef WANT_DEBUG
209− qCDebug(renderutils) << "GeometryCache::renderSphere()... --- CREATING INDICES BUFFER";
210− qCDebug(renderutils) << " radius:" << radius;
211− qCDebug(renderutils) << " slices:" << slices;
212− qCDebug(renderutils) << " stacks:" << stacks;
213− qCDebug(renderutils) << "indexCount:" << indexCount;
214− qCDebug(renderutils) << " indices:" << indices;
215− qCDebug(renderutils) << " _sphereIndices.size():" << _sphereIndices.size();
216− #endif
407+
408+ shapeData.setupVertices(_shapeVertices, vertices);
409+ // FIXME don't use solid indices for wire drawing.
410+ shapeData.setupIndices(_shapeIndices, indices, indices);
217411 }
218− #ifdef WANT_DEBUG
219− else if (registered) {
220− qCDebug(renderutils) << "renderSphere()... REUSING PREVIOUSLY REGISTERED INDICES BUFFER";
412+
413+ //Triangle,
414+ //Quad,
415+ //Circle,
416+ //Octahetron,
417+ //Dodecahedron,
418+ //Torus,
419+ //Cone,
420+ //Cylinder,
421+ // Line
422+ startingIndex = _shapeVertices->getSize() / SHAPE_VERTEX_STRIDE;
423+ {
424+ ShapeData& shapeData = _shapes[Line];
425+ shapeData.setupVertices(_shapeVertices, VVertex{
426+ vec3(-0.5, 0, 0), vec3(-0.5, 0, 0),
427+ vec3(0.5f, 0, 0), vec3(0.5f, 0, 0)
428+ });
429+ VIndex wireIndices;
430+ wireIndices.push_back(0 + startingIndex);
431+ wireIndices.push_back(1 + startingIndex);
432+
433+ shapeData.setupIndices(_shapeIndices, VIndex(), wireIndices);
221434 }
222− #endif
435+}
223436
224− if ((registered && (!_registeredSphereColors.contains(id) || _lastRegisteredSphereColors[id] != colorKey))
225− || (!registered && !_sphereColors.contains(colorKey))) {
437+gpu::Stream::FormatPointer& getSolidStreamFormat() {
438+ if (!SOLID_STREAM_FORMAT) {
439+ SOLID_STREAM_FORMAT = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
440+ SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT);
441+ SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT);
442+ }
443+ return SOLID_STREAM_FORMAT;
444+}
226445
227− if (registered && _registeredSphereColors.contains(id)) {
228− _registeredSphereColors[id].reset();
229− #ifdef WANT_DEBUG
230− qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED COLORS BUFFER";
231− #endif
232− }
233−
234− auto colorBuffer = std::make_shared<gpu::Buffer>();
235− if (registered) {
236− _registeredSphereColors[id] = colorBuffer;
237− _lastRegisteredSphereColors[id] = colorKey;
238− } else {
239− _sphereColors[colorKey] = colorBuffer;
240− }
446+gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() {
447+ if (!INSTANCED_SOLID_STREAM_FORMAT) {
448+ INSTANCED_SOLID_STREAM_FORMAT = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
449+ INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT);
450+ INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT);
451+ INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
452+ INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::INSTANCE_XFM, gpu::Stream::INSTANCE_XFM, TRANSFORM_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
453+ }
454+ return INSTANCED_SOLID_STREAM_FORMAT;
455+}
241456
242− int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
243− ((int(color.y * 255.0f) & 0xFF) << 8) |
244− ((int(color.z * 255.0f) & 0xFF) << 16) |
245− ((int(color.w * 255.0f) & 0xFF) << 24);
246457
247− int* colorData = new int[vertices];
248− int* colorDataAt = colorData;
458+GeometryCache::GeometryCache() {
459+ const qint64 GEOMETRY_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE;
460+ setUnusedResourceCacheSize(GEOMETRY_DEFAULT_UNUSED_MAX_SIZE);
461+ buildShapes();
462+}
249463
250− for(int v = 0; v < vertices; v++) {
251− *(colorDataAt++) = compactColor;
252− }
464+GeometryCache::~GeometryCache() {
465+ #ifdef WANT_DEBUG
466+ qCDebug(renderutils) << "GeometryCache::~GeometryCache()... ";
467+ qCDebug(renderutils) << " _registeredLine3DVBOs.size():" << _registeredLine3DVBOs.size();
468+ qCDebug(renderutils) << " _line3DVBOs.size():" << _line3DVBOs.size();
469+ qCDebug(renderutils) << " BatchItemDetails... population:" << GeometryCache::BatchItemDetails::population;
470+ #endif //def WANT_DEBUG
471+}
253472
254− colorBuffer->append(sizeof(int) * vertices, (gpu::Byte*) colorData);
255− delete[] colorData;
473+QSharedPointer<Resource> GeometryCache::createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
474+ bool delayLoad, const void* extra) {
475+ // NetworkGeometry is no longer a subclass of Resource, but requires this method because, it is pure virtual.
476+ assert(false);
477+ return QSharedPointer<Resource>();
478+}
256479
257− #ifdef WANT_DEBUG
258− qCDebug(renderutils) << "GeometryCache::renderSphere()... --- CREATING COLORS BUFFER";
259− qCDebug(renderutils) << " vertices:" << vertices;
260− qCDebug(renderutils) << " color:" << color;
261− qCDebug(renderutils) << " slices:" << slices;
262− qCDebug(renderutils) << " stacks:" << stacks;
263− qCDebug(renderutils) << " _sphereColors.size():" << _sphereColors.size();
264− #endif
265− }
266− #ifdef WANT_DEBUG
267− else if (registered) {
268− qCDebug(renderutils) << "renderSphere()... REUSING PREVIOUSLY REGISTERED COLORS BUFFER";
269− }
270− #endif
480+void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
481+ gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
482+ batch.setInputBuffer(gpu::Stream::COLOR, colorView);
483+ gpu::BufferView instanceXfmView(transformBuffer, 0, transformBuffer->getSize(), TRANSFORM_ELEMENT);
484+ batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView);
485+}
271486
272− gpu::BufferPointer verticesBuffer = registered ? _registeredSphereVertices[id] : _sphereVertices[radiusKey];
273− gpu::BufferPointer indicesBuffer = registered ? _registeredSphereIndices[id] : _sphereIndices[slicesStacksKey];
274− gpu::BufferPointer colorBuffer = registered ? _registeredSphereColors[id] : _sphereColors[colorKey];
275−
276− const int VERTICES_SLOT = 0;
277− const int NORMALS_SLOT = 1;
278− const int COLOR_SLOT = 2;
279− static gpu::Stream::FormatPointer streamFormat;
280− static gpu::Element positionElement, normalElement, colorElement;
281− if (!streamFormat) {
282− streamFormat = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
283− streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
284− streamFormat->setAttribute(gpu::Stream::NORMAL, NORMALS_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
285− streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
286− positionElement = streamFormat->getAttributes().at(gpu::Stream::POSITION)._element;
287− normalElement = streamFormat->getAttributes().at(gpu::Stream::NORMAL)._element;
288− colorElement = streamFormat->getAttributes().at(gpu::Stream::COLOR)._element;
289− }
487+void GeometryCache::renderShape(gpu::Batch& batch, Shape shape) {
488+ batch.setInputFormat(getSolidStreamFormat());
489+ _shapes[shape].draw(batch);
490+}
290491
291− gpu::BufferView verticesView(verticesBuffer, positionElement);
292− gpu::BufferView normalsView(verticesBuffer, normalElement);
293− gpu::BufferView colorView(colorBuffer, colorElement);
294−
295− batch.setInputFormat(streamFormat);
296− batch.setInputBuffer(VERTICES_SLOT, verticesView);
297− batch.setInputBuffer(NORMALS_SLOT, normalsView);
298− batch.setInputBuffer(COLOR_SLOT, colorView);
299− batch.setIndexBuffer(gpu::UINT16, indicesBuffer, 0);
492+void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape) {
493+ batch.setInputFormat(getSolidStreamFormat());
494+ _shapes[shape].drawWire(batch);
495+}
300496
301− if (solid) {
302− batch.drawIndexed(gpu::TRIANGLES, indices);
303− } else {
304− batch.drawIndexed(gpu::LINES, indices);
305− }
497+void GeometryCache::renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) {
498+ batch.setInputFormat(getInstancedSolidStreamFormat());
499+ setupBatchInstance(batch, transformBuffer, colorBuffer);
500+ _shapes[shape].drawInstances(batch, count);
501+}
502+
503+void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) {
504+ batch.setInputFormat(getInstancedSolidStreamFormat());
505+ setupBatchInstance(batch, transformBuffer, colorBuffer);
506+ _shapes[shape].drawWireInstances(batch, count);
507+}
508+
509+void GeometryCache::renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
510+ renderShapeInstances(batch, Cube, count, transformBuffer, colorBuffer);
306511 }
307512
513+void GeometryCache::renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
514+ renderWireShapeInstances(batch, Cube, count, transformBuffer, colorBuffer);
515+}
516+
517+void GeometryCache::renderCube(gpu::Batch& batch) {
518+ renderShape(batch, Cube);
519+}
520+
521+void GeometryCache::renderWireCube(gpu::Batch& batch) {
522+ renderWireShape(batch, Cube);
523+}
524+
525+void GeometryCache::renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
526+ renderShapeInstances(batch, Sphere, count, transformBuffer, colorBuffer);
527+}
528+
529+void GeometryCache::renderSphere(gpu::Batch& batch) {
530+ renderShape(batch, Sphere);
531+}
532+
533+void GeometryCache::renderWireSphere(gpu::Batch& batch) {
534+ renderWireShape(batch, Sphere);
535+}
536+
537+
308538 void GeometryCache::renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions, const glm::vec4& color) {
309539 IntPair key(xDivisions, yDivisions);
310540 Vec3Pair colorKey(glm::vec3(color.x, color.y, yDivisions), glm::vec3(color.z, color.y, xDivisions));
@@ -689,243 +919,6 @@ void GeometryCache::renderVertices(gpu::Batch& batch, gpu::Primitive primitiveTy · 378 unmodified lines
689919 }
690920 }
691921
692−static const int FLOATS_PER_VERTEX = 3;
693−static const int VERTICES_PER_TRIANGLE = 3;
694−
695−static const int CUBE_NUMBER_OF_FACES = 6;
696−static const int CUBE_VERTICES_PER_FACE = 4;
697−static const int CUBE_TRIANGLES_PER_FACE = 2;
698−static const int CUBE_VERTICES = CUBE_NUMBER_OF_FACES * CUBE_VERTICES_PER_FACE;
699−static const int CUBE_VERTEX_POINTS = CUBE_VERTICES * FLOATS_PER_VERTEX;
700−static const int CUBE_INDICES = CUBE_NUMBER_OF_FACES * CUBE_TRIANGLES_PER_FACE * VERTICES_PER_TRIANGLE;
701−
702−static const gpu::Element CUBE_POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
703−static const gpu::Element CUBE_NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
704−static const gpu::Element CUBE_COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA };
705−static const gpu::Element INSTANCE_XFM_ELEMENT{ gpu::MAT4, gpu::FLOAT, gpu::XYZW };
706−
707−gpu::BufferPointer GeometryCache::getCubeVertices(float size) {
708− if (!_solidCubeVertices.contains(size)) {
709− auto verticesBuffer = std::make_shared<gpu::Buffer>();
710− _solidCubeVertices[size] = verticesBuffer;
711−
712− GLfloat* vertexData = new GLfloat[CUBE_VERTEX_POINTS * 2]; // vertices and normals
713− GLfloat* vertex = vertexData;
714− float halfSize = size / 2.0f;
715−
716− static GLfloat cannonicalVertices[CUBE_VERTEX_POINTS] =
717− { 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0,v1,v2,v3 (front)
718− 1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, // v0,v3,v4,v5 (right)
719− 1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0,v5,v6,v1 (top)
720− -1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, // v1,v6,v7,v2 (left)
721− -1,-1,-1, 1,-1,-1, 1,-1, 1, -1,-1, 1, // v7,v4,v3,v2 (bottom)
722− 1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 }; // v4,v7,v6,v5 (back)
723−
724− // normal array
725− static GLfloat cannonicalNormals[CUBE_VERTEX_POINTS] =
726− { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front)
727− 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0,v3,v4,v5 (right)
728− 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0,v5,v6,v1 (top)
729− -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1,v6,v7,v2 (left)
730− 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // v7,v4,v3,v2 (bottom)
731− 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 }; // v4,v7,v6,v5 (back)
732−
733−
734− GLfloat* cannonicalVertex = &cannonicalVertices[0];
735− GLfloat* cannonicalNormal = &cannonicalNormals[0];
736−
737− for (int i = 0; i < CUBE_VERTICES; i++) {
738− // vertices
739− *(vertex++) = halfSize * *cannonicalVertex++;
740− *(vertex++) = halfSize * *cannonicalVertex++;
741− *(vertex++) = halfSize * *cannonicalVertex++;
742−
743− //normals
744− *(vertex++) = *cannonicalNormal++;
745− *(vertex++) = *cannonicalNormal++;
746− *(vertex++) = *cannonicalNormal++;
747− }
748− verticesBuffer->append(sizeof(GLfloat) * CUBE_VERTEX_POINTS * 2, (gpu::Byte*) vertexData);
749− }
750−
751− return _solidCubeVertices[size];
752−}
753−
754−gpu::BufferPointer GeometryCache::getSolidCubeIndices() {
755− if (!_solidCubeIndexBuffer) {
756− static GLubyte cannonicalIndices[CUBE_INDICES] = { 0, 1, 2, 2, 3, 0, // front
757− 4, 5, 6, 6, 7, 4, // right
758− 8, 9,10, 10,11, 8, // top
759− 12,13,14, 14,15,12, // left
760− 16,17,18, 18,19,16, // bottom
761− 20,21,22, 22,23,20 }; // back
762−
763− auto indexBuffer = std::make_shared<gpu::Buffer>();
764− _solidCubeIndexBuffer = indexBuffer;
765−
766− _solidCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Byte*) cannonicalIndices);
767− }
768− return _solidCubeIndexBuffer;
769−}
770−
771−
772−void GeometryCache::setupCubeVertices(gpu::Batch& batch, gpu::BufferPointer& verticesBuffer) {
773− static const int VERTEX_STRIDE = sizeof(GLfloat) * FLOATS_PER_VERTEX * 2; // vertices and normals
774− static const int NORMALS_OFFSET = sizeof(GLfloat) * FLOATS_PER_VERTEX;
775−
776− gpu::BufferView verticesView(verticesBuffer, 0, verticesBuffer->getSize(), VERTEX_STRIDE, CUBE_POSITION_ELEMENT);
777− gpu::BufferView normalsView(verticesBuffer, NORMALS_OFFSET, verticesBuffer->getSize(), VERTEX_STRIDE, CUBE_NORMAL_ELEMENT);
778− batch.setInputBuffer(gpu::Stream::POSITION, verticesView);
779− batch.setInputBuffer(gpu::Stream::NORMAL, normalsView);
780−}
781−
782−void GeometryCache::renderSolidCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
783− static gpu::Stream::FormatPointer streamFormat;
784− if (!streamFormat) {
785− streamFormat = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
786− streamFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, CUBE_POSITION_ELEMENT, 0);
787− streamFormat->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, CUBE_NORMAL_ELEMENT);
788− streamFormat->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, CUBE_COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
789− streamFormat->setAttribute(gpu::Stream::INSTANCE_XFM, gpu::Stream::INSTANCE_XFM, INSTANCE_XFM_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
790− }
791− batch.setInputFormat(streamFormat);
792−
793− gpu::BufferView colorView(colorBuffer, CUBE_COLOR_ELEMENT);
794− batch.setInputBuffer(gpu::Stream::COLOR, colorView);
795−
796− gpu::BufferView instanceXfmView(transformBuffer, 0, transformBuffer->getSize(), INSTANCE_XFM_ELEMENT);
797− batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView);
798−
799− gpu::BufferPointer verticesBuffer = getCubeVertices(1.0);
800− setupCubeVertices(batch, verticesBuffer);
801− batch.setIndexBuffer(gpu::UINT8, getSolidCubeIndices(), 0);
802− batch.drawIndexedInstanced(count, gpu::TRIANGLES, CUBE_INDICES);
803−}
804−
805−
806−void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::vec4& color) {
807− Vec2Pair colorKey(glm::vec2(color.x, color.y), glm::vec2(color.z, color.y));
808− if (!_solidCubeColors.contains(colorKey)) {
809− auto colorBuffer = std::make_shared<gpu::Buffer>();
810− _solidCubeColors[colorKey] = colorBuffer;
811−
812− int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
813− ((int(color.y * 255.0f) & 0xFF) << 8) |
814− ((int(color.z * 255.0f) & 0xFF) << 16) |
815− ((int(color.w * 255.0f) & 0xFF) << 24);
816− int colors[CUBE_VERTICES] = {
817− compactColor, compactColor, compactColor, compactColor,
818− compactColor, compactColor, compactColor, compactColor,
819− compactColor, compactColor, compactColor, compactColor,
820− compactColor, compactColor, compactColor, compactColor,
821− compactColor, compactColor, compactColor, compactColor,
822− compactColor, compactColor, compactColor, compactColor
823− };
824− colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
825− }
826− gpu::BufferPointer colorBuffer = _solidCubeColors[colorKey];
827−
828− static gpu::Stream::FormatPointer streamFormat;
829− if (!streamFormat) {
830− streamFormat = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
831− streamFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, CUBE_POSITION_ELEMENT, 0);
832− streamFormat->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, CUBE_NORMAL_ELEMENT);
833− streamFormat->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, CUBE_COLOR_ELEMENT);
834− }
835− batch.setInputFormat(streamFormat);
836−
837− gpu::BufferView colorView(colorBuffer, CUBE_COLOR_ELEMENT);
838− batch.setInputBuffer(gpu::Stream::COLOR, colorView);
839−
840− gpu::BufferPointer verticesBuffer = getCubeVertices(size);
841− setupCubeVertices(batch, verticesBuffer);
842−
843− batch.setIndexBuffer(gpu::UINT8, getSolidCubeIndices(), 0);
844− batch.drawIndexed(gpu::TRIANGLES, CUBE_INDICES);
845−}
846−
847−
848−void GeometryCache::renderWireCube(gpu::Batch& batch, float size, const glm::vec4& color) {
849− Vec2Pair colorKey(glm::vec2(color.x, color.y),glm::vec2(color.z, color.y));
850− static const int WIRE_CUBE_VERTICES_PER_EDGE = 2;
851− static const int WIRE_CUBE_TOP_EDGES = 4;
852− static const int WIRE_CUBE_BOTTOM_EDGES = 4;
853− static const int WIRE_CUBE_SIDE_EDGES = 4;
854− static const int WIRE_CUBE_VERTICES = 8;
855− static const int WIRE_CUBE_INDICES = (WIRE_CUBE_TOP_EDGES + WIRE_CUBE_BOTTOM_EDGES + WIRE_CUBE_SIDE_EDGES) * WIRE_CUBE_VERTICES_PER_EDGE;
856−
857− if (!_cubeVerticies.contains(size)) {
858− auto verticesBuffer = std::make_shared<gpu::Buffer>();
859− _cubeVerticies[size] = verticesBuffer;
860−
861− static const int WIRE_CUBE_VERTEX_POINTS = WIRE_CUBE_VERTICES * FLOATS_PER_VERTEX;
862− GLfloat* vertexData = new GLfloat[WIRE_CUBE_VERTEX_POINTS]; // only vertices, no normals because we're a wire cube
863− GLfloat* vertex = vertexData;
864− float halfSize = size / 2.0f;
865−
866− static GLfloat cannonicalVertices[] =
867− { 1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0, v1, v2, v3 (top)
868− 1,-1, 1, 1,-1,-1, -1,-1,-1, -1,-1, 1 // v4, v5, v6, v7 (bottom)
869− };
870−
871− for (int i = 0; i < WIRE_CUBE_VERTEX_POINTS; i++) {
872− vertex[i] = cannonicalVertices[i] * halfSize;
873− }
874−
875− verticesBuffer->append(sizeof(GLfloat) * WIRE_CUBE_VERTEX_POINTS, (gpu::Byte*) vertexData); // I'm skeptical that this is right
876− }
877−
878− if (!_wireCubeIndexBuffer) {
879− static GLubyte cannonicalIndices[WIRE_CUBE_INDICES] = {
880− 0, 1, 1, 2, 2, 3, 3, 0, // (top)
881− 4, 5, 5, 6, 6, 7, 7, 4, // (bottom)
882− 0, 4, 1, 5, 2, 6, 3, 7, // (side edges)
883− };
884−
885− auto indexBuffer = std::make_shared<gpu::Buffer>();
886− _wireCubeIndexBuffer = indexBuffer;
887−
888− _wireCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Byte*) cannonicalIndices);
889− }
890−
891− if (!_cubeColors.contains(colorKey)) {
892− auto colorBuffer = std::make_shared<gpu::Buffer>();
893− _cubeColors[colorKey] = colorBuffer;
894−
895− const int NUM_COLOR_SCALARS_PER_CUBE = 8;
896− int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
897− ((int(color.y * 255.0f) & 0xFF) << 8) |
898− ((int(color.z * 255.0f) & 0xFF) << 16) |
899− ((int(color.w * 255.0f) & 0xFF) << 24);
900− int colors[NUM_COLOR_SCALARS_PER_CUBE] = { compactColor, compactColor, compactColor, compactColor,
901− compactColor, compactColor, compactColor, compactColor };
902−
903− colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
904− }
905− gpu::BufferPointer verticesBuffer = _cubeVerticies[size];
906− gpu::BufferPointer colorBuffer = _cubeColors[colorKey];
907−
908− const int VERTICES_SLOT = 0;
909− const int COLOR_SLOT = 1;
910− static gpu::Stream::FormatPointer streamFormat;
911− static gpu::Element positionElement, colorElement;
912− if (!streamFormat) {
913− streamFormat = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
914− streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
915− streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
916− positionElement = streamFormat->getAttributes().at(gpu::Stream::POSITION)._element;
917− colorElement = streamFormat->getAttributes().at(gpu::Stream::COLOR)._element;
918− }
919−
920− gpu::BufferView verticesView(verticesBuffer, positionElement);
921− gpu::BufferView colorView(colorBuffer, colorElement);
922−
923− batch.setInputFormat(streamFormat);
924− batch.setInputBuffer(VERTICES_SLOT, verticesView);
925− batch.setInputBuffer(COLOR_SLOT, colorView);
926− batch.setIndexBuffer(gpu::UINT8, _wireCubeIndexBuffer, 0);
927− batch.drawIndexed(gpu::LINES, WIRE_CUBE_INDICES);
928−}
929922
930923 void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id) {
931924 bool registered = (id != UNKNOWN_ID);
@@ -1099,10 +1092,10 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co · 167 unmodified lines
10991092 batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
11001093 }
11011094
1102−void GeometryCache::renderUnitCube(gpu::Batch& batch) {
1103− static const glm::vec4 color(1);
1104− renderSolidCube(batch, 1, color);
1105−}
1095+//void GeometryCache::renderUnitCube(gpu::Batch& batch) {
1096+// static const glm::vec4 color(1);
1097+// renderSolidCube(batch, 1, color);
1098+//}
11061099
11071100 void GeometryCache::renderUnitQuad(gpu::Batch& batch, const glm::vec4& color, int id) {
11081101 static const glm::vec2 topLeft(-1, 1);
@@ -2043,8 +2036,8 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas · 934 unmodified lines
20432036 // need lightmap texcoord UV but doesn't have uv#1 so just reuse the same channel
20442037 networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum - 1, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
20452038 }
2046− if (mesh.clusterIndices.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW));
2047− if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW));
2039+ if (mesh.clusterIndices.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
2040+ if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
20482041 }
20492042 else {
20502043 int colorsOffset = mesh.tangents.size() * sizeof(glm::vec3);
@@ -2076,8 +2069,8 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas · 25 unmodified lines
20762069 if (mesh.tangents.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
20772070 if (mesh.colors.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB));
20782071 if (mesh.texCoords.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
2079− if (mesh.clusterIndices.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW));
2080− if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW));
2072+ if (mesh.clusterIndices.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
2073+ if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
20812074 }
20822075 }
20832076