Jump to content
  • Advertisement
Sign in to follow this  
adder_noir

Should I drop rendering 'by materialls'? Havne't a clue o)

This topic is 3010 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

Hi,

I've been doing alot of work writing my own mesh format. I've now done all that for statics only for now. I had a thought part way through that it would be so much easier to draw primitives all in one go per material for the model rather than having to stop and use the set texture command and draw primitive comand again every time you hit a new material in the mesh.

I also noticed that my Blender export used commoned vertices in the face index. Well that's no good as each triangle needs its own vertices so I ran some code through the face indices to give them each an individual identity and I made a copy of each vertex they were associated with every time they were found. So now for example instead of having:

4,0,3,
4,6,3,

It's more like

6,1,4,
7,12,5

For example. No face index appears twice in the index array now. Great. Also I ran the code like this with the new vertices array and it worked ok. So each face now has three independent vertices and three exclusive indices. It works very well.

But. I am having soooo many problems trying to get it to render by-material it's untrue. Seems if I want to draw only a portion of the mesh I have to declare every vertex in the buffer to the draw primitive command. For example for a cube with 12 triangle faces:

d3ddev->SetTexture(0, texture);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 36, 0, 12);

Works fine but:

d3ddev->SetTexture(0, texture);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 30, 0, 10);

Produces highly bizarre results. Normally one face moving totally out of dimensional relief with the others. It suggests a considerable problem with regards ordering of vertices in the vertex buffer. But I'm damned if I can find the problem.

So. What's the best thing to do here? Leave it un-sorted by material and just write an iterator loop per frame which displays the required faces and texture for whatever is present in the material array?

Or is there a a more sophisticated way of doing this altogether? Something known to the industry but not known to me at the present time? There is a very similar topic on the go right now but I can't follow it to be honest.

Any help would be appreciated. I'm not going anywhere till I've sorted out my mesh files ;o)

Share this post


Link to post
Share on other sites
Advertisement
You are close. You appear to be drawing indexed geometry, so rendering separate 'subsets' of your mesh with different materials is easy (if your index buffer is laid out correctly, which going by your example it should be).

Assuming:

- the first ten triangles in your index buffer use texture0
- the two triangles following use texture1

Then you would draw each subset like so:
d3ddev->SetTexture(0, texture0);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 36, 0, 10);
d3ddev->SetTexture(0, texture1);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 36, 30, 2);


If you haven't already, check out the section named 'Rendering from Vertex and Index Buffers' in the D3D docs, that may also help clear things up for you =)

Share this post


Link to post
Share on other sites
Ok as always seems to be the way once I take the step and risk embarassing myself on the internet by asking about a problem I'm having - I find the solution.

I still would appreciate any input offered here but I think now it's *reasonably* fair to say I've found the issue. I should have just re-shuffled the material and vertex arrays only based on material order. However I was also shuffling the face index array too, when I shouldn't have.

By shuffling the face array I've caused a bizarre disconnect to occur when rendering. Seems by shuffling the face index array by-material aswell as the others you're solving something, then shaking it up again needlessly.

I'm not explaining this well. I'll try again here:

By Materials Array
0
1
2
3
6
7
8
9
10
11
4
5

Above is how the 12 faces are ordered by material. Mat0 for 0 - 11 (excl. 4 & 5) and Mat1 for 4 & 5. What should happen now is the texcoords array should be shuffled to match it and the vertex array too. Example (rough):

newTexturesArray
0,0,1,0,1,1
0,0,1,1,0,1
0,0,1,0,1,1
0,0,1,1,0,1
0,0,1,0,0,1 - relocated to below
1,0,1,1,0,1 - relocated to below
0,0,1,0,0,1
1,0,1,1,0,1
0,0,1,0,1,1
0,0,1,1,0,1
0,0,1,0,0,1 - new position
1,0,1,1,0,1 - new position

The relocated bits show where the new position parts *were* in the old textures array. Same goes for the normals too.

BUT if you shuffle the index array too you cause problems again. I guess it might have been possible to shuffle the face index array and leave the rest alone? Not sure. Doesn't matter anyway as it's the vertices that are the most important I think. Either way but the time all this is written to a binary file it means all I have to do in DX is set one material at a time for the entire MATCOUNT I should not have to set it several times over as vertex and tex coord are lined up by material ready to go.

