Exporting3DTextures
From Ogre Wiki
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:
// 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.
#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);
}

