1
votes

I am trying to optimize drawing a cube with 3 different textures. An effect I want to achieve is:

enter image description here

What I am doing now is drawing cube using three Draw() calls:

            graphicsDevice.Textures[0] = cube.frontTexture;
            graphicsDevice
                .DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
                    36, 0, 2);

            graphicsDevice.Textures[0] = cube.backTexture;
            graphicsDevice
                .DrawIndexedPrimitives(PrimitiveType.TriangleList, 6, 0,
                    30, 0, 2);

            graphicsDevice.Textures[0] = cube.sideTexture;
            graphicsDevice
                .DrawIndexedPrimitives(PrimitiveType.TriangleList, 12, 0,
                    24, 0, 8);

Then my texture is processed in pixel shader I sample my texture:

texture Texture;
sampler textureSampler  : register(s0) = sampler_state {
    Texture = (Texture);
    Filter = MIN_MAG_MIP_POINT;
    AddressU = Wrap;
    AddressV = Wrap;
};

and produce output:

return tex2D(textureSampler, texCoord);    // I have my texCoords from vertex shader output

Unfortunately in my scene there are hundreds of similar cubes with different textures, as well as other objects and it has bad influence on FPS rate. What I noticed is that I can sample in my pixel shader more than one texture:

        graphicsDevice.Textures[0] = cube.frontTexture;
        graphicsDevice.Textures[1] = cube.backTexture;
        graphicsDevice.Textures[2] = cube.sideTexture;

Can I somehow stick each texture to proper face of cuboid in my pixel shader, in order to draw it in one Draw() call? I use Silverlight 5.0, but any answers also concerning XNA, or MonoGames will be appreciated :)

2

2 Answers

1
votes

You could take all 3 bitmaps that make up the 3 textures and add them to one big bitmap. The result would be one big texture or texture atlas. Then you just set the UV for each face to the appropriate parts of the large texture.

In this way, there is only ever one bound texture and no need to perform expensive texture context switches.

It's a common practice. It's popular too for sprite sheets.

1
votes

As @Micky says, it's good practice to use sprite sheets instead of thousands separate textures. In my case I'm want to have separate textures in file system, but few textures in the game, so I write special class to compose small textures in big sprite sheets and recalculate texture coords.

There is lot of code, so I'll better provide a link to sources.

Textures packing when game starting. If you don't mind about few seconds of processing, you can use it for your sprites.