2
\$\begingroup\$

I am trying to implement a relatively simple GUI system for use in a few simple games.

In this system, all Gui elements extend BaseControl. BaseControl has an update and draw method, as well as various parameters applicable to all controls (clipping, transforms, etc).

Let's say I have a Panel element, which contains other elements. The panel element will pass all its children a render target when it wants them to draw themselves.

There is a button that exists partially outside the bounds of the panel. If clipping is enabled in the panel, that button should show up clipped at the panel boundary. The button doesn't know it is out of bounds of its parent, nor should the button have to check if it needs to be clipped, or if clipping is enabled, or if a specific transform should be applied to it, etc.

Here's how I was going to go about handling clipping and other effects that should be controlled by the BaseControl class and not derived controls. Each control has an ID2D1BitmapRenderTarget, and they draw what they want onto it. When the BaseControl's internal Draw method gets what the derived control drew to it, it can modify it, get a Bitmap from its render target, and draw the bitmap to the parent's target.

So for example, if the parent is that panel with clipping enabled, it can perform any clipping on its internal Bitmap (which its children have drawn onto) before drawing that onto the window render target. Button draws to its own render target. Get bitmap from button's render target that is drawn to the Panel. The panel gets the bitmap from its render target, and clips the bitmap before drawing the contents to the window render target.

Right now, everything is drawing to a single render target (the window's render target). The problem is, once something is drawn to it, that drawing can't be editted. So if the internal draw method of a BaseControl, for example, had properties set to clip whatever the derived code drew, it would have no way to clip the now already drawn image without affecting other GUI controls or content drawn by other parts of the game.

Is it safe to have potentially a lot of ID2D1BitmapRenderTarget instances like this (there would be 1 for every control)? Is it as safe to make a lot of ID2D1BitmapRenderTargets as it is to make an ID2D1SolidColorBrush per control? Or is there a much better, more common sense way to accomplish what I'm trying to do that would only use one render target?

\$\endgroup\$
0
\$\begingroup\$

Okay, I think I've figured out how to properly do what I'm trying to do. I need to use the Direct2D ID2D1RenderTarget's layering and clipping abilities.

  1. Clipping can be done using PushAxisAlignedClip and PopAxisAlignedClipfunctions of the Render Target. Pass in the rectangle you want that represents the area that should be preserved to the Push function. Perform Draw calls. When the Pop function is called, only the region specified by the rectangle passed to the Push function will be drawn.
  2. Layering can be done using the PushLayer and PopLayer functions of the Render Target. All calls after the Push will be placed in a separate layer, and these will be finalized and "flattened" on the call to PopLayer. Microsoft recommends using layers sparingly on Windows 7 and back. Windows 8 and forward apparently have major enhancements done in the layering code, and it is recommended to use them.

If you didn't notice, the Push and Pop functions imply clipping and layering can be stacked on top of each other.

Using these two methods, I can now use a single render target that all controls can draw directly to, where Pushing and Popping clips and layers allow controls their own "sections" of the render target before finalizing draws. I believe this is the proper way to accomplish what I need to do.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.