diff --git a/src/effect/static.fx b/src/effect/static.fx index 3846deb..a6daccf 100644 --- a/src/effect/static.fx +++ b/src/effect/static.fx @@ -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); } diff --git a/src/main.cpp b/src/main.cpp index be82586..6d945ae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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); diff --git a/src/print.cpp b/src/print.cpp index a3ed138..0561030 100644 --- a/src/print.cpp +++ b/src/print.cpp @@ -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 }