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

原创 2003年02月17日 10:56:00

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

 

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

//

 

#include "stdafx.h"

#include "resource.h"

#include <ddraw.h>

 

#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;

}

//

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

上一次,我们创建DirectDraw7的接口指针时用的是DirectDrawCreateEx(NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL);其中m_pDD...
  • Timesking
  • Timesking
  • 2003年02月17日 11:03
  • 2138

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

//下面主要是消息循环,根普通程序不一样int APIENTRY WinMain(HINSTANCE hInstance,                     HINSTANCE hPrevIns...
  • Timesking
  • Timesking
  • 2003年02月17日 10:34
  • 1321

DirectX8.1的DirectDraw7研究手记(三)

 一、在何种情况下应该选择IDirectDrawSurface::Blt方法,在何种情况下应该选择IDirectDrawSurface::BltFast方法。(这段解释是从别人那里copy过来的,但不...
  • Timesking
  • Timesking
  • 2003年02月15日 13:31
  • 1981

DirectX8.1的DirectDraw7研究手记(一)

这几日修改以前写的基于GDI的小游戏,由于机器较慢,所以游戏运行很慢,所以决定研究一下用DirectX8.1的DirectDraw来把游戏修改一下。以前看过网上朋友写的DirectDraw的资料,大多...
  • Timesking
  • Timesking
  • 2003年02月05日 19:44
  • 1443

“变速齿轮”研究手记

注意:如果你看了本文,对我们这个软件有兴趣,请到我们的主页www.vrbrothers.com下载。注:为节省篇幅,本文对一些计算机术语直接使用而没有作详细的解释,读者若有不熟悉之处,建议参考清华大学...
  • rchu
  • rchu
  • 2001年03月05日 18:24
  • 1569

[转]VCL窗口函数注册机制研究手记,兼与MFC比较

    我们知道Windows平台上的GUI程序都必须遵循Windows的消息响应机制,可以简单概括如下,所有的窗口控件都向系统注册自身的窗口函数,运行期间消息可被指派至特定窗口控件的窗口函数处理。对...
  • nhczp
  • nhczp
  • 2007年03月17日 16:19
  • 1108

Delphi 中 COM 实现研究手记(一)

前言     前些日子用 Delphi 写了一个 Windows 外壳扩展程序,大家知道 Windows 外壳扩展实际上就是 COM 的一种应用 -- Shell COM,虽然整个程序写得还算比较顺利...
  • procedure1984
  • procedure1984
  • 2009年02月18日 18:27
  • 1180

读《匠人手记》札记

 好:久仰大名!从当当网上订的书一周才到。到了之后工作又忙没有时间看,现在终于到了假期可以抽出时间来拜读您的大作:现在把我的读后感献上。2009-01-01(农历二〇〇八年十二月初六)第一章:匆匆而过...
  • fisher3014
  • fisher3014
  • 2009年04月24日 21:40
  • 335

导出数据为Excel的几种方式

方法一:  最简单的方式就是在JSP页面的开始部分使用如下的头部信息    response.setHeader("Content-disposition","attachment; file...
  • u013749540
  • u013749540
  • 2016年06月06日 09:25
  • 473

《IT项目经理成长手记》读后有所思

最近看了一本潘东、韩秋泉先生合著的一本书《IT项目经理成长手记》,虽然与IT项目经理相关的书我看的不多,对于这个行业了解也不算太多,但是我依然认为这是一本很值得想要从事互联网产品、通信行业解决方案管理...
  • u013816144
  • u013816144
  • 2016年06月20日 21:53
  • 3921
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DirectX8.1的DirectDraw7研究手记(二) 中
举报原因:
原因补充:

(最多只允许输入30个字)