ITPub博客

首页 > 应用开发 > IT综合 > DirectX8.1的DirectDraw7研究手记(二) 中 (转)

DirectX8.1的DirectDraw7研究手记(二) 中 (转)

原创 IT综合 作者:worldblog 时间:2007-12-14 09:06:25 0 删除 编辑
DirectX8.1的DirectDraw7研究手记(二) 中 (转)[@more@]

我们边看程序边讲解,程序的框架是用vc6的windows application生成的hello World改写的。这里没有解释程序在Alt+Tab切换一次后图片不见的问题,也没有说为什么用BltFast而没用Blt,同样也没有说AddRef()函数是干什么的。没用g_lpdd->CreatePalette(,,,,);函数时,用256色即#define BPP 8时,可能会有颜色失真,而16位色/时就不必用这个函数了!也不会有颜色失真。不过先这样用着,以后我在解释。

 XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

// DirectX.cpp : Defines the entry point for the application.

//

 

#include "stdafx.h"

#include "resource.h"

#include

 

#define MAX_LOADSTRING 100

 

// Global Variables:

HINSTANCE hInst;      // current instance

TCHAR szTitle[MAX_LOADSTRING];      // The title bar text

TCHAR szWindowClass[MAX_LOADSTRING];  // The title bar text

 

// Foward declarations of functions included in this code module:

ATOM      MyRegisterClass(HINSTANCE hInstance);

BOOL      InitInstance(HINSTANCE, int);

LRESULT CALLBACK  WndProc(HWND, UINT, WPARAM, LPARAM);

//---------------------全局变量和一些预定义宏---------------------------------------

//这两个预定义宏是为了方便释放指针用的在下面的FreeDraw()函数中有用

#define SAFE_DELETE(p)  { if(p) { delete (p);  (p)=NULL; } }

#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

 

//显示模式的设定640×480×8

#define WIDTH 640

#define HEIGHT 480

#define BPP 8

//试试#define BPP 16会有什么效果??

//没用g_lpdd->CreatePalette(,,,,);函数时,用256色即#define BPP 8时,可能会有颜色失真,而16位色//时就不必用这个函数了!也不会有颜色失真。

HRESULT initDirectDraw(HINSTANCE hInst);//初始化DirectDraw

HRESULT MainLoop();//熟称GameLoop

void FreeDraw();//释放所有DirectDraw的指针

 

LPDIRECTDRAW7 g_lpdd;//指向实体的指针

LPDIRECTDRAWSURFACE7 g_lpFrontSurface;//A page

LPDIRECTDRAWSURFACE7 g_lpBackSurface;//B page

LPDIRECTDRAWSURFACE7 g_lpOffScreen;//用于后台的离屏页面

BOOL g_bActive=TRUE;//决定mainloop是否运行的标志

 

//-----------------------------------------------------------------------------

//Function:iniDirectDraw()

//用于初始化

//完成任务:创建g_lpdd指针实体、获取显示模式、设置显示模式、制作页面信息

//    创建主表面对象、提取后台缓存表面指针、用图片创建离屏页面

HRESULT initDirectDraw(HINSTANCE hInst)

{

  HRESULT hr;

  DDSURFACEDESC2 ddsd;

  DDSCAPS2 ddscaps;

 

  ZeroMemory(&ddsd,sizeof(ddsd));

  ZeroMemory(&ddscaps,sizeof(ddscaps));

 

  FreeDraw();

  //创建g_lpdd指针实体

  if(FAILED(hr = DirectDrawCreateEx(NULL, (void**)&g_lpdd,IID_IDirectDraw7, NULL)))

  return E_FAIL;

 

  //获取显示模式

  if(FAILED(hr = g_lpdd->SetCooperativeLevel(GetActiveWindow(),DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)))

  return E_FAIL;

 

  //设置显示模式

  if(FAILED(hr = g_lpdd->SetDisplayMode(WIDTH,HEIGHT,BPP,0,0)))

  return E_FAIL;

 

  //制作页面信息

  ddsd.dwSize = sizeof(ddsd);

  ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;

  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX;

  ddsd.dwBackBufferCount = 1 ;

  //创建主表面对象

  if(FAILED(hr = g_lpdd->CreateSurface(&ddsd,&g_lpFrontSurface,NULL)))

  return E_FAIL;

 

  //提取后台缓存表面指针

  ddscaps.dwCaps = DDSCAPS_BACKBUFFER;

  if(FAILED(hr = g_lpFrontSurface->GetAttachedSurface(&ddscaps,&g_lpBackSurface)))

  return E_FAIL;

 

  g_lpBackSurface->AddRef();//没有他似乎也能运行正常?

 

  //用图片创建离屏页面

  HBITMAP  hbm=NULL;

  BITMAP  bmp;

// Idb_BITMAP1是图片资源

  hbm = (HBITMAP) LoadImage( GetModuleHandle(NULL), MAKEINTRESOURCE( IDB_BITMAP1 ),

  IMAGE_BITMAP, 1500, 280, //图片读取进来后变形成多大的尺寸width,height

  LR_CREATEDIBSECTION );

 

  Getobject( hbm, sizeof(bmp), &bmp );

 

 

  ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

  ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VideOMEMORY;

  ddsd.dwWidth  = bmp.bmWidth ;

  ddsd.dwHeight = bmp.bmHeight ;

 

  hr = g_lpdd->CreateSurface(&ddsd,&g_lpOffScreen,NULL);

  if(FAILED(hr))

  {

  if(hr == DDERR_OUTOFVIDEOMEMORY)

  {//这是最后机会

    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |  DDSCAPS_SYSTEMMEMORY;

 

    if(FAILED(hr = g_lpdd->CreateSurface(&ddsd, &g_lpOffScreen, NULL )))

    return E_FAIL;

  }

  }

 

 

 

  HDC hdc;

  HDC  hdcImage;

 

  hdcImage = CreateCompatibleDC(NULL);

  selectObject(hdcImage, hbm);

 

  g_lpOffScreen->Restore();

  g_lpOffScreen->GetSurfaceDesc(&ddsd);

 

  if((hr = g_lpOffScreen->GetDC(&hdc))==DD_OK)

  {

    StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, 0, 0,

      bmp.bmWidth ,bmp.bmHeight  , SRCCOPY);

 

    g_lpOffScreen->ReleaseDC(hdc);

  }

 

  DeleteDC(hdcImage);

 

  return S_OK; 

}

 

//这里的宏在最上面定义了

void FreeDraw()

{

  SAFE_RELEASE(g_lpFrontSurface);

  SAFE_RELEASE(g_lpBackSurface);

  SAFE_RELEASE(g_lpOffScreen);

  SAFE_RELEASE(g_lpdd);

}

//Function:MainLoop()

//

//

HRESULT MainLoop()

{

  HRESULT hRet;

  RECT rect;

  rect.left =0;

  rect.top = 0;

  rect.right = 150;

  rect.bottom = 140;

//从离屏页面把存在OffScreen的图片取出rect举行位置的图片,拷贝到后台缓存中

  g_lpBackSurface->BltFast(0,0,g_lpOffScreen,&rect,DDBLTFAST_NOCOLORKEY);

//后台缓存画上了图象,那么就Flip放到前台让他显示出来

  g_lpFrontSurface->Flip(NULL, 0 );

  return S_OK;

}

//


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-993161/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    6241
  • 访问量
    2464800