Question about hardware instancing in Directx 9.0c

Started by
3 comments, last by bignose_game 13 years, 5 months ago
In Directx sdk instancing sample, it shows how to use hardware instancing to draw many boxes.
I want to use light map for each box, but I have the problem about the additional light map texture coordinate.

This is my vertex declaration. The additional texture coordinate is in stream 2
D3DVERTEXELEMENT9 g_VertexElemHardware[] = {    {0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},    {0,3*4,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,0},    {0,6*4,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},    {1,0,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,0},    {1,4,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,1},        //texture coordinate for light map    {2,0,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,1},    D3DDECL_END()};struct BOX_VERTEX_TEXTURECOORD{	float u,v;};IDirect3DVertexBuffer9 *g_pVBBoxTextureCoordinate=0;


I fill all texture coordinate into vertex buffer "g_pVBBoxTextureCoordinate".
Each instance's light map uv are differences.
Then use "SetStreamSourceFreq" to perform hardware instancing.

    V( pd3dDevice->SetStreamSource( 0, g_pVBBox, 0, sizeof(BOX_VERTEX)) );    V( pd3dDevice->SetStreamSourceFreq( 0, D3DSTREAMSOURCE_INDEXEDDATA | g_NumBoxes ) );	//g_NumBoxes: number of box to draw            V( pd3dDevice->SetStreamSource( 1, g_pVBInstanceData, 0, sizeof( BOX_INSTANCEDATA_POS ) ) );    V( pd3dDevice->SetStreamSourceFreq( 1, D3DSTREAMSOURCE_INSTANCEDATA | 1ul ) );    V( pd3dDevice->SetIndices( g_pIBBox ) );	//set the additional light map texture coordinate	V( pd3dDevice->SetStreamSource( 2, g_pVBBoxTextureCoordinate, 0, sizeof( BOX_VERTEX_TEXTURECOORD ) ) );		//how to set the light map texture coordinate instance data?	//V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INDEXEDDATA | 1ul));	//V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INDEXEDDATA | 24ul));   //the number 24 means one box have 24 vertices	//V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INSTANCEDATA | 1ul ) );	//V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INSTANCEDATA | 24ul ) );            V( g_pEffect->SetTechnique( g_HandleTechnique ) );            V( g_pEffect->Begin( &cPasses, 0 ) );    for( iPass = 0; iPass < cPasses; iPass++ )    {        V( g_pEffect->BeginPass( iPass ) );                    V( g_pEffect->SetTexture( g_HandleTexture, g_pBoxTexture ) );        V( g_pEffect->CommitChanges() );                    V( pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 4 * 6, 0, 6 * 2 ) );                    V( g_pEffect->EndPass() );    }    V( g_pEffect->End() );


But the box still get the wrong box light map uv coordinate.
This is my code.
1.
	V( pd3dDevice->SetStreamSource( 2, g_pVBBoxTextureCoordinate, 0, sizeof( BOX_VERTEX_TEXTURECOORD ) ) );	V( pd3dDevice->SetStreamSourceFreq(2,1ul)); //all box use the first uv

2.
	V( pd3dDevice->SetStreamSource( 2, g_pVBBoxTextureCoordinate, 0, sizeof( BOX_VERTEX_TEXTURECOORD ) ) );        //do not use SetStreamSourceFreq	//all box use the first uv


3.
	V( pd3dDevice->SetStreamSource( 2, g_pVBBoxTextureCoordinate, 0, sizeof( BOX_VERTEX_TEXTURECOORD ) ) );	V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INSTANCEDATA|1ul));        //uv error


4.
	V( pd3dDevice->SetStreamSource( 2, g_pVBBoxTextureCoordinate, 0, sizeof( BOX_VERTEX_TEXTURECOORD ) ) );	V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INDEXEDDATA|24ul));        //all box use the first uv


Does anyone try to add the addition uv coordinate when using hardware instancing?
I want to use hardware instancing to draw trees, and each tree has their own light map.

Thanks!
Advertisement
[edit] how many vertices in stream2 ?

the problem with creative use of stream frequencies is that once the instance pointer for a given stream reaches the end - you get random data coming back

there isn't much useful you can do beyond standard instancing

which is really annoying - if the pointers simply wrapped back to 0
it would open up a whole world of multiple instancing techniques

either put the texcoord into the stream0 vertex buffer
or put it in a texture and read it with vtf

the best pattern I found for instancing is to use an instance data texture
which is incrementally updated by flushing an update queue using dup

diagram of what I mean

0a01a12a20b*1b*2b*


* = junk
To skytiger:

How many vertices in stream2 ?
=> Stream 2 is the light map texture coordinate. The total number of vertices is (Box's total vertices)*(Box instance number).

the problem with creative use of stream frequencies is that once the instance pointer for a given stream reaches the end - you get random data coming back
=>Does it mean that I can't use "SetStreamSourceFreq" with difference frequency at the same time?

Thanks a lot!
I don't think it is possible to do this:

0 a 00
1 a 01
2 a 02
0 a 03
2 a 04
3 a 05
0 b 06
1 b 07
2 b 08
0 b 09
2 b 10
3 b 11

you will either get this:

0 a 00
1 a 01
2 a 02
0 a 00
2 a 02
3 a 03
0 b 00
1 b 01
2 b 02
0 b 00
2 b 02
3 b 03

or this:

0 a 00
1 a 00
2 a 00
0 a 00
2 a 00
3 a 00
0 b 01
1 b 01
2 b 01
0 b 01
2 b 01
3 b 01

neither of which helps you

your choice for each stream is:

- don't set frequency
- set index frequency
- set instance frequency

which will result in:

- don't set frequency
- set index frequency
your second vertex buffer will be indexed :-(

- set instance frequency
your second vertex buffer will be repeated :-(

on xbox360 it would be easy using vfetch

you could store you texture coordinates in a texture
and read the with Vertex Texture Fetch
you will have enough information to calculate the offsets
I will use vtf instruction to get the texture coordinate
Thanks a lot!

This topic is closed to new replies.

Advertisement