Batching [ SOLVED ]
Can anyone please help me or direct me on how to batching..?
I was doing this but with no success
1-loading a simple tree mesh =+150 vertices
2-optemize the mesh, all mesh optimize flags were used for..
3-generate attribute table
4-fill arrayed vertex buffer and index buffer from the generated attributes
5-looping to draw the arrayed indexed primitives, to apply materials and textures to each Array buffers
The result is an extreme mutant batch.. looks like martian trees
Ive used all the optimization flags but the attribute table still look random
Is it the right way to batching? Is there some article shows how?
Any help will be appreciated.
[Edited by - active_vertex on July 15, 2008 10:29:03 PM]
You might want to take a look at the SDK sample for instancing boxes.
That's a problem. You need to decide what you want to optimize for.
If your primary concern is changing materials, use ATTRSORT (alone). If you're using a single vertex buffer for all the trees, it's likely you don't need VERTEXCACHE. Using ATTRSORT and VERTEXCACHE together is a compromise.
If you use ATTRSORT alone, you'll end up with an attribute buffer something like ( 0,0,0,1,1,1,1,1,2,2,3,3,3,...) which may be more what you're looking for.
Also, if you have similar materials for each attribute group and changing textures is a concern, consider creating a texture atlas, a single texture created from multiple textures, and adjust the texture coordinates of your vertices to pick out the section of the single texture as required. That will reduce the number of attribute groups.
I can't tell from your description, but, if you're loading multiple copies of the vertices and applying different materials to each instance, that's not really "batching." That's just drawing lots of polys.
If you're using DX10, hardware instancing with a shader (see the SDK example) can be very efficient. Even in DX9 doing position array instancing using a shader will be much faster than the FFP.
Quote:all mesh optimize flags were used
That's a problem. You need to decide what you want to optimize for.
If your primary concern is changing materials, use ATTRSORT (alone). If you're using a single vertex buffer for all the trees, it's likely you don't need VERTEXCACHE. Using ATTRSORT and VERTEXCACHE together is a compromise.
If you use ATTRSORT alone, you'll end up with an attribute buffer something like ( 0,0,0,1,1,1,1,1,2,2,3,3,3,...) which may be more what you're looking for.
Also, if you have similar materials for each attribute group and changing textures is a concern, consider creating a texture atlas, a single texture created from multiple textures, and adjust the texture coordinates of your vertices to pick out the section of the single texture as required. That will reduce the number of attribute groups.
I can't tell from your description, but, if you're loading multiple copies of the vertices and applying different materials to each instance, that's not really "batching." That's just drawing lots of polys.
If you're using DX10, hardware instancing with a shader (see the SDK example) can be very efficient. Even in DX9 doing position array instancing using a shader will be much faster than the FFP.
Quote:If your primary concern is changing materials, use ATTRSORT (alone). If you're using a single vertex buffer for all the trees, it's likely you don't need VERTEXCACHE. Using ATTRSORT and VERTEXCACHE together is a compromise.
Yes that’s what I was doing,
Ok I will show you how I'am doing it
1 ..
loading a mesh with one subset, considering a cube mesh with position/normal/texture vertex format
after extracting the mesh’s vertex, index buffer then duplicate the data
as much as 150,000 times into batch buffer I could get 50fps and that’s much faster
believe it or not than the hardware instancing :-), here I used the atlas way for the textures
but it won’t work for materials because it will be applied to the whole batch
2..
loading the same mesh with multiple subsets, and that’s how I want to do it
I want to extract each subset’s vertices and indices
duplicate each vertices/indices in arrayed batch buffer , so I can loop through the array
to apply textures/materials but what I get from the attribute tables are so random
am I doing it right??
I’am considering the hard ware instancing. But not all adapters support vs3
[Edited by - active_vertex on July 14, 2008 2:17:11 PM]
Quote:am I doing it right?
Can't really tell without seeing the code. However, if you don't get the attribute arrangement you want, then no, you're not doing it right. [smile]
1. Load a multiple-attribute mesh.
2. Optimize (or OptimizeInPlace) with D3DXMESHOPT_ATTRSORT only. You should end up with an attribute buffer arranged with all faces with attrib=0, then all faces with attrib=1, etc., in order.
Just checking: you have to Optimize before you can get a valid attribute table.
Quote:I’am considering the hard ware instancing. But not all adapters support vs3
Yeah, that's a pain. Using array instancing with a VS 2_0 shader, instead, is little better than what you're doing.
Have you considered using a second stream source for the materials?
thank you ..
Theoretically for simplification..
Consider this quad
+z
..__________________
.6|......7/|.....8/|
..|....D/..|...E/..|
..|.../....|../....|
.3|./.....4|/.....5|
-x|________________|+x
..|......./|....../|
..|....A/..|...C/..|
..|.../....|../....|
.0|./.....1|/.....2|
..__________________
-z
4 Subsets .. a,b,c and d
8 faces
9 vertices .. 0 to 8
this is the xfile data..
Mesh {
9;
-0.500000;0.000000;-0.500000;,
0.000000;0.000000;-0.500000;,
0.500000;0.000000;-0.500000;,
-0.500000;0.000000;0.000000;,
0.000000;0.000000;0.000000;,
0.500000;0.000000;0.000000;,
-0.500000;0.000000;0.500000;,
0.000000;0.000000;0.500000;,
0.500000;0.000000;0.500000;;
8;
3;3,4,0;,
3;1,0,4;,
3;4,5,1;,
3;2,1,5;,
3;6,7,3;,
3;4,3,7;,
3;7,8,4;,
3;5,4,8;;
}
this what I'am doing
1:load mesh
2:mesh->optimize: attribute sort | vertex cache
3:mesh->get attribute table
4:create array[attribute count] vertex buffer , index buffer
5:BEGIN LOOP till < attribute count
6:mesh->lock vertex buffer at vertex start to fill as much as vertex count
7:mesh->lock index buffer at face start to fill as much as indices count
8:copy date into vertex buffer[count]
9:copy data into index buffer[count]
10:END LOOP
11:sorting and duplication(fill visible trees/clouds/terrains/particles from front to back)
reading data from stream i get this..
vertices..
-0.5;0.0;0.5
0.0;0.0;0.5
-0.5;0.0;0.0
0.0;0.0;0.0
-0.5;0.0;-0.5
0.0;0.0;-0.5
0.5;0.0;0.0
0.5;0.0;-0.5
0.5;0.0;0.5
indices..
0;1;2
3;2;1
2;3;4
5;4;3
3;6;5
7;5;6
1;8;3
6;3;8
it doesn’t make any sense to me!!
Quote: Can't really tell without seeing the code
Theoretically for simplification..
Consider this quad
+z
..__________________
.6|......7/|.....8/|
..|....D/..|...E/..|
..|.../....|../....|
.3|./.....4|/.....5|
-x|________________|+x
..|......./|....../|
..|....A/..|...C/..|
..|.../....|../....|
.0|./.....1|/.....2|
..__________________
-z
4 Subsets .. a,b,c and d
8 faces
9 vertices .. 0 to 8
this is the xfile data..
Mesh {
9;
-0.500000;0.000000;-0.500000;,
0.000000;0.000000;-0.500000;,
0.500000;0.000000;-0.500000;,
-0.500000;0.000000;0.000000;,
0.000000;0.000000;0.000000;,
0.500000;0.000000;0.000000;,
-0.500000;0.000000;0.500000;,
0.000000;0.000000;0.500000;,
0.500000;0.000000;0.500000;;
8;
3;3,4,0;,
3;1,0,4;,
3;4,5,1;,
3;2,1,5;,
3;6,7,3;,
3;4,3,7;,
3;7,8,4;,
3;5,4,8;;
}
this what I'am doing
1:load mesh
2:mesh->optimize: attribute sort | vertex cache
3:mesh->get attribute table
4:create array[attribute count] vertex buffer , index buffer
5:BEGIN LOOP till < attribute count
6:mesh->lock vertex buffer at vertex start to fill as much as vertex count
7:mesh->lock index buffer at face start to fill as much as indices count
8:copy date into vertex buffer[count]
9:copy data into index buffer[count]
10:END LOOP
11:sorting and duplication(fill visible trees/clouds/terrains/particles from front to back)
reading data from stream i get this..
vertices..
-0.5;0.0;0.5
0.0;0.0;0.5
-0.5;0.0;0.0
0.0;0.0;0.0
-0.5;0.0;-0.5
0.0;0.0;-0.5
0.5;0.0;0.0
0.5;0.0;-0.5
0.5;0.0;0.5
indices..
0;1;2
3;2;1
2;3;4
5;4;3
3;6;5
7;5;6
1;8;3
6;3;8
it doesn’t make any sense to me!!
Quote:2:mesh->optimize: attribute sort | vertex cache
Like I said before, if you combine attribute sorting and vertex caching, you won't get a straight attribute sort, which I think is what you want.
The vertex cache option for optimization tells the optimization routine to arrange the vertex buffer for efficiency, which it will do, perhaps compromising the attribute sorting. You're going to setup another vertex buffer for the way you want to be efficient, so use D3DXMESHOPT_ATTRSORT only!
Quote:Like I said before, if you combine attribute sorting and vertex caching, you won't get a straight attribute sort, which I think is what you want.
The vertex cache option for optimization tells the optimization routine to arrange the vertex buffer for efficiency, which it will do, perhaps compromising the attribute sorting. You're going to setup another vertex buffer for the way you want to be efficient, so use D3DXMESHOPT_ATTRSORT only!
thank you a lot and i really appreciate your helpful replys..
ok like i said before ,I’ve tried all optimization flags but that seems not working at
all, with attribute sort its working with vertices but not indices
Anyhow i finally managed to do it, extracted the vertices from the optimized mesh and indices from the original
_IndexBuffer[0] has subset A indices...._IndexBuffer[3] has subset D indices
_VertexBuffer[0] has subset A vertices.... _VertexBuffer[3] has subset D vertices
is that legal??? Because drawindexedprimitives is drawing nothing
Quote:extracted the vertices from the optimized mesh and indices from the original..is that legal??
Nope.
With the Optimize call, you've asked for the mesh to be rearranged. You should be using both the vertices and the indices from the optimized mesh.
If the attribute table entries indicate a successful attribute sort, then the problem is elsewhere.
EDIT:
Suggestion - post some of your actual code. You can use
[ source ]
your code
[ \source ]
(leaving out any spaces between the square brackets) to save a bit of screen space.
slimdx version..
you are right, I guess i know where is the problem
when i get the subset vertex buffer (4 vertices) each
the indices are like [6,7,4..4,3,7] it must be[0,3,4..4,1,0]
that’s when i use the optimized mesh for vertices and the original for indices
but when using the optimized for indices the result is messy
[Edited by - active_vertex on July 15, 2008 1:48:21 PM]
you are right, I guess i know where is the problem
when i get the subset vertex buffer (4 vertices) each
the indices are like [6,7,4..4,3,7] it must be[0,3,4..4,1,0]
that’s when i use the optimized mesh for vertices and the original for indices
but when using the optimized for indices the result is messy
Mesh _TmpMesh = _Mesh.Optimize(MeshOptimizeFlags.AttributeSort);_AttributeRange = _TmpMesh.GetAttributeTable();_VertexBuffer = new VertexBuffer[_AttributeRange.Length];_IndexBuffer = new IndexBuffer[_AttributeRange.Length]; for (int i = 0; i < _AttributeRange.Length; i++) { //////////////////////////////////////////////////////////////////////// // Get Mesh subsets Vertex buffer //////////////////////////////////////////////////////////////////////// _VertexBuffer = new VertexBuffer(Engine.Device, _AttributeRange.VertexCount * Vertex.SizeInByte, Usage.Dynamic | Usage.WriteOnly, _TmpMesh.VertexBuffer.Description.FVF, Pool.Default); using (DataStream ds = _TmpMesh.VertexBuffer.Lock(_AttributeRange.VertexStart * Vertex.SizeInByte, _AttributeRange.VertexCount * Vertex.SizeInByte, LockFlags.ReadOnly)) { _Vertex = ds.ReadRange<Vertex>((int)ds.Length); _TmpMesh.VertexBuffer.Unlock(); } using (DataStream ds = _VertexBuffer.Lock(0, 0, LockFlags.Discard)) { ds.WriteRange<Vertex>(_Vertex); _VertexBuffer.Unlock(); } _Vertex = null; //////////////////////////////////////////////////////////////////////// // Get Mesh subsets Index buffer (32bits) //////////////////////////////////////////////////////////////////////// _IndexBuffer = new IndexBuffer(Engine.Device, _AttributeRange.FaceCount * 3 * 4, Usage.Dynamic | Usage.WriteOnly, Pool.Default, false); using (DataStream ds = _TmpMesh.IndexBuffer.Lock(_AttributeRange.FaceStart * 3 * 4, _AttributeRange.FaceCount * 3 * 4, LockFlags.ReadOnly)) { _Index = ds.ReadRange<uint>((int)ds.Length); _Mesh.IndexBuffer.Unlock(); } using (DataStream ds = _IndexBuffer.Lock(0, 0, LockFlags.Discard)) { ds.WriteRange<uint>(_Index); _IndexBuffer.Unlock(); } _Index = null; }
[Edited by - active_vertex on July 15, 2008 1:48:21 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement