-
Notifications
You must be signed in to change notification settings - Fork 462
/
DebugRendererImp.h
191 lines (149 loc) · 6.64 KB
/
DebugRendererImp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#pragma once
#ifdef JPH_DEBUG_RENDERER
#include <Jolt/Renderer/DebugRenderer.h>
#else
// Hack to still compile DebugRenderer inside the test framework when Jolt is compiled without
#define JPH_DEBUG_RENDERER
// Make sure the debug renderer symbols don't get imported or exported
#define JPH_DEBUG_RENDERER_EXPORT
#include <Jolt/Renderer/DebugRenderer.h>
#undef JPH_DEBUG_RENDERER
#undef JPH_DEBUG_RENDERER_EXPORT
#endif
#include <Renderer/RenderPrimitive.h>
#include <Renderer/RenderInstances.h>
#include <Jolt/Core/Mutex.h>
#include <Jolt/Core/UnorderedMap.h>
class Renderer;
class Font;
/// Implementation of DebugRenderer
class DebugRendererImp final : public DebugRenderer
{
public:
JPH_OVERRIDE_NEW_DELETE
/// Constructor
DebugRendererImp(Renderer *inRenderer, const Font *inFont);
/// Implementation of DebugRenderer interface
virtual void DrawLine(RVec3Arg inFrom, RVec3Arg inTo, ColorArg inColor) override;
virtual void DrawTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3, ColorArg inColor, ECastShadow inCastShadow = ECastShadow::Off) override;
virtual Batch CreateTriangleBatch(const Triangle *inTriangles, int inTriangleCount) override;
virtual Batch CreateTriangleBatch(const Vertex *inVertices, int inVertexCount, const uint32 *inIndices, int inIndexCount) override;
virtual void DrawGeometry(RMat44Arg inModelMatrix, const AABox &inWorldSpaceBounds, float inLODScaleSq, ColorArg inModelColor, const GeometryRef &inGeometry, ECullMode inCullMode, ECastShadow inCastShadow, EDrawMode inDrawMode) override;
virtual void DrawText3D(RVec3Arg inPosition, const string_view &inString, ColorArg inColor, float inHeight) override;
/// Draw all primitives that were added
void Draw();
/// Clear all primitives (to be called after drawing)
void Clear();
private:
/// Helper functions to draw sub parts
void DrawLines();
void DrawTriangles();
void DrawTexts();
/// Helper functions to clear sub parts
void ClearLines();
void ClearTriangles();
void ClearTexts();
/// Implementation specific batch object
class BatchImpl : public RefTargetVirtual, public RenderPrimitive
{
public:
JPH_OVERRIDE_NEW_DELETE
BatchImpl(Renderer *inRenderer, D3D_PRIMITIVE_TOPOLOGY inType) : RenderPrimitive(inRenderer, inType) { }
virtual void AddRef() override { RenderPrimitive::AddRef(); }
virtual void Release() override { if (--mRefCount == 0) delete this; }
};
/// Finalize the current locked primitive and add it to the primitives to draw
void FinalizePrimitive();
/// Ensure that the current locked primitive has space for a primitive consisting inVtxSize vertices
void EnsurePrimitiveSpace(int inVtxSize);
Renderer * mRenderer;
/// Shaders for triangles
unique_ptr<PipelineState> mTriangleStateBF;
unique_ptr<PipelineState> mTriangleStateFF;
unique_ptr<PipelineState> mTriangleStateWire;
/// Shaders for shadow pass for triangles
unique_ptr<PipelineState> mShadowStateBF;
unique_ptr<PipelineState> mShadowStateFF;
unique_ptr<PipelineState> mShadowStateWire;
/// The shadow buffer (depth buffer rendered from the light)
Ref<Texture> mDepthTexture;
/// Lock that protects the triangle batches from being accessed from multiple threads
Mutex mPrimitivesLock;
Batch mEmptyBatch;
/// Properties for a single rendered instance
struct Instance
{
/// Constructor
Instance(Mat44Arg inModelMatrix, Mat44Arg inModelMatrixInvTrans, ColorArg inModelColor) : mModelMatrix(inModelMatrix), mModelMatrixInvTrans(inModelMatrixInvTrans), mModelColor(inModelColor) { }
Mat44 mModelMatrix;
Mat44 mModelMatrixInvTrans;
Color mModelColor;
};
/// Rendered instance with added information for lodding
struct InstanceWithLODInfo : public Instance
{
/// Constructor
InstanceWithLODInfo(Mat44Arg inModelMatrix, Mat44Arg inModelMatrixInvTrans, ColorArg inModelColor, const AABox &inWorldSpaceBounds, float inLODScaleSq) : Instance(inModelMatrix, inModelMatrixInvTrans, inModelColor), mWorldSpaceBounds(inWorldSpaceBounds), mLODScaleSq(inLODScaleSq) { }
/// Bounding box for culling
AABox mWorldSpaceBounds;
/// Square of scale factor for LODding (1 = original, > 1 = lod out further, < 1 = lod out earlier)
float mLODScaleSq;
};
/// Properties for a batch of instances that have the same primitive
struct Instances
{
Array<InstanceWithLODInfo> mInstances;
/// Start index in mInstancesBuffer for each of the LOD in the geometry pass. Length is one longer than the number of LODs to indicate how many instances the last lod has.
Array<int> mGeometryStartIdx;
/// Start index in mInstancesBuffer for each of the LOD in the light pass. Length is one longer than the number of LODs to indicate how many instances the last lod has.
Array<int> mLightStartIdx;
};
using InstanceMap = UnorderedMap<GeometryRef, Instances>;
/// Clear map of instances and make it ready for the next frame
void ClearMap(InstanceMap &ioInstances);
/// Helper function to draw instances
inline void DrawInstances(const Geometry *inGeometry, const Array<int> &inStartIdx);
/// List of primitives that are finished and ready for drawing
InstanceMap mWireframePrimitives;
InstanceMap mPrimitives;
InstanceMap mTempPrimitives;
InstanceMap mPrimitivesBackFacing;
int mNumInstances = 0;
Ref<RenderInstances> mInstancesBuffer[Renderer::cFrameCount];
/// Primitive that is being built + its properties
Batch mLockedPrimitive;
Vertex * mLockedVerticesStart = nullptr;
Vertex * mLockedVertices = nullptr;
Vertex * mLockedVerticesEnd = nullptr;
AABox mLockedPrimitiveBounds;
/// A single text string
struct Text
{
Text(Vec3Arg inPosition, const string_view &inText, ColorArg inColor, float inHeight) : mPosition(inPosition), mText(inText), mColor(inColor), mHeight(inHeight) { }
Vec3 mPosition;
String mText;
Color mColor;
float mHeight;
};
/// All text strings that are to be drawn on screen
Array<Text> mTexts;
Mutex mTextsLock;
/// Font with which to draw the texts
RefConst<Font> mFont;
/// A single line segment
struct Line
{
Float3 mFrom;
Color mFromColor;
Float3 mTo;
Color mToColor;
};
/// The list of line segments
Array<Line> mLines;
Mutex mLinesLock;
/// The shaders for the line segments
unique_ptr<PipelineState> mLineState;
};