读书人

问一个directdraw 关于DDSURFACEDESC2

发布时间: 2012-03-20 14:01:11 作者: rapoo

问一个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
[解决办法]
这个我不会,帮顶一下吧^_^

读书人网 >C++

热点推荐