创建一个16位全屏DirectDraw模式采取的步骤

来源:互联网 发布:究极风暴4官方优化补丁 编辑:程序博客网 时间:2024/06/06 21:57

LPDIRECTDRAW7         lpdd         = NULL;   // dd object
LPDIRECTDRAWSURFACE7  lpddsprimary = NULL;   // dd primary surface

DDSURFACEDESC2        ddsd;                  // a direct draw surface description struct

// 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);

// enable valid fields
ddsd.dwFlags = DDSD_CAPS;

// request primary surface
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

// create the primary surface
if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
   return(0);

这就写完了。现在你可以看到一个黑屏(如果住缓冲留有数据的话,也可能你会看到一些乱七八糟的东西)。

无论如何,为了往屏幕上写数据,你必须:

1、锁住主表面-----调用Lock()函数

2、建立16位RGB字----这可以通过使用定义的宏之一(_RGB16BIT555(r,g,b)     、_RGB16BIT565(r,g,b)),或者你自己来生成它

3、写像素----这意味着采用一个USHORT指针定位主缓冲,将像素写入VRAM缓冲

4、解锁主表面-----调用UnLock()函数。

下面给出16位像素绘制函数代码:

void  Polt_Pixel116(int x, int y ,int red , int green , int  blue , LPDIRECTDRAWSURFACE7  lpdds)

{

DDSURFACE2 ddsd;/////dd surface description

USHORT  pixel = _RGB16BIT565(red,green,blue); /////build up  color WORD

///now lock  video  buffer

DDRAW_INIT_STRUCT(ddsd);///---->#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR ,NULL);

///write the  pixel

////alias(别名、化名)  the surface  memory pointer to a USHORT ptr   就是声明一个指针指向主表面(当色深8位是指针类型位UCHAR* ,16位时为USHORT*,32.....)

USHORT *video_buffer = ddsd.lpSurface;

///write the  data

video_buffer[x + y*(ddsd.lPitch>>1)]  = pixel;

///unlock the  surface

lpdds->UnLock(NULL);

}//////end of  Polt_Pixel16

优化后的程序版本:

inline void Plot_Pixel_Fast16(int x, int y,
                                int red, int green, int blue,
                                USHORT *video_buffer, int lpitch)
{
// this function plots a pixel in 16-bit color mode
// assuming that the caller already locked the surface
// and is sending a pointer and byte pitch to it

// first build up color WORD
USHORT pixel = _RGB16BIT565(red,green,blue);

// write the data
video_buffer[x + y*(lpitch>>1)] = pixel;

} // end Plot_Pixel_Fast16

改写上述优化后的版本程序(更快的版本):

int   lpitch16 = (lpitch>>1);

inline void Plot_Pixel_Faster16(int x, int y,
                                int red, int green, int blue,
                                USHORT *video_buffer, int lpitch16)
{
// this function plots a pixel in 16-bit color mode
// assuming that the caller already locked the surface
// and is sending a pointer and byte pitch to it

// first build up color WORD
USHORT pixel = _RGB16BIT565(red,green,blue);//////上面说的第二步,创造一个RGB字

// write the data
video_buffer[x + y*lpitch16] = pixel;

} // end Plot_Pixel_Faster16

使用16位绘制像素函数的例子:

int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here

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


// plot 1000 random pixels to the primary surface and return
// 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);

// now ddsd.lPitch is valid and so is ddsd.lpSurface

// make a couple aliases to make code cleaner, so we don't
// have to cast
int lpitch16 = (int)(ddsd.lPitch >> 1);
USHORT *video_buffer = (USHORT *)ddsd.lpSurface;

// plot 1000 random pixels with random colors on the
// primary surface, they will be instantly visible
for (int index=0; index < 1000; index++)
    {
    // select random position and color for 640x480x16
    int red   = rand()%256;
    int green = rand()%256;
    int blue  = rand()%256;
    int x = rand()%640;
    int y = rand()%480;

    // plot the pixel
    Plot_Pixel_Faster16(x,y,red,green,blue,video_buffer,lpitch16);      

    } // end for index


// now unlock the primary surface
if (FAILED(lpddsprimary->Unlock(NULL)))
   return(0);

// return success or failure or your own return code here
return(1);

} // end Game_Main

原创粉丝点击