Cogs.Core
RenderList.h
1#pragma once
2
3#include "Resources/MaterialInstance.h"
4
5#include "IRenderer.h"
6#include "RenderMesh.h"
7#include "RenderStates.h"
8#include "RenderResource.h"
9#include "../Components/Core/RenderComponent.h"
10
11#include "Foundation/Geometry/BoundingBox.hpp"
12
13namespace Cogs::Core
14{
15 struct RenderTaskContext;
16 struct EffectBinding;
17
18 enum struct RenderItemFlags : uint16_t
19 {
20 None = 0,
21 Custom = 1 << 0,
22 CastShadows = 1 << 1,
23 CalculateDepth = 1 << 2,
24 Sprite = 1 << 3,
25 AlwaysOnTop = 1 << 4,
26 Clockwise = 1 << 5,
27 Transparent = 1 << 6,
28 Backdrop = 1 << 7,
29 CustomBucket = 1 << 8,
30 CustomBounds = 1 << 9,
31 Custom2 = 1 << 10,
32 DisableCulling = 1 << 11,
33 Instanced = 1 << 12,
34 ObjectBufferSlot = 1 << 13,
35 ObjectArrayBufferSlot = 1 << 14
36 };
37 ENABLE_ENUM_FLAGS(RenderItemFlags);
38
39 enum struct StateChangeFlags : uint16_t {
40 ChangeNone = 0,
41 ChangeTransform = 1 << 0,
42 ChangeMesh = 1 << 1,
43 ChangeMaterialInstance = 1 << 2,
44 ChangeMaterialVariant = 1 << 3,
45 ChangeRasterizerState = 1 << 4,
46 ChangeBlendState = 1 << 5,
47 ChangeDepthStencilState = 1 << 6,
48 ChangeLayer = 1 << 7,
49 ChangeViewport = 1 << 8,
50 ChangeViewportData = 1 << 9,
51 ChangeAll = 0xFFFF
52 };
53 ENABLE_ENUM_FLAGS(StateChangeFlags);
54
55 enum struct BucketType
56 {
57 Backdrop = 0,
59 Solid,
61 Transparent,
62 Annotation,
63 Overlay,
64 Custom,
65 Count
66 };
67
68 enum class BucketMask
69 {
70 BackDrop = 1 << size_t(BucketType::Backdrop),
71 Transparent = 1 << size_t(BucketType::Transparent),
72 Solid = (1 << size_t(BucketType::SolidOrderedBack)) | (1 << size_t(BucketType::Solid)) | (1 << size_t(BucketType::SolidOrderedFront)),
73 Opaque = Solid,
74 Annotation = 1 << size_t(BucketType::Annotation),
75 Overlay = 1 << size_t(BucketType::Overlay),
76 Custom = 1 << size_t(BucketType::Custom),
77 All = ~0,
78 None = 0,
79 };
80 ENABLE_ENUM_FLAGS(BucketMask);
81
82 inline bool hasBucket(BucketMask bucketMask, BucketType bucket)
83 {
84 return (size_t(bucketMask) & (size_t(1) << size_t(bucket))) != 0;
85 }
86
88 {
89 typedef void CustomCallback(RenderTaskContext*, DrawContext*, const RenderItem*);
90 typedef void CustomCallback2(RenderTaskContext*, DrawContext*, struct RenderListTask* task, const RenderItem*);
91
92
93 bool isCustom() const { return (flags & (RenderItemFlags::Custom | RenderItemFlags::Custom2)) != 0; }
94 bool isCustom1() const { return (flags & RenderItemFlags::Custom) != 0; }
95 bool isCustom2() const { return (flags & RenderItemFlags::Custom2) != 0; }
96 bool isSprite() const { return (flags & RenderItemFlags::Sprite) != 0; }
97 bool isClockwise() const { return (flags & RenderItemFlags::Clockwise) != 0; }
98 bool isTransparent() const { return (flags & RenderItemFlags::Transparent) != 0; }
99 bool isCustomBucket() const { return (flags & RenderItemFlags::CustomBucket) != 0; }
100 bool isBackdrop() const { return (flags & RenderItemFlags::Backdrop) != 0; }
101 bool needsDepthCalculation() const { return (flags & RenderItemFlags::CalculateDepth) != 0; }
102 bool hasBoundingBox() const { return (flags & RenderItemFlags::CustomBounds) != 0; }
103 bool isCulled() const { return !hasBoundingBox() && !isCustom(); }
104 bool isInstanced() const { return (flags & RenderItemFlags::Instanced) != 0; }
105 bool hasObjectBufferSlot() const { return (flags & RenderItemFlags::ObjectBufferSlot) != 0; }
106 bool hasObjectArrayBufferSlot() const { return (flags & RenderItemFlags::ObjectArrayBufferSlot) != 0; }
107
108 void setBounds(const Geometry::BoundingBox* bounds)
109 {
110 boundingBox = bounds;
111 flags |= RenderItemFlags::CustomBounds;
112 }
113
114 template<typename T>
115 void setCallbackData(T* t) const { callbackData = t; }
116
117 template<typename T>
118 void setCallbackData2(T* t) const { callbackData2 = t; }
119
120 template<typename T>
121 T* getCallbackData() const { return static_cast<T*>(callbackData); }
122
123 template<typename T>
124 T* getCallbackData2() const { return static_cast<T*>(callbackData2); }
125
126
127
128 const struct RenderMaterialInstance * renderMaterialInstance = nullptr;
129 const MaterialInstance * materialInstance = nullptr;
130
131 const struct CameraData * viewportData = nullptr;
132 const struct PoseData * poseData = nullptr;
133 union
134 {
135 uint32_t cullingIndex;
136 const Geometry::BoundingBox* boundingBox = nullptr;
137 };
138
139 union
140 {
142 struct
143 {
144 const glm::mat4* worldMatrix;
145
146 const RenderMesh* meshData;
147 uint32_t startIndex;
148 uint32_t numIndexes;
149
150 const RenderMesh* instanceData;
151 uint32_t startInstance;
152 uint32_t numInstances;
153
154 Cogs::PrimitiveType primitiveType;
155 };
156
158 struct
159 {
160 const MeshStreamsLayout* streamsLayout;
161 union
162 {
163 CustomCallback* callback;
164 CustomCallback2* callback2;
165 };
166 mutable void* callbackData;
167 mutable void* callbackData2;
168 };
169 };
170
172 RenderLayers layer = RenderLayers::None;
173 float depth = 0.f;
174 int32_t drawOrder = 0;
175 union {
176 uint32_t objectId = 0;
179 };
180 RenderItemFlags flags = RenderItemFlags::None;
181 StateChangeFlags stateChanges = StateChangeFlags::ChangeAll;
182
183 // Pipeline state
184 //
185 // Note: These will all be merged into one state handle moving to PSO in future
186 // graphics APIs.
187 uint16_t blendState = 0;
188 uint16_t depthState = 0;
189 uint16_t rasterizerState = 0;
190 uint8_t clipShapeIx = 0;
191
192 size_t hash(size_t hashValue = Cogs::hash()) const {
193 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(renderMaterialInstance), hashValue);
194 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(materialInstance), hashValue);
195 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(viewportData), hashValue);
196 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(poseData), hashValue);
197
198 if (hasBoundingBox()) {
199 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(boundingBox), hashValue);
200 }
201 else {
202 hashValue = Cogs::hash(cullingIndex, hashValue);
203 }
204
205 if (isCustom()) {
206 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(worldMatrix), hashValue);
207 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(meshData), hashValue);
208 hashValue = Cogs::hash(startIndex, hashValue);
209 hashValue = Cogs::hash(numIndexes, hashValue);
210 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(instanceData), hashValue);
211 hashValue = Cogs::hash(startInstance, hashValue);
212 hashValue = Cogs::hash(numInstances, hashValue);
213 hashValue = Cogs::hash(primitiveType, hashValue);
214 }
215 else {
216 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(streamsLayout), hashValue);
217 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(callback), hashValue);
218 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(callbackData), hashValue);
219 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(callbackData2), hashValue);
220 }
221
222 hashValue = Cogs::hash(lod.selectedLod, hashValue);
223 hashValue = Cogs::hash(lod.numLods, hashValue);
224 hashValue = Cogs::hash(lod.currentLod, hashValue);
225 hashValue = Cogs::hash(lod.lodFraction, hashValue);
226 hashValue = Cogs::hash(layer, hashValue);
227 hashValue = Cogs::hash(depth, hashValue);
228 hashValue = Cogs::hash(drawOrder, hashValue);
229 hashValue = Cogs::hash(objectId, hashValue);
230 hashValue = Cogs::hash(flags, hashValue);
231 hashValue = Cogs::hash(stateChanges, hashValue);
232 hashValue = Cogs::hash(blendState, hashValue);
233 hashValue = Cogs::hash(depthState, hashValue);
234 hashValue = Cogs::hash(rasterizerState, hashValue);
235 hashValue = Cogs::hash(clipShapeIx, hashValue);
236
237 return hashValue;
238 }
239 };
240
241 typedef std::vector<RenderItem> RenderItems;
242
243
244
246 {
247 RenderBatch() : allItems(1024)
248 {
249 current = allItems.data();
250 }
251
252 RenderItem * current = nullptr;
253
254 RenderItem * begin() { return allItems.data(); }
255 RenderItem * end() { return current; }
256 const RenderItem * begin() const { return allItems.data(); }
257 const RenderItem * end() const { return current; }
258 size_t size() const { return size_t(current - begin()); }
259 bool empty() const { return begin() == end(); }
260 RenderItem& operator[](size_t idx)
261 {
262 assert(idx < size());
263 return begin()[idx];
264 }
265 const RenderItem& operator[](size_t idx) const
266 {
267 assert(idx < size());
268 return begin()[idx];
269 }
270
271 void clear() { current = allItems.data(); }
272
273 RenderItem& alloc()
274 {
275 const size_t sz = size();
276 if (sz == allItems.size()) {
277 allItems.resize(allItems.size() * 2);
278 current = allItems.data() + sz;
279 }
280 return *current++;
281 }
282
283 RenderItem & createCustom()
284 {
285 RenderItem& item = alloc();
286 item = {};
287 item.cullingIndex = (uint32_t)-1;
288 item.flags = RenderItemFlags::Custom;
289 return item;
290 }
291
292 private:
293 RenderItems allItems;
294 public:
295 size_t hash = 0;
296 size_t generation = 0;
297 size_t missing = (size_t)-1;
298 };
299
301 {
302 RenderList() : batches({ &batch }) {}
303
304 RenderItem * begin() { return batch.begin(); }
305 RenderItem * end() { return batch.end(); }
306 const RenderItem * begin() const { return batch.begin(); }
307 const RenderItem * end() const { return batch.end(); }
308 size_t size() const { return batch.size(); }
309 void clear()
310 {
311 batch.clear();
312 batches = { &batch };
313 }
314
315 RenderItem & createCustom(const MeshStreamsLayout* streamsLayout)
316 {
317 RenderItem& rv = batch.createCustom();
318 rv.streamsLayout = streamsLayout;
319 return rv;
320 }
321
322 RenderBatch batch;
323
324 std::vector<RenderBatch *> batches;
325
326 RenderItems buckets[size_t(BucketType::Count)];
327
328 size_t hash = 0;
329 const struct CameraData * viewportData = nullptr;
330 struct ArrayObjectBuffer* arrayObjectBuffer = nullptr;
331 struct ListObjectBuffer* listObjectBuffer = nullptr;
332 struct ClipShapeCache* clipShapeCache = nullptr;
333 };
334
335}
336template<> inline Cogs::StringView getName<Cogs::Core::StateChangeFlags>() { return "StateChangeFlags"; }
337template<> inline Cogs::StringView getName<Cogs::Core::BucketMask>() { return "BucketMask"; }
338
Provides a weakly referenced view over the contents of a string.
Definition: StringView.h:50
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
@ CastShadows
Casts shadows.
@ DisableCulling
Disable culling and always force this component to be rendered.
@ SolidOrderedBack
Opaque ordered geometry behind un-ordered geometry.
@ Transparent
Transparent geometry rendered after the opaque geometry.
@ SolidOrderedFront
Opaque ordered geometry in front of un-ordered geometry.
@ Solid
Opaque geometry in arbitrary order.
@ Backdrop
Background geometry behind everything else.
RenderLayers
Contains common render layers.
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
Definition: HashFunctions.h:62
PrimitiveType
Primitive types for interpreting vertex data sent to the graphics pipeline.
Definition: Common.h:112
Contains data describing a Camera instance and its derived data structured such as matrix data and vi...
Definition: CameraSystem.h:67
Material instances represent a specialized Material combined with state for all its buffers and prope...
Lod data holding the LoD state of the entity this render component belongs to.
uint8_t numLods
Total number of LoDs available.
uint8_t currentLod
The assigned LoD of the current component.
uint8_t selectedLod
The selected LoD of the composite entity.
uint32_t objectBufferSlot
Set if ObjectBufferSlot is set (then transform and objectId is in the object buffer).
Definition: RenderList.h:177
int32_t drawOrder
Ordering of draw items within a bucket.
Definition: RenderList.h:174
uint32_t objectId
Lower 6 of upper 8 bits are instance id bits, lower 24 bits are object id.
Definition: RenderList.h:176
uint32_t objectArrayBufferSlot
Set if ObjectArrayBufferSlot is set (then transform and objectId is in the object buffer).
Definition: RenderList.h:178
RenderLayers layer
Visibility mask.
Definition: RenderList.h:172
StateChangeFlags stateChanges
Encodes what state changed from previous item, updated by FilterListTask.
Definition: RenderList.h:181
float depth
Used for depth-sorting of transparent objects.
Definition: RenderList.h:173