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
33 33
34const int GeometryCache::UNKNOWN_ID = -1;34const int GeometryCache::UNKNOWN_ID = -1;
35 35
36GeometryCache::GeometryCache() :36static const uint FLOATS_PER_VERTEX = 3;
37 _nextID(0)37static const uint VERTICES_PER_TRIANGLE = 3;
38{38static const uint TRIANGLES_PER_QUAD = 2;
39 const qint64 GEOMETRY_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE;39static const uint CUBE_FACES = 6;
40 setUnusedResourceCacheSize(GEOMETRY_DEFAULT_UNUSED_MAX_SIZE);40static const uint CUBE_VERTICES_PER_FACE = 4;
41static const uint CUBE_VERTICES = CUBE_FACES * CUBE_VERTICES_PER_FACE;
42static const uint CUBE_VERTEX_POINTS = CUBE_VERTICES * FLOATS_PER_VERTEX;
43static const uint CUBE_INDICES = CUBE_FACES * TRIANGLES_PER_QUAD * VERTICES_PER_TRIANGLE;
44static const uint SPHERE_LATITUDES = 24;
45static const uint SPHERE_MERIDIANS = SPHERE_LATITUDES * 2;
46static const uint SPHERE_INDICES = SPHERE_MERIDIANS * (SPHERE_LATITUDES - 1) * TRIANGLES_PER_QUAD * VERTICES_PER_TRIANGLE;
47
48static const gpu::Element POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
49static const gpu::Element NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
50static const gpu::Element COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA };
51static const gpu::Element TRANSFORM_ELEMENT{ gpu::MAT4, gpu::FLOAT, gpu::XYZW };
52
53static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT;
54static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT;
55
56static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals
57static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3);
58
59
60void 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);
41}67}
42 68
43GeometryCache::~GeometryCache() {69void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, const VIndex& indices, const VIndex& wireIndices) {
44 #ifdef WANT_DEBUG70 _indices = indexBuffer;
45 qCDebug(renderutils) << "GeometryCache::~GeometryCache()... ";71 if (!indices.empty()) {
46 qCDebug(renderutils) << " _registeredLine3DVBOs.size():" << _registeredLine3DVBOs.size();72 _indexOffset = indexBuffer->getSize();
47 qCDebug(renderutils) << " _line3DVBOs.size():" << _line3DVBOs.size();73 _indexCount = indices.size();
48 qCDebug(renderutils) << " BatchItemDetails... population:" << GeometryCache::BatchItemDetails::population;74 indexBuffer->append(indices);
49 #endif //def WANT_DEBUG75 }
50}
51 76
52QSharedPointer<Resource> GeometryCache::createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,77 if (!wireIndices.empty()) {
53 bool delayLoad, const void* extra) {78 _wireIndexOffset = indexBuffer->getSize();
54 // NetworkGeometry is no longer a subclass of Resource, but requires this method because, it is pure virtual.79 _wireIndexCount = wireIndices.size();
55 assert(false);80 indexBuffer->append(wireIndices);
56 return QSharedPointer<Resource>();81 }
57}82}
58 83
59const int NUM_VERTICES_PER_TRIANGLE = 3;84void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const {
60const int NUM_TRIANGLES_PER_QUAD = 2;85 batch.setInputBuffer(gpu::Stream::POSITION, _positionView);
61const int NUM_VERTICES_PER_TRIANGULATED_QUAD = NUM_VERTICES_PER_TRIANGLE * NUM_TRIANGLES_PER_QUAD;86 batch.setInputBuffer(gpu::Stream::NORMAL, _normalView);
62const int NUM_COORDS_PER_VERTEX = 3;87}
63 88
64void GeometryCache::renderSphere(gpu::Batch& batch, float radius, int slices, int stacks, const glm::vec4& color, bool solid, int id) {89void GeometryCache::ShapeData::draw(gpu::Batch& batch) const {
65 bool registered = (id != UNKNOWN_ID);90 if (_indexCount) {
91 setupBatch(batch);
92 batch.setIndexBuffer(gpu::UINT16, _indices, _indexOffset);
93 batch.drawIndexed(gpu::TRIANGLES, _indexCount);
94 }
95}
66 96
67 Vec2Pair radiusKey(glm::vec2(radius, slices), glm::vec2(stacks, 0));97void GeometryCache::ShapeData::drawWire(gpu::Batch& batch) const {
68 IntPair slicesStacksKey(slices, stacks);98 if (_wireIndexCount) {
69 Vec3Pair colorKey(glm::vec3(color.x, color.y, slices), glm::vec3(color.z, color.w, stacks));99 setupBatch(batch);
100 batch.setIndexBuffer(gpu::UINT16, _indices, _wireIndexOffset);
101 batch.drawIndexed(gpu::LINES, _wireIndexCount);
102 }
103}
70 104
71 int vertices = slices * (stacks - 1) + 2; 105void GeometryCache::ShapeData::drawInstances(gpu::Batch& batch, size_t count) const {
72 int indices = slices * (stacks - 1) * NUM_VERTICES_PER_TRIANGULATED_QUAD;106 if (_indexCount) {
107 setupBatch(batch);
108 batch.setIndexBuffer(gpu::UINT16, _indices, _indexOffset);
109 batch.drawIndexedInstanced(count, gpu::TRIANGLES, _indexCount);
110 }
111}
73 112
74 if ((registered && (!_registeredSphereVertices.contains(id) || _lastRegisteredSphereVertices[id] != radiusKey))113void GeometryCache::ShapeData::drawWireInstances(gpu::Batch& batch, size_t count) const {
75 || (!registered && !_sphereVertices.contains(radiusKey))) {114 if (_wireIndexCount) {
115 setupBatch(batch);
116 batch.setIndexBuffer(gpu::UINT16, _indices, _wireIndexOffset);
117 batch.drawIndexedInstanced(count, gpu::LINES, _wireIndexCount);
118 }
119}
76 120
77 if (registered && _registeredSphereVertices.contains(id)) {121const VVertex& icosahedronVertices() {
78 _registeredSphereVertices[id].reset();122 static const float phi = (1.0 + sqrt(5.0)) / 2.0;
79 #ifdef WANT_DEBUG123 static const float a = 0.5;
80 qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED VERTICES BUFFER";124 static const float b = 1.0 / (2.0 * phi);
81 #endif125
82 }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}
83 150
84 auto verticesBuffer = std::make_shared<gpu::Buffer>();151const VVertex& tetrahedronVertices() {
85 if (registered) {152 static const float a = 1.0f / sqrt(2.0f);
86 _registeredSphereVertices[id] = verticesBuffer;153 static const auto A = vec3(0, 1, a);
87 _lastRegisteredSphereVertices[id] = radiusKey;154 static const auto B = vec3(0, -1, a);
88 } else {155 static const auto C = vec3(1, 0, -a);
89 _sphereVertices[radiusKey] = verticesBuffer;156 static const auto D = vec3(-1, 0, -a);
90 }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}
91 165
92 GLfloat* vertexData = new GLfloat[vertices * NUM_COORDS_PER_VERTEX];166VVertex tesselate(const VVertex& startingTriangles, int count) {
93 GLfloat* vertex = vertexData;167 VVertex triangles = startingTriangles;
168 if (0 != (triangles.size() % 3)) {
169 throw std::runtime_error("Bad number of vertices for tesselation");
170 }
94 171
95 // south pole172 for (size_t i = 0; i < triangles.size(); ++i) {
96 *(vertex++) = 0.0f;173 triangles[i] = glm::normalize(triangles[i]);
97 *(vertex++) = 0.0f;174 }
98 *(vertex++) = -1.0f * radius;
99 175
100 //add stacks vertices climbing up Y axis176 VVertex newTriangles;
101 for (int i = 1; i < stacks; i++) {177 while (count) {
102 float phi = PI * (float)i / (float)(stacks) - PI_OVER_TWO;178 newTriangles.clear();
103 float z = sinf(phi) * radius;179 newTriangles.reserve(triangles.size() * 4);
104 float stackRadius = cosf(phi) * radius;180 for (size_t i = 0; i < triangles.size(); i += 3) {
105 181 const vec3& a = triangles[i];
106 for (int j = 0; j < slices; j++) {182 const vec3& b = triangles[i + 1];
107 float theta = TWO_PI * (float)j / (float)slices;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}
108 209
109 *(vertex++) = sinf(theta) * stackRadius;210// FIXME solids need per-face vertices, but smooth shaded
110 *(vertex++) = cosf(theta) * stackRadius;211// components do not. Find a way to support using draw elements
111 *(vertex++) = z;212// or draw arrays as appropriate
213// Maybe special case cone and cylinder since they combine flat
214// and smooth shading
215void 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;
112 }288 }
113 }289 }
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 }
114 303
115 // north pole304 VIndex wireIndices{
116 *(vertex++) = 0.0f;305 0, 1, 1, 2, 2, 3, 3, 0, // front
117 *(vertex++) = 0.0f;306 20, 21, 21, 22, 22, 23, 23, 20, // back
118 *(vertex++) = 1.0f * radius;307 0, 23, 1, 22, 2, 21, 3, 20 // sides
119 308 };
120 verticesBuffer->append(sizeof(GLfloat) * vertices * NUM_COORDS_PER_VERTEX, (gpu::Byte*) vertexData);309 for (int i = 0; i < wireIndices.size(); ++i) {
121 delete[] vertexData;310 indices[i] += startingIndex;
122 311 }
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;
128 312
129 qCDebug(renderutils) << " _sphereVertices.size():" << _sphereVertices.size();313 shapeData.setupIndices(_shapeIndices, indices, wireIndices);
130 #endif
131 }314 }
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))) {
140 315
141 if (registered && _registeredSphereIndices.contains(id)) {316 // Tetrahedron
142 _registeredSphereIndices[id].reset();317 startingIndex = _shapeVertices->getSize() / SHAPE_VERTEX_STRIDE;
143 #ifdef WANT_DEBUG318 {
144 qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED INDICES BUFFER";319 ShapeData& shapeData = _shapes[Tetrahedron];
145 #endif320 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 }
146 }337 }
338 shapeData.setupVertices(_shapeVertices, vertices);
147 339
148 auto indicesBuffer = std::make_shared<gpu::Buffer>();340 VIndex indices;
149 if (registered) {341 for (size_t i = 0; i < vertexCount; i += 3) {
150 _registeredSphereIndices[id] = indicesBuffer;342 for (size_t j = 0; j < 3; ++j) {
151 _lastRegisteredSphereIndices[id] = slicesStacksKey;343 indices.push_back(i + j + startingIndex);
152 } else {344 }
153 _sphereIndices[slicesStacksKey] = indicesBuffer;
154 }345 }
155 346
156 GLushort* indexData = new GLushort[indices];347 VIndex wireIndices{
157 GLushort* index = indexData;348 0, 1, 1, 2, 2, 0,
158 349 0, 3, 1, 3, 2, 3,
159 int indexCount = 0;350 };
160 351
161 // South cap352 for (int i = 0; i < wireIndices.size(); ++i) {
162 GLushort bottom = 0;353 wireIndices[i] += startingIndex;
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;
170 }354 }
171 355
172 // (stacks - 2) ribbons356 shapeData.setupIndices(_shapeIndices, indices, wireIndices);
173 for (int i = 0; i < stacks - 2; i++) {357 }
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;
190 358
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 }
191 }376 }
192 }377 }
193 378
194 // north cap379 shapeData.setupVertices(_shapeVertices, vertices);
195 bottom = (stacks - 2) * slices + 1;380 // FIXME don't use solid indices for wire drawing.
196 top = bottom + slices;381 shapeData.setupIndices(_shapeIndices, indices, indices);
197 for (int i = 0; i < slices; i++) { 382 }
198 *(index++) = bottom + (i + 1) % slices;
199 *(index++) = bottom + i;
200 *(index++) = top;
201
202 indexCount += 3;
203 383
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 }
204 }406 }
205 indicesBuffer->append(sizeof(GLushort) * indices, (gpu::Byte*) indexData);407
206 delete[] indexData;408 shapeData.setupVertices(_shapeVertices, vertices);
207 409 // FIXME don't use solid indices for wire drawing.
208 #ifdef WANT_DEBUG410 shapeData.setupIndices(_shapeIndices, indices, indices);
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
217 }411 }
218 #ifdef WANT_DEBUG412
219 else if (registered) {413 //Triangle,
220 qCDebug(renderutils) << "renderSphere()... REUSING PREVIOUSLY REGISTERED INDICES BUFFER";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);
221 }434 }
222 #endif435}
223 436
224 if ((registered && (!_registeredSphereColors.contains(id) || _lastRegisteredSphereColors[id] != colorKey)) 437gpu::Stream::FormatPointer& getSolidStreamFormat() {
225 || (!registered && !_sphereColors.contains(colorKey))) {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}
226 445
227 if (registered && _registeredSphereColors.contains(id)) {446gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() {
228 _registeredSphereColors[id].reset();447 if (!INSTANCED_SOLID_STREAM_FORMAT) {
229 #ifdef WANT_DEBUG448 INSTANCED_SOLID_STREAM_FORMAT = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
230 qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED COLORS BUFFER";449 INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT);
231 #endif450 INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT);
232 }451 INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
233 452 INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::INSTANCE_XFM, gpu::Stream::INSTANCE_XFM, TRANSFORM_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
234 auto colorBuffer = std::make_shared<gpu::Buffer>();453 }
235 if (registered) {454 return INSTANCED_SOLID_STREAM_FORMAT;
236 _registeredSphereColors[id] = colorBuffer;455}
237 _lastRegisteredSphereColors[id] = colorKey;
238 } else {
239 _sphereColors[colorKey] = colorBuffer;
240 }
241 456
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);
246 457
247 int* colorData = new int[vertices];458GeometryCache::GeometryCache() {
248 int* colorDataAt = colorData;459 const qint64 GEOMETRY_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE;
460 setUnusedResourceCacheSize(GEOMETRY_DEFAULT_UNUSED_MAX_SIZE);
461 buildShapes();
462}
249 463
250 for(int v = 0; v < vertices; v++) {464GeometryCache::~GeometryCache() {
251 *(colorDataAt++) = compactColor;465 #ifdef WANT_DEBUG
252 }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}
253 472
254 colorBuffer->append(sizeof(int) * vertices, (gpu::Byte*) colorData);473QSharedPointer<Resource> GeometryCache::createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
255 delete[] colorData;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}
256 479
257 #ifdef WANT_DEBUG480void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
258 qCDebug(renderutils) << "GeometryCache::renderSphere()... --- CREATING COLORS BUFFER";481 gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
259 qCDebug(renderutils) << " vertices:" << vertices;482 batch.setInputBuffer(gpu::Stream::COLOR, colorView);
260 qCDebug(renderutils) << " color:" << color;483 gpu::BufferView instanceXfmView(transformBuffer, 0, transformBuffer->getSize(), TRANSFORM_ELEMENT);
261 qCDebug(renderutils) << " slices:" << slices;484 batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView);
262 qCDebug(renderutils) << " stacks:" << stacks;485}
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
271 486
272 gpu::BufferPointer verticesBuffer = registered ? _registeredSphereVertices[id] : _sphereVertices[radiusKey];487void GeometryCache::renderShape(gpu::Batch& batch, Shape shape) {
273 gpu::BufferPointer indicesBuffer = registered ? _registeredSphereIndices[id] : _sphereIndices[slicesStacksKey];488 batch.setInputFormat(getSolidStreamFormat());
274 gpu::BufferPointer colorBuffer = registered ? _registeredSphereColors[id] : _sphereColors[colorKey];489 _shapes[shape].draw(batch);
275 490}
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 }
290 491
291 gpu::BufferView verticesView(verticesBuffer, positionElement);492void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape) {
292 gpu::BufferView normalsView(verticesBuffer, normalElement);493 batch.setInputFormat(getSolidStreamFormat());
293 gpu::BufferView colorView(colorBuffer, colorElement);494 _shapes[shape].drawWire(batch);
294 495}
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);
300 496
301 if (solid) {497void GeometryCache::renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) {
302 batch.drawIndexed(gpu::TRIANGLES, indices);498 batch.setInputFormat(getInstancedSolidStreamFormat());
303 } else {499 setupBatchInstance(batch, transformBuffer, colorBuffer);
304 batch.drawIndexed(gpu::LINES, indices);500 _shapes[shape].drawInstances(batch, count);
305 }501}
502
503void 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
509void GeometryCache::renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
510 renderShapeInstances(batch, Cube, count, transformBuffer, colorBuffer);
306}511}
307 512
513void GeometryCache::renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
514 renderWireShapeInstances(batch, Cube, count, transformBuffer, colorBuffer);
515}
516
517void GeometryCache::renderCube(gpu::Batch& batch) {
518 renderShape(batch, Cube);
519}
520
521void GeometryCache::renderWireCube(gpu::Batch& batch) {
522 renderWireShape(batch, Cube);
523}
524
525void GeometryCache::renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
526 renderShapeInstances(batch, Sphere, count, transformBuffer, colorBuffer);
527}
528
529void GeometryCache::renderSphere(gpu::Batch& batch) {
530 renderShape(batch, Sphere);
531}
532
533void GeometryCache::renderWireSphere(gpu::Batch& batch) {
534 renderWireShape(batch, Sphere);
535}
536
537
308void GeometryCache::renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions, const glm::vec4& color) {538void GeometryCache::renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions, const glm::vec4& color) {
309 IntPair key(xDivisions, yDivisions);539 IntPair key(xDivisions, yDivisions);
310 Vec3Pair colorKey(glm::vec3(color.x, color.y, yDivisions), glm::vec3(color.z, color.y, xDivisions));540 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
689 }919 }
690}920}
691 921
692static const int FLOATS_PER_VERTEX = 3;
693static const int VERTICES_PER_TRIANGLE = 3;
694
695static const int CUBE_NUMBER_OF_FACES = 6;
696static const int CUBE_VERTICES_PER_FACE = 4;
697static const int CUBE_TRIANGLES_PER_FACE = 2;
698static const int CUBE_VERTICES = CUBE_NUMBER_OF_FACES * CUBE_VERTICES_PER_FACE;
699static const int CUBE_VERTEX_POINTS = CUBE_VERTICES * FLOATS_PER_VERTEX;
700static const int CUBE_INDICES = CUBE_NUMBER_OF_FACES * CUBE_TRIANGLES_PER_FACE * VERTICES_PER_TRIANGLE;
701
702static const gpu::Element CUBE_POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
703static const gpu::Element CUBE_NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
704static const gpu::Element CUBE_COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA };
705static const gpu::Element INSTANCE_XFM_ELEMENT{ gpu::MAT4, gpu::FLOAT, gpu::XYZW };
706
707gpu::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
754gpu::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
772void 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
782void 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
806void 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
848void 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}
929 922
930void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id) {923void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id) {
931 bool registered = (id != UNKNOWN_ID);924 bool registered = (id != UNKNOWN_ID);
@@ -1099,10 +1092,10 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co · 167 unmodified lines
1099 batch.draw(gpu::TRIANGLE_STRIP, 4, 0);1092 batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
1100}1093}
1101 1094
1102void GeometryCache::renderUnitCube(gpu::Batch& batch) {1095//void GeometryCache::renderUnitCube(gpu::Batch& batch) {
1103 static const glm::vec4 color(1);1096// static const glm::vec4 color(1);
1104 renderSolidCube(batch, 1, color);1097// renderSolidCube(batch, 1, color);
1105}1098//}
1106 1099
1107void GeometryCache::renderUnitQuad(gpu::Batch& batch, const glm::vec4& color, int id) {1100void GeometryCache::renderUnitQuad(gpu::Batch& batch, const glm::vec4& color, int id) {
1108 static const glm::vec2 topLeft(-1, 1);1101 static const glm::vec2 topLeft(-1, 1);
@@ -2043,8 +2036,8 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas · 934 unmodified lines
2043 // need lightmap texcoord UV but doesn't have uv#1 so just reuse the same channel2036 // need lightmap texcoord UV but doesn't have uv#1 so just reuse the same channel
2044 networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum - 1, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));2037 networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum - 1, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
2045 }2038 }
2046 if (mesh.clusterIndices.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 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));
2047 if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW));2040 if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
2048 }2041 }
2049 else {2042 else {
2050 int colorsOffset = mesh.tangents.size() * sizeof(glm::vec3);2043 int colorsOffset = mesh.tangents.size() * sizeof(glm::vec3);
@@ -2076,8 +2069,8 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas · 25 unmodified lines
2076 if (mesh.tangents.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));2069 if (mesh.tangents.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
2077 if (mesh.colors.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB));2070 if (mesh.colors.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB));
2078 if (mesh.texCoords.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));2071 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));2072 if (mesh.clusterIndices.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
2080 if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW));2073 if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
2081 }2074 }
2082 }2075 }
2083 2076