Explorar el Código

Debug renderer can now draw a triangle with or without shadows (#639)

This will be needed for drawing soft bodies and is split off in a separate change because it is not dependent on it.
Jorrit Rouwe hace 2 años
padre
commit
6785742b9d

+ 8 - 8
Jolt/Renderer/DebugRenderer.h

@@ -80,8 +80,8 @@ public:
 		Wireframe,						///< Draw as wireframe
 	};
 
-	/// Draw a single back face culled triangle without any shadows
-	virtual void						DrawTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3, ColorArg inColor) = 0;
+	/// Draw a single back face culled triangle
+	virtual void						DrawTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3, ColorArg inColor, ECastShadow inCastShadow = ECastShadow::Off) = 0;
 
 	/// Draw a box
 	void								DrawBox(const AABox &inBox, ColorArg inColor, ECastShadow inCastShadow = ECastShadow::On, EDrawMode inDrawMode = EDrawMode::Solid);
@@ -91,7 +91,7 @@ public:
 	void								DrawSphere(RVec3Arg inCenter, float inRadius, ColorArg inColor, ECastShadow inCastShadow = ECastShadow::On, EDrawMode inDrawMode = EDrawMode::Solid);
 	void								DrawUnitSphere(RMat44Arg inMatrix, ColorArg inColor, ECastShadow inCastShadow = ECastShadow::On, EDrawMode inDrawMode = EDrawMode::Solid);
 
-	/// Draw a capsule with one half sphere at (0, -inHalfHeightOfCylinder, 0) and the other half sphere at (0, inHalfHeightOfCylinder, 0) and radius inRadius. 
+	/// Draw a capsule with one half sphere at (0, -inHalfHeightOfCylinder, 0) and the other half sphere at (0, inHalfHeightOfCylinder, 0) and radius inRadius.
 	/// The capsule will be transformed by inMatrix.
 	void								DrawCapsule(RMat44Arg inMatrix, float inHalfHeightOfCylinder, float inRadius, ColorArg inColor, ECastShadow inCastShadow = ECastShadow::On, EDrawMode inDrawMode = EDrawMode::Solid);
 
@@ -99,8 +99,8 @@ public:
 	/// The cylinder will be transformed by inMatrix
 	void								DrawCylinder(RMat44Arg inMatrix, float inHalfHeight, float inRadius, ColorArg inColor, ECastShadow inCastShadow = ECastShadow::On, EDrawMode inDrawMode = EDrawMode::Solid);
 
-	/// Draw a bottomless cone. 
-	/// @param inTop Top of cone, center of base is at inTop + inAxis. 
+	/// Draw a bottomless cone.
+	/// @param inTop Top of cone, center of base is at inTop + inAxis.
 	/// @param inAxis Height and direction of cone
 	/// @param inPerpendicular Perpendicular vector to inAxis.
 	/// @param inHalfAngle Specifies the cone angle in radians (angle measured between inAxis and cone surface).
@@ -120,11 +120,11 @@ public:
 	/// @param inDrawMode determines if we draw the geometry solid or in wireframe.
 	void								DrawSwingLimits(RMat44Arg inMatrix, float inSwingYHalfAngle, float inSwingZHalfAngle, float inEdgeLength, ColorArg inColor, ECastShadow inCastShadow = ECastShadow::On, EDrawMode inDrawMode = EDrawMode::Solid);
 
-	/// Draw a pie (part of a circle). 
+	/// Draw a pie (part of a circle).
 	/// @param inCenter The center of the circle.
 	/// @param inRadius Radius of the circle.
 	/// @param inNormal The plane normal in which the pie resides.
-	/// @param inAxis The axis that defines an angle of 0 radians. 
+	/// @param inAxis The axis that defines an angle of 0 radians.
 	/// @param inMinAngle The pie will be drawn between [inMinAngle, inMaxAngle] (in radians).
 	/// @param inMaxAngle The pie will be drawn between [inMinAngle, inMaxAngle] (in radians).
 	/// @param inColor Color to use for drawing the pie.
@@ -199,7 +199,7 @@ public:
 
 	/// Create a primitive for a convex shape using its support function
 	using SupportFunction = function<Vec3 (Vec3Arg inDirection)>;
-	Batch								CreateTriangleBatchForConvex(SupportFunction inGetSupport, int inLevel, AABox *outBounds = nullptr); 
+	Batch								CreateTriangleBatchForConvex(SupportFunction inGetSupport, int inLevel, AABox *outBounds = nullptr);
 	GeometryRef							CreateTriangleGeometryForConvex(SupportFunction inGetSupport);
 
 	/// Determines which polygons are culled

