Hi all, it seems that I have hit another wall. I can't see the particles at all
I think I have properly initialized all related buffers. But for some reason, even though the particle's current amount is behaving properly, I can't see any particles on screen. As a side note, I tried using the Graphic Diagnostic Tool (VS 2013) and RenderDoc (Crytek) to debug the shaders, but for some reason the app crashes if I try to capture the current frame info. They work properly if I don't execute the particle system tho, so the problem is probably caused by the compute shaders.
As always, any help is greatly appreciated.
Related Structures
// Render
struct Transforms
{
D3DMATRIX WorldViewMatrix;
D3DMATRIX ProjMatrix;
};
Render Function
// Command the particle system calculations (update and render)
void Particleclass::Draw(float elapsedMiliSeconds,D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix,D3DXMATRIX projectionMatrix)
{
// Check if the PS has started
if (State == ParticleSystemState::UNSTARTED)
return;
// Timescale
float elapsedSeconds = elapsedMiliSeconds / 1000.0f;
///////////////////////////////////////////////////////////////////
// Simulation
///////////////////////////////////////////////////////////////////
if (State == ParticleSystemState::PLAYING)
Update(elapsedSeconds);
///////////////////////////////////////////////////////////////////
// Render
///////////////////////////////////////////////////////////////////
// Check if there are enough particles in the system
if (currentParticles <= 0) return;
// To render, we need to only select the particles that exist after the update.
m_D3D->GetDeviceContext()->CopyStructureCount(g_pParticlesToRender, 0, InputState);
// Set input layouyt
m_D3D->GetDeviceContext()->IASetInputLayout(pInputLayout);
// Set the type of primitive that should be rendered from this vertex buffer, in this case, the info is stored as point particles.
m_D3D->GetDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
// Set the vertex and pixel shaders that will be used to render this triangle.
m_D3D->GetDeviceContext()->VSSetShader(vs_pVertex, NULL, 0);
m_D3D->GetDeviceContext()->PSSetShader(ps_pPixel, NULL, 0);
m_D3D->GetDeviceContext()->GSSetShader(gs_pGeometry, NULL, 0);
// m_D3D->GetDeviceContext()->DSSetShader(NULL, NULL, 0); // Domain Shader (Not Yet)
// Set blend and stencil model
// Bind blend state
float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
UINT sampleMask = 0xffffffff;
m_D3D->GetDeviceContext()->OMSetBlendState(pBlendState, blendFactor, sampleMask);
// Bind stencil depth
m_D3D->GetDeviceContext()->OMSetDepthStencilState(pDepthState, 0);
// Set this frame information
Transforms transforms;
transforms.ProjMatrix = projectionMatrix;
transforms.WorldViewMatrix = worldMatrix * viewMatrix;
// Map this frame info
D3D11_MAPPED_SUBRESOURCE mappedResource;
m_D3D->GetDeviceContext()->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
memcpy_s(mappedResource.pData, sizeof(Transforms), &transforms, sizeof(transforms));
m_D3D->GetDeviceContext()->Unmap(m_matrixBuffer, 0);
// Draw the particles
m_D3D->GetDeviceContext()->DrawInstancedIndirect(g_pParticlesToRender, 0); // Check if there are enough particles in the system
}
Render Program
//--------------------------------------------------------------------------------
// Resources
//--------------------------------------------------------------------------------
cbuffer Transforms
{
matrix WorldViewMatrix;
matrix ProjMatrix;
};
cbuffer ParticleRenderParameters
{
float4 EmitterLocation;
float4 ConsumerLocation;
};
static const float scale = 0.5f;
static const float4 g_positions[4] =
{
float4(-scale, scale, 0, 0),
float4(scale, scale, 0, 0),
float4(-scale, -scale, 0, 0),
float4(scale, -scale, 0, 0),
};
static const float2 g_texcoords[4] =
{
float2(0, 1),
float2(1, 1),
float2(0, 0),
float2(1, 0),
};
struct Particle
{
float3 position;
float3 direction;
float time;
};
StructuredBuffer<Particle> SimulationState;
Texture2D ParticleTexture : register(t0);
SamplerState LinearSampler : register(s0);
//--------------------------------------------------------------------------------
// Inter-stage structures
//--------------------------------------------------------------------------------
struct VS_INPUT
{
uint vertexid : SV_VertexID;
};
//--------------------------------------------------------------------------------
struct GS_INPUT
{
float3 position : Position;
};
//--------------------------------------------------------------------------------
struct PS_INPUT
{
float4 position : SV_Position;
float2 texcoords : TEXCOORD0;
float4 color : Color;
};
//--------------------------------------------------------------------------------
GS_INPUT VSMAIN(in VS_INPUT input)
{
GS_INPUT output;
output.position.xyz = SimulationState[input.vertexid].position;
return output;
}
//--------------------------------------------------------------------------------
[maxvertexcount(4)]
void GSMAIN(point GS_INPUT input[1], inout TriangleStream<PS_INPUT> SpriteStream)
{
PS_INPUT output;
float4 color = float4(1.0f, 1.0f, 1.0f, 0.8f);
// Transform to view space
float4 viewposition = mul(float4(input[0].position, 1.0f), WorldViewMatrix);
// Emit two new triangles
for (int i = 0; i < 4; i++)
{
// Transform to clip space
output.position = mul(viewposition + g_positions[i], ProjMatrix);
output.texcoords = g_texcoords[i];
output.color = color;
SpriteStream.Append(output);
}
SpriteStream.RestartStrip();
}
//--------------------------------------------------------------------------------
float4 PSMAIN(in PS_INPUT input) : SV_Target
{
//float4 color = ParticleTexture.Sample(LinearSampler, input.texcoords);
//color = color * input.color;
float4 color = input.color;
return(color);
}
//--------------------------------------------------------------------------------