Download presentation
Presentation is loading. Please wait.
Published byAusten Dorsey Modified over 9 years ago
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)
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.