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