draw instanced cubes

This commit is contained in:
Zack Buhman 2026-01-13 18:00:11 -06:00
parent 9449f3f4d7
commit efa08063c0
3 changed files with 163 additions and 48 deletions

View File

@ -11,6 +11,7 @@ struct VS_INPUT_INSTANCED
float3 Normal : NORMAL;
float2 Tex : TEXCOORD0;
row_major float4x4 mTransform : mTransform;
uint InstanceID : SV_InstanceID;
};
struct PS_INPUT
@ -54,17 +55,6 @@ PS_INPUT VS(VS_INPUT input)
return output;
}
PS_INPUT VSInstanced(VS_INPUT_INSTANCED input)
{
VS_INPUT input_vs = (VS_INPUT)0;
input_vs.Pos = mul(input.Pos, input.mTransform);
input_vs.Normal = input.Normal;
input_vs.Tex = input.Tex;
return VS(input_vs);
}
PS_OUTPUT PS(PS_INPUT input)
{
PS_OUTPUT output;
@ -73,6 +63,23 @@ PS_OUTPUT PS(PS_INPUT input)
return output;
}
PS_INPUT VSInstanced(VS_INPUT_INSTANCED input)
{
VS_INPUT input_vs = (VS_INPUT)0;
input_vs.Pos = mul(float4(input.Pos.xyz, 1), input.mTransform);
//input_vs.Pos = float4(input.Pos.xyz, 1) + float4(0, input.InstanceID * 3, 0, 0);
input_vs.Normal = input.Normal;
input_vs.Tex = input.Tex;
return VS(input_vs);
}
float4 PSInstanced(PS_INPUT input) : SV_TARGET0
{
return float4(1, 1, 1, 1);
}
BlendState DisableBlending
{
BlendEnable[0] = FALSE;
@ -102,7 +109,7 @@ technique10 StaticInstanced
{
SetVertexShader(CompileShader(vs_4_0, VSInstanced()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0, PS()));
SetPixelShader(CompileShader(ps_4_0, PSInstanced()));
SetBlendState(DisableBlending, float4(0.0, 0.0, 0.0, 0.0), 0xffffffff);
SetDepthStencilState(EnableDepth, 0);
}

View File

@ -95,6 +95,7 @@ ID3D10Effect * g_pEffectStatic = NULL;
ID3D10EffectTechnique * g_pTechniqueStatic = NULL;
ID3D10EffectTechnique * g_pTechniqueStaticInstanced = NULL;
ID3D10InputLayout * g_pVertexLayoutStatic = NULL;
ID3D10InputLayout * g_pVertexLayoutStaticInstanced = NULL;
ID3D10EffectMatrixVariable * g_pWorldVariableStatic = NULL;
ID3D10EffectMatrixVariable * g_pViewVariableStatic = NULL;
@ -102,6 +103,10 @@ ID3D10EffectMatrixVariable * g_pProjectionVariableStatic = NULL;
ID3D10EffectMatrixVariable * g_pWorldNormalVariableStatic = NULL;
ID3D10EffectVectorVariable * g_pOutputColorVariableStatic = NULL;
// instance data
ID3D10Buffer * g_pVolumeMeshInstanceData = NULL;
const int g_iNumVolumeMeshInstances = 8;
// cube
const DWORD g_dwVertexBufferCountCube = 3;
ID3D10Buffer * g_pVertexBufferCube[g_dwVertexBufferCountCube];
@ -746,27 +751,57 @@ HRESULT InitStaticEffect()
g_pTechniqueStatic = g_pEffectStatic->GetTechniqueByName("Static");
g_pTechniqueStaticInstanced = g_pEffectStatic->GetTechniqueByName("StaticInstanced");
//////////////////////////////////////////////////////////////////////
// layout
//////////////////////////////////////////////////////////////////////
D3D10_INPUT_ELEMENT_DESC layout[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 2, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
};
UINT numElements = (sizeof (layout)) / (sizeof (layout[0]));
// static
{
D3D10_INPUT_ELEMENT_DESC layout[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 2, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
};
UINT numElements = (sizeof (layout)) / (sizeof (layout[0]));
D3D10_PASS_DESC passDesc;
g_pTechniqueStatic->GetPassByIndex(0)->GetDesc(&passDesc);
D3D10_PASS_DESC passDesc;
g_pTechniqueStatic->GetPassByIndex(0)->GetDesc(&passDesc);
hr = g_pd3dDevice->CreateInputLayout(layout, numElements,
passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize,
&g_pVertexLayoutStatic);
if (FAILED(hr)) {
print("CreateInputLayout\n");
return hr;
hr = g_pd3dDevice->CreateInputLayout(layout, numElements,
passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize,
&g_pVertexLayoutStatic);
if (FAILED(hr)) {
print("CreateInputLayout\n");
return hr;
}
}
// static instanced
{
D3D10_INPUT_ELEMENT_DESC layout[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 2, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
{"mTransform", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 3, 0 , D3D10_INPUT_PER_INSTANCE_DATA, 1},
{"mTransform", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 3, 16, D3D10_INPUT_PER_INSTANCE_DATA, 1},
{"mTransform", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 3, 32, D3D10_INPUT_PER_INSTANCE_DATA, 1},
{"mTransform", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 3, 48, D3D10_INPUT_PER_INSTANCE_DATA, 1},
};
UINT numElements = (sizeof (layout)) / (sizeof (layout[0]));
D3D10_PASS_DESC passDesc;
g_pTechniqueStaticInstanced->GetPassByIndex(0)->GetDesc(&passDesc);
hr = g_pd3dDevice->CreateInputLayout(layout, numElements,
passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize,
&g_pVertexLayoutStaticInstanced);
if (FAILED(hr)) {
print("CreateInputLayout\n");
return hr;
}
}
//////////////////////////////////////////////////////////////////////
@ -782,6 +817,61 @@ HRESULT InitStaticEffect()
return S_OK;
}
HRESULT InitInstancedVertexBuffer()
{
HRESULT hr;
//////////////////////////////////////////////////////////////////////
// vertex buffers
//////////////////////////////////////////////////////////////////////
D3D10_BUFFER_DESC bd;
// mTransform
bd.Usage = D3D10_USAGE_DYNAMIC;
bd.ByteWidth = (sizeof (XMMATRIX)) * g_iNumVolumeMeshInstances;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
hr = g_pd3dDevice->CreateBuffer(&bd, NULL, &g_pVolumeMeshInstanceData);
if (FAILED(hr)) {
print("CreateBuffer\n");
return hr;
}
//////////////////////////////////////////////////////////////////////
// vertex buffer data
//////////////////////////////////////////////////////////////////////
FontVertex * pData;
hr = g_pVolumeMeshInstanceData->Map(D3D10_MAP_WRITE_DISCARD,
0,
(void **)&pData);
if (FAILED(hr)) {
print("g_pVolumeMeshInstanceData->Map");
}
float offset = 4.0f;
XMMATRIX transforms[8] = {
XMMatrixTranslation( offset, offset, offset),
XMMatrixTranslation( offset, -offset, offset),
XMMatrixTranslation(-offset, -offset, offset),
XMMatrixTranslation(-offset, offset, offset),
XMMatrixTranslation( offset, offset, -offset),
XMMatrixTranslation( offset, -offset, -offset),
XMMatrixTranslation(-offset, -offset, -offset),
XMMatrixTranslation(-offset, offset, -offset),
};
memcpy(pData, transforms, (sizeof (XMMATRIX)) * g_iNumVolumeMeshInstances);
g_pVolumeMeshInstanceData->Unmap();
return S_OK;
}
HRESULT LoadMeshStatic(const Mesh * mesh)
{
HRESULT hr;
@ -1026,6 +1116,12 @@ HRESULT InitDirect3DDevice()
return hr;
}
hr = InitInstancedVertexBuffer();
if (FAILED(hr)) {
print("InitInstancedVertexBuffer\n");
return hr;
}
//////////////////////////////////////////////////////////////////////
// transform matrices
//////////////////////////////////////////////////////////////////////
@ -1033,8 +1129,8 @@ HRESULT InitDirect3DDevice()
g_World1 = XMMatrixIdentity();
g_World2 = XMMatrixIdentity();
XMVECTOR Eye = XMVectorSet(0.0f, 1.0f, -2.0f, 0.0f);
XMVECTOR At = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMVECTOR Eye = XMVectorSet(0.0f, 0.0f, -2.0f, 0.0f);
XMVECTOR At = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
g_View = XMMatrixLookAtLH(Eye, At, Up);
@ -1329,12 +1425,13 @@ static inline int sprint(LPCSTR fmt, ...)
void RenderFont()
{
HRESULT hr;
//////////////////////////////////////////////////////////////////////
// dynamic vertex buffer
//////////////////////////////////////////////////////////////////////
FontVertex * pData;
HRESULT hr;
hr = g_pVertexBuffersFont[0]->Map(D3D10_MAP_WRITE_DISCARD,
0,
(void **)&pData);
@ -1538,38 +1635,49 @@ void RenderVolume(float t)
void RenderVolumeMesh()
{
const Mesh * mesh = cube::node_0.mesh;
int indices_length = mesh->indices_size / (sizeof (DWORD));
int index_count_per_instance = mesh->indices_size / (sizeof (DWORD));
g_pViewVariableStatic->SetMatrix((float *)&g_View);
g_pProjectionVariableStatic->SetMatrix((float *)&g_Projection);
ID3D10Buffer * pVB[4] = {
g_pVertexBufferCube[0],
g_pVertexBufferCube[1],
g_pVertexBufferCube[2],
g_pVolumeMeshInstanceData,
};
UINT stride[] = {
(sizeof (mesh->position[0])),
(sizeof (mesh->normal[0])),
(sizeof (mesh->texcoord_0[0])),
(sizeof (XMMATRIX)),
};
UINT offset[] = { 0, 0, 0 };
g_pd3dDevice->IASetInputLayout(g_pVertexLayoutStatic);
g_pd3dDevice->IASetVertexBuffers(0, g_dwVertexBufferCountCube, g_pVertexBufferCube, stride, offset);
UINT offset[] = { 0, 0, 0, 0 };
g_pd3dDevice->IASetInputLayout(g_pVertexLayoutStaticInstanced);
g_pd3dDevice->IASetVertexBuffers(0, 4, pVB, stride, offset);
g_pd3dDevice->IASetIndexBuffer(g_pIndexBufferCube, DXGI_FORMAT_R32_UINT, 0);
g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D10_TECHNIQUE_DESC techDesc;
g_pTechniqueStatic->GetDesc(&techDesc);
g_pTechniqueStaticInstanced->GetDesc(&techDesc);
XMMATRIX mWorldScale = XMMatrixScaling(0.2f, 0.2f, 0.2f);
XMMATRIX mWorldTranslate = XMMatrixTranslation(0.5f, 0.5f, 0.5f);
XMMATRIX mWorldTranslate = XMMatrixTranslation(0.0f, 0.0f, 1.5f);
XMMATRIX mWorld = mWorldScale * mWorldTranslate;
g_pWorldVariableStatic->SetMatrix((float *)&mWorld);
XMMATRIX mWorldNormal = XMMatrixIdentity();
g_pWorldNormalVariableStatic->SetMatrix((float *)&mWorldNormal);
XMVECTOR vColor = XMVectorSet(0.0f, 0.9f, 0.0f, 1.0f);
XMVECTOR vColor = XMVectorSet(0.0f, 0.4f, 0.3f, 1.0f);
g_pOutputColorVariableStatic->SetFloatVector((float *)&vColor);
int instance_count = g_iNumVolumeMeshInstances;
for (UINT p = 0; p < techDesc.Passes; p++) {
g_pTechniqueStatic->GetPassByIndex(p)->Apply(0);
g_pd3dDevice->DrawIndexed(indices_length, 0, 0);
g_pTechniqueStaticInstanced->GetPassByIndex(p)->Apply(0);
g_pd3dDevice->DrawIndexedInstanced(index_count_per_instance,
instance_count,
0, 0, 0);
}
}
@ -1606,7 +1714,7 @@ void Render()
//RenderBloom();
//print("%f\n", t);
//RenderVolume(t);
//RenderVolumeMesh();
RenderVolumeMesh();
// present
g_pSwapChain->Present(0, 0);

View File

@ -19,10 +19,10 @@ void print(LPCSTR fmt, ...)
args);
va_end(args);
#ifdef _DEBUG
//OutputDebugStringA(buf);
size_t length = end - &buf[0];
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleA(hOutput, buf, (DWORD)length, NULL, NULL);
OutputDebugStringA(buf);
//size_t length = end - &buf[0];
//HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//WriteConsoleA(hOutput, buf, (DWORD)length, NULL, NULL);
#endif
}
@ -42,9 +42,9 @@ void printW(LPCWSTR fmt, ...)
args);
va_end(args);
#ifdef _DEBUG
//OutputDebugStringW(buf);
size_t length = end - &buf[0];
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleW(hOutput, buf, (DWORD)length, NULL, NULL);
OutputDebugStringW(buf);
//size_t length = end - &buf[0];
//HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//WriteConsoleW(hOutput, buf, (DWORD)length, NULL, NULL);
#endif
}