Files
LifeProject/LifeGraphics/debug/IDebugDrawer.h
T
2025-05-13 02:46:21 +03:00

231 lines
6.0 KiB
C++

#ifndef IDebugDrawer_h__
#define IDebugDrawer_h__
#include "render/IRenderer.h"
#include "math/LifeMath.h"
#include <math/Spline.h>
namespace LifeGraphics
{
#define MAX_VERTEX_COUNT 1024
struct DebugVertex
{
LifeMath::float3 position;
LifeMath::float3 color;
const DebugVertex operator *(float val) const
{
DebugVertex result;
result.color = this->color * val;
result.position = this->position * val;
return result;
}
const DebugVertex operator +(const DebugVertex& val) const
{
DebugVertex result;
result.color = this->color + val.color;
result.position = this->position + val.position;
return result;
}
const DebugVertex& operator *=(float val)
{
this->color *= val;
this->position *= val;
return *this;
}
};
struct CB_2D_DATA
{
LifeMath::float4 screen_size;
};
class IDebugDrawer
{
private:
IShader* debugVS;
IShader* debugPS;
IShader* debugVS_2d;
IShader* debugPS_2d;
IInputLayout* inputLayout;
IVertexBuffer* debugVB;
DebugVertex geom[MAX_VERTEX_COUNT];
int vertexCount;
IConstantBuffer* cb_2d;
DebugVertex* buf;
public:
IDebugDrawer(IRenderer* _renderer)
:vertexCount(0)
{
//Vertex shader
String vs(STR(
"struct VS_INPUT" \
"{" \
" float4 Position : POSITION;" \
" float3 Color : LineColor;" \
"}; " \
"struct VS_OUTPUT " \
"{" \
" float4 Position : SV_Position;" \
" float3 Color : TEXCOORD0;" \
"};" \
"cbuffer perCameraData : register(b1)" \
"{" \
" row_major matrix matView;" \
" row_major matrix matProjection;" \
" row_major matrix matInvVP;" \
" float4 camPos;" \
" float4 camDir;" \
" float4 camNearFar;" \
" float4 corners[4];" \
"};"\
"VS_OUTPUT main_VS( VS_INPUT Input )" \
"{"\
" VS_OUTPUT Output = (VS_OUTPUT)0;" \
" float4 pos = float4(Input.Position.xyz, 1.0f);" \
" Output.Color = Input.Color;" \
" Output.Position = mul(pos, matInvVP);" \
" return( Output );" \
"}"
));
//Pixel shader
String ps(STR(
"struct PS_INPUT " \
"{" \
" float4 Position : SV_Position;" \
" float3 Color : TEXCOORD0;" \
"};" \
"float4 main_PS( PS_INPUT Input ) : SV_Target" \
"{" \
" return float4(Input.Color, 1.0f);" \
"}"
));
String vs_line_2d(STR(
"cbuffer RT_Size: register(b1)" \
"{float bbWidth : packoffset(c0.x);float bbHeight : packoffset(c0.y);};" \
"struct VS_INPUT {float3 Position : POSITION0;float3 Color : LineColor0;};" \
"struct VS_OUTPUT {float4 Position : SV_Position;float4 Color :TEXCOORD0;};" \
"VS_OUTPUT main_VS( VS_INPUT Input ){" \
"VS_OUTPUT Output;Output.Position = float4(Input.Position.xy, 0.0f, 1.0f);" \
"Output.Position.xy = Output.Position.xy/float2(bbWidth, -bbHeight)*2.0f + float2(-1.0f,1.0f);" \
"Output.Color = float4(Input.Color.xyz, 1.0f); return( Output );}"
));
String ps_2d_line(STR(
"struct PS_INPUT {" \
"float4 Position : SV_Position;" \
"float4 Color : TEXCOORD0;};" \
"float4 main_PS( PS_INPUT Input ) : SV_Target" \
"{ return Input.Color;}"
));
buf = new DebugVertex[2*256];
debugVS = ResourceManager::me()->CompileUserShaderVS(vs.c_str(), vs.length());
debugPS = ResourceManager::me()->CompileUserShaderPS(ps.c_str(), ps.length());
debugVS_2d = ResourceManager::me()->CompileUserShaderVS(vs_line_2d.c_str(), vs_line_2d.length());
debugPS_2d = ResourceManager::me()->CompileUserShaderPS(ps_2d_line.c_str(), ps_2d_line.length());
IInputElement* elements = new IInputElement[2];
elements[0] = IInputElement("POSITION", 0, 0, FORMAT_R32G32B32_FLOAT, 0, 0, 0);
elements[1] = IInputElement("LineColor", 0, 12, FORMAT_R32G32B32_FLOAT, 0, 0, 0);
inputLayout = CG::me()->GetRenderer()->CreateInputLayout(elements, 2, debugVS);
debugVB = CG::me()->GetRenderer()->CreateVertexBufferDynamic(sizeof(DebugVertex)* MAX_VERTEX_COUNT,sizeof(DebugVertex));
cb_2d = CG::me()->GetRenderer()->CreateConstantBuffer(sizeof(CB_2D_DATA));
}
void DrawSpline2D(DebugVertex* points, int discr_rate)
{
int offset = 0;
DebugVertex prev;
prev = points[0];
for(int i = 1; i <= discr_rate; i++)
{
//DebugVertex newP;
DebugVertex newP = LifeCore::CubicBezier<DebugVertex>((1.0f / (float)discr_rate) * (float)i, points[0], points[1], points[2], points[3]);
buf[offset++] = prev;
buf[offset++] = newP;
prev = newP;
}
DrawLines2D(buf, discr_rate);
}
void DrawLines2D(DebugVertex* data, int line_count)
{
LifeCore::IDataStream* stm = debugVB->Map(0, LF_Discard | LF_NoOverwrite);
stm->Write(data, line_count * 2 * sizeof(DebugVertex));
debugVB->Unmap();
CB_2D_DATA d;
d.screen_size = LifeMath::float4(640, 480,0,0);
cb_2d->Update(&d, sizeof(CB_2D_DATA));
IRenderer* r = CG::me()->GetRenderer();
r->SetVSConstantBuffer(cb_2d, 1);
r->SetVertexBuffer(debugVB);
r->SetInputLayout(inputLayout);
r->SetPrimitiveTopology(PT_LINE_LIST);
r->SetVertexShader(debugVS_2d);
r->SetPixelShader(debugPS_2d);
r->Draw(line_count * 2, 0);
}
void Render()
{
if(vertexCount > 1)
{
LifeCore::IDataStream* stm = debugVB->Map(0, LF_Discard);
stm->Write(&geom[0], vertexCount * sizeof(DebugVertex));
debugVB->Unmap();
IRenderer* r = CG::me()->GetRenderer();
r->SetVertexBuffer(debugVB);
r->SetInputLayout(inputLayout);
r->SetPrimitiveTopology(PT_LINE_LIST);
r->SetVertexShader(debugVS);
r->SetPixelShader(debugPS);
r->Draw(vertexCount, 0);
}
}
void Flush()
{
vertexCount = 0;
}
/*void PushLine(const LifeMath::float3& v1, const LifeMath::float3& v2)
{
if(vertexCount < MAX_VERTEX_COUNT)
{
geom[vertexCount] = v1;
vertexCount++;
}
if(vertexCount < MAX_VERTEX_COUNT)
{
geom[vertexCount] = v2;
vertexCount++;
}
}*/
void PushLine(const DebugVertex& v1, const DebugVertex& v2)
{
//if(vertexCount < MAX_VERTEX_COUNT)
//{
geom[vertexCount++] = v1;
//}
//if(vertexCount < MAX_VERTEX_COUNT)
//{
geom[vertexCount++] = v2;
//}
}
};
}
#endif // IDebugDrawer_h__