Sign in to follow this  
Raeldor

Loading textures without D3DX

Recommended Posts

I have a TGA class, which loads TGA data into memory. I want to create a D3D texture from this. What is the best way to do this without using D3DX? How does this work if the texture is in video memory etc.? Thanks!

Share this post


Link to post
Share on other sites
If you are only going to be using DirectX in your application (ie it doesn't use OpenGL as well), then you may want to consider using the D3DX function(s), because they load pretty much every common type of image file. Plus, they have been optimized and tested extensively.

However, if you want to load the data yourself, there are a few steps to follow:

(1) Create 2 blank textures using IDirect3DDevice9::CreateTexture(). One should be created in D3DPOOL_SYSTEMMEM and the other should be created in D3DPOOL_DEFAULT.

Since textures created in video memory (the default pool) cannot be locked (and hence modified), we must first fill the system texture with the image data. Then, we can copy the data from the system texture into the video texture using a D3D API.

(2) Lock the D3DPOOL_SYSTEMMEM texture, fill in the pixels, and unlock. For a more detailed account of this process, read this KBase article. You are going to have to modify the code given in that article, based on the pixel format of the texture and your read/write permissions.

(3) Call IDirect3DDevice9::UpdateTexture(), specifying the two appropriate textures. Your video mem texture should now contain the contents of the system mem texture.

(4) Release the system mem texture, since we don't need it anymore.

Share this post


Link to post
Share on other sites
Quote:
Original post by circlesoft
If you are only going to be using DirectX in your application (ie it doesn't use OpenGL as well), then you may want to consider using the D3DX function(s), because they load pretty much every common type of image file. Plus, they have been optimized and tested extensively.

However, if you want to load the data yourself, there are a few steps to follow:

(1) Create 2 blank textures using IDirect3DDevice9::CreateTexture(). One should be created in D3DPOOL_SYSTEMMEM and the other should be created in D3DPOOL_DEFAULT.

Since textures created in video memory (the default pool) cannot be locked (and hence modified), we must first fill the system texture with the image data. Then, we can copy the data from the system texture into the video texture using a D3D API.

(2) Lock the D3DPOOL_SYSTEMMEM texture, fill in the pixels, and unlock. For a more detailed account of this process, read this KBase article. You are going to have to modify the code given in that article, based on the pixel format of the texture and your read/write permissions.

(3) Call IDirect3DDevice9::UpdateTexture(), specifying the two appropriate textures. Your video mem texture should now contain the contents of the system mem texture.

(4) Release the system mem texture, since we don't need it anymore.


Thank you for your advice. I am trying to extrapolate my engine from the underlying 3D api so I can use either D3D or OpenGL (for portability). That's quite long winded compared to the opengl version, but hey... if it works, then I only have to do it once :)

Share this post


Link to post
Share on other sites
If you need to change the video mode, or anything else that requires you to call IDirect3DDevice9::Reset(), then you need to release any and all D3DPOOL_DEFAULT resources and recreate them after the Reset() finishes.

You could also use the D3DPOOL_MANAGED pool to get past this. It keeps a copy in system and video memory, and the system memory copy is locked when you call Lock(). The system memory resource is then copied to the video memory resource upon Unlock().

Share this post


Link to post
Share on other sites
Ah, the docs are a little misleading here. The LockRect() page states that "Textures created with D3DPOOL_DEFAULT are not lockable. Textures created in video memory are lockable when created with USAGE_DYNAMIC.". I interpreted that as you cannot lock default pool textures, even with a dynamic usage flag. However, you can.

Check out the "Using Dynamic Textures" section on this SDK page. Dynamic textures require hardware support, however all recent cards support them, dating back to Radeon 7500s and GeForce3s.

You cannot use D3DPOOL_MANAGED and D3DUSAGE_DYNAMIC together, though.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this