Designing a Model Format

[Very much simplified discussion. Make the answer as technical as you like.]

I’ve been living with single textured objects for a while and have decided to upgrade that portion of code. I hit a problem however when looking at how I will store Texture UV coordinates.

Imagine a model of a simple house. You would have two surfaces, Brick Walls and Tiles using a shared set or vertices and normals. However at the corners of the house you have some vertices that are shared by both surfaces.

To render the roof you supply the indices for the verts. The normals are fine because the normal array mirrors the vert array. However to supply the texture coordinate array and allow the indices to work it, it has to support all the possible indices for that surface.

The way I see it, in effect for each textured ‘part’ your model has you’ll need a separate texture array that has potentially as many elements in it as you have verts.

For example imagine now a high poly building, loads of brick poly’s withe a small number of glass polygons. Just say the glass polygons are in the 10000 rang but there are only a 100 of them. To create a texture buffer that will accept an index of 10000-10100 you’d need to waste a large chunk of space.

Am I getting this wrong? I don’t want to have to resort to a pallet texture for each game model.

Thoughts?

Chris

Each different part of the house should be one call to glDrawElements(). Store a separate array of indices into the list of vertices for each different part of the house. Also, for each part of the house, store the texture coordinates for each of the vertices that are referred to by the index array. In between calls to glDrawElements, update the memory specified in glTexCoordPointer with the proper texture coordinates for the vertices that are about to be drawn.

Hope this helps…I’m not entirely sure what you are asking here.

[This message has been edited by ioquan (edited 09-12-2002).]

>>>>>The way I see it, in effect for each textured ‘part’ your model has you’ll need a separate texture array that has potentially as many elements in it as you have verts.<<<<

No not really, you can have flags that say the object known as glass does that have associated texture coord 0 or texture coord 1.

You need to split your house model into a hierarchal form. I dont know what model format your using, but choose one that is decent.

V-man

  • I’m writing my own model format. I currently use lightwave. The model format as a file is not so much the problem, rather the in game version.

-I do use a hierarchical structure. (as follows)

I have a Model class that as a bunch of surfaces.

Much simplified Psudo:

Model
{
Vertices
Normals
Surfaces
}

Surface
{
Indices
TextureID
TextureCoordinates
}

To render:

for each Surface in model
{
SetVertices(model->Vertices)
SetNormals(model->Vertices)
SetTexCoords(Surface.TextureCoordinates)
DrawElements(Surface.Indices)
}

The problem here is that the indices provided that work fine for the verts \ normals would potentially require the texture coordinate array to be just as large, in case that surface used, say the last vert in the array. I believe the index use on the vert
ormal ex arrays is the same.

So whats the problem? Image an object with 50 textures, say a mothership. the mothership at 100,000 verts. Now I need 50 texture coordinate arrays all with 100,000 elements in it, even though a few of the texture might only be used on a single quad.

Is this true? Is there a way around this?

Just say for example the mothership has a single quad for the engine. Just say it’s indices are 100,001, 100,002, 100,003, 100,004 in the vertex array.

Now the DrawElements call is going to attempt to access the TexCoord array with these same indices isn’t it? so it’ll need an array with 100004 elements (vector2f’s) just for a single quad.

This can’t be correct…

That’s pretty wasteful.

I was suggesting that you use flags in your structure:

Object {
BOOL DoesThisObjectUseTexCoord0;
BOOL DoesThisObjectUseTexCoord1;
GLuint TextureID_Unit0;
GLuint TextureID_Unit1;
float *TexCoord_Unit0;
float *TexCoord_Unit1;
//add as many units as your engine is designed for

}

and then you enable texture_coordinate or not based on flags and you bind to texture
and call
glDrawElements per Object

Why would you want to store a set of coordinates for every single texture used by the mega_object? Break the mega_object into smaller objects and make that into a hierarchy.

The advantage of that is that texturing and other effects for mega_object are handled on a per component basis, and transform can be applied to the mega_object.

Hope that makes sense.
V-man

Ok.

From your example that means that each surface on the model, say the ‘Left Turret’ will have all the verts, texcoord and normals that it needs to render, in effect you’ll end up with a large number of redundant verts as each ‘join’ at a texture boundry will see the same vert twice.

It that right? Is this problem just a tradeoff as to what causes the smallest inefficiency?

Originally posted by gimp:
[b]Ok.

From your example that means that each surface on the model, say the ‘Left Turret’ will have all the verts, texcoord and normals that it needs to render, in effect you’ll end up with a large number of redundant verts as each ‘join’ at a texture boundry will see the same vert twice.

It that right? Is this problem just a tradeoff as to what causes the smallest inefficiency?[/b]

You were talking about storing tex coords per texture even if they never got used. Pretty wasteful if you ask me.

So to avoid the redundent vertex problem, you want to create a wasteful tex coord problem.

How do you plan on using VAR with this and other such technologies?

I dont think duplicating a small percentage of an object’s vertices will kill the graphics card. I wouldn’t worry about that.

V-man