PDA

View Full Version : DirectDraw Hello World



sekelsenmat
24-02-2007, 04:33 PM
Hi,

I am trying to create a DirectX extremely simple application with Lazarus and clootie headers for Pascal.

I tryed to convert some c++ code to pascal, but it uses the old procedural interface that doesn¬„t seam to be on clooties headers. The headers come with lot¬„s of examples, but they are all for Direct3D, and not DirectDraw.

Basically I want to transform the IDirectDraw interface into a object, and then call 2 functions from that object, SetCooperativeLevel and CreateSurface.

But I never utilized COM or DirectX before, so I have no idea where to begin... can anyone help me?

thanks,

savage
24-02-2007, 10:21 PM
I would suggest you join the JEDI-DirectXExamples ( http://groups.yahoo.com/group/JEDI-DirectXExamples/join ), if you go the file area you should find a native non-VCL DirectDraw example that I ported a few years ago as well as a few other examples that were ported from the Direct X SDK.

Note that I will need to approve you joining tthe mailing list to avoid Spam, so please be descriptive in the reason for joining the mailing list so I know it's you and not some Spam bot.

Clootie
25-02-2007, 11:50 AM
It looks you are converting not C++ but "pure" C code. MS provides special "object to procedural" layer for "C" compilers. There is no need for such thing in ObjectPascal.

So generally if you see IDirectDraw_Create(handle, bla-bla); call in C code you should convert it as:
var
handle: IDirectDraw;
begin
...
handle.Create(bla-bla)
...

savage
25-02-2007, 03:17 PM
If you can't be bothered joining up, have a look at this from DDUtil.pas and see if it works with FPC...


function TDisplay.CreateFullScreenDisplay( h_Wnd : HWND; dwWidth, dwHeight, dwBPP : LongWord ) : HRESULT;
var
hr : HRESULT;
ddsd : TDDSURFACEDESC2;
ddscaps : TDDSCAPS2;
begin
// Cleanup anything from a previous call
DestroyObjects;

// DDraw stuff begins here
hr := DirectDrawCreateEx( nil, m_pDD, IID_IDirectDraw7, nil );
if ( hr <> DD_OK ) then
begin
result := E_FAIL;
exit;
end;

// Set cooperative level
hr := m_pDD.SetCooperativeLevel( h_Wnd, DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN );
if ( hr <> DD_OK ) then
begin
result := E_FAIL;
exit;
end;

// Set the display mode
hr := m_pDD.SetDisplayMode( dwWidth, dwHeight, dwBPP, 0, 0 );
if ( hr <> DD_OK ) then
begin
result := E_FAIL;
exit;
end;


// Create primary surface (with backbuffer attached)
FillChar( ddsd, SizeOf( ddsd ), 0 ); //ZeroMemory( @ddsd, SizeOf( ddsd ) );
ddsd.dwSize := SizeOf( ddsd );
ddsd.dwFlags := DDSD_CAPS or DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or DDSCAPS_COMPLEX or DDSCAPS_3DDEVICE;
ddsd.dwBackBufferCount := 1;

hr := m_pDD.CreateSurface( ddsd, m_pddsFrontBuffer, nil );
if ( hr <> DD_OK ) then
begin
result := E_FAIL;
exit;
end;

// Get a pointer to the back buffer
FillChar( ddscaps, SizeOf( ddscaps ), 0 ); //ZeroMemory( @ddscaps, SizeOf( TDDSCAPS2 ) );
ddscaps.dwCaps := DDSCAPS_BACKBUFFER;

hr := m_pddsFrontBuffer.GetAttachedSurface( ddscaps, m_pddsBackBuffer );
if ( hr <> DD_OK ) then
begin
result := E_FAIL;
exit;
end;

m_hWnd := h_Wnd;
m_bWindowed := false;
UpdateBounds;

FWidth := dwWidth;
FHeight := dwHeight;

result := DD_OK;
end;

or

function TDisplay.CreateWindowedDisplay( h_Wnd : HWND; dwWidth, dwHeight : LongWord ) : HRESULT;
var
hr : HRESULT;
rcWork : TRect;
rc : TRect;
dwStyle : LongWord;
pcClipper : IDIRECTDRAWCLIPPER;
ddsd : TDDSURFACEDESC2;
begin
// Cleanup anything from a previous call
DestroyObjects;

// DDraw stuff begins here
hr := DirectDrawCreateEx( nil, m_pDD, IID_IDirectDraw7, nil );
if ( hr <> DD_OK ) then
begin
result := E_FAIL;
exit;
end;

// Set cooperative level
hr := m_pDD.SetCooperativeLevel( h_Wnd, DDSCL_NORMAL );
if ( hr <> DD_OK ) then
begin
result := E_FAIL;
exit;
end;

// If we are still a WS_POPUP window we should convert to a normal app
// window so we look like a windows app.
dwStyle := GetWindowLong( h_Wnd, GWL_STYLE ); //GetWindowStyle( h_Wnd );
dwStyle := dwStyle and not WS_POPUP;
dwStyle := dwStyle or WS_OVERLAPPED or WS_CAPTION or WS_THICKFRAME or WS_MINIMIZEBOX;
SetWindowLong( h_Wnd, GWL_STYLE, dwStyle );

// Aet window size
SetRect( rc, 0, 0, dwWidth, dwHeight );

AdjustWindowRectEx( rc, GetWindowLong( h_Wnd, GWL_STYLE ) {GetWindowStyle(h_Wnd)}, ( GetMenu( h_Wnd ) <> 0 ), GetWindowLong( h_Wnd, GWL_EXSTYLE ) {GetWindowExStyle(h_Wnd) } );

SetWindowPos( h_Wnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE );

SetWindowPos( h_Wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or SWP_NOACTIVATE );

// Make sure our window does not hang outside of the work area
SystemParametersInfo( SPI_GETWORKAREA, 0, @rcWork, 0 );
GetWindowRect( h_Wnd, rc );
if ( rc.left < rcWork.left ) then
rc.left := rcWork.left;
if ( rc.top < rcWork.top ) then
rc.top := rcWork.top;
SetWindowPos( h_Wnd, 0, rc.left, rc.top, 0, 0, SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE );

// Create the primary surface
FillChar( ddsd, SizeOf( ddsd ), 0 ); //ZeroMemory( @ddsd, SizeOf( ddsd ) );
ddsd.dwSize := SizeOf( ddsd );
ddsd.dwFlags := DDSD_CAPS;
ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE;

hr := m_pDD.CreateSurface( ddsd, m_pddsFrontBuffer, nil );
if ( hr <> DD_OK ) then
begin
result := E_FAIL;
exit;
end;


// Create the backbuffer surface
ddsd.dwFlags := DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN or DDSCAPS_3DDEVICE;
ddsd.dwWidth := dwWidth;
ddsd.dwHeight := dwHeight;

hr := m_pDD.CreateSurface( ddsd, m_pddsBackBuffer, nil );
if ( hr <> DD_OK ) then
begin
result := E_FAIL;
exit;
end;

hr := m_pDD.CreateClipper( 0, pcClipper, nil );
if ( hr <> DD_OK ) then
begin
result := E_FAIL;
exit;
end;

hr := pcClipper.SetHWnd( 0, h_Wnd );
if ( hr <> DD_OK ) then
begin
pcClipper := nil;
result := E_FAIL;
exit;
end;

hr := m_pddsFrontBuffer.SetClipper( pcClipper );
if ( hr <> DD_OK ) then
begin
pcClipper := nil;
result := E_FAIL;
exit;
end;

// Done with clipper
pcClipper := nil;

m_hWnd := h_Wnd;
m_bWindowed := true;
UpdateBounds;

FWidth := dwWidth;
FHeight := dwHeight;

result := DD_OK;
end;

sekelsenmat
26-02-2007, 08:17 PM
Thanks, I managed to get it working =)