الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

please help for this DirectDraw Code

مغلق
بدأه aeamg2005 في 1 يونيو 2007 · 1 رد · 1,514 مشاهدة · في DirectX
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

what is the error in the following code

it's compiles successfully but with no output on the screen


#include <windows.h>
#include <ddraw.h>

HWND main_window_handle;
HINSTANCE hinstance_app;

LPDIRECTDRAW lpDD; // DirectDraw object defined in DDRAW.H
LPDIRECTDRAWSURFACE lpDDSPrimary; // DirectDraw primary surface
LPDIRECTDRAWSURFACE lpDDSBack; // DirectDraw back surface
LPDIRECTDRAWPALETTE lpDDpal;

LPDIRECTDRAWSURFACE lpDDSOne;
LPDIRECTDRAWSURFACE lpDDSMySprite;


bool DirectDrawInit(HWND hwnd);
bool CreatePrimarySurface();
void UpdateFrame(void);
void finiObjects( void );
void InitBackGroundAndSprite();

IDirectDrawSurface* DDLoadBitmap(IDirectDraw* pDD, LPCSTR szBitmap);
IDirectDrawSurface* CreateOffScreenSurface(IDirectDraw* pDD, int dx, int dy);
HRESULT DDCopyBitmap(IDirectDrawSurface* pDDS, HBITMAP hbm, int dx, int dy);
IDirectDrawPalette* DDLoadPalette(IDirectDraw* pDD, LPCSTR szBitmap);


// macros for dealing with keyboard
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)



LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

// WINMAIN ////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance,
LPSTR lpcmdline, int ncmdshow)
{
WNDCLASSEX winclass; // this holds the class we create
HWND hwnd; // generic window handle
MSG msg; // generic message
//HDC hdc; // graphics device context
char* WINDOW_CLASS_NAME = "MyClass";

// first fill in the window class structure
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WndProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

// save hinstance in global
hinstance_app = hinstance;

// register the window class
if (!RegisterClassEx(&winclass))
return(0);

// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
WINDOW_CLASS_NAME, // class
"Direct Draw on the fly", // title
WS_POPUPWINDOW | WS_VISIBLE,
200,200, // initial x,y
550,450, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
hinstance, // instance of this application
NULL))) // extra creation parms
return(0);

// save main window handle
main_window_handle = hwnd;

// initialize game here
DirectDrawInit(hwnd);
CreatePrimarySurface();
InitBackGroundAndSprite();

::MessageBox(0,"game init is ok",0,0);
// enter main event loop
while(TRUE)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT)
break;

// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end if

// main game processing goes here
UpdateFrame();
} // end while

// closedown game here
finiObjects();

// return to Windows like this
return(msg.wParam);
} // end WinMain

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM
wParam, LPARAM lParam)
{
// Step # 10 WinProc - The switch statement for handling windows messages
switch (iMsg)
{
case WM_DESTROY :
PostQuitMessage (0);
return 0;
}

return DefWindowProc (hwnd, iMsg, wParam, lParam);
}


/*
* Function to initialize DirectDraw
* Demonstrates:
* 1) Creating the Direct Draw Object
* 2) Setting the Cooperative level
* 3) Setting the Display mode
*
*/
bool DirectDrawInit(HWND hwnd)
{
HRESULT ddrval;

/*
* Create the main DirectDraw object.
*
* This function takes care of initializing COM and Constructing
* the DirectDraw object.
*/
ddrval = DirectDrawCreate(NULL, &lpDD, NULL);
if(ddrval != DD_OK)
{
return false;
}

/*
* The cooperative level determines how much control we have over the
* screen. This must at least be either DDSCL_EXCLUSIVE or DDSCL_NORMAL
*
* DDSCL_EXCLUSIVE allows us to change video modes, and requires
* the DDSCL_FULLSCREEN flag, which will cause the window to take over
* the fullscreen. This is the preferred DirectDraw mode because it allows
* us to have control of the whole screen without regard for GDI.
*
* DDSCL_NORMAL is used to allow the DirectDraw app to run windowed.
*/
ddrval = lpDD->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if(ddrval != DD_OK)
{
lpDD->Release();
return false;
}

/*
* Set the video mode to 640x480x8
* This is allowed because we have set exclusive mode above
*/
ddrval = lpDD->SetDisplayMode(640, 480, 8);
if(ddrval != DD_OK)
{
lpDD->Release();
return false;
}

return(true);
}


