April 26, 2024, 10:11:23 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Button Controls in a Direct X window

Started by GWS, May 31, 2012, 02:47:35 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

GWS

May 31, 2012, 02:47:35 PM Last Edit: June 03, 2012, 11:42:48 AM by GWS
Hi,

A problem when using 2D/3D DirectX screens in a game program, is that the usual GDI windows buttons don't behave well with DX screens, if they work at all.

DirectX "owns" the drawing surface of a buffer so it will happily overwrite any GDI drawn controls like buttons.

As soon as you do a FLIP you are telling DirectX to overwrite everything on the drawing surface with the contents of the backbuffer, including any controls. The controls are still there, there just isn't a connection between DX and GDI that would tell the buttons to redraw themselves everytime you flip a buffer.

Some controls are horrendously slow to invalidate and redraw, at least in terms of frames per second.

If you had a game, and it had to wait for a bunch of GDI controls to redraw on every flip, then your game would be very jittery and jerky.

The GDI subsystem isn't synchronous, which means there is no guarantee by the OS when a control will be redrawn, just that it will be redrawn "sometime" in the future when it is invalidated.

For an office application you don't notice it, since the speed of invalidating a window, which all controls are based on, isn't as important as the function of the program.

But for a 2D program that depends on how fast a buffer can be rendered and flipped the speed of updating the contents of that buffer are paramount.

The majority of 2D game writers choose to create their own buttons and controls.

It's much faster to draw a few sprites and use the built in collision detecting routines.

The following example uses a 2x2 sprite as a 'hotspot' pointer to follow the cursor, and a bitmap for the 'control' button.

Then on a mouse down event, move the 2x2 sprite to the mouse position and do a collision test. (You could even animate the buttons by using as many frames for the sprite as you want).

[I'm indebted to Paul for the above explanation of how DX screens relate to GDI controls]

The only snag is when positioning the hotspot using @mouseX and @mouseY.

The @mouseY value is affected by the window's caption bar which is about 18 pixels high.  So you need to use @mouseY + 18 for the vertical position of the hotspot sprite.

The bitmap 'button' that you use is probably best left blank - then you can add the text explaining it's function from within your program as in the following program.  This allows you to reuse the button, with the font, text and text colour to suit the application.

A test program is attached ..

all the best, :)

Graham



Tomorrow may be too late ..

GWS

Whoops ! .. I'd left the point sprite visible while trying it out.

I've made it now so you can't see the point as you click the mouse on the screen away from the button.

I've placed the modified version in the first post.  :)

The attachment below contains some pretty buttons that you might find a use for.  They can be easily modified for size and colour in any graphics program.

Graham
Tomorrow may be too late ..

GWS

OK, last change ..  ::)

The position of the mouse given by mouseX and mouseY was bothering me.
They are affected by the window caption and the borders.  So to get an accurate value, a correction factor is required.

I've added these to the program in the first post, which is now accurate.

The corrections are: kx = (7 * mx / wW + 0.5) and  ky = (26 * my / wH + 0.5)

.. where 7 is the width of the borders in pixels, 26 is the height of the caption in pixels.
   mx = mouseX and my = mouseY
   wW = the window width, and wH is the window height.

(The 0.5 is just to round the calculation to the nearest integer value).

This shouldn't be a problem in a fullscreen window, but I haven't tried that yet.

So that's it - I'm happy now ..  ;D

all the best, :)

Graham


Tomorrow may be too late ..