Exporting 3D Textures
Welcome to the page about exporting 3D textures. It is fun, simple, everyone should do it!
to DevIL .RAW
Exporting raw volume data to DevIL .raw format is simple:
Copy to clipboard
// Extents uint32 dims[3] = {width, height, depth}; // Image data uint8 *data; FILE *f = fopen(outfile, "wb"); assert(f); fwrite(dims, 3, 4, f); char bpp = 4; // channels char bpc = 1; // byte per component fwrite(&bpp, 1, 1, f); fwrite(&bpc, 1, 1, f); // ABGR fwrite(data, dims[0]*dims[1]*dims[2], 4, f);
to .DDS
Below is a source fragment that will convert "RDoutput.raw" in DevIL .RAW format to "RDoutput.dds" as a Direct3D volume.
This is a somewhat more compact and portable format than the .RAW format used above. It is more involved because it needs a working D3D9 and windows context to work.
Copy to clipboard
#include <iostream> #include <cstdio> #include <cassert> #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include <IL/il.h> #include <IL/ilu.h> LPDIRECT3D9 gD3dObject=NULL; LPDIRECT3DDEVICE9 gD3dDevice=NULL; int checkError(HRESULT hr) { if(FAILED(hr)) { std::cerr << "D3D9 failure" << std::endl; exit(0); } } LRESULT WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { return DefWindowProc( hWnd, uMsg, wParam, lParam ); } int WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { size_t width, height, depth; char *infile="RDoutput.raw"; char *outfile="RDoutput.dds"; std::cerr << "Main begins" << std::endl; ilInit(); ilEnable( IL_FILE_OVERWRITE ); std::cerr << "Creating window" << std::endl; std::string name = "Window"; // Register the window class // NB allow 4 bytes of window data for D3D9RenderWindow pointer WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW, (WNDPROC)WndProc, 0, 0, hInst, LoadIcon( NULL, IDI_APPLICATION ), LoadCursor( NULL, IDC_ARROW ), (HBRUSH)GetStockObject( BLACK_BRUSH ), NULL, TEXT(name.c_str()) }; RegisterClass( &wndClass ); // Create our main window // Pass pointer to self HWND hWnd = CreateWindow(TEXT(name.c_str()), TEXT(name.c_str()), WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0L, 0L, hInst, 0); ShowWindow(hWnd, SW_SHOWNORMAL); UpdateWindow(hWnd); std::cerr << "Creating D3D9" << std::endl; gD3dObject = Direct3DCreate9(D3D_SDK_VERSION); D3DPRESENT_PARAMETERS presParams; ZeroMemory(&presParams, sizeof(presParams)); presParams.Windowed = TRUE; presParams.BackBufferFormat = D3DFMT_UNKNOWN; presParams.BackBufferCount = 1; presParams.SwapEffect = D3DSWAPEFFECT_DISCARD; presParams.hDeviceWindow = hWnd; //presParams.BackBufferWidth = 640; //presParams.BackBufferHeight = 480; checkError(gD3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING, &presParams, &gD3dDevice)); ILuint ImageName; ilGenImages( 1, &ImageName ); ilBindImage( ImageName ); // Put it right side up ilEnable(IL_ORIGIN_SET); ilSetInteger(IL_ORIGIN_MODE, IL_ORIGIN_UPPER_LEFT); ilLoad(IL_RAW, infile); width = ilGetInteger(IL_IMAGE_WIDTH); height = ilGetInteger(IL_IMAGE_HEIGHT); depth = ilGetInteger(IL_IMAGE_DEPTH); std::cerr << "Dimensions " << width << " " << height << " " << depth << std::endl; ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE); assert(ilGetInteger(IL_IMAGE_WIDTH) == width); std::cerr << "Creating volume texture" << std::endl; LPDIRECT3DVOLUMETEXTURE9 pVolumeTexture; checkError(D3DXCreateVolumeTexture( gD3dDevice, width, height, depth, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pVolumeTexture )); std::cerr << "Converting image" << std::endl; // Data unsigned char *data = (unsigned char*)ilGetData(); std::cerr << "Acquiring volume" << std::endl; D3DBOX srcBox, destBox; LPDIRECT3DVOLUME9 volume; checkError(pVolumeTexture->GetVolumeLevel(0, &volume)); std::cerr << "Loading image into D3DX" << std::endl; srcBox.Left = 0; srcBox.Top = 0; srcBox.Right = width; srcBox.Bottom = height; srcBox.Front = 0; srcBox.Back = depth; destBox = srcBox; unsigned int *datax = (unsigned int*)ilGetData(); int rowPitch = width*4; int slicePitch = rowPitch*height; checkError( D3DXLoadVolumeFromMemory( volume, 0, 0, datax, D3DFMT_A8R8G8B8, rowPitch, slicePitch, 0, &srcBox, D3DX_DEFAULT, 0 ) ); std::cerr << "Writing data" << std::endl; D3DXSaveVolumeToFile(outfile, D3DXIFF_DDS, volume, 0, 0); std::cerr << "Done" << std::endl; ilDeleteImages(1, &ImageName); }