//---------------------------------------------------------------------------- // Title: How to fake DX10 instancing on DX9 hardware // // Author: Ivica Kolic // E-mail: Ivica.Kolic@gmail.com // // Copyright (c) Ivica Kolic. All rights reserved. // // Description: Code shows how to consturct DX9 alternative for // DX10's "uint idx:SV_InstanceID" which is used for instancing. // //---------------------------------------------------------------------------- // GLOBAL VARIABLES: LPDIRECT3DVERTEXBUFFER9 _pInstanceVertexBuffer; // Konstant vertex buffer used for instancing LPDIRECT3DVERTEXDECLARATION9 _pVertexDeclaration; // Vertex declaration enriched with instancing index LPDIRECT3DDEVICE9 _d3dDevice; // Rendering device // SAMPLE OF VERTEX DECLARATION: const D3DVERTEXELEMENT9 vertexElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {1, 0, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1}, // This comes from instancing D3DDECL_END() }; _d3dDevice->CreateVertexDeclaration( vertexElements, &_pVertexDeclaration ); // SETTING UP INSTANCING VERTEX BUFFER (CONSTANT): float instanceVertices[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f }; _d3dDevice->CreateVertexBuffer( sizeof(instanceVertices), 0, 0, D3DPOOL_DEFAULT, &_pInstanceVertexBuffer, NULL ); void* pVertices; _pInstanceVertexBuffer->Lock(0, sizeof(instanceVertices), &pVertices, 0); memcpy(pVertices, instanceVertices, sizeof(instanceVertices)); _pInstanceVertexBuffer->Unlock(); // RENDERING (_iNumberOfInstances times): _pd3dDevice9->SetVertexDeclaration(_pVertexDeclaration); _pd3dDevice9->SetStreamSource(1, _pInstanceVertexBuffer, 0, sizeof(float)); _pd3dDevice9->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | _iNumberOfInstances)); _pd3dDevice9->SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1)); RenderGeometry(); // this will set stream source 0 and indices... // Shut down instancing after rendering is done: _pd3dDevice9->SetStreamSourceFreq(0,1); _pd3dDevice9->SetStreamSourceFreq(1,1); // SHADER PART: struct VS_P_N_T { float4 pos : POSITION; float3 normal : NORMAL; float2 tex : TEXCOORD0; float idx : TEXCOORD1; // idx comes from instancing vertex buffer filled with constants: 0, 1, 2, 3, 4, 5, 6, 7. }; // "float idx : TEXCOORD1" is replacement for DX10's "uint idx:SV_InstanceID"