Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 DirectDraw Basics CIS 487/587 Bruce R. Maxim UM-Dearborn.

Similar presentations


Presentation on theme: "1 DirectDraw Basics CIS 487/587 Bruce R. Maxim UM-Dearborn."— Presentation transcript:

1 1 DirectDraw Basics CIS 487/587 Bruce R. Maxim UM-Dearborn

2 2 What is the process? You need to ensure that Ddraw.lib and Ddraw.h are included in your project 1.Create and DirectDraw object and obtain access to it (IDirectDraw is main COM object interface 2.Set video mode and cooperation level and create one or more DirectDraw surfaces (IDirectDrawSurface)

3 3 What is the process? 3.You may need to create a color pallete (IDirectDrawPalette) 4.Create a clipper (IDirectDrawClipper)

4 4 LaMothe Examples

5 5 Game Programs The way LaMothe does things in WinMain once the window is opened and registered // initialize game here Game_Init(); // enter main event loop while(TRUE) { // the usual message stuff goes here // main game processing goes here Game_Main(); } // end while // closedown game here Game_Shutdown();

6 6 Game_Init() int Game_Init(void *parms = NULL, int num_parms = 0) { // create IDirectDraw interface 7.0 object and test for error if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, ID_IDirectDraw7, NULL))) return(0); // set cooperation to normal since this will be a windowed app lpdd->SetCooperativeLevel(main_window_handle, DDSCL_NORMAL); // return success or failure return(1); } // end Game_Init

7 7 Game_Main( ) int Game_Main(void *parms = NULL, int num_parms = 0) { // main loop of the game, do all your processing here // if user is hitting ESC and send WM_CLOSE if (KEYDOWN(VK_ESCAPE)) SendMessage(main_window_handle,WM_CLOSE,0,0); // return success or failure return(1); } // end Game_Main

8 8 Game_ShutDown( ) int Game_Shutdown(void *parms = NULL, int num_parms = 0) { // simply blow away the IDirectDraw7 interface if (lpdd) { lpdd->Release(); lpdd = NULL; } // end if // return success return(1); } // end Game_Shutdown

9 9 Cooperation Level This allows you to specify the type of application –Windowed or full-screen –ModeX video modes (320x200, 320x240) –Allow ctl-atl-del to get out of game

10 10 Cooperation Level In a windowed application you might use lpdd->SetCooperativeLevel(main_window_handle, DDSCL_NORMAL); In a full-screen application you might use lpdd->SetCooperativeLevel(main_window_handle, DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);

11 11 Selecting Video Mode One of the most important features of DirectX The function to use if SetDisplayMode( ) This will be done in GameInit( ) after setting the cooperation level // set display mode to 640x480x8 if (FAILED(lpdd->SetDisplayMode(640,480,8,0,0))) { // error return(0); } // end if

12 12 Full Screen Popup Sometimes it is good to create a popup window that appears to be full screen To get this to work on any computer yo need to use GetSystemMetrics( ) to get the current screen size and use the returned values when the popup window is created

13 13 Surfaces In DirectDraw displayable memory is referred to as a surface The primary surface represents the visible video screen and is mapped to the video memory on the video card (VRAM)

14 14 Surfaces A surface can be any size, but the primary surface must match the current screen resolution Surfaces can be created in video memory of system memory All surfaces have the same properties with respect to bit depth and color space

15 15 Game Surfaces Games typically have –Primary display surface (visible video screen) –Secondary display surface for animation (aka “backbuffer”) –Off screen surfaces (for bit maps, sprites, screen items, etc)

16 16 Creating Surfaces // You create a primary surface after setting display mode // clear ddsd and set size memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); // enable valid fields ddsd.dwFlags = DDSD_CAPS; // request primary surface when create ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // create the primary surface if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL))) { return(0); // error } // end if

17 17 Building Pallete Array for (int color=1; color < 255; color++) { // fill with random RGB values palette[color].peRed = rand()%256; palette[color].peGreen = rand()%256; palette[color].peBlue = rand()%256; palette[color].peFlags = PC_NOCOLLAPSE; } // end for color // now fill in entry 0 and 255 with black and white palette[0].peRed = 0; palette[0].peGreen = 0; palette[0].peBlue = 0; palette[0].peFlags = PC_NOCOLLAPSE; palette[255].peRed = 255; palette[255].peGreen = 255; palette[255].peBlue = 255; palette[255].peFlags = PC_NOCOLLAPSE;

18 18 Using Pallete // create the palette object after surface created if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette,&lpddpal, NULL))) { return(0); // error } // end if // attach the palette to the primary surface if (FAILED(lpddsprimary->SetPalette(lpddpal))) { return(0); // error } // end if

19 19 Game_Shutdown( ) // cleanup in reverse of object creation order // first the palette if (lpddpal) { lpddpal->Release(); lpddpal = NULL; } // end if // now the primary surface if (lpddsprimary) { lpddsprimary->Release(); lpddsprimary = NULL; } // end if // now blow away the IDirectDraw7 interface if (lpdd) { lpdd->Release(); lpdd = NULL; } // end if

20 20 Linear vs Non-Linear Memory In an ideal world your video card has a horizontal pixel memory pitch that matches the way pixels are stored in system memory If that were true and you have 640 pixels with 8 bit color there would be 640 bytes of memory per video line With non-linear memory they won’t always match (so you will to think about pixel placement in light of this and changing video resolutions)

21 21 Plotting 8 Bit Pixels If you are using 640x480x8 mode and you have 640 bytes per line To access any screen pixel using (x,y) you could do it as follows UCHAR *video_buffer = (UCHAR *)ddsd.lpSurface; video_buffer[x+y*640] = color;

22 22 Plotting Pixels If you are using 640x480x16 mode and you have 640 words per line To access any screen pixel using (x,y) you could do it as follows USHORT *video_buffer = (USHORT *)ddsd.lpSurface; video_buffer[x+y*640] = color;

23 23 Drawing in DirectX Drawing (rendering) in DirectX is different than drawing use GDI GDI has lots of very slow drawing functions DirectX has a small number of very fast drawing functions (programmers use their own libraries and engines) In DirectX it is very important to lock a surface before you draw and unlock it when you are done

24 24 Initial Surface Parameters // Set the global drawing surface description LPDIRECTDRAW7 lpdd = NULL; // dd object LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // dd primary surface LPDIRECTDRAWSURFACE7 lpddsback = NULL; // dd back surface LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to dd palette LPDIRECTDRAWCLIPPER lpddclipper = NULL; // dd clipper PALETTEENTRY palette[256]; // color palette PALETTEENTRY save_palette[256]; // used to save palettes DDSURFACEDESC2 ddsd; // surface description DDBLTFX ddbltfx; // used to fill DDSCAPS2 ddscaps; // surface capabilities HRESULT ddrval; // result from dd calls

25 25 Plotting Pixels // clear ddsd and set size, never assume it's clean memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); // lock surface if (FAILED(lpddsprimary->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL))) { return(0); // error } // end if // now ddsd.lPitch is valid and so is ddsd.lpSurface int mempitch = (int)ddsd.lPitch; UCHAR *video_buffer = (UCHAR *)ddsd.lpSurface; video_buffer[x+y*mempitch] = color; // now unlock the primary surface if (FAILED(lpddsprimary->Unlock(NULL))) return(0)


Download ppt "1 DirectDraw Basics CIS 487/587 Bruce R. Maxim UM-Dearborn."

Similar presentations


Ads by Google