Using GDI to draw in textures with alpha

Started by
3 comments, last by ValMan 15 years, 3 months ago
Hello, I am trying to draw into a texture using GDI. This is done by getting the texture's surface and then calling surface->GetDC(). The only problem is, that this cannot be done for textures that contain alpha channels. Even if I create a temporary "GDI" texture, which has no alpha channel, and then copy from it into the real texture, the alpha values will be destroyed (set to 0). There are two solutions I can think of, and both seem very inefficient: 1) update the alpha values manually, by locking the texture. 2) Create an alpha-only texture (i.e. D3DFMT_A8) that contains the alpha map of the texture, and configure the texture stage states so that the alpha values will be taken from there. I would appreciate any other idea to solve this problem. Thanks, Uri.
Advertisement
Quote:Original post by UriKiller
Hello,
I am trying to draw into a texture using GDI. This is done by getting
the texture's surface and then calling surface->GetDC().
The only problem is, that this cannot be done for textures that contain
alpha channels. Even if I create a temporary "GDI" texture, which has no alpha channel, and then copy from it into the real texture, the alpha values
will be destroyed (set to 0).
There are two solutions I can think of, and both seem very inefficient:
1) update the alpha values manually, by locking the texture.
2) Create an alpha-only texture (i.e. D3DFMT_A8) that contains the alpha map
of the texture, and configure the texture stage states so that the alpha
values will be taken from there.

I would appreciate any other idea to solve this problem.

Thanks,
Uri.
What GDI functions do you need? The GDI functions are pretty slow, and you definitely shouldn't be using them to update a texture every frame; so you should be using GDI just at creation time, in which case 1) is a perfectly reasonably option.
I do not update the texture every frame, using the GDI functions. But I do
draw on the texure occasionaly (this is a GUI engine, so each change inside
the window is such an occasion) using GDI functions such as:
Brush functions: FillRect()
Text Functions: DrawText(), GetTextExtentPoint32().
Pen/Line functions: MoveToEx, LineTo.
And maybe more.

I know that some of these may be replaced with D3DX helper classes, but
if I would want to replace all these functions with D3D/D3DX ones, I would have
to reimplement many stuff.

I also find it simpler to use the GDI functions, and most of them aren't slower
when drawing into memory textures.
What Steve meant was, GDI methods are slow in general because they're executed on the CPU. Direct2D will pull all this functionality onto the GPU, using the CPU as a fallback only when necessary, but that's a Windows 7 feature and requires the beta SDK to use. Might be worth looking into regardless, but in the meantime, you really are better off unifying your engine to a single API, in this case DirectX. Interop is great when it's necessary; in your case it doesn't sound necessary, and you'll probably find more creative uses for your GDI-less methods once they're running faster.

GDNet+. It's only $5 a month. You know you want it.

You should be using render targets instead of dynamic textures with GDI to do your GUI. FillRect's equivalent in DirectX is Clear(), DrawText can be accomplished with D3DX's D3DXFont class (or make your own), Lines can be drawn using either custom textures or with LineStrip primitives.

I normally make lines a part of GUI's background texture and same with all the state images for the buttons of the same GUI window, so I have a lower penalty with less texture switches. But if you were going to have a texture just to draw a line, swithing states for drawing colored lines is probably going to be cheaper. Then there is also D3DXLine which draws beautiful anti-aliased lines, but I couldn't use it myself because it has a different batching mechanism than D3DXSprite, so using it would require breaking a sprite batch (which means I have to track where that batch was started, and restart it afterwards, etc, etc, lots of work)

Last thing is, you can't use alpha with GDI functions because they don't properly handle alpha (that's something you already read in D3D docs).

This topic is closed to new replies.

Advertisement