/*
* Create a Primary surface that is flippable, with an
* attached backbuffer
*/
bool CreatePrimarySurface()
{
DDSURFACEDESC ddsd;
DDSCAPS ddscaps;
HRESULT ddrval;

// Create the primary surface with 1 back buffer
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;

ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
if(ddrval != DD_OK)
{
lpDD->Release();
return false;
}

// Get the pointer to the back buffer
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
if(ddrval != DD_OK)
{
lpDDSPrimary->Release();
lpDD->Release();
return false;
}

return(true);
}


/*
* Function to create an offscreen surface and load a bitmap from
* disk into it. The szBitmap field is the filename of the Bitmap.
*/
IDirectDrawSurface* DDLoadBitmap(IDirectDraw* pDD, LPCSTR szBitmap)
{
HBITMAP hbm;
BITMAP bm;
IDirectDrawSurface* pDDS;

// LoadImage has some added functionality in Windows 95 that allows
// you to load a bitmap from a file on disk.
hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if(hbm == NULL)
return NULL;

GetObject(hbm, sizeof(bm), &bm); // get size of bitmap

/*
* create a DirectDrawSurface for this bitmap
* source to function CreateOffScreenSurface() follows immediately
*/

pDDS = CreateOffScreenSurface(pDD, bm.bmWidth, bm.bmHeight);
if(pDDS) {
::MessageBox(0,"loading bitmap into memory is ok",0,0);
DDCopyBitmap(pDDS, hbm, bm.bmWidth, bm.bmHeight);
}

DeleteObject(hbm);

return pDDS;
}


/*
* Creates a DirectDraw Surface of a specified size
* This surface will be in video memory if enough is
* available, otherwise it will be created in system memory
*/
IDirectDrawSurface* CreateOffScreenSurface(IDirectDraw* pDD, int dx, int dy)
{
DDSURFACEDESC ddsd;
IDirectDrawSurface *pDDS;

//
// create a DirectDrawSurface for this bitmap
//
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwHeight = dy;
ddsd.dwWidth = dx;

if(pDD->CreateSurface(&ddsd, &pDDS, NULL) != DD_OK)
{
return NULL;
} else {
return pDDS;
}
}


/*
* This function copies a previously loaded bitmap into a DirectDraw surface.
* Notice that we can obtain a GDI style device context for a
* DirectDraw surface, with which to BitBlt the bitmap into the
* surface.
*/
HRESULT DDCopyBitmap(IDirectDrawSurface* pDDS, HBITMAP hbm, int dx, int dy)
{
HDC hdcImage;
HDC hdc;
HRESULT hr;
HBITMAP hbmOld;

//
// select bitmap into a memoryDC so we can use it.
//
hdcImage = CreateCompatibleDC(NULL);
hbmOld = (HBITMAP)SelectObject(hdcImage, hbm);

if ((hr = pDDS->GetDC(&hdc)) == DD_OK)
{
BitBlt(hdc, 0, 0, dx, dy, hdcImage, 0, 0, SRCCOPY);
pDDS->ReleaseDC(hdc);
}

SelectObject(hdcImage, hbmOld);
DeleteObject(hdcImage);

return(hr);
}



/*
We need to set the palette for the primary surface. This implies that all of the
bitmaps that are created for the game should all have been created with the same
palette. Here is a function to create a DirectDraw palette for a given bitmap
*/

