首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

问一个directdraw 关于DDSURFACEDESC2 的有关问题

2012-03-20 
问一个directdraw 关于DDSURFACEDESC2 的问题。函数GameInit在WinMain的时间循环前,GameMain在循环中。intGa

问一个directdraw 关于DDSURFACEDESC2 的问题。
函数GameInit在WinMain的时间循环前,GameMain在循环中。
int   Game_Init(void   *parms   =   NULL,   int   num_parms   =   0)
{
//   this   is   called   once   after   the   initial   window   is   created   and
//   before   the   main   event   loop   is   entered,   do   all   your   initialization
//   here

//   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)))
      {
      //   error
      return(0);
      }   //   end   if

//   set   display   mode   to   640x480x8
if   (FAILED(lpdd-> SetDisplayMode(SCREEN_WIDTH,   SCREEN_HEIGHT,   SCREEN_BPP,0,0)))
      {
      //   error
      return(0);
      }   //   end   if


//   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)))
      {
      //   error
      return(0);
      }   //   end   if

//   build   up   the   palette   data   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;

        //   set   flags   field   to   PC_NOCOLLAPSE
        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;

//   create   the   palette   object
if   (FAILED(lpdd-> CreatePalette(DDPCAPS_8BIT   |   DDPCAPS_ALLOW256   |  
                                                                DDPCAPS_INITIALIZE,  
                                                                palette,&lpddpal,   NULL)))
{
//   error
return(0);
}   //   end   if

//   finally   attach   the   palette   to   the   primary   surface
if   (FAILED(lpddsprimary-> SetPalette(lpddpal)))
        {
        //   error
        return(0);
        }   //   end   if

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

}   //   end   Game_Init

/////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////

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
memset(&ddsd,0,sizeof(ddsd));  
ddsd.dwSize   =   sizeof(ddsd);

if   (FAILED(lpddsprimary-> Lock(NULL,   &ddsd,
                                      DDLOCK_SURFACEMEMORYPTR   |   DDLOCK_WAIT,
                                      NULL)))
      {
      //   error
      return(0);
      }   //   end   if

//   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   mempitch                 =   (int)ddsd.lPitch;


UCHAR   *video_buffer   =   (UCHAR   *)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   640x480x8
        UCHAR   color   =   rand()%256;
        int   x   =   rand()%640;
        int   y   =   rand()%480;

        //   plot   the   pixel
        video_buffer[x+y*mempitch]   =   color;                

        }   //   end   for   index

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

//   sleep   a   bit
Sleep(30);

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

}   //   end   Game_Main


在GameInit   中,   ddsd被初始化,   ddsd.dwSize,   ddsd.Caps.dwCaps,   ddsd.dwFlags都被初始化。
可是在GameMain中,   ddsd   被memeset   为0,并且重新赋值ddsd.dwSize,   小弟一开始以为这样做的话那么在GameInit中对ddsd的dwSize,Caps.dwCaps,   ddsd.dwFlags的赋值就是多于的,   于是去掉。       但是结果却是程序执行崩溃。   请问一下这是为什么?   在Gameinit中的初始化,不会被memset为0么?谢谢大家!




[解决办法]
很显然ddsd在使用之前都必须被memset和设置dwSize,所以你去掉这些当然会出错。
[解决办法]

GameInit中对ddsd的dwSize,Caps.dwCaps, ddsd.dwFlags的赋值
是给lpdd_primary初使化用的,生成的lpdd_primary对应ddsd中的内容(对编译器说我要生成一个ddsd样式的lpdd_primary)
删除了当然lpdd_primary就不行了(要编译器生成一个??样式的lpdd_primary)

而在GameMain中ddsd 被memeset 为0是因为
我要找一个空的ddsd来接收被Lock的表面的信息(address of struct to receive info)
如果还不太清楚,可以新定义一个 DDSURFACEDESC2 ddsd2;
然后用ddsd2来当Lock的参数,效果是一样的,Lock只是想找一个空的
DDSURFACEDESC2 来接收被Lock的表面的信息

上面的代码好熟悉,我猜想lz正在看windows游戏编程大师技巧,因为我正在看,呵呵~
大家可以交流一下
tiancaiak@yahoo.com.cn
[解决办法]
这个我不会,帮顶一下吧^_^

热点排行