Sign in to follow this  
LordFallout

Create a Texture from Pixel values

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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));

Share this post


Link to post
Share on other sites
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;
}


Share this post


Link to post
Share on other sites
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






Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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

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