/*
* Creates a DirectDraw palette for a given bitmap on disk.
* The parameter szBitmap is the file name of the bitmap.
*
*/
IDirectDrawPalette* DDLoadPalette(IDirectDraw* pDD, LPCSTR szBitmap)
{
IDirectDrawPalette* DDpal;
int i;
int n;
int fh;
PALETTEENTRY ape[256];

if(szBitmap && (fh = _lopen(szBitmap, OF_READ)) != -1)
{
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;

_lread(fh, &bf, sizeof(bf));
_lread(fh, &bi, sizeof(bi));
_lread(fh, ape, sizeof(ape));
_lclose(fh);

if (bi.biSize != sizeof(BITMAPINFOHEADER))
n = 0;
else if (bi.biBitCount > 8)
n = 0;
else if (bi.biClrUsed == 0)
n = 1 << bi.biBitCount;
else
n = bi.biClrUsed;

//
// a DIB color table has its colors stored BGR not RGB
// so flip them around.
//
for(i=0; i<n; i++ )
{
BYTE r = ape.peRed;
ape.peRed = ape.peBlue;
ape.peBlue = r;
}
}

if(pDD->CreatePalette(DDPCAPS_8BIT, ape, &DDpal, NULL) != DD_OK)
{
return NULL;
} else {
return DDpal;
}
}
/*
Next we set this palette to the primary surface like this:

lpDDPal = DDLoadPalette(lpDD, szBitmap); // Call the function above to load the palette

if (lpDDPal)
lpDDSPrimary->SetPalette(lpDDPal); // this sets the palette for the primary surface

*/


/*
// Set the color key for this bitmap.
//
// Whatever color is at entry 255 in the palette will be the
// transparent color for blits. This color is black unless
// you used the DDPCAPS_ALLOW256 flag when the palette was
// created

DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = 0xff;
ddck.dwColorSpaceHighValue = 0xff;

// lpDDSSomeBitmapSurface is a DirectDraw surface with a
// bitmap loaded into it. This needs to be done for each
// surface containing a bitmap.
lpDDSSomeBitmapSurface->SetColorKey( DDCKEY_SRCBLT, &ddck );
*/


void UpdateFrame(void)
{
// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
SendMessage(main_window_handle,WM_CLOSE,0,0);

RECT rcRect;
HRESULT ddrval;
int xpos, ypos;

// Blit the stuff for the next frame
SetRect(&rcRect, 0, 0, 640, 480);

// blit the background bitmap. This is a 640x480 bitmap,
// so it will fill the screen (remember, we set the video
// mode to 640x480x8.
// The parameter lpDDSOne is a hypothetical surface with this
// background bitmap loaded. LpDDSBack is our backbuffer.
ddrval = lpDDSBack->BltFast(0, 0, lpDDSOne, &rcRect, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);

if(ddrval != DD_OK)
return;

SetRect(&rcRect, 0, 0, 32, 32); // our fictitious sprite bitmap is 32x32 in size

// xpos and ypos represent some appropriate location for the sprite.
// lpDDSMySprite is just a surface with the bitmap for our sprite.
xpos = 100;
ypos = 100;
ddrval = lpDDSBack->BltFast( xpos, ypos, lpDDSMySprite,
&rcRect, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
if( ddrval != DD_OK )
{
return;
}

// Flip the surfaces
ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );
}
/*
Notice that the first call to BltFast(), the one that is blitting the background,
uses the flag DDBLTFAST_NOCOLORKEY. This tells BltFast to ignore the color key,
and can improve the performance of the blit on some cards. This means that any
transparent areas on this bitmap will be copied and therefore not be transparent,
but this is OK since this is the background bitmap and not a sprite like image.
*/