+ 2 - 1
Jolt/Renderer/DebugRendererPlayback.cpp

@@ -112,6 +112,7 @@ void DebugRendererPlayback::Parse(StreamIn &inStream)
 				inStream.Read(triangle.mV2);
 				inStream.Read(triangle.mV3);
 				inStream.Read(triangle.mColor);
+				inStream.Read(triangle.mCastShadow);
 			}
 
 			// Read all texts
@@ -153,7 +154,7 @@ void DebugRendererPlayback::DrawFrame(uint inFrameNumber) const
 		mRenderer.DrawLine(line.mFrom, line.mTo, line.mColor);
 
 	for (const DebugRendererRecorder::TriangleBlob &triangle : frame.mTriangles)
-		mRenderer.DrawTriangle(triangle.mV1, triangle.mV2, triangle.mV3, triangle.mColor);
+		mRenderer.DrawTriangle(triangle.mV1, triangle.mV2, triangle.mV3, triangle.mColor, triangle.mCastShadow);
 
 	for (const DebugRendererRecorder::TextBlob &text : frame.mTexts)
 		mRenderer.DrawText3D(text.mPosition, text.mString, text.mColor, text.mHeight);

+ 9 - 8
Jolt/Renderer/DebugRendererRecorder.cpp

@@ -10,18 +10,18 @@
 
 JPH_NAMESPACE_BEGIN
 
-void DebugRendererRecorder::DrawLine(RVec3Arg inFrom, RVec3Arg inTo, ColorArg inColor) 
-{ 
+void DebugRendererRecorder::DrawLine(RVec3Arg inFrom, RVec3Arg inTo, ColorArg inColor)
+{
 	lock_guard lock(mMutex);
 
 	mCurrentFrame.mLines.push_back({ inFrom, inTo, inColor });
 }
 
-void DebugRendererRecorder::DrawTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3, ColorArg inColor)
+void DebugRendererRecorder::DrawTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3, ColorArg inColor, ECastShadow inCastShadow)
 {
 	lock_guard lock(mMutex);
 
-	mCurrentFrame.mTriangles.push_back({ inV1, inV2, inV3, inColor });
+	mCurrentFrame.mTriangles.push_back({ inV1, inV2, inV3, inColor, inCastShadow });
 }
 
 DebugRenderer::Batch DebugRendererRecorder::CreateTriangleBatch(const Triangle *inTriangles, int inTriangleCount)
@@ -94,15 +94,15 @@ void DebugRendererRecorder::DrawGeometry(RMat44Arg inModelMatrix, const AABox &i
 }
 
 void DebugRendererRecorder::DrawText3D(RVec3Arg inPosition, const string_view &inString, ColorArg inColor, float inHeight)
-{ 	
-	lock_guard lock(mMutex);  
+{
+	lock_guard lock(mMutex);
 
 	mCurrentFrame.mTexts.push_back({ inPosition, inString, inColor, inHeight });
 }
 
 void DebugRendererRecorder::EndFrame()
-{ 	
-	lock_guard lock(mMutex);  
+{
+	lock_guard lock(mMutex);
 
 	mStream.Write(ECommand::EndFrame);
 
@@ -124,6 +124,7 @@ void DebugRendererRecorder::EndFrame()
 		mStream.Write(triangle.mV2);
 		mStream.Write(triangle.mV3);
 		mStream.Write(triangle.mColor);
+		mStream.Write(triangle.mCastShadow);
 	}
 	mCurrentFrame.mTriangles.clear();
 

+ 4 - 3
Jolt/Renderer/DebugRendererRecorder.h

@@ -26,12 +26,12 @@ public:
 
 	/// 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) override;
+	virtual void						DrawTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3, ColorArg inColor, ECastShadow inCastShadow) 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;
-	
+
 	/// Mark the end of a frame
 	void								EndFrame();
 
@@ -51,7 +51,7 @@ public:
 		RVec3							mTo;
 		Color							mColor;
 	};
-	
+
 	/// Holds a single triangle
 	struct TriangleBlob
 	{
@@ -59,6 +59,7 @@ public:
 		RVec3							mV2;
 		RVec3							mV3;
 		Color							mColor;
+		ECastShadow						mCastShadow;
 	};
 
 	/// Holds a single text entry

