tasks

  • when new text is displayed on a target object, clear/erase the old text bubble first
  • separate actions in defaultactions.cpp
  • introduce stream versioning
  • replace stream/destream operators by save/load functions
  • implement clone function in context menu
  • add spawn window to spawn button
  • open creator window upon button press
  • allow for new actions that enable/disable target actions or triggers (see next post)
  • new member for actions/triggers: m_bEnabled
  • clean up source of group and window classes – lots of unnecessary code now that they contain a grid that does the layouting for them

actions & triggers

recent additions to the UI and the action/trigger mechanism has enabled me to add triggers to objects which in turn start actions as they fire.
Actions can have a set of follow-up actions which are executed once the first action has finished.

All of this can be configured in the user interface, using a generic configuration window approach.
The only thing(s) left to do are:

  • write access modifiers for each of the action’s / trigger’s properties
  • update the methods that create the generic editor boxes to reflect the interface change (so that the properties can be configured using the new access modifiers)
  • ultimately write stream/destream operators or save/load methods for the actions & triggers so the whole configuration can be stored in the world file.

quick video of the UI in action:

Alpha blending in render targets

rendering UI elements can be very time consuming – especially when multiple layers of stacked objects such as containers and windows are being drawn semi-transparently.

One way of reducing rendering time i<pre lang=”cpp”>s to cache certain UI elements – a window for example usually remains the same until it has changed its size or displays new content. Since that happens extremely rarely when compared to the ~60 times a second it is being rendered, caching seems like a sensible move.

There’s only one problem:

rendering (semi-)transparent elements to a render target doesn’t exactly work the way you’d expect it to. This is due to the fact that during rendering, pixels get blended together using a set of render states and texture stage states. If the color of a pixel gets computed using a certain blend function, its alpha value gets computed the same way. This usually results in oddly looking UI elements with parts that have a higher transparency than intended.

Googling for a while has brought up the idea of premultiplied alpha channels which – in some cases – help. The idea behind this is to (as the name implies) premultiply a pixel’s alpha value with its color components.

This seems to work fine for single-layered elements. As soon as several UI elements overlap (a transparent button inside a window for example), this method fails as well.

Some more research brought up a DirectX9 renderstate that can be activated to enable a different blending operation for alpha values.

D3DRS_SEPARATEALPHABLENDENABLE

What this renderstate – once enabled – does is allow to set a different blend function for alpha values of a pixel.

pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA)
pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);

This snippet blends the color components of a pixel together using their respective alpha values as one would expect:

res.rgb =p0.rgb * (1 – p1.a) + p1.rgb * p1.a;

But the alpha component of the resulting pixel gets computed differently:

res.a = p0.a * (1 – p1.a)  + p1.a;

I’m still experimenting with this, but it seems to be a step in the right direction.

p.s.

a quick performance check of caching UI elements vs. not caching them turned out to reduce rendering time for my example scene to almost 50%.

screenshots

motion blur and shadowed grass in action

shadow_on_grassmotionblur

threading in directx:

enabling thread-safety in directx weighs in with about 7-8% performance loss. If resources such as vertex buffers have to be created in different threads while the engine is rendering, there’s no way around that.

Put it down as a sacrifice to the graphics gods, swallow hard twice and move on.