Jump to content
  • Advertisement
Sign in to follow this  
ilflyer12

Writing Data to a Texture using LockRect

This topic is 4168 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey everyone. I am trying to manually write data to a texture once it has been locked with LockRect. The problem is that when i save the texture to an image so that i can make sure it works, i get an all black texture which means it is not writing. I am pretty sure the reason it is not working is one of two reasons. First of all, my texture is of type D3DFMT_A16B16G16R16F and when i lock the rect i am casting the data to BYTE * since that is what everything i have seen does. However, a byte is only 8 bits long and not the 16 like texture has and i get errors errors if i use a WORD instead. Does anyone know if this still is correct? Secondly, the only other thing i can see that i could possibly doing wrong is how i am referencing the pixels. To compute a position I am doing the following: rect_temp.Pitch * t + 4 * k + 1, where t is a row and k is the column. Is this referencing correctly? Here is all of the code for that part just because it probably will make help easier. Thanks for all of your help, i really appreciate it.
        LPDIRECT3DTEXTURE9 Diffuse

	HRESULT hr = pd3dDevice->CreateTexture(SVB.width, SVB.height, 1, 0, D3DFMT_A16B16G16R16F, D3DPOOL_MANAGED, &Diffuse, NULL);

	D3DLOCKED_RECT rect_temp;
	Diffuse->LockRect(0, &rect_temp, NULL, D3DLOCK_DISCARD);
	BYTE *bitPointer=(BYTE *)rect_temp.pBits;
	
	for (int t = 0; t < SVB.height; t++)
	{
		for (int k = 0; k < 200; k++)
		{
			bitPointer[rect_temp.Pitch * t + 4 * k + 1] = 128; 
			bitPointer[rect_temp.Pitch * t + 4 * k + 2] = 128; 
			bitPointer[rect_temp.Pitch * t + 4 * k + 3] = 128; 
			bitPointer[rect_temp.Pitch * t + 4 * k] = 0; 
		}
	}

Share this post


Link to post
Share on other sites
Advertisement
off the top of my head:

-Does SVB.width/4 = 200 ?
-Are you Unlocking the Texture after finishing writing data?

and maybe try :

for (int k = 0; k < 100; k++)
{
bitPointer[rect_temp.Pitch * t + 8 * k] = 0;
bitPointer[rect_temp.Pitch * t + 8 * k + 1] = 0;
bitPointer[rect_temp.Pitch * t + 8 * k + 2] = 128;
bitPointer[rect_temp.Pitch * t + 8 * k + 3] = 0;
bitPointer[rect_temp.Pitch * t + 8 * k + 4] = 128;
bitPointer[rect_temp.Pitch * t + 8 * k + 5] = 0;
bitPointer[rect_temp.Pitch * t + 8 * k + 6] = 128;
bitPointer[rect_temp.Pitch * t + 8 * k + 7] = 0;

}


however i have no experience with this format "D3DFMT_A16B16G16R16F" so I may be wrong :p

Share this post


Link to post
Share on other sites
Off the top of my head, a texture with a format of ARGB16F expects 16-bit floating-point values. I'm not really sure what happens if you set a byte value of 128.

The correct way to assign values into this kind of texture is:

1) Get the address of the pixel. From what I can tell, you're doing this correctly. Make sure to keep the pointer as a pointer to byte, so that when you increment it, it increments in bytes. [EDIT] actually, you might not be. A 16-bit float is 2 bytes, so you should be multiplying K by 8.

2) Cast the pointer to a pointer to D3DXFLOAT16.

3) Assign it a floating point value (probably 1.0f, though I'm not too sure with 16-bit floating-point values. I know you'd want 1.0f with 32-bit).

4) Unlock and cheer.

Hope this helps.

Share this post


Link to post
Share on other sites
Thanks for the help and sorry its taken me so long to reply but i went on vacation. The advice was helpful but it still does not work. Here is my adjusted code.

D3DLOCKED_RECT rect_temp;
Diffuse->LockRect(0, &rect_temp, NULL, D3DLOCK_DISCARD);
BYTE *bitPointer=(BYTE *)rect_temp.pBits;

for (int t = 0; t < SVB.height; t++)
{
for (int k = 0; k < 200; k++)
{
((D3DXFLOAT16)bitPointer[rect_temp.Pitch * t + 8 * k + 2]) = 0.0;
((D3DXFLOAT16)bitPointer[rect_temp.Pitch * t + 8 * k + 4]) = 1.0f;
((D3DXFLOAT16)bitPointer[rect_temp.Pitch * t + 8 * k + 6]) = 0;
((D3DXFLOAT16)bitPointer[rect_temp.Pitch * t + 8 * k]) = 0;
}
}

Diffuse->UnlockRect(0);

D3DXSaveTextureToFile(L"DiffuseTest.jpg", D3DXIFF_JPG, Diffuse, NULL);


I still get an all black texture. The reason it am only going to width 200 is that i need to make sure i can write this out since i am going to be using this texture to store some spatially varying diffuse values in the texture which will be accessed from the GPU. Please let me know if you have any other advice or knowledge of how to work with textures of this kind because i really need 16 bit accuracy. Thanks soooo much

Share this post


Link to post
Share on other sites
This generally isn't a good idea, but try filling the texture with rand()om numbers. If it's still all black, it's likely there's some other problem, since I would assume that filling the texture with random gibberish would produce at least a wee bit of colour.

Also, have you tried displaying the texture instead of saving it as a JPEG? It might be that D3DX can't save it as a JPEG for some reason (Maybe it can't convert 16-bit floats to an 8-bit value for JPEGs or something). That's a complete guess of course - are you linking wth d3dx9d.lib, and using the debug runtimes? YOu might get some unexpected information spat out.

Share this post


Link to post
Share on other sites
1. While I have no experience with 16-bit formats, if I were at your place and hit the roadblock, I`d step down and would try to find the first lesser format where it works and compare the differences.
Rewriting this for some regular format shouldn`t take more than 1 or 2 hrs (including debugging), so for start, try this with some regular D3DFMT_A8R8G8B8.

2. I also noticed you don`t check error codes from DX functions. Check each dx function inside debugger whether it returns S_OK.

3. What about DX Debug output ? Doesn`t DX complain at all ?

4. Another issue could be in memory exceptions - are you catching them ? Maybe the loop doesn`t even finish since it might try accessing outside the array, thus leaving the loop and kumping at place where you have your catch handler (if you are actually catching the exceptions, that is - since those aren`t in the posted code samples).

5. Check the DX docs and search for your format whether you don`t find some additional info/examples/limitations in comparison to other regular formats.

6. I might be wrong here, but I heard there are some serious differences with regards to implementation of FP textures/RTs between nVidia and ATI. Maybe those are related just to AA (with combination with , e.g., HDR), but there might be some other issues too.

Those are the first things I would do before deciding what to do next.

EDIT : Ahhh, Steve beat me to some suggestions ;-)
EDIT2 : Reformatting.

[Edited by - VladR on July 19, 2007 3:39:12 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!