Jump to content
  • Advertisement
Sign in to follow this  
active_vertex

Batching [ SOLVED ]

This topic is 3719 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
Advertisement
If you want to batch meshes, I suggest you look into instancing. There's an example in the SDK.

Share this post


Link to post
Share on other sites
You might want to take a look at the SDK sample for instancing boxes.
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
thank you ..

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!!

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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





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]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!