+ 25 - 27
TestFramework/Renderer/DebugRendererImp.cpp

@@ -57,7 +57,7 @@ DebugRendererImp::DebugRendererImp(Renderer *inRenderer, const Font *inFont) :
 	mTriangleStateBF = mRenderer->CreatePipelineState(vtx_triangle.Get(), triangles_vertex_desc, ARRAYSIZE(triangles_vertex_desc), pix_triangle.Get(), D3D12_FILL_MODE_SOLID, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, PipelineState::EDepthTest::On, PipelineState::EBlendMode::AlphaBlend, PipelineState::ECullMode::Backface);
 	mTriangleStateFF = mRenderer->CreatePipelineState(vtx_triangle.Get(), triangles_vertex_desc, ARRAYSIZE(triangles_vertex_desc), pix_triangle.Get(), D3D12_FILL_MODE_SOLID, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, PipelineState::EDepthTest::On, PipelineState::EBlendMode::AlphaBlend, PipelineState::ECullMode::FrontFace);
 	mTriangleStateWire = mRenderer->CreatePipelineState(vtx_triangle.Get(), triangles_vertex_desc, ARRAYSIZE(triangles_vertex_desc), pix_triangle.Get(), D3D12_FILL_MODE_WIREFRAME, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, PipelineState::EDepthTest::On, PipelineState::EBlendMode::AlphaBlend, PipelineState::ECullMode::Backface);
-	
+
 	// Shadow pass
 	ComPtr<ID3DBlob> vtx_shadow = mRenderer->CreateVertexShader("Assets/Shaders/TriangleDepthVertexShader.hlsl");
 	ComPtr<ID3DBlob> pix_shadow = mRenderer->CreatePixelShader("Assets/Shaders/TriangleDepthPixelShader.hlsl");
@@ -81,7 +81,7 @@ DebugRendererImp::DebugRendererImp(Renderer *inRenderer, const Font *inFont) :
 	DebugRenderer::Initialize();
 }
 
