working with large textures

Started by
3 comments, last by Adam_42 14 years, 1 month ago
Hi, I use MDX & VS 2008 (C#), I have to display several large textures (as geographic maps, I'm creating a program like NASA world wind or google earth), my textures are large and it is my main problem, for instance I have several 6000x6000 textures, and as you know D3D cannot load these large textures (I use Loadfromfile and it gives me error on these big files), so I It is the code I use to divide my large texture into several smaller textures: for (int iLoop = 0; iLoop < areaList.Count; iLoop++) { Rectangle rect = (Rectangle)areaList[iLoop];//an array of RECTs previously filled string fileName = _filename + (iLoop).ToString() + ".BMP"; Bitmap newBmp = new Bitmap(rect.Width, rect.Height,System.Drawing.Imaging.PixelFormat.Format24bppRgb); Graphics newBmpGraphics = Graphics.FromImage(newBmp); newBmpGraphics.DrawImage(inputImg, new Rectangle(0, 0, rect.Width, rect.Height), rect, GraphicsUnit.Pixel); newBmpGraphics.Save(); newBmp.Save(fileName, System.Drawing.Imaging.ImageFormat.Bmp); } but sometimes this codes gives me error (Out of memory), so I think I cannot count on this algorithm, perhaps I should read all pixels and save them manually to smaller parts. Can I load only a specific part of these large textures into D3D memory? Can I use D3D to divide my large textures (BMP or JPEG) into smaller textures? is there any samples? thanks
Visit galaxyroad.com which soon will have english contents too
Advertisement
Quote:Original post by vcGamer
[snip]
Bitmap newBmp = new Bitmap(rect.Width, rect.Height,System.Drawing.Imaging.PixelFormat.Format24bppRgb);
[snip]

but sometimes this codes gives me error (Out of memory), so I think I cannot count on this algorithm, perhaps I should read all pixels and save them manually to smaller parts.
That loads the entire bitmap into memory. If it's actually stores as 24bpp internally, then that's 103MB of memory per bitmap, which is quite a lot.

Quote:Original post by vcGamer
Can I load only a specific part of these large textures into D3D memory? Can I use D3D to divide my large textures (BMP or JPEG) into smaller textures?
I doubt there's any D3DX function to do this, but there's nothing to stop you parsing the BMP file yourself - it's not compressed, so you can easily load in 256x256 (Or whatever) chunks. JPEG will be more work; I don't know of any library which can load a JPEG in pieces.

You'll need to:
Create a (small) texture
Open the BMP file
Lock the texture to access its data
Copy data from the BMP file to the texture
Unlock the texture
Close the BMP file
Move onto the next chunk
thanks Steve, as I'll have several big textures, dividing them to small parts will end to several hundred textures (for instance I'll have 1000 500x500 BMP files), and it seems that loading these 1000 files into D3D memory (i.e. loading them all using TextureLoader.FromFile) will not be efficient (I think D3D cannot store so many textures at once), therefore I've decided to load only textures that I need in each scene, I think based on the distance between viewer & globe I won't need more than 10 textures at each scene, so is it logical to load( TextureLoader.FromFile)/unload (Texture = null) each time my scene changes?
I think loading/unloading fewer than 10 textures is not a serious problem for D3D, and I suppose it won't cause much FPS loss (of course I will create my small BMPs at app init and will load/unload them in runtime)

thanks
Visit galaxyroad.com which soon will have english contents too
Quote:Original post by vcGamer
thanks Steve, as I'll have several big textures, dividing them to small parts will end to several hundred textures (for instance I'll have 1000 500x500 BMP files), and it seems that loading these 1000 files into D3D memory (i.e. loading them all using TextureLoader.FromFile) will not be efficient (I think D3D cannot store so many textures at once), therefore I've decided to load only textures that I need in each scene, I think based on the distance between viewer & globe I won't need more than 10 textures at each scene, so is it logical to load( TextureLoader.FromFile)/unload (Texture = null) each time my scene changes?
I think loading/unloading fewer than 10 textures is not a serious problem for D3D, and I suppose it won't cause much FPS loss (of course I will create my small BMPs at app init and will load/unload them in runtime)
Yeah, you'll need some sort of caching system. If you have so much data that you're running out of address space (Each application has roughly 1.5GB of address space on a 32-bit system), then you'll need to start caching from disk as well, which means you'll have two layers of caching.
It may be a good idea not to use the managed pool for D3D resources, since this keeps them in system memory and copies them to device memory (the default pool) as they're used. Instead, you might have more success creating your textures in the default pool, and swapping them in and out as needed (Although you should probably not be destroying and re-creating textures, just reloading the contents).
Also don't forget that D3D supports compressed textures, that stay compressed even in video memory.

DXT1 textures are 1/8th the size of an XRGB texture, and although the compression is somewhat lossy the memory savings usually make up for it. For textures with an alpha channel you want DXT5 which uses 4:1 compression.

You can convert to DXT format by changing the format parameter in the texture load or save function. You may need to use one of the overloads which takes more parameters.

For example those 1,000 500x500 images would take up 128MB (about 170MB with mipmaps) compared to 1GB (about 1.3GB with mipmaps) uncompressed.

Compressed textures usually render slightly quicker too as they need less memory bandwidth.

This topic is closed to new replies.

Advertisement