Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 DirectDraw and Bitmaps Part 1 CIS 487/587 Bruce R. Maxim UM-Dearborn.

Similar presentations


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

1 1 DirectDraw and Bitmaps Part 1 CIS 487/587 Bruce R. Maxim UM-Dearborn

2 2 Screen Basics A standard 640x480x8 screen buffer has 307,200 pixels Without 3D acceleration hardware, software-based rasterization is not practical for more than 256 colors For bitmap work this is 3D acceleration is a little less critical

3 3 16 Bit Encoding There are several 16 bit high-color pixel encoding schemes –Alpha 5.5.5 –X 5.5.5 –5.6.5 (most common) Getting the pixel format right before plotting is important You can choose to set it to 5.6.5 yourself if you wish

4 4 Writing a Screen Pixel Lock the surface using Lock( ) Build the 16-bit RGB word using the macro _RGB16BIT5.6.5 Write the pixel using a USHORT pointer into VRAM Unlock the primary surface using unlock

5 5 LaMothe Examples

6 6 Ddraw 16-bit Pixel Plotting // done as global declarations // builds a 16 bit color value in 5.6.5 format (green dominate mode) #define _RGB16BIT565(r,g,b) ((b&31) + ((g&63) << 5) + ((r&31) << 11)) // initializes a direct draw struct #define DDRAW_INIT_STRUCT(ddstruct) {memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); } inline void Plot_Pixel_Faster16(int x, int y, int red, int green, int blue, USHORT *video_buffer, int lpitch16) { // plots a pixel in 16-bit color mode assumes caller already locked the // surfaceand is sending a pointer and byte pitch to it USHORT pixel = _RGB16BIT565(red,green,blue); // first build up color WORD video_buffer[x + y*lpitch16] = pixel; // write the data } // end Plot_Pixel_Faster16

7 7 Game_Main( ) // clear ddsd and set size, never assume it's clean DDRAW_INIT_STRUCT(ddsd); // lock the primary surface if (FAILED(lpddsprimary->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL))) return(0); int lpitch16 = (int)(ddsd.lPitch >> 1); USHORT *video_buffer = (USHORT *)ddsd.lpSurface; // plot the pixel once position and color is set Plot_Pixel_Faster16(x,y,red,green,blue,video_buffer,lpitch16); // now unlock the primary surface if (FAILED(lpddsprimary->Unlock(NULL))) return(0);

8 8 Game_Init( ) // create IDirectDraw interface 7.0 object and test for error if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL))) return(0); // set cooperation to full screen if (FAILED(lpdd->SetCooperativeLevel(main_window_handle, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))) return(0); // set display mode to 640x480x16 if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0))) return(0); // clear ddsd and set size memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; // enable valid fields ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // request primary surface // create the primary surface if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL))) return(0);

9 9 Game_Shutdown( ) // blow away the primary surface if (lpddsprimary) { lpddsprimary->Release(); lpddsprimary = NULL; } // end if // blow away the IDirectDraw interface if (lpdd) { lpdd->Release(); lpdd = NULL; } // end if

10 10 Plotting 24 Bit Pixels inline void Plot_Pixel_24(int x, int y, int red, int green, int blue, UCHAR *video_buffer, int lpitch) { // function plots pixel in 24-bit color mode assumes caller locked surface // and is sending a pointer and byte pitch to it // in byte or 8-bit math the proper address is: 3*x + y*lpitch // this is the address of low order byte which is the Blue channel // since data is in RGB order DWORD pixel_addr = (x+x+x) + y*lpitch; // write the data, first blue video_buffer[pixel_addr] = blue; // now red video_buffer[pixel_addr+1] = green; // finally green video_buffer[pixel_addr+2] = red; } // end Plot_Pixel_24

11 11 Plotting 32 Bit Pixels // builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode) #define _RGB32BIT(a,r,g,b) ((b)+ ((g)<<8) + ((r)<<16) + ((a)<<24)) inline void Plot_Pixel_32(int x, int y, int alpha,int red, int green, int blue, UINT *video_buffer, int lpitch32) { // this function plots a pixel in 32-bit color mode // assuming that the caller already locked the surface // and is sending a pointer and DWORD aligned pitch to it // first build up color WORD UINT pixel = _RGB32BIT(alpha,red,green,blue); // write the data video_buffer[x + y*lpitch32] = pixel; } // end Plot_Pixel_32

12 12 Animation and Bitmaps DirectDraw gives you two choices for doing continuous animation –Page flipping (using primary and secondary surfaces) –Double buffering (using system memory for back buffer and programmer to flips the pages) In both cases DirectDraw does the hard work of page flipping (regardless of whether VRAM is linear or non-linear)

13 13 Overview of Double Buffering Game_Init( ) –new is used to allocate double buffer Game_Sutdown( ) –Double buffer must be freed up Game_Main( ) –Double buffer is erased and 5000 pixels are drawn “offline” –Check is made for linear memory and then buffer is copied to screen memory

14 14 Game_Init( ) // once the primary surface, cooperation, display mode, and palette // are defined // allocate double buffer if ((double_buffer=new UCHAR[SCREEN_WIDTH * SCREEN_HEIGHT])==NULL) return(0);

15 15 Game_Shutdown( ) // blow away the palette, surface, and direct draw interface first // release the memory used for double buffer if (double_buffer) { delete double_buffer; double_buffer = NULL; } // end if

16 16 Game_Main( ) UCHAR *primary_buffer = NULL; // alias to primary surface buffer // erase double buffer memset((void *)double_buffer,0, SCREEN_WIDTH*SCREEN_HEIGHT); double_buffer[x+y*SCREEN_WIDTH] = col; // plot at least one pixel // copy the double buffer into the primary buffer DDRAW_INIT_STRUCT(ddsd); // lock the primary surface lpddsprimary->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL); // get video pointer to primary surfce primary_buffer = (UCHAR *)ddsd.lpSurface;

17 17 Game_Main( ) // test if memory is linear if (ddsd.lPitch == SCREEN_WIDTH) { // copy memory from double buffer to primary buffer memcpy((void *)primary_buffer, (void *)double_buffer, SCREEN_WIDTH*SCREEN_HEIGHT); } // end if else { // non-linear // make copy of source and destination addresses UCHAR *dest_ptr = primary_buffer; UCHAR *src_ptr = double_buffer;

18 18 Game_Main( ) // memory is non-linear, copy line by line for (int y=0; y < SCREEN_HEIGHT; y++) { // copy line memcpy((void *)dest_ptr, (void *)src_ptr, SCREEN_WIDTH); // advance pointers to next line dest_ptr+=ddsd.lPitch; src_ptr +=SCREEN_WIDTH; } // end for } // end else // now unlock the primary surface if (FAILED(lpddsprimary->Unlock(NULL))) return(0);

19 19 Back Buffer Steps 1.Allocate memory for back buffer with same pixel dimensions as primary 2.In main loop erase back buffer 3.Perform game logic 4.Render the next frame in the back buffer 5.Copy the back buffer to the primary buffer (surface) 6.Synchronize display to desired frame rate 7.Go to step 2


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

Similar presentations


Ads by Google