In most games, each of these materials is split up into itâs own drawcall, so thatâs one glDrawElements per material.
There are various ways to optimize this.
One aspect is to only bind shader programs when needed, for example when two materials have the same shader/material with only textures differing.
Another big part involves how you structure your VBOs. For example you can create one VBO+IBO per material. This may be beneficial for example when a certain material/shader requires vertex colors, but another material on the same model doesnât require it and/or have different vertex attributes (tangents, multiple UV channels). Conversely, sometimes it is more efficient (performance wise) to create one VBO for the whole model, and have multiple IBOs per material, so you donât have to switch between VBOs.
In other situations you may want to interleave attributes, which complicates the above.
Then thereâs âatlassesâ, a technique in which you combine textures/materials onto a single one large sheet and let a complex shader do the work to sort out which polygons should have what texture/material properties (only try this if you know what you are doing).
So it really depends on what you want to do, what kind of geometry data you have (what vertex attributes, and how much) , how different your shader/materials are, and what you demand of performance. So the only accurate answer is: âit dependsâ.
Personally, I prefer simplicity, and create one VBO+IBO for each group of polygons that have the same material, as this can be nicely abstracted with classes, and is easy to write exporter tools for, ease of file parsing etc.
Pseudo code (read from bottom up):
// texture class
class CTexture
{
GLuint tex; // GL texture handle
bool generateMipmaps; // texture properties
// etc
bool Load(char *filename);
void Bind(int texunit);
}
// shader class
class CShader
{
GLuint program; // GL shader program handle
int uniformDiffuseLoc; // uniform location handles
int uniformAmbientLoc; // ...
// etc
bool Load(char *filename);
void Bind();
}
// material definition (could be authored and stored in text files)
class CMaterial
{
CTexture *diffuseTex; // points to a diffuse texture class
CTexture *normalTex; // points to a normal map texture class
CShader *shader; // points to a shader class instance
GLfloat diffuse[4]; // holds uniform diffuse color value
GLfloat ambient[3]; // holds uniform ambient color value
GLfloat alphaTest; // alpha test cutoff
// etc
void Bind();
}
// contains a group of polygons with same
class CMeshLODMat
{
CMaterial *material; // pointer to material class
int numVerts; // number of vertices in VBO
int numElements; // i.e. number of triangles*3
bool hasNormals; // ...
vec3 vert[]; // vertex array read from file
vec3 norm[]; // vertex normal array read from file
vec2 texc[]; // texture coordinate array
ushort index[]; // index array
GLuint vbo; // GL handle to VBO constructed from the above
GLuint ibo; // GL handle to IBO constructed from the above
bool ReadChunk(FILE *f);
void Draw();
}
// contains geometry for a model with different materials
class CMeshLOD
{
int matNum; // number of materials on model
CMeshLODMat mat[]; // LOD material class array
bool ReadChunk(FILE *f); // reads part of model file
void Draw();
}
// contains array of models with different Levels Of Detail (LOD)
class CMesh
{
int lodNum; // number of LOD levels
CMeshLOD lod[]; // array of LODs
bool Load(char *filename); // loads a model from file
void Draw();
}
Iâm also obliged to warn you that .3ds is a terrible format, due to complexity and simply broken data storage. Attributes such as vertex colors, texture coordinates and vertex normals are subjected to data corruption in certain (but very common) conditions. Look at WaveFront/OBJ for a more elegant interchange format, but avoid the 3dsmax OBJ exporter like the pest; it is dysfunctional at best and writes unnecessarily large and messy files.
It is not that difficult to write MEL/MAX/PYTHON scripts to export data from your favorite modeling package, and will probably give you far more simpler, efficient and flexibility than any other asset interchange format in the long run (forget XML/COLLADA) if it is only a small to medium size project such as a game.
Good luck, I hope that gives you some ideas.