Dynamically creating a texture for a memory buffer

Started by
5 comments, last by QuadMV 18 years, 9 months ago
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
3DMUVE is an amateur game development team, and the designer and developer of a new gaming technology “MUVE” for the gaming industry.
Advertisement
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.
[auto-logout - me above]

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

That's awesome, thanks, exactly what I was looking for. If I have problems I'll let you know.

3DMUVE is an amateur game development team, and the designer and developer of a new gaming technology “MUVE” for the gaming industry.
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 bufferD3DCOLOR pBuffer = new D3DCOLOR[512 * 512];//Fill in buffer with color data//pBuffer[...] = D3DCOLOR_ARGB(...);//Create the texture and get the primary surfaceIDirect3DTexture9* pTexture;IDirect3DSurface9* pSurface;pDevice->CreateTexture(512, 512, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);pTexture->GetSurfaceLevel(0, &pSurface);//Load the buffer into the surfaceRECT Rectangle = { 0, 0, 512, 512 };D3DXLoadSurfaceFromMemory(pSurface, NULL, &Rectangle, (void*)pBuffer, D3DFMT_A8R8G8B8, sizeof(D3DCOLOR) * 512, NULL, &Rectangle, D3DX_FILTER_NONE, 0x00000000);//CleanuppSurface->Release();delete [] pBuffer;
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Thanks, I'll review it when I get a chance, but S1CA's example worked perfectly for me.
3DMUVE is an amateur game development team, and the designer and developer of a new gaming technology “MUVE” for the gaming industry.
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.

3DMUVE is an amateur game development team, and the designer and developer of a new gaming technology “MUVE” for the gaming industry.

This topic is closed to new replies.

Advertisement