231 lines
6.0 KiB
C++
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__
|