HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RE_ElementArray.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: RE_ElementArray.h ( RE Library, C++)
7  *
8  * COMMENTS:
9  * Abstracts a vertex element array, which is used for indexing which
10  * points make up a primitive. This class provides several important
11  * abstractions:
12  *
13  * - allows primitives to be specified one at a time or in batches
14  * - dices up long element arrays into sizes the HW can support
15  * - uses a primitive restart index automatically for variable-sized prims
16  * - builds an edge array so that geometry shaders can determine false
17  * edges (the array is a 2-comp array of {index,maxindex}).
18  */
19 #ifndef RE_ElementArray_h
20 #define RE_ElementArray_h
21 
22 #include "RE_API.h"
23 #include "RE_Render.h"
24 #include "RE_VertexArray.h"
25 
26 #include <UT/UT_NonCopyable.h>
27 #include <UT/UT_ValArray.h>
28 
29 #include <iosfwd>
30 
31 class re_ElementChunk;
32 
34 {
35 public:
36  explicit RE_ElementArray(bool use_buffers = true);
37  ~RE_ElementArray();
38 
40 
41  /// Returns the amount of main memory (NOT graphics memory!)
42  /// owned by this RE_ElementArray.
43  int64 getMemoryUsage(bool inclusive) const;
44 
45  // Establish the base cache name for the element arrays created.
46  void setCacheName(const char *cachename);
47 
48  // Sets the version of this particular element array.
49  void setCacheVersion(RE_CacheVersion version);
50  RE_CacheVersion getCacheVersion() const;
51 
52  // Returns true if all element buffers were found in the cache, with
53  // the appropriate version.
54  bool findCachedVersion(RE_CacheVersion version);
55 
56  // Set up the element buffer type. These cannot be called while within a
57  // begin/endPrims(), however you can switch types and start a new
58  // begin/endPrims pair (don't do this often, however, as the buffers will
59  // be very small chunks and the #draw calls will increase substantially)
60  void setElementType(RE_GPUType type);
61 
62  // Set the primitive type that the element array represents. This cannot
63  // be changed between begin/endPrims().
64  void setPrimitiveType(RE_PrimType type, int vertices_per_patch = 0);
65 
66  // Alternate way to set the type, by the length of the vertex array being
67  // indexed.
68  void setNumPoints(int points);
69 
70  // If true, quads and polygons are tessellated to triangles. If primitive
71  // restart is not supported, polygons are always tessellated to triangles,
72  // otherwise triangle tessellation is disabled by default.
73  void tessellateToTriangles(bool enable);
74 
75  // enables or disables the generation of a primitive info buffer. It is
76  // disabled by default. This also enables triangle tessellation.
77  void requirePrimInfo(bool enable);
78 
79  // enables or disables the generation of a vertex info buffer. It is
80  // disabled by default. This also enables triangle tessellation.
81  void requireVertexInfo(bool enable);
82 
83  // Adds primitive connectivity information to the arrays. beginPrims()
84  // must be called before any addPrim() calls are done, and endPrims()
85  // before a draw() is issued.
86 
87  // beginPrims() may fail if a unbounded primitive is used without the
88  // RE_EXT_PRIMITIVE_RESTART extension. 'num_vertex_hint' gives the element
89  // array an initial hint as to how many vertices will be in the array.
90  bool beginPrims(RE_Render *r,
91  bool clear_old = false,
92  int num_vertex_hint = 0);
93 
94  // Adds a single primitive. May fail if npts doesn't fit the current
95  // primitive (4, TRIANGLES). 'real_npnts' is used if mixed size polygons
96  // up to 'npnts' is size are being output through a fixed GL size type.
97  bool addPrim(RE_Render *r, int npnts, int *pnt_indices,
98  int *prim_info = nullptr,
99  uint8 *vert_info = nullptr,
100  int base_prim = -1,
101  int base_vert = -1);
102 
103  // Specifies indicies for multiple primitives.
104  bool addPrims(RE_Render *r, int npnts, int *prim_indices,
105  int *prim_info = nullptr,
106  uint8 *vert_info = nullptr,
107  bool simple_pindex = false,
108  int pindex_start = 0);
109 
110  // Special case for pre-convexed models.
111  bool addTriangle(RE_Render *r, int *pnt_indices, int *prim_info,
112  uint8 *vert_info );
113 
114  // Must be called after a beginPrims() and before a draw().
115  bool endPrims(RE_Render *r);
116 
117  // Upload all information at once without doing begin/end.
118  bool addTriangleChunk(RE_Render *r, int num_triangles,
119  const int *pnt_indices, // num*3
120  const int *prim_info = nullptr, // num*4
121  const uint8 *vert_info = nullptr); // num*4
122 
123  // Draws the primitives using the element arrays. Other vertex arrays must
124  // already be enabled. Instanced drawing is only supported if
125  // RE_EXT_DRAW_INSTANCED is supported.
126  // if 'prim' is not RE_PRIM_AS_IS, it will override the primitive type
127  // specified by setPrimitiveType.
128  void draw(RE_Render *r,
129  RE_Geometry *geo = nullptr,
130  RE_PrimType prim = RE_PRIM_AS_IS);
131  void drawInstanced(RE_Render *r, int num_instances,
132  RE_Geometry *geo = nullptr,
133  RE_PrimType prim = RE_PRIM_AS_IS);
134 
135  // Returns the minimum and maximum number edges in the primitives added.
136  // These are not defined for element arrays fetched from the cache, only
137  // newly created ones.
138  int getMinEdges() const;
139  int getMaxEdges() const;
140 
141  // Number of arrays created, equal to the number of GL draw calls draw()
142  // performs. This is not defined for element arrays fetched from the
143  // cache, only newly created ones.
144  int getNumArrays() const;
145 
146  int getNumVertices() const;
147  int getNumOrigVertices() const;
148  int getNumPrimitives() const { return myNumPrims; }
149  RE_PrimType getPrimitiveType() const { return myPrimType; }
150  int getVerticesPerPatch() const { return myVerticesPerPatch; }
151 
152  /// Return the size of all underlying arrays
153  int64 getSizeBytes() const;
154 
155  // Only used by RE_Geometry.
156  void clearCachedData() { myHasGeoPrimInfo = -1; }
157 
158  // debug print method
159  void print(std::ostream &os);
160 
161 private:
162  void completeElementBuffer(RE_Render *r);
163  RE_VertexArray *completePrimInfoBuffer(RE_Render *r, const char *cachename);
164  RE_VertexArray *completeVertInfoBuffer(RE_Render *r, const char *cachename);
165  void drawPrivate(RE_Render *r, int num_instances,
166  RE_Geometry *geo, RE_PrimType prim);
167 
168  void bumpBufferSizes(int nprims);
169 
170  RE_GPUType myElementType;
171  RE_PrimType myPrimType;
172  UT_String myCacheName;
173  RE_CacheVersion myCacheVersion;
174  bool myUseBaseVertex;
175  bool myAddingPrims;
176  bool myUsePrimRestart;
177  bool myLineSegmentMode;
178  bool myFilledMode;
179  bool myRequirePrimInfo;
180  bool myRequireVertInfo;
181  bool myTessellateToTriangles;
182 
183  // Global
184  int myMinPrimEdges;
185  int myMaxPrimEdges;
186  int myNumPrims;
187  int myNumOrigVertices;
188  int myPrimIndex;
189  int myVerticesPerPatch;
190 
191  // Per chunk
192  int myChunkMinEdges;
193  int myChunkMaxEdges;
194  int myChunkNumPrims;
195  int myChunkMinIndex;
196  int myChunkMaxIndex;
197 
198  // Current element chunk
199  int myElementSize;
200  int myElementIndex;
201  int *myElementBuffer;
202 
203  int myHasGeoPrimInfo;
204  int myPrimInfoSize;
205  int myPrimInfoIndex;
206  int *myPrimInfoBuffer;
207 
208  int myHasGeoVertInfo;
209  int myVertInfoSize;
210  int myVertInfoIndex;
211  uint32 *myVertInfoBuffer;
212 
213  // Previously processed chunks
215 
216  // cached data for drawing
217  void *myLastShader;
218  int myLastShaderSerial;
219  int myLastShaderPrimInfoIndex;
220  int myLastShaderVertInfoIndex;
221 };
222 
223 // Inlines
224 inline int
226 {
227  return myMinPrimEdges;
228 }
229 
230 inline int
232 {
233  return myMaxPrimEdges;
234 }
235 
236 inline int
238 {
239  return myChunks.entries();
240 }
241 
242 inline void
244 {
245  drawPrivate(r, 0, geo, prim);
246 }
247 
248 inline void
250  RE_Geometry *geo,
251  RE_PrimType prim)
252 {
253  UT_ASSERT(num_instances>0);
256  drawPrivate(r, num_instances, geo, prim);
257 }
258 
259 #endif
int getMinEdges() const
GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glad.h:2676
#define RE_API
Definition: RE_API.h:10
A collection of vertex arrays defining a geometry object. This class acts as a wrapper around multipl...
Definition: RE_Geometry.h:52
int getVerticesPerPatch() const
RE_PrimType getPrimitiveType() const
unsigned char uint8
Definition: SYS_Types.h:36
RE_GPUType
Definition: RE_Types.h:52
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
int getMaxEdges() const
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
long long int64
Definition: SYS_Types.h:116
void draw(RE_Render *r, RE_Geometry *geo=nullptr, RE_PrimType prim=RE_PRIM_AS_IS)
bool hasGLExtension(RE_Extension e) const
GT_API const UT_StringHolder version
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:655
int getNumArrays() const
int getNumPrimitives() const
unsigned int uint32
Definition: SYS_Types.h:40
Simple class for a mutli-integer cache tag.
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
void drawInstanced(RE_Render *r, int num_instances, RE_Geometry *geo=nullptr, RE_PrimType prim=RE_PRIM_AS_IS)
GLboolean r
Definition: glcorearb.h:1222
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2903
RE_PrimType
Definition: RE_Types.h:199