PDA

View Full Version : DirectDraw object without DXDraw1 component



anubis79
16-01-2004, 02:42 PM
Again me. I need a DirectDraw object and it's surfaces that aren't created from DXDraw1.DDraw. Is it possible in Delphix and how?

Clootie
17-01-2004, 04:34 PM
DirectDrawCreate / DirectDrawCreateEx ...

anubis79
18-01-2004, 12:17 PM
At the end I've created a Directdraw object and surfaces. Now please look at these codes. They use DelphiX header but a question will come for you.var
Form1: TForm1;
TDDR: IDirectDraw; // temporary interface to query IDirectDraw7
DDR: IDirectDraw7; // DirectDraw object
PS: IDirectDrawSurface7; // a Primary Surface
OSS: IDirectDrawSurface7; // an off-screen surface
SD: TDDSurfaceDesc2; // Surface description
Bitmap: TBitmap;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
Bitmap := TBitmap.Create;
Bitmap.LoadFromFile('your bmp');

DirectX.DirectDrawCreate(nil, TDDR, nil);
TDDR.QueryInterface(DirectX.IID_IDirectDraw7, DDR); // look for IDirectDraw7
TDDR := nil; // now we don't need it. Because we have DDR from IDirectDraw7

DDR.SetCooperativeLevel(Form1.Handle, DirectX.DDSCL_NORMAL); // sharing desktop
{and we don't describe a Display Mode so GDI's Display mode is valid}

FillChar(SD, Sizeof(TDDSurfaceDesc2), 0);
SD.dwSize := Sizeof(TDDSurfaceDesc2);
SD.dwFlags := DirectX.DDSD_CAPS;
SD.ddsCaps.dwCaps := DirectX.DDSCAPS_PRIMARYSURFACE;

DDR.CreateSurface(SD, PS, nil); // we get a described primary surface

FillChar(SD, Sizeof(TDDSurfaceDesc2), 0); // planning an off-screen surface
SD.dwSize := Sizeof(TDDSurfaceDesc2);
SD.dwFlags := DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH;
SD.ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN;
SD.dwHeight := Bitmap.Height;
SD.dwWidth := Bitmap.Width;

DDR.CreateSurface(SD, OSS, nil); // have an off-screen surface

end;

procedure TForm1.Button1Click(Sender: TObject);
var
Can: TCanvas;
VDC: HDC;
begin
Can := TCanvas.Create;
OSS.GetDC(VDC); // capture an DC for using a var Canvas (Can)
Can.Handle := VDC; // using the same memory
Can.Draw(0, 0, Bitmap);
OSS.ReleaseDC(VDC); // After drawing release must be called.
PS.BltFast(Form1.ClientOrigin.X,Form1.ClientOrigin .Y, OSS, Bitmap.Canvas.ClipRect, DDBLTFAST_WAIT);
Can.Handle := 0;
Can.Free;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Bitmap.Free;
end;

If you compile it you will see your bmp on the form. My aim was to create an independent off-screen which not get the same BPP with Primary Surface. To realize it add DDSD_PIXELFORMAT to the dwFlags and after SD.dwWidth := Bitmap.Width add SD.ddpfPixelFormat.dwRGBBitCount := 8; and code will be changed like this:
var
Form1: TForm1;
TDDR: IDirectDraw; // temporary interface to query IDirectDraw7
DDR: IDirectDraw7; // DirectDraw object
PS: IDirectDrawSurface7; // a Primary Surface
OSS: IDirectDrawSurface7; // an off-screen surface
SD: TDDSurfaceDesc2; // Surface description
Bitmap: TBitmap;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
Bitmap := TBitmap.Create;
Bitmap.LoadFromFile('your bmp');

DirectX.DirectDrawCreate(nil, TDDR, nil);
TDDR.QueryInterface(DirectX.IID_IDirectDraw7, DDR); // look for IDirectDraw7
TDDR := nil; // now we don't need it. Because we have DDR from IDirectDraw7

DDR.SetCooperativeLevel(Form1.Handle, DirectX.DDSCL_NORMAL); // sharing desktop
{and we don't describe a Display Mode so GDI's Display mode is valid}

FillChar(SD, Sizeof(TDDSurfaceDesc2), 0);
SD.dwSize := Sizeof(TDDSurfaceDesc2);
SD.dwFlags := DirectX.DDSD_CAPS;
SD.ddsCaps.dwCaps := DirectX.DDSCAPS_PRIMARYSURFACE;

DDR.CreateSurface(SD, PS, nil); // we get a described primary surface

FillChar(SD, Sizeof(TDDSurfaceDesc2), 0); // planning an off-screen surface
SD.dwSize := Sizeof(TDDSurfaceDesc2);
SD.dwFlags := DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH or DDSD_PIXELFORMAT;
SD.ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN;
SD.dwHeight := Bitmap.Height;
SD.dwWidth := Bitmap.Width;
SD.ddpfPixelFormat.dwRGBBitCount := 8;

DDR.CreateSurface(SD, OSS, nil); // have an off-screen surface

end;

procedure TForm1.Button1Click(Sender: TObject);
var
Can: TCanvas;
VDC: HDC;
begin
Can := TCanvas.Create;
OSS.GetDC(VDC); // capture an DC for using a var Canvas (Can)
Can.Handle := VDC; // using the same memory
Can.Draw(0, 0, Bitmap);
OSS.ReleaseDC(VDC); // After drawing release must be called.
PS.BltFast(Form1.ClientOrigin.X,Form1.ClientOrigin .Y, OSS, Bitmap.Canvas.ClipRect, DDBLTFAST_WAIT);
Can.Handle := 0;
Can.Free;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Bitmap.Free;
end;

When you compile and click the button1 you will have an exception. Why?I need your helps. What is the problem with it? Please give some advice about it.