Sign in to follow this  

Dynamically creating a texture for a memory buffer

Recommended Posts

Can anyone point me towards a good sample on how to best create a texture from raw RGB or RGBA data in a memory buffer? I don't want to become an expert on different formats like bmp or jpg, I just want to take the 512x512 memory area I have allocated, which is filled with dynamically generated color information, and I want to make a texture out of it. Thanks

Share this post

Link to post
Share on other sites
Guest Anonymous Poster
Method #1: The traditional way

a. call IDirect3DDevice9::CreateTexture() to create an empty texture of the required type/dimensions/pixel format.

b. call IDirect3DTexture9::LockRect() on the texture to get a pointer to the memory the texture is in.

c. copy from your memory buffer to the locked texture, remembering to pay attention to the "Pitch" member of the D3DLOCKED_RECT structure (i.e. you'll usually need to copy to the locked texture a line at a time).

d. call IDirect3DTexture9::UnlockRect() when you've finished writing to the texture.

Method #2: Leverage a super-simple file format and let D3DX do the work

a. the D3DX functions (e.g. D3DXCreateTextureFromFileInMemory()) support a file format called PPM (Portable Pix Map) for RGB data.

b. binary PPM files have a simple ASCII header, followed by raw image data.

c. Like this:

// 512x512, 255 is max value per colour component
const char* header = "P6\n512 512\n255\n";
size_t headersize = strlen(header);

// allocate user memory + set PPM header
unsigned char* fileinmemory = new unsigned char [ headersize + (512*512*3) ];
memcpy( fileinmemory, header, headersize );

// offset to file in memory
unsigned char* rawimage = fileinmemory + headersize;

// set first pixel in image to pink
rawimage[0] = 255;
rawimage[1] = 0;
rawimage[2] = 255;

// get D3DX to create the texture
D3DXCreateTextureFromFileInMemoryEx( device, fileinmemory, headersize+(512*512*3), 512, 512, 1, usage, D3DFMT_R8G8B8, D3DPOOL_MANAGED, filter, mipfilter, 0, NULL, NULL, &lpMyTexture );

d. the above can be simplified further - but it is limited to RGB integer data.

e. PPM files (and their variants) can be handy for debugging since you can just write what's in memory straight out to disk with a really simple header attached in a couple of lines of code; those files will then load into many paint packages and other utilities.

Share this post

Link to post
Share on other sites
Just in case S1CA's examples don't work for you (though I certainly wouldn't expect that to be the case), or you like the look of this better, here's what I do. It depends on D3DXLoadSurfaceFromMemory to load data from just a random chunk of memory onto a surface. It basically wraps the whole LockRect()/Copy/UnlockRect() functionality into a single function call. Plus it can handle stretching/shrinking, a color key, and format conversion.

//Create the buffer
D3DCOLOR pBuffer = new D3DCOLOR[512 * 512];

//Fill in buffer with color data
//pBuffer[...] = D3DCOLOR_ARGB(...);

//Create the texture and get the primary surface
IDirect3DTexture9* pTexture;
IDirect3DSurface9* pSurface;
pDevice->CreateTexture(512, 512, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);
pTexture->GetSurfaceLevel(0, &pSurface);

//Load the buffer into the surface
RECT Rectangle = { 0, 0, 512, 512 };
D3DXLoadSurfaceFromMemory(pSurface, NULL, &Rectangle, (void*)pBuffer, D3DFMT_A8R8G8B8, sizeof(D3DCOLOR) * 512, NULL, &Rectangle, D3DX_FILTER_NONE, 0x00000000);

delete [] pBuffer;

Share this post

Link to post
Share on other sites
Thanks to Agony, It turned out I did need your implementation after all. The first one was great, nice and easy, but I really needed to include an alpha channel, not just RGB. Although I'm sure there are similarly easy graphic formats to use, which would include a 4th channel, I really do like your implementation better because I don't need to know or care of graphic formats, I'm just dealing with the raw data, and I like that.

Thanks again.

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