-void DebugRendererImp::DrawLine(RVec3Arg inFrom, RVec3Arg inTo, ColorArg inColor) 
+void DebugRendererImp::DrawLine(RVec3Arg inFrom, RVec3Arg inTo, ColorArg inColor)
 {
 	RVec3 offset = mRenderer->GetBaseOffset();
 
@@ -92,7 +92,7 @@ void DebugRendererImp::DrawLine(RVec3Arg inFrom, RVec3Arg inTo, ColorArg inColor
 	line.mToColor = inColor;
 
 	lock_guard lock(mLinesLock);
-	mLines.push_back(line); 
+	mLines.push_back(line);
 }
 
 DebugRenderer::Batch DebugRendererImp::CreateTriangleBatch(const Triangle *inTriangles, int inTriangleCount)
@@ -121,13 +121,13 @@ DebugRenderer::Batch DebugRendererImp::CreateTriangleBatch(const Vertex *inVerti
 void DebugRendererImp::DrawGeometry(RMat44Arg inModelMatrix, const AABox &inWorldSpaceBounds, float inLODScaleSq, ColorArg inModelColor, const GeometryRef &inGeometry, ECullMode inCullMode, ECastShadow inCastShadow, EDrawMode inDrawMode)
 {
 	lock_guard lock(mPrimitivesLock);
-	
+
 	RVec3 offset = mRenderer->GetBaseOffset();
 
 	Mat44 model_matrix = inModelMatrix.PostTranslated(-offset).ToMat44();
 	AABox world_space_bounds = inWorldSpaceBounds;
 	world_space_bounds.Translate(Vec3(-offset));
-	   
+
 	// Our pixel shader uses alpha only to turn on/off shadows
 	Color color = inCastShadow == ECastShadow::On? Color(inModelColor, 255) : Color(inModelColor, 0);
 
@@ -183,7 +183,7 @@ void DebugRendererImp::EnsurePrimitiveSpace(int inVtxSize)
 {
 	const int cVertexBufferSize = 10240;
 
-	if (mLockedPrimitive == nullptr 
+	if (mLockedPrimitive == nullptr
 		|| mLockedVerticesEnd - mLockedVertices < inVtxSize)
 	{
 		FinalizePrimitive();
@@ -199,7 +199,7 @@ void DebugRendererImp::EnsurePrimitiveSpace(int inVtxSize)
 	}
 }
 
-void DebugRendererImp::DrawTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3, ColorArg inColor)
+void DebugRendererImp::DrawTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3, ColorArg inColor, ECastShadow inCastShadow)
 {
 	RVec3 offset = mRenderer->GetBaseOffset();
 
@@ -207,14 +207,12 @@ void DebugRendererImp::DrawTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3,
 	Vec3 v2(inV2 - offset);
 	Vec3 v3(inV3 - offset);
 
-	lock_guard lock(mPrimitivesLock); 
+	lock_guard lock(mPrimitivesLock);
 
 	EnsurePrimitiveSpace(3);
 
-	// Set alpha to zero to tell our pixel shader to not cast shadows for this triangle
-	// this is because our algorithm only renders shadows for backfacing triangles and this
-	// triangle doesn't have one
-	Color color(inColor, 0);
+	// Set alpha to zero if we don't want to cast shadows to notify the pixel shader
+	Color color(inColor, inCastShadow == ECastShadow::Off? 0 : 0xff);
 
 	// Construct triangle
 	new ((Triangle *)mLockedVertices) Triangle(v1, v2, v3, color);
@@ -253,15 +251,15 @@ void DebugRendererImp::DrawText3D(RVec3Arg inPosition, const string_view &inStri
 
 	Vec3 pos(inPosition - offset);
 
-	lock_guard lock(mTextsLock);  
-	mTexts.emplace_back(pos, inString, inColor, inHeight); 
+	lock_guard lock(mTextsLock);
+	mTexts.emplace_back(pos, inString, inColor, inHeight);
 }
 
 void DebugRendererImp::DrawLines()
 {
 	JPH_PROFILE_FUNCTION();
 
-	lock_guard lock(mLinesLock); 
+	lock_guard lock(mLinesLock);
 
 	// Draw the lines
 	if (!mLines.empty())
@@ -280,7 +278,7 @@ void DebugRendererImp::DrawTriangles()
 {
 	JPH_PROFILE_FUNCTION();
 
-	lock_guard lock(mPrimitivesLock); 
+	lock_guard lock(mPrimitivesLock);
 
 	// Finish the last primitive
 	FinalizePrimitive();
@@ -352,7 +350,7 @@ void DebugRendererImp::DrawTriangles()
 
 				// Loop over both passes: 0 = light, 1 = geometry
 				Array<int> *start_idx[] = { &v.second.mLightStartIdx, &v.second.mGeometryStartIdx };
-				for (int type = 0; type < 2; ++type) 
+				for (int type = 0; type < 2; ++type)
 				{
 					// Reserve space for instance indices
 					Array<int> &type_start_idx = *start_idx[type];
@@ -459,7 +457,7 @@ void DebugRendererImp::DrawTriangles()
 
 void DebugRendererImp::DrawTexts()
 {
-	lock_guard lock(mTextsLock); 
+	lock_guard lock(mTextsLock);
 
 	JPH_PROFILE_FUNCTION();
 
@@ -484,15 +482,15 @@ void DebugRendererImp::Draw()
 }
 
 void DebugRendererImp::ClearLines()
-{ 
-	lock_guard lock(mLinesLock); 
-	mLines.clear(); 
+{
+	lock_guard lock(mLinesLock);
+	mLines.clear();
 }
 
 void DebugRendererImp::ClearMap(InstanceMap &ioInstances)
 {
 	Array<GeometryRef> to_delete;
-	
+
 	for (InstanceMap::value_type &kv : ioInstances)
 	{
 		if (kv.second.mInstances.empty())
@@ -506,12 +504,12 @@ void DebugRendererImp::ClearMap(InstanceMap &ioInstances)
 }
 
 void DebugRendererImp::ClearTriangles()
-{ 
-	lock_guard lock(mPrimitivesLock); 
+{
+	lock_guard lock(mPrimitivesLock);
 
 	// Close any primitive that's being built
-	FinalizePrimitive(); 
-	
+	FinalizePrimitive();
+
 	// Move primitives to draw back to the free list
 	ClearMap(mWireframePrimitives);
 	ClearMap(mPrimitives);
@@ -522,7 +520,7 @@ void DebugRendererImp::ClearTriangles()
 
 void DebugRendererImp::ClearTexts()
 {
-	lock_guard lock(mTextsLock); 
+	lock_guard lock(mTextsLock);
 	mTexts.clear();
 }
 

+ 4 - 4
TestFramework/Renderer/DebugRendererImp.h

@@ -35,18 +35,18 @@ public:
 
 	/// 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) 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();
@@ -119,7 +119,7 @@ private:
 		/// 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
 	{