Create a Texture from Pixel values

Started by
6 comments, last by LordFallout 16 years ago
Hello everyone, i was hoping someone could help me out, basically im using noise to generate random clouds. This allows me to generate an array of pixels containing the data i would like to display however im trying to get this onto a texture in order to use it on my sky plane in DirectX, is there an easy way to convert this array of colours into a texture, i cant seem to find any useful information about it.
Advertisement
its possible to get a pointer to a directx texture using the LockRect() function.

i.e.

D3DLOCKED_RECT locked;
HRESULT hr=texture->LockRect(0,&locked,NULL,0);

BYTE *bytePointer=(BYTE*)locked.pBits;

you can then use this pointer to access the bytes of the texture directly.

if you call CreateTexture to create a 32bit image in memory it should be no
trouble to set the r,g,b,a components (1 byte per colour)

afterwards you call the unlock function.

hope this helps.
http://www.fotofill.co.uk
Quote:Original post by moosedude
its possible to get a pointer to a directx texture using the LockRect() function.

i.e.

D3DLOCKED_RECT locked;
HRESULT hr=texture->LockRect(0,&locked,NULL,0);

BYTE *bytePointer=(BYTE*)locked.pBits;

you can then use this pointer to access the bytes of the texture directly.

if you call CreateTexture to create a 32bit image in memory it should be no
trouble to set the r,g,b,a components (1 byte per colour)

afterwards you call the unlock function.

hope this helps.


Ok, so would it be possible to mem copy, i store them as floats at the moment, so my data structure is like so:

R: float
G: float
B: float
A: float

and there store in a structure, would it be ok to just memcpy this whole thing over or is it arranged in a different way in the directX texture, i.e. is it arranged with all reds first, then all greens, etc?
Doing a straight memcpy in that case would only work if your texture format was a 128-bit floating point texture (R32G32B32A32F or somesuch).

You'll need to convert your floating-point data to whatever format your texture is in. If, for example, it is R8G8B8A8 you can convert your structure like so:
D3DCOLOR dest = D3DCOLOR_ARGB((BYTE)(src.A * 255.0f), (BYTE)(src.R * 255.0f), (BYTE)(src.G * 255.0f), (BYTE)(src.B * 255.0f));
NextWar: The Quest for Earth available now for Windows Phone 7.
Quote:Original post by LordFallout
Quote:Original post by moosedude
its possible to get a pointer to a directx texture using the LockRect() function.

i.e.

D3DLOCKED_RECT locked;
HRESULT hr=texture->gt;LockRect(0,&locked,NULL,0);

BYTE *bytePointer=(BYTE*)locked.pBits;

you can then use this pointer to access the bytes of the texture directly.

if you call CreateTexture to create a 32bit image in memory it should be no
trouble to set the r,g,b,a components (1 byte per colour)

afterwards you call the unlock function.

hope this helps.


Ok, so would it be possible to mem copy, i store them as floats at the moment, so my data structure is like so:

R: float
G: float
B: float
A: float

and there store in a structure, would it be ok to just memcpy this whole thing over or is it arranged in a different way in the directX texture, i.e. is it arranged with all reds first, then all greens, etc?


Take note of the memory pitch(actual width of the texture's memory when writing into it. Take a look at this snippet for an example of locking texture's rect and writing into it

	// lock and access texture memory map to acquire heightmap array values	D3DLOCKED_RECT sRect;	if ( FAILED( pd3dTexture->LockRect( 0, &sRect, NULL, NULL ) ) )	{		m_pDebug->Log( "HEIGHTMAP::Create() - Failed to lock texture memory" );		return false;	}	BYTE *bytes = ( BYTE* )sRect.pBits; // start of the memory block  	for( int z = 0; z < m_vSize.y(); z++ )		for( int x = 0; x < m_vSize.x(); x++ )		{			BYTE *b = bytes + z * sRect.Pitch + x; // pitch is the actual width of memory block			m_pHeightMap[ x + z * m_vSize.x() ] = ( *b / 255.0f ) * m_fMaxHeight;		}						//Unlock the texture	if ( FAILED( pd3dTexture->UnlockRect( 0 ) ) )	{		m_pDebug->Log( "HEIGHTMAP::Create() - Failed to unlock texture memory" );		return false;	}
Hi.
I think you can do something like this to
DWORD* imageData = (DWORD*)lockedRect.pBits;		//ErrorReport.AddErrorMessage("Piexl test");	for(int h = 0; h < sdc.Height; h++)	{		for(int j = 0; j < sdc.Width; j++)		{			D3DXCOLOR FinalColor  = imageData[h *lockedRect.Pitch / 4 + j];									//noise; do stuff                        FinalColor.r = ???;                        FinalColor.g = ????;                        FinalColor.b = ?????;                        FinalColor.a = ????;			imageData[h * lockedRect.Pitch / 4 + j] = FinalColor;		}	}		texture->UnlockRect(0);		       return texture;}//end C
This information should work, im going to try it out now, the problem is i dont really know why, why does this work, i cant seem to find any info in the SDK, where did you guys find out about these methods?
i decided to try out this method:

	DWORD* imageData = (DWORD*)RC.pBits;	for(int y = 0; y < 256; y++)	{		for(int x = 0; x < 256; x++)		{									D3DCOLOR dest;									if(x <= 100 && y <= 100)			{				dest = D3DCOLOR_ARGB((DWORD)(0.5f * 255.0f), (DWORD)(0.8 * 255.0f), (DWORD)(0.9 * 255.0f), (DWORD)(0.3 * 255.0f));			}			else if(x <= 200 && y <= 200)			{				dest = D3DCOLOR_ARGB((DWORD)(255.0f), (DWORD)(255.0f), (DWORD)(100.0f), (DWORD)(50.0f));			}			else			{				dest = D3DCOLOR_ARGB((DWORD)(255.0f), (DWORD)(100.0f), (DWORD)(0.0f), (DWORD)(255.0f));			}			imageData[y * (RC.Pitch / 4) + x] = dest;		}	}


I'm not using my texture colours yet because this is just a test, the only problem is that the texture seems to get overwritten with the latest colour, when i draw it its a purple colour.

Is there any obvious reason to why this might happen?

The texture is created as a D3DFMT_A8R8G8B8

This topic is closed to new replies.

Advertisement