Overte C++ Documentation
GeometryCache.h
1 //
2 // GeometryCache.h
3 // interface/src/renderer
4 //
5 // Created by Andrzej Kapolka on 6/21/13.
6 // Copyright 2013 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_GeometryCache_h
13 #define hifi_GeometryCache_h
14 
15 #include "model-networking/ModelCache.h"
16 
17 #include <array>
18 
19 #include <QMap>
20 #include <QRunnable>
21 
22 #include <DependencyManager.h>
23 
24 #include <shared/Shapes.h>
25 
26 #include <gpu/Batch.h>
27 #include <gpu/Stream.h>
28 
29 #include <render/ShapePipeline.h>
30 
31 #include <graphics/Material.h>
32 #include <graphics/Asset.h>
33 
34 #include "FadeObjectParams.shared.slh"
35 
36 class SimpleProgramKey;
37 
38 typedef QPair<glm::vec2, float> Vec2FloatPair;
39 typedef QPair<Vec2FloatPair, Vec2FloatPair> Vec2FloatPairPair;
40 typedef QPair<glm::vec2, glm::vec2> Vec2Pair;
41 typedef QPair<Vec2Pair, Vec2Pair> Vec2PairPair;
42 typedef QPair<glm::vec3, glm::vec3> Vec3Pair;
43 typedef QPair<glm::vec4, glm::vec4> Vec4Pair;
44 typedef QPair<Vec3Pair, Vec2Pair> Vec3PairVec2Pair;
45 typedef QPair<Vec3Pair, glm::vec4> Vec3PairVec4;
46 typedef QPair<Vec3Pair, Vec4Pair> Vec3PairVec4Pair;
47 typedef QPair<Vec4Pair, glm::vec4> Vec4PairVec4;
48 typedef QPair<Vec4Pair, Vec4Pair> Vec4PairVec4Pair;
49 
50 inline uint qHash(const Vec2FloatPairPair& v, uint seed) {
51  // multiply by prime numbers greater than the possible size
52  return qHash(v.first.first.x + 5009 * v.first.first.y + 5011 * v.first.second +
53  5021 * v.second.first.x + 5023 * v.second.first.y + 5039 * v.second.second);
54 }
55 
56 inline uint qHash(const Vec2Pair& v, uint seed) {
57  // multiply by prime numbers greater than the possible size
58  return qHash(v.first.x + 5009 * v.first.y + 5011 * v.second.x + 5021 * v.second.y, seed);
59 }
60 
61 inline uint qHash(const glm::vec4& v, uint seed) {
62  // multiply by prime numbers greater than the possible size
63  return qHash(v.x + 5009 * v.y + 5011 * v.z + 5021 * v.w, seed);
64 }
65 
66 inline uint qHash(const Vec2PairPair& v, uint seed) {
67  // multiply by prime numbers greater than the possible size
68  return qHash(v.first.first.x + 5009 * v.first.first.y
69  + 5011 * v.first.second.x + 5021 * v.first.second.y
70  + 5023 * v.second.first.x + 5039 * v.second.first.y
71  + 5051 * v.second.second.x + 5059 * v.second.second.y, seed);
72 }
73 
74 inline uint qHash(const Vec3Pair& v, uint seed) {
75  // multiply by prime numbers greater than the possible size
76  return qHash(v.first.x + 5009 * v.first.y + 5011 * v.first.z
77  + 5021 * v.second.x + 5023 * v.second.y + 5039 * v.second.z, seed);
78 }
79 
80 inline uint qHash(const Vec4Pair& v, uint seed) {
81  // multiply by prime numbers greater than the possible size
82  return qHash(v.first.x + 5009 * v.first.y + 5011 * v.first.z + 5021 * v.first.w
83  + 5023 * v.second.x + 5039 * v.second.y + 5051 * v.second.z + 5059 * v.second.w , seed);
84 }
85 
86 inline uint qHash(const Vec3PairVec2Pair& v, uint seed) {
87  // multiply by prime numbers greater than the possible size
88  return qHash(v.first.first.x + 5009 * v.first.first.y + 5011 * v.first.first.z +
89  5021 * v.first.second.x + 5023 * v.first.second.y + 5039 * v.first.second.z +
90  5051 * v.second.first.x + 5059 * v.second.first.y +
91  5077 * v.second.second.x + 5081 * v.second.second.y, seed);
92 }
93 
94 inline uint qHash(const Vec3PairVec4& v, uint seed) {
95  // multiply by prime numbers greater than the possible size
96  return qHash(v.first.first.x + 5009 * v.first.first.y + 5011 * v.first.first.z +
97  5021 * v.first.second.x + 5023 * v.first.second.y + 5039 * v.first.second.z +
98  5051 * v.second.x + 5059 * v.second.y + 5077 * v.second.z + 5081 * v.second.w, seed);
99 }
100 
101 
102 inline uint qHash(const Vec3PairVec4Pair& v, uint seed) {
103  // multiply by prime numbers greater than the possible size
104  return qHash(v.first.first.x + 5009 * v.first.first.y + 5011 * v.first.first.z
105  + 5023 * v.first.second.x + 5039 * v.first.second.y + 5051 * v.first.second.z
106  + 5077 * v.second.first.x + 5081 * v.second.first.y + 5087 * v.second.first.z + 5099 * v.second.first.w
107  + 5101 * v.second.second.x + 5107 * v.second.second.y + 5113 * v.second.second.z + 5119 * v.second.second.w,
108  seed);
109 }
110 
111 inline uint qHash(const Vec4PairVec4& v, uint seed) {
112  // multiply by prime numbers greater than the possible size
113  return qHash(v.first.first.x + 5009 * v.first.first.y + 5011 * v.first.first.z + 5021 * v.first.first.w
114  + 5023 * v.first.second.x + 5039 * v.first.second.y + 5051 * v.first.second.z + 5059 * v.first.second.w
115  + 5077 * v.second.x + 5081 * v.second.y + 5087 * v.second.z + 5099 * v.second.w,
116  seed);
117 }
118 
119 inline uint qHash(const Vec4PairVec4Pair& v, uint seed) {
120  // multiply by prime numbers greater than the possible size
121  return qHash(v.first.first.x + 5009 * v.first.first.y + 5011 * v.first.first.z + 5021 * v.first.first.w
122  + 5023 * v.first.second.x + 5039 * v.first.second.y + 5051 * v.first.second.z + 5059 * v.first.second.w
123  + 5077 * v.second.first.x + 5081 * v.second.first.y + 5087 * v.second.first.z + 5099 * v.second.first.w
124  + 5101 * v.second.second.x + 5107 * v.second.second.y + 5113 * v.second.second.z + 5119 * v.second.second.w,
125  seed);
126 }
127 
128 struct FadeBuffers {
129  void append(const FadeObjectParams& fadeParams);
130 
131  void clear();
132 
133  void bind(gpu::Batch& batch) const;
134 
135  gpu::BufferPointer _fade1Buffer { std::make_shared<gpu::Buffer>(gpu::Buffer::VertexBuffer) };
136  gpu::BufferPointer _fade2Buffer { std::make_shared<gpu::Buffer>(gpu::Buffer::VertexBuffer) };
137  gpu::BufferPointer _fade3Buffer { std::make_shared<gpu::Buffer>(gpu::Buffer::VertexBuffer) };
138  gpu::BufferPointer _fade4Buffer { std::make_shared<gpu::Buffer>(gpu::Buffer::VertexBuffer) };
139  gpu::BufferPointer _fade5Buffer { std::make_shared<gpu::Buffer>(gpu::Buffer::VertexBuffer) };
140  gpu::BufferPointer _fade6Buffer { std::make_shared<gpu::Buffer>(gpu::Buffer::VertexBuffer) };
141  gpu::BufferPointer _fade7Buffer { std::make_shared<gpu::Buffer>(gpu::Buffer::VertexBuffer) };
142 };
143 
145 class GeometryCache : public Dependency {
146  SINGLETON_DEPENDENCY
147 
148 public:
149  enum Shape {
150  Line,
151  Triangle,
152  Quad,
153  Hexagon,
154  Octagon,
155  Circle,
156  Cube,
157  Sphere,
158  Tetrahedron,
159  Octahedron,
160  Dodecahedron,
161  Icosahedron,
162  Torus,
163  Cone,
164  Cylinder,
165  NUM_SHAPES,
166  };
167 
173  static GeometryCache::Shape getShapeForEntityShape(int entityShapeEnum);
174  static QString stringFromShape(GeometryCache::Shape geoShape);
175 
176  static void computeSimpleHullPointListForShape(int entityShape, const glm::vec3 &entityExtents, QVector<glm::vec3> &outPointList);
177 
178  int allocateID() { return _nextID++; }
179  void releaseID(int id);
180  static const int UNKNOWN_ID;
181 
182  // Bind the pipeline and get the state to render static geometry
183  void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool transparent = false, bool unlit = false, bool depthBias = false,
184  bool isAntiAliased = true, bool forward = false, graphics::MaterialKey::CullFaceMode cullFaceMode = graphics::MaterialKey::CullFaceMode::CULL_BACK);
185  // Get the pipeline to render static geometry
186  static gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool unlit = false, bool depthBias = false,
187  bool fading = false, bool isAntiAliased = true, bool forward = false, graphics::MaterialKey::CullFaceMode cullFaceMode = graphics::MaterialKey::CullFaceMode::CULL_BACK);
188 
189  static void initializeShapePipelines();
190  render::ShapePipelinePointer getShapePipelinePointer(bool transparent, bool unlit, bool forward, bool fading = false,
191  graphics::MaterialKey::CullFaceMode cullFaceMode = graphics::MaterialKey::CULL_BACK) { return _shapePipelines[std::make_tuple(transparent, unlit, forward, fading, cullFaceMode)]; }
192 
193  // Static (instanced) geometry
194  void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
195  void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
196  void renderShapeFadeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer, const FadeBuffers& fadeBuffers);
197  void renderWireShapeFadeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer, const FadeBuffers& fadeBuffers);
198 
199  void renderShapeInstance(RenderArgs* args, gpu::Batch& batch, Shape shape, bool wire, const glm::vec4& color,
200  const render::ShapePipelinePointer& pipeline);
201 
202  void renderSolidSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color,
203  const render::ShapePipelinePointer& pipeline);
204  void renderSolidSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec3& color,
205  const render::ShapePipelinePointer& pipeline) {
206  renderSolidSphereInstance(args, batch, glm::vec4(color, 1.0f), pipeline);
207  }
208 
209  void renderWireCubeInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color,
210  const render::ShapePipelinePointer& pipeline);
211  void renderWireCubeInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec3& color,
212  const render::ShapePipelinePointer& pipeline) {
213  renderWireCubeInstance(args, batch, glm::vec4(color, 1.0f), pipeline);
214  }
215 
216  void renderShapeFadeInstance(RenderArgs* args, gpu::Batch& batch, Shape shape, bool wire, const glm::vec4& color,
217  const FadeObjectParams& fadeParams, const render::ShapePipelinePointer& pipeline);
218 
219  // Dynamic geometry
220  void renderShape(gpu::Batch& batch, Shape shape, gpu::BufferPointer& colorBuffer);
221  void renderWireShape(gpu::Batch& batch, Shape shape, gpu::BufferPointer& colorBuffer);
222  void renderShapeFade(gpu::Batch& batch, Shape shape, gpu::BufferPointer& colorBuffer, const FadeBuffers& fadeBuffers);
223  void renderWireShapeFade(gpu::Batch& batch, Shape shape, gpu::BufferPointer& colorBuffer, const FadeBuffers& fadeBuffers);
224  size_t getShapeTriangleCount(Shape shape);
225 
226  void renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
227  int majorRows, int majorCols, float majorEdge,
228  int minorRows, int minorCols, float minorEdge,
229  const glm::vec4& color, bool forward, int id);
230 
231  void renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id);
232 
233  void renderUnitQuad(gpu::Batch& batch, const glm::vec4& color, int id);
234 
235  void renderQuad(gpu::Batch& batch, int x, int y, int width, int height, const glm::vec4& color, int id)
236  { renderQuad(batch, glm::vec2(x,y), glm::vec2(x + width, y + height), color, id); }
237 
238  void renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, int id);
239  void renderQuadFade(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, const FadeBuffers& fadeBuffers, int id);
240 
241  void renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
242  const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner,
243  const glm::vec4& color, int id);
244  void renderQuadFade(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
245  const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner,
246  const glm::vec4& color, const FadeBuffers& fadeBuffers, int id);
247 
248  void renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id);
249 
250  void renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, const glm::vec3& bottomLeft,
251  const glm::vec3& bottomRight, const glm::vec3& topRight,
252  const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft,
253  const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight,
254  const glm::vec4& color, int id);
255 
256 
257  void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& color, int id)
258  { renderLine(batch, p1, p2, color, color, id); }
259 
260  void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
261  const glm::vec3& color1, const glm::vec3& color2, int id)
262  { renderLine(batch, p1, p2, glm::vec4(color1, 1.0f), glm::vec4(color2, 1.0f), id); }
263 
264  void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
265  const glm::vec4& color, int id)
266  { renderLine(batch, p1, p2, color, color, id); }
267 
268  void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
269  const glm::vec4& color1, const glm::vec4& color2, int id);
270 
271  void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id)
272  { renderDashedLine(batch, start, end, color, 0.05f, 0.025f, id); }
273 
274  void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color,
275  const float dash_length, const float gap_length, int id);
276 
277  void updateVertices(int id, const QVector<glm::vec2>& points, const glm::vec4& color);
278  void updateVertices(int id, const QVector<glm::vec2>& points, const QVector<glm::vec4>& colors);
279  void updateVertices(int id, const QVector<glm::vec3>& points, const glm::vec4& color);
280  void updateVertices(int id, const QVector<glm::vec3>& points, const QVector<glm::vec4>& colors);
281  void updateVertices(int id, const QVector<glm::vec3>& points, const QVector<glm::vec2>& texCoords, const glm::vec4& color);
282  void renderVertices(gpu::Batch& batch, gpu::Primitive primitiveType, int id);
283 
284  void renderTorus(gpu::Batch& batch, float innerRadius, gpu::BufferPointer& colorBuffer, int id);
285  void renderTorusFade(gpu::Batch& batch, float innerRadius, gpu::BufferPointer& colorBuffer, const FadeBuffers& fadeBuffers, int id);
286 
288  void useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend = false);
289 
290  struct ShapeVertex {
291  ShapeVertex(const vec3& pos, const vec3& normal, const vec2& uv, const vec3& tangent) : pos(pos), normal(normal), uv(uv), tangent(tangent) {}
292 
293  vec3 pos;
294  vec3 normal;
295  vec2 uv;
296  vec3 tangent;
297  };
298 
299  struct ShapeData {
300  gpu::BufferView _positionView;
301  gpu::BufferView _normalView;
302  gpu::BufferView _texCoordView;
303  gpu::BufferView _tangentView;
304  gpu::BufferView _indicesView;
305  gpu::BufferView _wireIndicesView;
306 
307  void setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector<ShapeVertex>& vertices);
308  void setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices);
309  void setupBatch(gpu::Batch& batch) const;
310  void draw(gpu::Batch& batch) const;
311  void drawWire(gpu::Batch& batch) const;
312  void drawInstances(gpu::Batch& batch, size_t count) const;
313  void drawWireInstances(gpu::Batch& batch, size_t count) const;
314  };
315 
316  using VShape = std::array<ShapeData, NUM_SHAPES>;
317 
320  const ShapeData * getShapeData(Shape shape) const;
321 
322  graphics::MeshPointer meshFromShape(Shape geometryShape, glm::vec3 color);
323 
324  static uint32_t toCompactColor(const glm::vec4& color);
325 
326 private:
327 
328  GeometryCache();
329  virtual ~GeometryCache();
330  void buildShapes();
331 
332  typedef QPair<int, int> IntPair;
333  typedef QPair<unsigned int, unsigned int> VerticesIndices;
334 
335 
336  VShape _shapes;
337 
338  gpu::PipelinePointer _standardDrawPipeline;
339  gpu::PipelinePointer _standardDrawPipelineNoBlend;
340 
341  gpu::BufferPointer _shapeVertices { std::make_shared<gpu::Buffer>(gpu::Buffer::VertexBuffer) };
342  gpu::BufferPointer _shapeIndices { std::make_shared<gpu::Buffer>(gpu::Buffer::IndexBuffer) };
343 
344  class GridSchema {
345  public:
346  // data is arranged as majorRow, majorCol, minorRow, minorCol
347  glm::vec4 period;
348  glm::vec4 offset;
349  glm::vec4 edge;
350  };
351  using GridBuffer = gpu::BufferView;
352  void useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bool transparent, bool forward);
353  static std::map<std::pair<bool, bool>, gpu::PipelinePointer> _gridPipelines;
354 
355  class BatchItemDetails {
356  public:
357  static int population;
358  gpu::BufferPointer verticesBuffer;
359  gpu::BufferPointer normalBuffer;
360  gpu::BufferPointer colorBuffer;
361  gpu::BufferPointer uniformBuffer;
362  gpu::Stream::FormatPointer streamFormat;
363  gpu::BufferStreamPointer stream;
364 
365  int vertices;
366  int vertexSize;
367  bool isCreated;
368 
369  BatchItemDetails();
370  BatchItemDetails(const GeometryCache::BatchItemDetails& other);
371  ~BatchItemDetails();
372  void clear();
373  };
374 
375  QHash<IntPair, VerticesIndices> _coneVBOs;
376 
377  int _nextID{ 1 };
378 
379  QHash<int, Vec3PairVec4Pair> _lastRegisteredQuad3DTexture;
380  QHash<int, BatchItemDetails> _registeredQuad3DTextures;
381 
382  QHash<int, Vec4PairVec4> _lastRegisteredQuad2DTexture;
383  QHash<int, BatchItemDetails> _registeredQuad2DTextures;
384 
385  QHash<int, Vec4PairVec4> _lastRegisteredQuad2DTextureFade;
386  QHash<int, BatchItemDetails> _registeredQuad2DTexturesFade;
387 
388  QHash<int, Vec3PairVec4> _lastRegisteredQuad3D;
389  QHash<int, BatchItemDetails> _registeredQuad3D;
390 
391  QHash<int, Vec4Pair> _lastRegisteredQuad2D;
392  QHash<int, BatchItemDetails> _registeredQuad2D;
393 
394  QHash<int, Vec4Pair> _lastRegisteredQuad2DFade;
395  QHash<int, BatchItemDetails> _registeredQuad2DFade;
396 
397  QHash<int, Vec3Pair> _lastRegisteredBevelRects;
398  QHash<int, BatchItemDetails> _registeredBevelRects;
399 
400  QHash<int, Vec3Pair> _lastRegisteredLine3D;
401  QHash<int, BatchItemDetails> _registeredLine3DVBOs;
402 
403  QHash<int, Vec2Pair> _lastRegisteredLine2D;
404  QHash<int, BatchItemDetails> _registeredLine2DVBOs;
405 
406  QHash<int, BatchItemDetails> _registeredVertices;
407 
408  QHash<int, Vec3PairVec2Pair> _lastRegisteredDashedLines;
409  QHash<int, BatchItemDetails> _registeredDashedLines;
410 
411  QHash<int, Vec2FloatPairPair> _lastRegisteredGridBuffer;
412  QHash<int, GridBuffer> _registeredGridBuffers;
413 
414  QHash<int, float> _lastRegisteredTorusBuffer;
415  QHash<int, BatchItemDetails> _registeredTorusBuffers;
416 
417  QHash<int, float> _lastRegisteredTorusBufferFade;
418  QHash<int, BatchItemDetails> _registeredTorusBuffersFade;
419 
420  // transparent, unlit, forward, fade
421  static std::map<std::tuple<bool, bool, bool, bool>, gpu::ShaderPointer> _shapeShaders;
422  // transparent, unlit, forward, fade
423  static std::map<std::tuple<bool, bool, bool, bool, graphics::MaterialKey::CullFaceMode>, render::ShapePipelinePointer> _shapePipelines;
424  static QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
425 
426  static render::ShapePipelinePointer getShapePipeline(bool textured = false, bool transparent = false, bool unlit = false,
427  bool depthBias = false, bool forward = false, graphics::MaterialKey::CullFaceMode cullFaceMode = graphics::MaterialKey::CullFaceMode::CULL_BACK);
428  static render::ShapePipelinePointer getFadingShapePipeline(bool textured = false, bool transparent = false, bool unlit = false,
429  bool depthBias = false, bool forward = false, graphics::MaterialKey::CullFaceMode cullFaceMode = graphics::MaterialKey::CullFaceMode::CULL_BACK);
430 };
431 
432 #endif // hifi_GeometryCache_h
Stores cached geometry.
Definition: GeometryCache.h:145
void useSimpleDrawPipeline(gpu::Batch &batch, bool noBlend=false)
Set a batch to the simple pipeline, returning the previous pipeline.
Definition: GeometryCache.cpp:2166
static GeometryCache::Shape getShapeForEntityShape(int entityShapeEnum)
Definition: GeometryCache.cpp:612
const ShapeData * getShapeData(Shape shape) const
Definition: GeometryCache.cpp:601