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

一个严重打击菜鸟的有关问题,小弟我只是想blt一张位图而已

2012-03-02 
一个严重打击初学者的问题,我只是想blt一张位图而已!如题,本人初学directdraw,想载入一张位图到一个离屏表

一个严重打击初学者的问题,我只是想blt一张位图而已!
如题,本人初学directdraw,想载入一张位图到一个离屏表面,然后直接blt到主表面

具体问题就出在每次执行离屏表面blt到主表面的时候总是报错,blt失败!

但是如果我把离屏表面换成后备缓冲,先将位图载入到后备缓冲然后再blt到主表面却总能成功!

但是就这么一个问题愣是一天没有实现。快疯了

以下是完整的程序源码。使用directx8(程序编译成功!没有任何报错)

#define WIN32_LEAN_AND_MEAN
#define INITGUID// make sure directX guids are included

#include <windows.h>
#include <windowsx.h>

#include <ddraw.h>

#pragma comment(lib,"ddraw.lib")

#define WINDOW_CLASS_NAME "WINCLASS"

// default screen size
#define SCREEN_WIDTH 640 // size of screen
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 32 // bits per pixel

// initializes a direct draw struct
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

HWNDmain_window_handle= NULL; 
intvirtual_code= 0;
unsigned intkey_state= 1000;

LPDIRECTDRAW7 lpdd = NULL; // directdraw 对象
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // directdraw 主表面
LPDIRECTDRAWSURFACE7 lpddsback = NULL; // directdraw 后备缓冲或者离屏表面
LPDIRECTDRAWCLIPPER lpddclipper = NULL; // directdraw 剪裁器
DDSURFACEDESC2 ddsd; // 一个用来描述directdraw表面的结构

RECT source_rect = {0,0,SCREEN_WIDTH,SCREEN_HEIGHT};
RECT dest_rect = {0,0,SCREEN_WIDTH,SCREEN_HEIGHT};

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

void CreateSurface(LPDIRECTDRAWSURFACE7 *lpSource, int xs, int ys)
{

  DDRAW_INIT_STRUCT(ddsd);
  ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  ddsd.dwWidth = xs;
  ddsd.dwHeight = ys;
  if(lpdd->CreateSurface(&ddsd, lpSource, NULL) != DD_OK)
{
//MessageBox(NULL, "创建表面失败","错误信息!",MB_OK | MB_ICONEXCLAMATION);
}
}

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

void DrawHBitmap(IDirectDrawSurface7 *lpSurface, HBITMAP hBitmap, int x, int y, int width, int height)
{
  HDC hdcImage;
  HDC hdc;
  BITMAP bm;

  if (lpSurface == NULL || hBitmap == NULL)
  return;
  lpSurface->Restore();

  hdcImage = CreateCompatibleDC(NULL);
  SelectObject(hdcImage, hBitmap);

  GetObject(hBitmap, sizeof(bm), &bm);
  width = width == 0 ? bm.bmWidth : width;
  height = height == 0 ? bm.bmHeight : height;

  if(lpSurface->GetDC(&hdc) != DD_OK)
{
MessageBox(NULL, "设备获取失败","错误信息!",MB_OK | MB_ICONEXCLAMATION);
}
  BitBlt(hdc, x, y, width, height, hdcImage, 0, 0, SRCCOPY);
  lpSurface->ReleaseDC(hdc);
  DeleteDC(hdcImage);
}

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

void CreateBitmapSurface(LPDIRECTDRAWSURFACE7 lpSurface, char *fname, int xs, int ys)
{
  HBITMAP hBitmap;

  CreateSurface(&lpSurface,xs, ys);
  hBitmap = (HBITMAP)LoadImage(NULL, fname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  DrawHBitmap(lpSurface, hBitmap, 0, 0, xs, ys);
  DeleteObject(hBitmap);
}

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

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

int Game_Init(void *parms = NULL, int num_parms = 0)
{


// 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 640x480x8
if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))

return(0);
}

// clear ddsd and set size
DDRAW_INIT_STRUCT(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);
}

