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
17 enum struct RenderItemFlags : uint16_t
18 {
19 None = 0,
20 Custom = 1 << 0,
21 CastShadows = 1 << 1,
22 CalculateDepth = 1 << 2,
23 Sprite = 1 << 3,
24 AlwaysOnTop = 1 << 4,
25 Clockwise = 1 << 5,
26 Transparent = 1 << 6,
27 Backdrop = 1 << 7,
28 CustomBucket = 1 << 8,
29 CustomBounds = 1 << 9,
30 Custom2 = 1 << 10,
31 DisableCulling = 1 << 11,
32 Instanced = 1 << 12,
33 ObjectBufferSlot = 1 << 13
34 };
35 ENABLE_ENUM_FLAGS(RenderItemFlags);
36
37 enum struct StateChangeFlags : uint16_t {
38 ChangeNone = 0,
39 ChangeTransform = 1 << 0,
40 ChangeMesh = 1 << 1,
41 ChangeMaterialInstance = 1 << 2,
42 ChangeMaterialVariant = 1 << 3,
43 ChangeRasterizerState = 1 << 4,
44 ChangeBlendState = 1 << 5,
45 ChangeDepthStencilState = 1 << 6,
46 ChangeLayer = 1 << 7,
47 ChangeViewport = 1 << 8,
48 ChangeViewportData = 1 << 9,
49 ChangeAll = 0xFFFF
50 };
51 ENABLE_ENUM_FLAGS(StateChangeFlags);
52
53 enum struct BucketType
54 {
55 Backdrop = 0,
57 Solid,
59 Transparent,
60 Annotation,
61 Overlay,
62 Custom,
63 Count
64 };
65
66 enum class BucketMask
67 {
68 BackDrop = 1 << size_t(BucketType::Backdrop),
69 Transparent = 1 << size_t(BucketType::Transparent),
70 Solid = (1 << size_t(BucketType::SolidOrderedBack)) | (1 << size_t(BucketType::Solid)) | (1 << size_t(BucketType::SolidOrderedFront)),
71 Opaque = Solid,
72 Annotation = 1 << size_t(BucketType::Annotation),
73 Overlay = 1 << size_t(BucketType::Overlay),
74 Custom = 1 << size_t(BucketType::Custom),
75 All = ~0,
76 None = 0,
77 };
78 ENABLE_ENUM_FLAGS(BucketMask);
79
80 inline bool hasBucket(BucketMask bucketMask, BucketType bucket)
81 {
82 return (size_t(bucketMask) & (size_t(1) << size_t(bucket))) != 0;
83 }
84
86 {
87 typedef void CustomCallback(RenderTaskContext*, DrawContext*, const RenderItem*);
88 typedef void CustomCallback2(RenderTaskContext*, DrawContext*, struct RenderListTask* task, const RenderItem*);
89
90
91 bool isCustom() const { return (flags & (RenderItemFlags::Custom | RenderItemFlags::Custom2)) != 0; }
92 bool isCustom1() const { return (flags & RenderItemFlags::Custom) != 0; }
93 bool isCustom2() const { return (flags & RenderItemFlags::Custom2) != 0; }
94 bool isSprite() const { return (flags & RenderItemFlags::Sprite) != 0; }
95 bool isClockwise() const { return (flags & RenderItemFlags::Clockwise) != 0; }
96 bool isTransparent() const { return (flags & RenderItemFlags::Transparent) != 0; }
97 bool isCustomBucket() const { return (flags & RenderItemFlags::CustomBucket) != 0; }
98 bool isBackdrop() const { return (flags & RenderItemFlags::Backdrop) != 0; }
99 bool needsDepthCalculation() const { return (flags & RenderItemFlags::CalculateDepth) != 0; }
100 bool hasBoundingBox() const { return (flags & RenderItemFlags::CustomBounds) != 0; }
101 bool isCulled() const { return !hasBoundingBox() && !isCustom(); }
102 bool isInstanced() const { return (flags & RenderItemFlags::Instanced) != 0; }
103 bool hasObjectBufferSlot() const { return (flags & RenderItemFlags::ObjectBufferSlot) != 0; }
104
105 void setBounds(const Geometry::BoundingBox* bounds)
106 {
107 boundingBox = bounds;
108 flags |= RenderItemFlags::CustomBounds;
109 }
110
111 template<typename T>
112 void setCallbackData(T* t) const { callbackData = t; }
113
114 template<typename T>
115 void setCallbackData2(T* t) const { callbackData2 = t; }
116
117 template<typename T>
118 T* getCallbackData() const { return static_cast<T*>(callbackData); }
119
120 template<typename T>
121 T* getCallbackData2() const { return static_cast<T*>(callbackData2); }
122
123
124
125 const struct RenderMaterialInstance * renderMaterialInstance = nullptr;
126 const MaterialInstance * materialInstance = nullptr;
127
128 const struct EffectBinding * binding = nullptr;
129 const struct CameraData * viewportData = nullptr;
130 const struct PoseData * poseData = nullptr;
131 union
132 {
133 uint32_t cullingIndex;
134 const Geometry::BoundingBox* boundingBox = nullptr;
135 };
136
137 VertexArrayObjectHandle vertexArrayObject = VertexArrayObjectHandle::NoHandle; // FIXME: input layout and vao is mutually exclusive
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;
178 };
179 RenderItemFlags flags = RenderItemFlags::None;
180 StateChangeFlags stateChanges = StateChangeFlags::ChangeAll;
181
182 // Pipeline state
183 //
184 // Note: These will all be merged into one state handle moving to PSO in future
185 // graphics APIs.
186 uint16_t blendState = 0;
187 uint16_t depthState = 0;
188 uint16_t rasterizerState = 0;
189 uint8_t clipShapeIx = 0;
190
191 size_t hash(size_t hashValue = Cogs::hash()) const {
192 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(renderMaterialInstance), hashValue);
193 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(materialInstance), hashValue);
194 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(binding), 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 hashValue = Cogs::hash(vertexArrayObject.handle);
205
206 if (isCustom()) {
207 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(worldMatrix), hashValue);
208 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(meshData), hashValue);
209 hashValue = Cogs::hash(startIndex, hashValue);
210 hashValue = Cogs::hash(numIndexes, hashValue);
211 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(instanceData), hashValue);
212 hashValue = Cogs::hash(startInstance, hashValue);
213 hashValue = Cogs::hash(numInstances, hashValue);
214 hashValue = Cogs::hash(primitiveType, hashValue);
215 }
216 else {
217 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(streamsLayout), hashValue);
218 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(callback), hashValue);
219 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(callbackData), hashValue);
220 hashValue = Cogs::hash(reinterpret_cast<intptr_t>(callbackData2), hashValue);
221 }
222
223 hashValue = Cogs::hash(lod.selectedLod, hashValue);
224 hashValue = Cogs::hash(lod.numLods, hashValue);
225 hashValue = Cogs::hash(lod.currentLod, hashValue);
226 hashValue = Cogs::hash(lod.lodFraction, hashValue);
227 hashValue = Cogs::hash(layer, hashValue);
228 hashValue = Cogs::hash(depth, hashValue);
229 hashValue = Cogs::hash(drawOrder, hashValue);
230 hashValue = Cogs::hash(objectId, hashValue);
231 hashValue = Cogs::hash(flags, hashValue);
232 hashValue = Cogs::hash(stateChanges, hashValue);
233 hashValue = Cogs::hash(blendState, hashValue);
234 hashValue = Cogs::hash(depthState, hashValue);
235 hashValue = Cogs::hash(rasterizerState, hashValue);
236 hashValue = Cogs::hash(clipShapeIx, hashValue);
237
238 return hashValue;
239 }
240 };
241
242 typedef std::vector<RenderItem> RenderItems;
243
244
245
247 {
248 RenderBatch() : allItems(1024)
249 {
250 current = allItems.data();
251 }
252
253 RenderItem * current = nullptr;
254
255 RenderItem * begin() { return allItems.data(); }
256 RenderItem * end() { return current; }
257 const RenderItem * begin() const { return allItems.data(); }
258 const RenderItem * end() const { return current; }
259 size_t size() const { return size_t(current - begin()); }
260 bool empty() const { return begin() == end(); }
261 RenderItem& operator[](size_t idx)
262 {
263 assert(idx < size());
264 return begin()[idx];
265 }
266 const RenderItem& operator[](size_t idx) const
267 {
268 assert(idx < size());
269 return begin()[idx];
270 }
271
272 void clear() { current = allItems.data(); }
273
274 RenderItem& alloc()
275 {
276 const size_t sz = size();
277 if (sz == allItems.size()) {
278 allItems.resize(allItems.size() * 2);
279 current = allItems.data() + sz;
280 }
281 return *current++;
282 }
283
284 RenderItem & createCustom()
285 {
286 RenderItem& item = alloc();
287 item = {};
288 item.cullingIndex = (uint32_t)-1;
289 item.flags = RenderItemFlags::Custom;
290 return item;
291 }
292
293 private:
294 RenderItems allItems;
295 public:
296 size_t hash = 0;
297 size_t generation = 0;
298 size_t missing = (size_t)-1;
299 };
300
302 {
303 RenderList() : batches({ &batch }) {}
304
305 RenderItem * begin() { return batch.begin(); }
306 RenderItem * end() { return batch.end(); }
307 const RenderItem * begin() const { return batch.begin(); }
308 const RenderItem * end() const { return batch.end(); }
309 size_t size() const { return batch.size(); }
310 void clear()
311 {
312 batch.clear();
313 batches = { &batch };
314 }
315
316 RenderItem & createCustom(const MeshStreamsLayout* streamsLayout)
317 {
318 RenderItem& rv = batch.createCustom();
319 rv.streamsLayout = streamsLayout;
320 return rv;
321 }
322
323 RenderBatch batch;
324
325 std::vector<RenderBatch *> batches;
326
327 RenderItems buckets[size_t(BucketType::Count)];
328
329 size_t hash = 0;
330 const struct CameraData * viewportData = 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:24
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
RenderLayers layer
Visibility mask.
Definition: RenderList.h:172
StateChangeFlags stateChanges
Encodes what state changed from previous item, updated by FilterListTask.
Definition: RenderList.h:180
float depth
Used for depth-sorting of transparent objects.
Definition: RenderList.h:173
static const Handle_t NoHandle
Represents a handle to nothing.
Definition: Common.h:78
handle_type handle
Internal resource handle.
Definition: Common.h:75