Tuesday, September 22, 2009

Touch Demo Part I

Over the next few posts I am going to walk you through building one of the touch demos I used in my CodeRage 4 Session. This demo demonstrates using Direct2D and the WM_TOUCH message. Before we get started here is a brief explanation of these two technologies.

Since Windows Vista GDI has become a legacy drawing API supported with software rendering on top of Direct3D. Direct3D is great but it is very raw. This is where Direct2D shines for applications. Direct2D has all the performance benefits of Direct3D and adds support for bitmaps and text and support for GDI Interop all with a much simpler API. And Delphi 2010 has made it even simpler by wrapping it up with a TDirect2DCanvas that is very similar to TCanvas. Direct2D supports remote rendering through Remote Desktop which is very cool.

WM_TOUCH is the raw multi-touch message that provides various states of contact with the input digitizer for hot sizzling touch applications.

Now that we got that out of the way, create yourself a VCL Application. We want to start painting with Direct2D so add Direct2D and D2D1 to the uses and a TDirect2DCanvas property to your form like this:


private
FCanvas: TDirect2DCanvas;
...
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

property Canvas: TDirect2DCanvas read FCanvas
write FCanvas;
end;
...
constructor TTouchForm.Create(AOwner: TComponent);
begin
inherited;
FCanvas := TDirect2DCanvas.Create(Handle);
end;

destructor TTouchForm.Destroy;
begin
FCanvas.Free;
inherited;
end;

This creates a Direct2D surface (TDirect2DCanvas) that we can draw to instead of the traditional GDI surface (TCanvas).

Depending on the type of application you build you may experience some flicker. To avoid this handle the message WM_ERASEBKGND and returns true.

procedure TTouchForm.WMEraseBkgnd(
var Message: TWMEraseBkgnd);
begin
Message.Result := 1;
end;

Next override Paint and just draw a line:

procedure TTouchForm.Paint;
begin
Canvas.BeginDraw;
try
Canvas.Pen.Color := clRed;
Canvas.MoveTo(10, 10);
Canvas.LineTo(40, 40);
finally
Canvas.EndDraw;
end;
end;

If you run your application at this point and resize the form you will noticed that the line changes size. This is because the view port is resizing to scale to the window and your line will do the same. To prevent this override the Resize method and add the following:

procedure TTouchForm.Resize;
var
HwndTarget: ID2D1HwndRenderTarget;
begin
inherited;
if Supports(Canvas.RenderTarget,
ID2D1HwndRenderTarget, HwndTarget) then
HwndTarget.Resize(D2D1SizeU(ClientWidth, ClientHeight));
Invalidate;
end;

Now you have a form that renders everything drawn to the Canvas through a Direct2D surface.

UPDATE: Added Invalidate to Resize because when resizing the window larger it will force a redraw but smaller will not because typically a redraw isn't required.

7 comments:

Anonymous said...

your tutorial is realy exiting... finllay now i know how to handle realy multitouch inputs, not only these gestures. my testproject worked realy well.. but i still cannot figure out the multibutton handling...
can you maybe post the sourcecode of your touchmove project that i get some light into the dark ? ;-)

Chris Bensen said...

This project will be the entire TouchMove project. So keep reading...

Anonymous said...

Just gave it a try here on Win7, and I notice that it only redraws when you make the window larger, not smalller.

I am wondering if that is to be expected here?

Chris Bensen said...

Anonymous,

Oh yeah. Add an Invalidate in the Resize method. I just updated the example.

Paracet PainRelieve said...

Noooo , I can not run This DEMO at all.
It's Error in Form create events at
=============================================
FCanvas := TDirect2DCanvas.Create(Handle);
=============================================
with message Access violation At address XXXXXXXX
in module TouchMove1.exe . Read of Address 00000000

It's seem to Call nil object.

Chris Bensen said...

@Paracet - are you by any chance debugging the project? There is a video driver bug for some brands of video cards (ATI I believe) that prevents debugging Direct2D. Try running without debugging.

Paracet PainRelieve said...

Oh my god, im so unfortune i used ATI Card.

Post a Comment