CreateBitmapSurface(lpddsback,"bitmap24.bmp",SCREEN_WIDTH,SCREEN_HEIGHT);

// 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)
{
if (KEYDOWN(VK_ESCAPE))
SendMessage(main_window_handle,WM_CLOSE,0,0);

///*
if((lpddsprimary->Blt(&dest_rect,lpddsback,&source_rect,DDBLT_WAIT,NULL))!=DD_OK)
{
MessageBox(NULL, "Blt失败!","错误信息!",MB_OK | MB_ICONEXCLAMATION);
}
//*/

return(1);
} // end Game_Main

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

int Game_Shutdown(void *parms = NULL, int num_parms = 0)
{

// now the primary surface
if (lpddsprimary)
{
lpddsprimary->Release();
lpddsprimary = NULL;
} // end if

// now blow away the IDirectDraw4 interface
if (lpdd)
{
lpdd->Release();
lpdd = NULL;
}

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

} // end Game_Shutdown


LRESULT CALLBACK WindowProc(
HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam
)
{
PAINTSTRUCT ps;
HDC hdc;

switch(msg)
{
case WM_CREATE:
{
return(0);
break;
}
case WM_PAINT:
{
hdc = BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return(0);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return(0);
break;
}
case WM_KEYDOWN:
{
virtual_code = (int)wparam;
key_state = (int)lparam;
switch(virtual_code)

case VK_ESCAPE:{PostMessage(hwnd,WM_CLOSE,0,0);break;}
}
break;
}
default:break;
}

return (DefWindowProc(hwnd,msg,wparam,lparam));
}

int WINAPI WinMain(
HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow
)
{
WNDCLASSEX winclass;//窗口类
HWND hwnd;//窗口句柄
MSG msg;

winclass.cbSize= sizeof(WNDCLASSEX);//该结构本身大小
winclass.style= CS_DBLCLKS | CS_OWNDC |//窗口属性样式
CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc= WindowProc;//指向事件处理句柄的函数指针
winclass.cbClsExtra= 0;
winclass.cbWndExtra= 0;
winclass.hInstance= hinstance;//当前运行程序的实例句柄
winclass.hIcon= LoadIcon(NULL, IDI_APPLICATION);//应用程序的图标
winclass.hCursor= LoadCursor(NULL, IDC_ARROW);//鼠标图标
winclass.hbrBackground= (HBRUSH)GetStockObject(BLACK_BRUSH);//窗口背景
winclass.lpszMenuName= NULL;
winclass.lpszClassName= WINDOW_CLASS_NAME;//窗口类名(标识)
winclass.hIconSm= LoadIcon(NULL, IDI_APPLICATION);

//注册窗口类
if(!RegisterClassEx(&winclass))
{
MessageBox(


NULL, 
"窗口注册失败!",
"错误信息",
MB_OK | MB_ICONEXCLAMATION
);
return(0);
}

//创建窗口
if(!(hwnd = CreateWindowEx(
NULL,
WINDOW_CLASS_NAME,//所创建窗口的基类名
"My First Directx Program",//窗口标题
WS_POPUP | WS_VISIBLE,//说明窗口外观和行为的通用窗口标志
(GetSystemMetrics(SM_CXSCREEN)-400)/2,
(GetSystemMetrics(SM_CYSCREEN)-400)/2,//窗口左上角位置的像素坐标
400,400,//以像素标识的窗口宽度和高度
NULL,//指向父窗口的句柄
NULL,//指向附属于该窗口的菜单的句柄
hinstance,//指向应用程序的实例
NULL
)
)
)
{
MessageBox(
NULL, 
"窗口创建失败!",
"错误信息",
MB_OK | MB_ICONEXCLAMATION
);
return(0);
}

main_window_handle = hwnd;

Game_Init();

//主事件循环
while(TRUE)
{
//测试消息序列中是否有消息
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Game_Main();
}

Game_Shutdown();
return(msg.wParam);

}


[解决办法]
因为CreateBitmapSurface中的 lpddsback 是值参数,所以不会函数里的改动并不会改变该参数的值。你可以看看两种方式下,其实lpddsback的值是不一样的!

热点排行