Search code examples
opengltexturestexturing

OpenGL - Different textures on different surfaces of the same object


I'm trying to draw a car for a game I'm making using OpenGL. The car object is stored in an .obj file with an accompanying .mtl file.

The car has 500+ vertices, 100+ faces and needs over 50 different textures applied to them, using my own vertex and fragment shader. I've gone about this by using buffer objects, which sends all information about my object at once. My problem is trying to apply different textures to different surfaces of the same object.

The answers I've found to this problem are to bind a texture to a certain texture number (i.e. GL_TEXTURE0, GL_TEXTURE1, etc...) and pass in a Sampler2D to the fragment shader referencing it. However, can I store over 50 textures in this way? As far as I can tell it goes to GL_TEXTURE32.

Also, how would I tell the shader to only apply a texture to a certain face of the car object?


Solution

  • You cannot render the model this way, where you bind all the textures at once. A fragment shader, even for high-end GL 4.1-class hardware, can only access 16 textures. That is, it can only have 16 samplers.

    The total texture count is higher because other shader stages can use textures as well.

    The correct way to deal with it is to do one of the following:

    1. Return to your modeller and have them reduce the texture count of the model.
    2. Have a tool build a texture atlas (ie: put all of the images into a single texture), changing the model's texture coordinates appropriately. Depending on the hardware you plan to support, this can be a large 2D texture or a 2D texture array. The latter will require a 3rd value for the texture coordinate: the index of the image in the array.
    3. Sort the triangles by texture. For each texture, render all of the triangles that use that texture.

    #3 is the only solution that doesn't require changing data. But be warned: if you render this car often (say, thousands of times per frame) the state change overhead can be a performance issue. Some combination of #1 and #2 is the generally preferred method.

    BTW, if your model only has a few hundred faces, but 50 textures, then it's likely something went horribly wrong in the modelling process.