Skip to main content
GameDev.net gamedev.net
🔒 Locked

Howto lock texture created as render target (D3DUSAGE_RENDERTARGET)?

Started by langtudontinh Jun 13, 2005 at 4:19 AM 12 replies 15.4k views
Original Post
langtudontinh
langtudontinh
Hello, I am working on Direct3D, need to render a scene into a texture. Every thing works well, the broblem is I want to apply alpha for the texture (which is a render target). The texture could not be locked. Please, show me the way to apply alpha to the rendered texture! Thanks, ltdt.
Cambo_frog
Cambo_frog
Did you create the texture in the default pool?
If you specify D3DUSAGE_RENDERTARGET you must also use D3DPOOL_DEFAULT.

From the SDK help file on D3DXCreateTextureFromFileEx
Quote:
If either D3DUSAGE_RENDERTARGET or D3DUSAGE_DYNAMIC is specified, Pool must be set to D3DPOOL_DEFAULT, and the application should check that the device supports this operation by calling IDirect3D9::CheckDeviceFormat.


***EDIT***

I tried Creating a texture with D3DUSAGE_RENDERTARGET in the default pool which succeeded but LockRect fails with debug output:
Quote:
Lock is not supported for textures allocated with POOL_DEFAULT unless they are marked D3DUSAGE_DYNAMIC

If I try using D3DUSAGE_RENDERTARGET | D3DUSAGE_DYNAMIC for usage, then D3DXCreateTextureFromFileEx fails with debug output:
Quote:
Dynamic textures cannot be rendertargets or depth/stencils

So it looks like it is not possible (unless anyone knows better?).

Maybe there is alternative method you could use?
Could you expand on what you mean by "I want to apply alpha for the texture (which is a render target)"?

HTH,
Cambo_frog

[Edited by - Cambo_frog on June 13, 2005 5:45:29 AM]
For the love of god, please tell me that you've just omitted your error checking code for brevity, and you don't really assume that all those functions succeed.
langtudontinh
langtudontinh
Quote:
Original post by Cambo_frog
Did you create the texture in the default pool?
If you specify D3DUSAGE_RENDERTARGET you must also use D3DPOOL_DEFAULT.


Of course, I spcified D3DPOOL_DEFAULT. Pls see the question!

thanks,
ltdt.
Cambo_frog
Cambo_frog
Quote:
Of course, I spcified D3DPOOL_DEFAULT. Pls see the question!

thanks,
ltdt.


Sorry, I don't see any mention of D3DPOOL_DEFAULT in your original post.

Anyway, please see my edit of my original reply.

HTH,
Cambo_frog

For the love of god, please tell me that you've just omitted your error checking code for brevity, and you don't really assume that all those functions succeed.
langtudontinh
langtudontinh
In sumary, the thing I want to know is:
Is is possible to lock a rendered texture to modify some pixels?
Cambo_frog
Cambo_frog
Quote:
Original post by langtudontinh
In sumary, the thing I want to know is:
Is is possible to lock a rendered texture to modify some pixels?


Hi langtudontinh,
I don't know if you catched my edit of my original reply so I will repeat below.

I tried Creating a texture with D3DUSAGE_RENDERTARGET in the default pool which succeeded but LockRect fails with debug output:
Quote:
Lock is not supported for textures allocated with POOL_DEFAULT unless they are marked D3DUSAGE_DYNAMIC


If I try using D3DUSAGE_RENDERTARGET | D3DUSAGE_DYNAMIC for usage, then D3DXCreateTextureFromFileEx fails with debug output:
Quote:
Dynamic textures cannot be rendertargets or depth/stencils


In addition the SDK help file says for IDirect3DTexture9::LockRect
Quote:
Textures created with D3DPOOL_DEFAULT are not lockable


In summary, D3DUSAGE_RENDERTARGET requires D3DXPOOL_DEFAULT so a texture created with D3DUSAGE_RENDERTARGET is not lockable, and I don't know of a way to modify individual pixels in a texture without locking it.

HTH,
Cambo_frog
For the love of god, please tell me that you've just omitted your error checking code for brevity, and you don't really assume that all those functions succeed.
langtudontinh
langtudontinh
Thank Cambo_frog. But, is there another way to access pixel from the rendered texture?
Anyone else, pls shares your idea!!!

ltdt.
programmer_tom
programmer_tom

yes, you can access the pixel data of a render target texture.

an easy way is to use the new CopyRects() style function UpdateSurface().

can you be more specific about what you need to do?




Cambo_frog
Cambo_frog
Quote:
Original post by programmer_tom

yes, you can access the pixel data of a render target texture.

an easy way is to use the new CopyRects() style function UpdateSurface().

can you be more specific about what you need to do?


Hi programmer_tom,

From the OP's post I guessed he wanted to render to to a texture ( as a render target) and the read back from it (he wanted to lock) and adjust the alpha values in the texture in some way and write back.

How does your suggestion of using UpdateSurface fit in with this?
What is the source surface and what is the destination surface?
if the source surface is from a texture created with D3DUSAGE_RENDERTARGET this will not work as textures using D3DUSAGE_RENDERTARGET need to be created in D3DPOOL_DEFAULT and the SDK help for UpdateSurface states:
Quote:
The source surface must have been created with D3DPOOL_SYSTEMMEM.


I would like to reitterate your question to the OP:
can you be more specific about what you need to do?

TIA,
Cambo_frog
For the love of god, please tell me that you've just omitted your error checking code for brevity, and you don't really assume that all those functions succeed.
neneboricua19
neneboricua19
What programmer_tom is talking about is that you can use UpdateSurface or maybe StretchRect to copy the data from the render target texture to another texture that can be locked by your application.

neneboricua
Cambo_frog
Cambo_frog
Quote:
Original post by neneboricua19
What programmer_tom is talking about is that you can use UpdateSurface or maybe StretchRect to copy the data from the render target texture to another texture that can be locked by your application.

neneboricua


Your post implies UpdateSurface can copy a source render target texture surface to a destination texture surface("copy the data from the render target texture to another texture" ), but this is not possible according to the SDK help file

The SDK help specifies textures which will be render targets (Created with D3DUSAGE_RENDERTARGET) must be created in D3DPOOL_DEFAULT.

The SDK help for UpdateSurface states "The source surface must have been created with D3DPOOL_SYSTEMMEM"

HTH,
Cambo_frog
For the love of god, please tell me that you've just omitted your error checking code for brevity, and you don't really assume that all those functions succeed.
neneboricua19
neneboricua19
Quote:
Original post by Cambo_frog
Your post implies UpdateSurface can copy a source render target texture surface to a destination texture surface("copy the data from the render target texture to another texture" ), but this is not possible according to the SDK help file

The SDK help specifies textures which will be render targets (Created with D3DUSAGE_RENDERTARGET) must be created in D3DPOOL_DEFAULT.

The SDK help for UpdateSurface states "The source surface must have been created with D3DPOOL_SYSTEMMEM"

Did you look at StretchRect? It should be possible to do what you want with StretchRect.

As others have asked, what are you trying to do? Eventhough it is possible to copy data from your render target texture to another texture and lock it, the result will not be very efficient. Depending on what you're trying to do, there may be a more efficient way to accomoplish the same thing.

neneboricua
langtudontinh
langtudontinh
The problem could be solved by using GetRenderTargetData to download from video to system memory, then using UpdateSurface to update surface gotten from rendered texture. But it comsumes time so much!!!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.