0
\$\begingroup\$

I'm trying to think of the best way to manage textures in my 2D game.

First, I am using DX11, so right now my "textures" are just pointers to a ID3D11ShaderResourceView created by D3DX11CreateShaderResourceViewFromFile. Is this how I should be loading content?

Right now my basic idea is to create a hashmap of textures with string references.

When an object is created that uses a texture it passes the reference of the texture to the hashmap and gets back a pointer to the texture. If the texture isn't loaded it will use the string to find the correct texture to load, add it to the map and pass back the pointer, so it automatically loads new textures as required (my game is turn based, and many small pauses would have no real effect).

But here are my issues:

  1. Is the above method the best method I could be using (without it becoming overly complex)

  2. ID3D11ShaderResourceView. Is this how I should be storing texture data in DX11?

  3. Ideally I want to have all my texture data compressed in a file. Right now I am simply loading jpgs and so on. But I have no idea how to compress these images and selectively re-load them as required. Ideally I would want to compress them to be locatable in the file using the reference string used when searching the hashmap too.

\$\endgroup\$
1
\$\begingroup\$

Yes, just keeping around the ID3D11ShaderResourceView is generally fine. Note that you can call its GetResource() method to retrieve the underlying ID3D11Texture2D object if you should ever need that for some reason.

What you're doing now sounds fine for a small game and hobby development. Eventually, there are a few enhancements you might want to consider:

  • Make a list of all the textures used in a level or game section, and load them all up front rather than as you encounter them during gameplay; even if your game is turn-based, not having pauses to load textures is a better user experience.
  • Similarly, you can load textures on a background thread so that your main rendering thread isn't stalled. The D3D11 device is automatically multithreaded, so you can create D3D objects on other threads without worries. This does require some inter-thread communication to ensure you don't try to use a texture before it's done loading.
  • As far as compression goes, there are two different concepts here - compression of the actual texture data in a GPU-friendly format, and putting all the textures in one file to reduce disk seeks. For the compression part, consider converting your textures to .dds format and using DXT compression, which is natively supported by GPUs (JPEG is not). The .dds format also allows you to store mipmaps, so you're not re-generating the mips every time you load the texture.

    For the aggregating-into-one-file part, you can use .zip files as a simple way to aggregate things. The simplest thing to do is probably to load the entire .zip into memory in one shot, which is the fastest way to do I/O. Then, with the file in memory, you can decompress individual textures out of it as you need (or just decompress them all at once). There are plenty of zip file libraries that can take care of the details, and you can find articles/tutorials about this on the web.

\$\endgroup\$
0
\$\begingroup\$

Yes, the approach that you have described is quite common due to the shareable nature of textures. Having a texture cache like this is very useful to avoid reloading the same texture more than once. Storing every loaded texture in a hash-table and looking up the table first is probably the easiest way to do it.

About using or not the raw API object ID3D11ShaderResourceView, this is a matter that is very specific of your project. If you never plan on porting your game to some other non-MS platform, then it would be OK to sprinkle a few D3D calls around. If you plan to port it at some point, the best would be to wrap this object in a custom Texture class. Another reason you might have to wrap it into a custom class would be to extend its functionality. Does ID3D11ShaderResourceView have all the methods you need? If not, it might be a good idea to define your own Texture type that has a ID3D11ShaderResourceView pointer.

For the third question, one easy way to pack all textures in a single file and avoid a lot of code change is to just store them all in a compressed (ZIP) folder and decompress the folder at startup. Take a look at a compression API, such as miniZ. Another option would be a Texture Atlas, but this might imply some changes to code and mesh assets.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.