/*
* Call Release on all objects we created to clean up
*/
void finiObjects( void )
{
if( lpDD != NULL )
{
if( lpDDSPrimary != NULL )
{
lpDDSPrimary->Release();
lpDDSPrimary = NULL;
}

if( lpDDSOne != NULL )
{
lpDDSOne->Release();
lpDDSOne = NULL;
}

if( lpDDpal != NULL )
{
lpDDpal->Release();
lpDDpal = NULL;
}

if( lpDDSMySprite != NULL )
{
lpDDSMySprite->Release();
lpDDSMySprite = NULL;
}
}
lpDD->Release();
lpDD = NULL;
} /* finiObjects */



/*
- Losing Surfaces
One very important area of robustness that the code samples above ignored is what
happens if the user switches away from a fullscreen DirectDraw app to some other
app running in the system. First of all, your code needs to handle the WM_ACTIVATEAPP
message and set a flag when your app goes inactive. In the idle section of your
PeekMessage loop, check this flag, and don't try to update your display when you're not active.

But the real issue is that once you switch to another app, you have left
the DirectDraw environment and allowed GDI to become active. GDI is oblivious
to DirectDraw, and will overwrite the areas of display memory in use by your
DirectDraw surfaces. This means that your bitmaps get wiped out and will need
to be reloaded. Fortunately, when you call a function that operates on a surface,
such as Flip() or BltFast(), DirectDraw will return an error of DDERR_SURFACELOST to
let you know if the surface was lost. So, your code has to check for this error and
reload the bitmaps into the surfaces if this error occurs.

ddrval = lpDDSPrimary->Blt( &rcRectDest, lpDDSBack, &rcRectSrc, DDBLT_WAIT, NULL);
if( ddrval == DDERR_SURFACELOST )
{
ddrval = restoreAll();
}

ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT);

if( ddrval == DDERR_SURFACELOST )
{
ddrval = restoreAll();
}
:
:

void restoreAll()
{
// for each surface your app has created you should do the following:
ddrval = lpMyDDSurface->Restore(); // this reattaches the video memory to the surface
if( ddrval == DD_OK )
{
lpTempDDS ->DDReLoadBitmap(); // this will be the same as the function above
// that was originally used to load the bitmap
// with the exception that the surface is already
// created and ready to go
}
}
*/



void InitBackGroundAndSprite()
{
// load our background bitmap into lpDDSOne
lpDDSOne = DDLoadBitmap(lpDD, "back.bmp");

if(lpDDSOne)
{
// set it's pallete
lpDDpal = DDLoadPalette(lpDD, "back.bmp");
if(lpDDpal)
{
lpDDSPrimary->SetPalette(lpDDpal);
::MessageBox(0,"back is ok",0,0);
lpDDSOne->SetPalette(lpDDpal);
}
}

// load our sprite bitmap into lpDDSMySprite
lpDDSMySprite = DDLoadBitmap(lpDD, "sprite.bmp");
if(lpDDSMySprite)
::MessageBox(0,"sprite is ok",0,0);

// there is no need to load the palette for the sprite bitmap
// because when we load it for the primary surface, it's already for all sprites also
}

Ahmed Ezz

Software Engineer

ezzelden.ahmed@yahoo.com

http://ahmedezz.110mb.com/

انما عمرك بأعمالك ، فكم تريد أن تعيش؟

#2

انا مش شايف اخطاء حاولت اعمل كوبايل لكن للاسف عندي فيجول 2005 وعالجت الاخطاء كلها و لكن جه في ربط المكتبة directdraw شكلها لم تصبح تُدعم ، انصحك بالتغيير الان كلياً و الانتقال الي دايركت اكس 9 علي الاقل الان !!

يجب ان تكون الصورة 256 لون و لها palette ...

BEng , Electronics and communications.

Embedded systems engineer.

Graphics Programmer

عالم الكومبيوتر هو من لديه المعرفة في علوم الكومبيوتر ، الرياضيات ، هندسة الالكترونيات -احمد صالح

هذا الموضوع مغلق.

مواضيع مشابهة