I'm still confused by all this tbh. I've been going so fast I've left myself behind if you know what I mean. I think with this new information - assuming it's correct - it's time to start to solidify this code and properly comment my code files and write a diary report about how it's done.

Hope that's made some sense. If anyone is interested about this please ask ;o)

Share this post


Link to post
Share on other sites
Quote:
Original post by teutonicus
You are close. You appear to be drawing indexed geometry, so rendering separate 'subsets' of your mesh with different materials is easy (if your index buffer is laid out correctly, which going by your example it should be).

Assuming:

- the first ten triangles in your index buffer use texture0
- the two triangles following use texture1

Then you would draw each subset like so:
d3ddev->SetTexture(0, texture0);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 36, 0, 10);
d3ddev->SetTexture(0, texture1);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 36, 30, 2);


If you haven't already, check out the section named 'Rendering from Vertex and Index Buffers' in the D3D docs, that may also help clear things up for you =)


Sincere apologies sir/madam I did not see this post before I replied. Please accept my apologies. That is most helpful indeed. By some miracle if you have a look at my above post I have now got it to work in this fashion:

d3ddev->SetTexture(0, texture0);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 30, 0, 10);
d3ddev->SetTexture(0, texture1);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 30, 0, 6, 0, 2);


At least it sure as hell looks like I have right now. Thanks so much for the help. I'm still very much overwhelmed by all this though and I haven't thorouhgly tested it yet so do expect more posts in the near future ;o)

Share this post


Link to post
Share on other sites
Ok I got the following 162 faced model to load with very little effort using this method.

http://img826.imageshack.us/img826/6669/gamepic.jpg

Looks like it *might* be it. My confidence is shot to pieces though after weeks of battling code from an improver's perspective :oP

All worked out well finally. I wrote a search function which returned the number of times each material appears in the sorted materials array and plugged these values into the draw primitive stuff:

void draw_cube (LPDIRECT3DTEXTURE9 texture,
LPDIRECT3DTEXTURE9 texture1)
{
d3ddev->SetTexture(0, texture1);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 120, 0, 40);

d3ddev->SetTexture(0, texture);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 120, 0, 366, 0, 122);
}


The command line prompt showed 40 repititions of mat0 and 122 repititions of mat1. Plugging those face numbers into the Draw Primitive with a * 3 factor for the vertices quantity did it no sweat. Loaded fast too!

Still feel I'm over-egging things tho. It's dawning on m that myabe ths is what the default draw subset function does. Lines things up by material for you. Get the feeling I'm re-inventing the wheel a bit. Not sure if I can use Draw Subset with a custom mesh file though. Anyways for now - it's working. For how long - well... hmmmm :o)

Hopefully this stuff will stand me in good stead when I come to render terrain.

Thanks for the help too teutonicus. I will need alot more in the future too if you can spare the time. Cheers! ;o)

Share this post


Link to post
Share on other sites
Here it is on a 4000+ face model with most importatly two textures:

http://img837.imageshack.us/img837/4594/gamepic1.jpg

All I had to do to render it was type the following:

void draw_cube (LPDIRECT3DTEXTURE9 texture,
LPDIRECT3DTEXTURE9 texture1)
{
d3ddev->SetTexture(0, texture);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 12771, 0, 4257);

d3ddev->SetTexture(0, texture1);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 12771, 0, 621, 0, 207);
}


Something's finally going my way! But for how long? This is such a deep subject ;o)

Share this post


Link to post
Share on other sites
What you are doing sounds a lot like LPD3DXMESH->OptimizeInPlace with attribute sort and vertex caching options. You might take a look at that and, if possible, load your data into a ID3DXMesh, optimize it and use DrawSubset calls.

Share this post


Link to post
Share on other sites
Sounds way better than what I'm doing right now. Thanks for the tip. Do yo think I can get my own format into this function? It's been reduced to just a set of arrays now, maybe too late?

Thanks m8 voted u up too ;o)

Share this post


Link to post
Share on other sites
Quote:
Do yo think I can get my own format into this function?

If your vertex format consists of a combination of position, normal, color, texture coordinate, etc., yes.

Not sure what your "set of arrays" contains, but, if structured properly, you may be able to create a mesh and load your data directly into the mesh's vertex/index/attribute buffers.

You should take a look at some the examples in the SDK for creating and rendering meshes. They illustate the details far better than I can.

Certainly if you have questions when you run into problems, post again.

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!