Sign in to follow this  

Extracting values from a surface

Recommended Posts

Hi I've been able to extract colour values from a D3DFMT_A8R8G8B8 texture as there is a lot of code available that demonstrates how to do it. However, I'm having difficult extracting colour values from D3DFMT_A16B16G16R16F textures. Can anyone tell me how to do this, for D3DFMT_A8R8G8B8 textures I use the following code:
 			D3DLOCKED_RECT lockedRect;
								&lockedRect,	// pointer to receive locked data
								0,				// lock entire surface
								0);				// no lock flags specified

			float* dataHolder = textureInfo[j];
			memset(dataHolder, 0, sizeof(float)*Pixels*Pixels*3);

			// Iterate through each pixel in the surface and set it to red.
			BYTE *bytePointer=(BYTE*)lockedRect.pBits;			
			for (DWORD y=0;y<desc.Height;y++)
				for (DWORD x=0;x<desc.Width;x++)
					DWORD index=(x*4+(y*(lockedRect.Pitch)));
					// Blue
					BYTE r=bytePointer[index];
					dataHolder[y*desc.Width*3 + x*3 + 2] = (float)r; 

					// Green
					BYTE g=bytePointer[index+1];
					dataHolder[y*desc.Width*3 + x*3 + 1] = (float)g; 

					// Red
					BYTE b=bytePointer[index+2];
					dataHolder[y*desc.Width*3 + x*3 + 0] = (float)b; 

					// Alpha
				//	BYTE a=bytePointer[index+3];  


I've tried using D3DXFLOAT16 *bytePointer=(D3DXFLOAT16*)lockedRect.pBits; and D3DXFLOAT16 r=bytePointer[index]; but I get memory exceptions and to be honest I don't really know what I'm doign :D Thanks

Share this post

Link to post
Share on other sites
If your current D3DFMT_A8R8G8B8 code is working, it should also work fine for the D3DFMT_A16B16G16R16F format. Just use a 16 bit pointer instead of 8 bits. Be aware of the pitch value though. lockedRect.Pitch is in bytes, so you'll need to divide that by 2 if you're working with a 16-bit pointer. And that is assuming the pitch is divisible by 2.

edit: Err, umm, also, I failed to realize that the data is BGR instead of RGB. So you'll have to reverse the way you read that.

Share this post

Link to post
Share on other sites
If my texture is 1x1 then am I right in assuming I don't need to worry about the pitch?


edit: Do you mean you're getting memory exceptions with the 1x1 texture?

Share this post

Link to post
Share on other sites
Actually, I looked at what was happening deeper and it appears that the lock_rect method call is failing.

I tried D3DFMT_A8R8G8B8 format and getting DirectX to autogenerate all mipmaps. I have a 64x64 texture and its creating 7 levels. When I try to access any of the levels the lock_rect method always fails.

By the way, my texture is a rendertarget, is that a problem? Also, if it is then is the only way to lock and read the values of the texture to copy it to another texture that isn't a render target?

Share this post

Link to post
Share on other sites
I haven't messed with render targets much. Have you tried enabling Direct3D-debug mode with full output? It might tell you what the problem is there.

Sorry, wish I could be more helpful.

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