用Direct3D实现三维漫游

用Direct3D实现三维漫游
用Direct3D实现三维漫游

用Direct3D实现三维漫游

成都理工学院 17# 岳朝伟

朋友,喜欢玩游戏吗?自从计算机诞生以来,人们对计算机游戏就充满了热情,以前对字符型的游戏就乐此不疲,随着时代的发展,人们的要求也越来越高,三维实时游戏和多媒体应用已经成为人们追求的热点。

而Microsoft公司推出的DirectX正是这样一个热点的集合。如果你想抓住时代的潮流,并喜欢迎接挑战的话,本文将是一个很好的去处。同时,本人将以此文讲述用Direct3D保留模式的各种编程技巧和应用,而对于有关基本的DirectX的介绍,请参阅相关的文章。

程序调试环境:Win98、Visual C++6.0,它们都内嵌了DirectX 5.0,同时,为了大家调试的方便和确保程序正常运行,我们将使用最低级的DirectX驱动程序。

一、Direct3DRM中的基本概念

1.0、Direct3D简介

Direct3D是Microsoft公司推出的DirectX的一部分,它又包括立即模式(Direct3DIM)和保留模式(Direct3DRM)。同时,即使是一个最基本的Direct3D例程也必须包含DirectDraw 对象,它们是紧密的结合在一起的,因此,你在编写Direct3D应用程序之前还应先对DirectDraw有一定的认识!Direct3D立即模式是一种较低级的三维模式,因而牵涉到各种复杂的三维图形学的知识,而保留模式是建立在一系列的类调用的基础之上,其中大量的底层操作和运算都被封装在这些类当中,因此适合快速的创建一个三维环境并希望能实时的操作它。本程序就是利用它建立了一个可以用方向键控制的三维漫游程序!

2.0、Direct3DRM中有关图形学的基本内容介绍

Direct3DRM中牵涉到很多三维图形学的东西,这里本人对程序当中将要涉及到的最重要的部分作一简单介绍,让大家对Direct3DRM尽快的有一个感性的认识。

照相机(camera)场景(scene)视点(viewport)框架(frame)的概念及它们之间的关系:(这些概念与一些三维图形软件中的概念相当一致,如3DS ,因此你要是有这方面软件、的使用经验的话,你会更容易的理解这些概念)

框架(frame):它是将各种三维网格托住的支架,同时,它还将灯光,照相机,物体等都虚拟成现实世界中的东西,它们都需要放在某一特定的物理框架上才能被托住,不至于落下来。各个框架之间的关系也非常符合现实世界中的各物体的位置关系,即要想被看见,则它必须在照相机框架的前面,同理,物体要想被灯光照着也必须在灯光框架的前方。各个框架之间可以形成一个树结构,多个框架组合在一起就形成了场景。

场景(scene):是一个根框架,场景中的所有其它框架都应建立在它的基础之上,它是所有其它框架的父框架,而它没有父框架,且一个视点只能有一个场景。

照相机:它是建立在视点当中的用于可视的框架,在现实世界中可以将它想象成人的眼睛。同时,可以任意设置场景中的任一框架为照相机,方法有两种,一种是在创建Viewport 时直接给定某一框架为Camera,二是用Viewport对象提供的SetCamera()设置,因此,当你需要改变不同的视角时就可以用SetCamera()来调整观察的相对视角,但在适时漫游当中无需这样做,用第一种方法就足够了。

视点:它是用于决定在场景中的什么位置可以看到物体,这里的物体实质上已经变成了框架,而框架当中往往又包含了某一可见的网格。而视点实质上是一个二维矩形区域,且只有沿X,Y的正方向上可见的区域才能被渲染,且所有可见的物体被着色时都将自动变换成照相机坐标,这一点与人眼的作用相对应。

某一框架(在场景当中,且能被Viewport所见)

框架当中的网格

Viewport(视点),Camera附属于Viewport,通过Camera

的坐标调整即实现三维漫游同时场景也是相对于

Viewport重合的(实质上比Viewport

大)

3.0、回调函数

下面介绍一下Direct3DRM当中经常用到的一类函数----回调函数(CallBackfunction),这种函数必须深入理解才能明白Direct3DRM当中的各个调用过程,以后才能自如的添加你自己的代码。回调函数的特殊性:

●回调函数的创建不是任意的,都应遵循某一特定的结构和参数列表,且必须以这样

的参数形式才能被其它函数正确调用。

●回调函数的调用是附属于某一特定的函数,而不能单独使用,且还不能通过跟踪父

函数来达到跟踪回调函数的目的,而这样做只能导致回调函数已经执行了。因此为

了调试或检验回调函数体的代码,必须采用调试窗口当中的Run to Cursor的方法

来调试,这样才能让调试器跟踪进入回调函数体。

●回调函数的深入理解:(只针对设备的查找用到的回调函数),因它是一种自动查找

函数,故在其父函数找到某一特定的设备或驱动程序后它就会自动调用给定的回调

函数,这样就形成一个循环,:父函数查找设备—回调函数检验设备—回调函

数返回—再由父函数查找。其中当回调函数返回D3DENUMRET_OK则让父函

数继续查找形成循环,返回D3DENUMRET_CANCEL则停止查找父函数结束。

●其它形式的回调函数:最常用于Direct3DRM当中的是Movecallback function(),它

于设备查找回调函数的明显区别在于设备查找回调函数只跟随父函数执行一次,而

Movecallback()会在接口IDirect3DRMViewport:::Move()调用的美一次都要执行各

个框架的Movecallback(),这样可以统一管理各个框架的动作,且一个回调函数可

以应用于多个框架,同时,它在Direct3DRM当中对动画的应用起着相当重要的作

用,即在插值动画与一般的动画当中都必须使用回调函数来逐帧的渲染你设定的每

一个动作。

小结:这里讲述的回调函数只能让你有一个感性的认识,具体认识到具体的程序当中才能体会。接下来我们将进入代码的添加阶段,并给出详细的注释,你可得仔细看好了。

4.0、窗口框架的生成

我们将利用MFC和DirectX SDK进行建造,这样做的好处是可以结合了它们各自的优点。同时,大多数的Win32例子均采用SDK编写—晦涩难懂,但代码高效,而MFC却一目了然。还有我们为了调试的方便,将建立窗口形式的Direct3D应用程序。这里我们将借助MFC提供的对话框模板加以改进就能实现MFC和DirectX SDK的无缝联接。具体表现为在对话框

类中的InitInstance()中将自己创建的窗口类变为主窗口,则以后对系统的操作将完全转化为对这个自定义窗口的操作,也就任由你摆布了。具体代码添加过程如下。

初始化基本窗口类模板步骤:

●首先启动VC++6.0,从File下选择New,选择Project下MFCAPPWizard(exe),

命名为D3Dtest,除向导第二项全部不选外,接受其它所有缺省值。

●去掉对话框资源,在FileView处去掉D3DtestDlg.cpp和D3DtestDlg.h。在

ResourceView处去掉Dialog栏。

●打开主菜单下Insert,从NewClass下Name栏输入d3dwnd在Base Class栏选

generic CWnd 作为基类。OK

●打开d3dwnd.cpp文件,在View主菜单下选ClassVizard,class name选d3dwnd

类,Message分别双击选WM_PAINT、WM_DESTROY、WM_MOVE、WM_SIZE、

WM_KEYDOWN默认消息处理函数名,OK。

●打开d3dwnd.cpp创建自定义函数(具体方法是在ClassView列表中d3dwnd处单击

右键选add Member Function)名为:

void SetFreshRegion(HWND win);// 窗口更新

void ShowInfo(); // 将渲染结果放到前台

HRESULT D3DGetSurfDesc(LPDDSURFACEDESC lpDDSurfDesc,

LPDIRECTDRAWSURFACE lpDDSurf);

void ClearBuffer(LPDIRECTDRAWSURFACE lpbuffer);// 初始化面对象

BOOL Createfaces(int w,int h); // 创建面对象

void CleanUp();// 释放各个对象

BOOL MyScene();// 初始化场景内容

BOOL CreateDevAndView(LPDIRECTDRAWCLIPPER lpclipper,

int driver, int width, int height);

BOOL EnumDrivers();// 查询驱动设备

BOOL RenderLoop();// 着色循环

BOOL InitD3D(HWND win);// 初始化D3DRM

BOOL Create3DWnd();// 创建3D窗口

●打开D3Dtest.cpp文件,在View主菜单下选ClassVizard,class name选CD3DtestApp

类Message栏分别双击InitInstance、ExitInstance、OnIdle然后OK即可。这里重载这些函数是进行渲染的需要。

以上建立了基本类模板和主窗口的基本消息处理函数,下面是在各个文件中添加的代码:

为了能够正确的编译并连接,我们将作如下的准备:

工程项目设置:在Project主菜单下选Settings,在link栏的object/library modules处加入如下的.lib文件才能保证程序的正确连接:dinput.lib ddraw.lib d3dxof.lib d3drm.lib dxguid.lib winmm.lib

网格准备:这里用DirectX SDK提供的sphere3.x和triplane.x

图片准备:背景用DirectX SDK提供的lake.bmp,球体帖图用它提供的tutor.bmp(长宽均满足2的整数次幂)

●首先创建一个名为D3Daid.h的头文件,并加入当前工程当中。这个文件主要记录程序

当中用到的各种自定义结构,这里为了方便将它们综合在一个文件当中。添加代码如下:

struct Aid_Value

{

CRect client_rect;//自己建立的窗口客户矩形区域

POINT startpoint;//窗口客户区的起点(相对整个屏幕)

LPDIRECT3DRMDEVICE dev;//D3D保留模式设备对象指针

LPDIRECTDRAW lpddraw;//DDraw对象指针

LPDIRECTDRAWSURFACE lpprimary;//主面对象(大小为800X600)

LPDIRECTDRAWSURFACE lpback;//后台面对象(大小与窗口一样)

LPDIRECT3DRMVIEWPORT view;//保留模式视点对象指针

LPDIRECT3DRMFRAME scene;//场景框架

LPDIRECT3DRMFRAME camera;//照相机框架

GUID DriverGUID[5];//可能找到的全局统一标识符结构

char DriverName[5][50];//可能找到的三维驱动设备名称

D3DV ALUE dx,dy,dz;//照相机的漫游坐标

D3DV ALUE Rotate_rad;//旋转弧度

int NumDrivers;//可能找到的驱动设备数目

int CurrDriver;//当前使用的驱动设备

BOOL bRotate;//旋转标志(在三维漫游当中使用)

BOOL bMove;//移动标志(通上)

BOOL bQuit;//程序结束标志

BOOL bInitialized;//程序被初始化标志

BOOL bMinimized;//程序最小化标志

int BPP;//当前系统使用的颜色位数

};

●打开D3Dtest.h添加代码如下:

#include "d3dwnd.h"

class CD3DtestApp : public CWinApp

{

public:

d3dwnd * p3Dwnd;//自定义的窗口对象指针

int failcount;//渲染失败数目

};

●打开d3dwnd.h添加代码如下:

#define INITGUID//预定义COM构件的全局统一标识符

#include "d3drmwin.h"//D3D保留模式

#include "D3Daid.h"//自定义结构

●打开D3Dtest.cpp添加代码如下:这里不用系统产生的InitInstance()函数

BOOL CD3DtestApp::InitInstance()

{

p3Dwnd=new d3dwnd;//分配空间

p3Dwnd->Create3DWnd();//创建窗口并初始化D3DRM

m_pMainWnd=p3Dwnd;//让自定义窗口设为当前线程的主窗口

m_pMainWnd->ShowWindow(SW_SHOW);//显示窗口

m_pMainWnd->UpdateWindow();//更新窗口

failcount=0;//初始化渲染失败次数

return TRUE;

}

BOOL CD3DtestApp::OnIdle(LONG lCount)

{

// TODO: Add your specialized code here and/or call the base class

i f(!p3Dwnd->RenderLoop())//当没有消息处理时就进行渲染

++failcount;

i f(failcount>2)

p3Dwnd->CleanUp();//如果失败三次则退出程序

r eturn TRUE;// 这里不执行系统的空闲函数CWinApp::OnIdle(lCount);

}

int CD3DtestApp::ExitInstance()

{

// TODO: Add your specialized code here and/or call the base class

d elet

e p3Dwnd;//退出程序时去掉窗口指针

r eturn CWinApp::ExitInstance();

}

●打开d3dwnd.cpp添加代码如下:

#include "math.h"

#define MAX_DRIVERS 5//最大驱动器数目

#define PI2 6.28318f//圆周

#define Rotate_step PI2/100.0f//旋转步长

#define Move_step 0.5f//移动步长

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

#define MSG(str) MessageBox(str, "Application Message", MB_OK )

//预定义两个常用的宏

HWND hwnd=NULL;//初始化主窗口句柄

LPDIRECT3DRM lpD3DRM=NULL;//初始化D3D保留模式对象指针

LPDIRECTDRAWCLIPPER lpDDClipper=NULL;//初始化裁剪对象指针Aid_Value myvalue;//自定义结构对象

DWORD BppToDDbd(int bpp)//进行颜色位数匹配

{

switch(bpp)

{

case 1:

return DDBD_1;

case 2:

return DDBD_1;

case 4:

return DDBD_4;

case 8:

return DDBD_8;

case 16:

return DDBD_16;

case 24:

return DDBD_24;

case 32:

return DDBD_32;

default:

return 0;

}

}

//设备查找回调函数

//回调函数将找到的一个匹配的设备驱动器后,进行填充并退出设备查找//匹配准则是:与当前的系统的颜色位数一致,一般都使用硬件抽象层HRESULT WINAPI enumDeviceFunc(GUID* lpGuid,

LPSTR lpDeviceDescription,LPSTR lpDeviceName,

LPD3DDEVICEDESC lpHWDesc,LPD3DDEVICEDESC lpHELDesc,

LPVOID lpContext)

{

LPD3DDEVICEDESC lpdesc;//D3D设备描述结构

int *lpStartDriver=(int *)lpContext;

lpdesc=lpHWDesc->dcmColorModel?lpHWDesc:lpHELDesc;

if(!lpdesc->dwDeviceRenderBitDepth&BppToDDbd(myvalue.BPP))

return D3DENUMRET_OK;

memcpy(&myvalue.DriverGUID[myvalue.NumDrivers],lpGuid,sizeof(GUID)); lstrcpy(&myvalue.DriverName[myvalue.NumDrivers][0],lpDeviceName);

if(lpdesc==lpHWDesc&&lpdesc->dcmColorModel!=D3DCOLOR_MONO) *lpStartDriver=myvalue.NumDrivers ;

myvalue.NumDrivers++;

if(myvalue.NumDrivers==5)

return (D3DENUMRET_CANCEL);

return D3DENUMRET_OK;

void UserControl(LPDIRECT3DRMFRAME frame, void* arg, D3DV ALUE delta) {

LPDIRECT3DRMFRAME scene;

frame->GetScene(&scene);

if(myvalue.bMove)

{

frame->AddTranslation(D3DRMCOMBINE_AFTER,

myvalue.dx,myvalue.dy,myvalue.dz);

frame->SetPosition(scene,myvalue.dx,myvalue.dy,myvalue.dz);

myvalue.bMove = FALSE;

}

if(myvalue.bRotate)

{

frame->AddRotation(D3DRMCOMBINE_REPLACE,

0,1,0,myvalue.Rotate_rad);

frame->SetPosition(scene,myvalue.dx,myvalue.dy,myvalue.dz);

myvalue.bRotate = FALSE;

}

SAFE_RELEASE(scene);

}

//以上是全局函数和变量的声名,应把它们放在d3dwnd::d3dwnd()构造函数之前//以下是自定义函数的实体和各个消息响应函数

//创建窗口并初始化D3D的各种对象

BOOL d3dwnd::Create3DWnd()

{

LPCTSTR m_name=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, AfxGetApp()->LoadCursor(IDC_ARROW),//光标

(HBRUSH)GetStockObject(BLACK_BRUSH),//窗口背景

AfxGetApp()->LoadIcon(IDR_MAINFRAME)//图标

);//窗口注册

BOOL bret = CreateEx(WS_EX_APPWINDOW,m_name,"Direct3DRM Example", WS_VISIBLE|WS_OVERLAPPEDWINDOW,//定义窗口属性

CW_USEDEFAULT,CW_USEDEFAULT,400,400,//窗口大小和起始位置

NULL,NULL,NULL);//创建窗口

if(!bret)

return FALSE;

hwnd=GetSafeHwnd();

if(!InitD3D(hwnd))//初始化D3D

{

MSG("InitDirect3D Failed!");

OnDestroy();

return FALSE;

return TRUE;

}

BOOL d3dwnd::InitD3D(HWND win)

{

LPDIRECT3DRMTEXTURE lptex=NULL;//背景文理帖图

//注意:D3D中的文理帖图的长宽都必须是2的整数次幂

HDC hdc;

ZeroMemory(&myvalue,sizeof(myvalue));//初始化自定义结构对象

hdc=::GetDC(win);//取得当前窗口的设备句柄

myvalue.BPP=::GetDeviceCaps(hdc,BITSPIXEL);//取得系统的当前颜色位数

::ReleaseDC(win,hdc);

SetFreshRegion(win);//更新窗口位置

if(!EnumDrivers())//查找匹配的驱动设备

return FALSE;

myvalue.lpddraw->SetCooperativeLevel(win,DDSCL_NORMAL);

//设置协作等级(这里是窗口协作等级)

if(!Createfaces(myvalue.client_rect.Width(),myvalue.client_rect.Height()))

return FALSE; //根据窗口的大小来建立各种要用到的面对象

::Direct3DRMCreate(&lpD3DRM);//创建D3D保留模式对象

lpD3DRM->CreateFrame(NULL,&myvalue.scene );//创建场景根框架

lpD3DRM->CreateFrame(myvalue.scene,&myvalue.camera);//创建场景中照相机框架if(myvalue.scene->SetOrientation(NULL,D3DV AL(0.0),D3DV AL(0.0),D3DV AL(1.0), D3DV AL(0.0),D3DV AL(-1.0),D3DV AL(0.0))!=D3DRM_OK)

//设置场景的方向(默认的方向)

return FALSE;

lpD3DRM->LoadTexture("lake.bmp",&lptex);//创建背景纹理帖图

myvalue.scene->SetSceneBackgroundImage(lptex);//设置背景帖图

/*myvalue.scene->SetSceneBackgroundRGB(0.5f,0.6f,0.7f);

//背景用一纯色

*/

//根据窗口的大小创建渲染设备和渲染视点

if(!CreateDevAndView(lpDDClipper,myvalue.CurrDriver,

myvalue.client_rect.right,myvalue.client_rect.bottom))

return FALSE;

if(!MyScene())//创建好场景中使用的各种物体和帖图

return FALSE;

myvalue.bInitialized=TRUE;//D3DRM被初始化

SAFE_RELEASE(lptex);//去掉临时对象

return TRUE;

}

BOOL d3dwnd::RenderLoop()

{

if(myvalue.bMinimized||!myvalue.bInitialized)

return TRUE;

//Frame的move()函数使场景中所有与场景框架有层次关系的子框架以一定的速度轮流改变

//它们轮流改变的速度由函数的参数决定,此处为0.25

//并且这些子框架改变的依据是同这些子框架自身的运动状态联系在一起的。

//也就是说,各个子框架都可以具有自身独立的运动,而这些运动将在Move()作用后体现出来

//可见这个Move()函数的作用实在是太大了。并且它还能给你很多的启示!!!!!

if(myvalue.scene->Move(D3DV AL(0.25))!=D3DRM_OK)

return FALSE;

if(myvalue.view->Clear()!=D3DRM_OK)

return FALSE;

//这里渲染的场景将包括属于它的各个子框架也会被渲染

//并且这些框架被渲染后并不会立即被放到显示设备上显示出来,

//而这一步是分配给显示设备处理的

if(myvalue.view->Render(myvalue.scene)!=D3DRM_OK)

return FALSE;

if(myvalue.dev->Update()!=D3DRM_OK)

return FALSE;

//注意:这里的对场景的渲染、更新都是在后台面对象上进行,这是由于

//我们在创建渲染设备时所决定的,请仔细看渲染设备的创建代码就会清楚

//而我们的最终目的是在主面对象上显示,故用到下面的自定义函数

ShowInfo();

return TRUE;

}

BOOL d3dwnd::EnumDrivers()

{

HRESULT rval;

LPDIRECT3D lpd3d;

::DirectDrawCreate(NULL,&myvalue.lpddraw ,NULL);//创建DDraw对象

rval=myvalue.lpddraw->QueryInterface(IID_IDirect3D,(void**)&lpd3d);

//查询并创建D3D即时模式对象(因D3DRM当中没有定义驱动设备查找函数)

if(rval!=DD_OK)

{

myvalue.lpddraw->Release();

return FALSE;

}

myvalue.CurrDriver =-1;

lpd3d->EnumDevices(enumDeviceFunc,&myvalue.CurrDriver);//驱动设备查找

if(myvalue.NumDrivers ==0)

return FALSE;

lpd3d->Release();

return TRUE;

}

BOOL d3dwnd::CreateDevAndView(LPDIRECTDRAWCLIPPER lpclipper, int driver, int width, int height)

{

HRESULT rval;

rval=lpD3DRM->CreateDeviceFromSurface(&myvalue.DriverGUID[driver],

myvalue.lpddraw,myvalue.lpback,&myvalue.dev);

//用后台面对象创建渲染设备,这样可以方便的向前台面对象写入信息而不会

//发生闪烁的现象

width=myvalue.dev->GetWidth();

height=myvalue.dev->GetHeight();

//取得设备的高宽,当设备未创建成功程序会在这里崩溃

rval=lpD3DRM->CreateViewport(myvalue.dev,myvalue.camera,

0,0,width,height,&myvalue.view);//创建场景中的视点对象if(rval!=D3DRM_OK)

{

myvalue.dev->Release();

return FALSE;

}

//myvalue.view->SetField(0.5f );

//The screen Clip area is a rect(-0.5,-0.5)---(0.5,0.5);

//屏幕尺寸是(-0.5,-0.5)---(0.5,0.5),这是个系统默认值。

//可由SetField()调整

rval=myvalue.view->SetBack(D3DV AL(1000.0));

//设置可见的camera锥体区域,一般front默认为距离camera为1个单位

//并且只有在front和back之间的锥体区域才能被viewport渲染

if(rval!=D3DRM_OK)

{

myvalue.dev->Release();

myvalue.view->Release();

return FALSE;

}

//设置设备的渲染质量

rval=myvalue.dev->SetBufferCount(1);

rval=myvalue.dev->SetQuality(D3DRMLIGHT_ON|D3DRMFILL_SOLID|D3DRMSHAD E_GOURAUD );

if(rval!=D3DRM_OK)

return FALSE;

return TRUE;

}

BOOL d3dwnd::MyScene()

{

LPDIRECT3DRMFRAME lplightframe1=NULL;//灯光框架

LPDIRECT3DRMFRAME lpsphere3_frame=NULL;//球体框架

LPDIRECT3DRMFRAME lpplane_frame=NULL;//飞机框架

LPDIRECT3DRMLIGHT lplight1=NULL;//灯光对象

LPDIRECT3DRMLIGHT lplight2=NULL;

LPDIRECT3DRMTEXTURE lptex=NULL;//用于球体的帖图

LPDIRECT3DRMWRAP lpwrap =NULL;//用于计算球体的帖图坐标对象

LPDIRECT3DRMMESHBUILDER lpsphere3_builder=NULL;//球体网格

lpD3DRM->CreateFrame(myvalue.scene,&lplightframe1);//创建灯光框架

lpD3DRM->CreateFrame(myvalue.scene,&lpsphere3_frame);//创建球体框架

lpD3DRM->CreateFrame(myvalue.scene,&lpplane_frame);

lpD3DRM->CreateLightRGB(D3DRMLIGHT_POINT,D3DV AL(0.8),

D3DV AL(0.8),D3DV AL(0.8),&lplight1);//创建点光源

lplightframe1->AddLight(lplight1);//将灯对象加入灯光框架

lpD3DRM->CreateLightRGB(D3DRMLIGHT_AMBIENT,D3DV AL(0.5),

D3DV AL(0.5),D3DV AL(0.5),&lplight2);//创建大气灯光

//因环境光是只属于场景的故它不需要另外设置框架,直接将其加入场景即可

myvalue.scene->AddLight(lplight2);

//设置灯光、照相机、飞机和球体框架的位置

lplightframe1->SetPosition(myvalue.scene,0.0f,0.0f,1.0f);

myvalue.camera->SetPosition(myvalue.scene,0.0f,0.0f,0.0f ) ;

lpsphere3_frame->SetPosition(myvalue.scene,0.0f,0.0f,20.0f);

lpplane_frame->SetPosition(myvalue.scene, 0.0f,1.0f,12.0f);

//飞机框架直接从文件中调用

lpplane_frame->Load("triplane.x",NULL,D3DRMLOAD_FROMFILE,NULL,NULL);

lpsphere3_frame->SetOrientation(myvalue.scene,D3DV AL(0.0),D3DV AL(0.0),D3DV AL(1.0 ),

D3DV AL(0.0),D3DV AL(1.0),D3DV AL(0.0));

//为球体框架赋一旋转动画

lpsphere3_frame->SetRotation(myvalue.scene,D3DV AL(0.0),D3DV AL(0.1),

D3DV AL(0.0),D3DV AL(0.05));

lpD3DRM->CreateMeshBuilder(&lpsphere3_builder);

lpsphere3_builder->Load("sphere3.x",NULL,D3DRMLOAD_FROMFILE,NULL,NULL);

lpsphere3_builder->Scale(D3DV AL(2),D3DV AL(2),D3DV AL(2));//放大2倍

lpsphere3_builder->SetColorRGB(D3DV AL(1),D3DV AL(1),D3DV AL(1));

D3DV ALUE miny,maxy,height;

D3DRMBOX box;

lpsphere3_builder->GetBox(&box);

maxy=box.max.y;

miny=box.min.y;

height=maxy-miny;

lpD3DRM->CreateWrap(D3DRMWRAP_CYLINDER,NULL ,

D3DV AL(0.0),D3DV AL(0.0),D3DV AL(0.0),

D3DV AL(0.0),D3DV AL(1.0),D3DV AL(0.0),

D3DV AL(0.0),D3DV AL(0.0),D3DV AL(1.0),

D3DV AL(0.0),D3DDivide(miny,height),

D3DV AL(1.0),D3DDivide(D3DV AL(1.0),height),&lpwrap);

//创建一求形帖图坐标,并赋给球体对象

lpwrap->Apply((LPDIRECT3DRMOBJECT)lpsphere3_builder);

//create the texture from the .bmp file and give the sphere3

mesh(LPDIRECT3DRMVISUAL)lpsphere3_builder

lpD3DRM->LoadTexture("tutor.bmp",&lptex);

lpsphere3_builder->SetTexture(lptex);

lpsphere3_frame->AddVisual((LPDIRECT3DRMVISUAL)lpsphere3_builder);

//球体框架加入可视对象

//lpplane_frame->AddVisual((LPDIRECT3DRMVISUAL)lpplane_builder);

myvalue.camera->AddChild(lplightframe1);

//让点光源跟随照相机移动,为以后的三维漫游作好准备

myvalue.camera->AddMoveCallback(UserControl,NULL);

lplightframe1->Release();

lpsphere3_frame->Release();

lpplane_frame->Release();

lpsphere3_builder->Release();

lplight1->Release();

lplight2->Release();

lptex->Release();

lpwrap->Release();//以上是释放临时对象

return TRUE;

}

void d3dwnd::CleanUp()

{

SAFE_RELEASE(myvalue.lpprimary);

SAFE_RELEASE(myvalue.lpback);

SAFE_RELEASE(lpDDClipper);

myvalue.bInitialized =FALSE;

SAFE_RELEASE(myvalue.scene);

SAFE_RELEASE(myvalue.camera);

SAFE_RELEASE(myvalue.view);

SAFE_RELEASE(myvalue.dev);

SAFE_RELEASE(lpD3DRM);

SAFE_RELEASE(myvalue.lpddraw);

myvalue.bQuit=TRUE;

}

BOOL d3dwnd::Createfaces(int w, int h)

{

DDSURFACEDESC ddsd;

HWND win;

HRESULT aa;

win=GetSafeHwnd();

memset(&ddsd,0,sizeof(DDSURFACEDESC));

ddsd.dwSize = sizeof( ddsd );

ddsd.dwFlags = DDSD_CAPS ;

ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

aa= myvalue.lpddraw->CreateSurface(&ddsd,&myvalue.lpprimary,NULL);

//创建主面对象(系统默认为全屏)

if(aa!=DD_OK)

return FALSE;

ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;

ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |DDSCAPS_VIDEOMEMORY|

DDSCAPS_3DDEVICE;

ddsd.dwWidth =w;

ddsd.dwHeight =h;

aa= myvalue.lpddraw->CreateSurface(&ddsd, &myvalue.lpback, NULL);

//创建后台面对象

if(aa!=DD_OK)

return FALSE;

myvalue.lpddraw->CreateClipper(0,&lpDDClipper,NULL);

//创建裁剪对象

lpDDClipper->SetHWnd(0,win);//将裁剪对象赋给窗口

myvalue.lpprimary->SetClipper(lpDDClipper);

//也将此裁剪对象赋给主面对象

ClearBuffer(myvalue.lpprimary);//初始化面对象表面

ClearBuffer(myvalue.lpback);

return TRUE;

}

void d3dwnd::ClearBuffer(LPDIRECTDRAWSURFACE lpbuffer)

{

DDSURFACEDESC ddsd;

RECT dst;

DDBLTFX ddbltfx;

if(!lpbuffer)

return;

D3DGetSurfDesc(&ddsd, lpbuffer);

memset(&ddbltfx, 10, sizeof(ddbltfx));

ddbltfx.dwSize = sizeof(DDBLTFX);

SetRect(&dst, 0, 0, ddsd.dwWidth, ddsd.dwHeight);

lpbuffer->Blt(&dst, NULL, NULL,

DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx);

}

HRESULT d3dwnd::D3DGetSurfDesc(LPDDSURFACEDESC lpDDSurfDesc, LPDIRECTDRAWSURFACE lpDDSurf)

{

HRESULT result;

memset(lpDDSurfDesc, 0, sizeof(DDSURFACEDESC));

lpDDSurfDesc->dwSize = sizeof(DDSURFACEDESC);

result = lpDDSurf->GetSurfaceDesc(lpDDSurfDesc);

return result;

}

//响应毁灭消息

void d3dwnd::OnDestroy()

{

CleanUp();

CWnd::OnDestroy();

// TODO: Add your message handler code here

}

//响应窗口重画消息,这里让D3D保留模式接管这个消息

void d3dwnd::OnPaint()

{

LPDIRECT3DRMWINDEVICE lpd3drmwindev;

CRect re;

PAINTSTRUCT ps;

HWND h_win;

HDC hdc;

h_win=GetSafeHwnd();

if(!myvalue.bInitialized||!myvalue.dev)

return;

if(::GetUpdateRect(h_win,&re,FALSE))

{

hdc=::BeginPaint(h_win,&ps);

myvalue.dev->QueryInterface(IID_IDirect3DRMWinDevice,

(void**)&lpd3drmwindev);

lpd3drmwindev->HandlePaint(ps.hdc);

lpd3drmwindev->Release();

::EndPaint(h_win,&ps);

}

RenderLoop();

}

//只要窗口的大小发生改变则重新创建渲染设备和视点对象

void d3dwnd::OnSize(UINT nType, int cx, int cy)

{

int width =cx;

int height =cy;

if(width && height &&myvalue.view &&myvalue.dev)

{

int view_width = myvalue.view->GetWidth();

int view_height = myvalue.view->GetHeight();

int dev_width = myvalue.dev->GetWidth();

int dev_height = myvalue.dev->GetHeight();

if(view_width==width&&view_height==height&&!myvalue.bMinimized)

return;

myvalue.bInitialized = FALSE;

SAFE_RELEASE(myvalue.view);

SAFE_RELEASE(myvalue.dev);

SAFE_RELEASE(myvalue.lpprimary);

SAFE_RELEASE(myvalue.lpback);

SAFE_RELEASE(lpDDClipper);

SetFreshRegion(hwnd);

Createfaces(width,height);

if(!CreateDevAndView(lpDDClipper,myvalue.CurrDriver,width,height))

{

myvalue.CurrDriver = 0;

MSG("Failed to create the D3DRM device.\n" );

d3dwnd::OnDestroy();

return;

}

myvalue.bInitialized = TRUE;

myvalue.bMinimized = FALSE;

}

else

{

myvalue.bMinimized = TRUE;

}

}

//当设备在后台面对象上渲染结束后,将渲染结果从后台面对象拷贝到前台主面对象void d3dwnd::ShowInfo()

{

CRect re;

re.left=myvalue.startpoint.x;

re.top=myvalue.startpoint.y;

re.right=myvalue.client_rect.Width()+re.left;

re.bottom=myvalue.client_rect.Height()+re.top;

//更新区域

myvalue.lpprimary->Blt(&re,myvalue.lpback,&myvalue.client_rect,DDBLT_WAIT,NULL);/ /|DDBLT_KEYSRC

}

void d3dwnd::SetFreshRegion(HWND win)

{

myvalue.startpoint.x=myvalue.startpoint.y=0;

//这里必须将此设置为0,否则下面的函数将上次的结果与当前结果相加

::ClientToScreen(win, &myvalue.startpoint);

::GetClientRect(win,&myvalue.client_rect);

}

//当窗口移动时作的的消息响应

void d3dwnd::OnMove(int x, int y)

{

myvalue.startpoint.x=x;

myvalue.startpoint.y=y;

// TODO: Add your message handler code here

}

void d3dwnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)

{

switch(nChar)

{

case VK_UP:

myvalue.dx+=Move_step*(D3DV ALUE)sin((double)myvalue.Rotate_rad);

myvalue.dz+=Move_step*(D3DV ALUE)cos((double)myvalue.Rotate_rad);

myvalue.bMove = TRUE;

break;

case VK_DOWN:

myvalue.dx-=Move_step*(D3DV ALUE)sin((double)myvalue.Rotate_rad);

myvalue.dz-=Move_step*(D3DV ALUE)cos((double)myvalue.Rotate_rad);

myvalue.bMove = TRUE;

break;

case VK_LEFT:

myvalue.Rotate_rad-=Rotate_step;

if(myvalue.Rotate_rad<=(-PI2))

myvalue.Rotate_rad+=PI2;

myvalue.bRotate = TRUE;

break;

case VK_RIGHT:

myvalue.Rotate_rad+=Rotate_step;

if(myvalue.Rotate_rad>=PI2)

myvalue.Rotate_rad-=PI2;

myvalue.bRotate = TRUE;

break;

}

//CWnd::OnKeyDown(nChar, nRepCnt, nFlags);

}

小结:以上程序编译并执行后,可以看到一个地球仪在一个美丽的背景当中不停的旋转,一架飞机停在空中,同时你还可以通过方向键进行三维漫游进行多角度观察。并且你还可以象处理Windows一般窗口那样进行拖动、放大、缩小、最小化、最大化等操作。这里再提醒一下,在运行或编译前一定要把前面准备步骤当中的东西备齐才能看到预想的结果。

Direct3D应用中的2D应用

Direct3D应用中的2D应用 2D Application 收藏(转载)2D Application 这一章将讨论IDirect3DDevices9接口怎样应用到简单的两维应用程序里去。然而,接下来讨论的方法和接口的方法不仅仅只应用在两维应用程序里面。 开始我们将看看IDirect3DSurface9接口,它用于存放像素数据。我们将看看怎样创建surfaces,怎样填充数据,并且执行像素拷贝操作。 接下来,我们讨论IDirect3DSwapChain9接口管理back buffer 集合。设备创建的时候都会携带一个默认的swap chain,但是也可以为window模式下多个视图创建新的swap chain。 再接下来,我们将讨论Presentation,Present 也是 IDirect3DDevice9提供的方法。 即使Direct3D可以不使用GDI,但是他们也要处理发送到应用程序top-level窗口的消息。我们推荐使用Direct3D应用程序来处理窗口消息。DirectX 并没有提供直接方法来将

GDI和Direct3D结合起来。但是,通常是在内存DC和流水线产生的结果像素数据上执行GDI操作。

最后,我们将讨论流水线的Video scan out部分以及swap chain从back buffer到front back 的过程。video scan out 电流读取数据,使用cursor overlay,gamma校正以及像素数据转化成monitor的模拟信号。Pixel Surface Pixel 面是像素数据的矩形集合。像素数据的内存layout 是通过D3DFORMAT定义的。在设备上使用surface有几处地方:back buffer surfaces, depth/stencil buffer surfaces,纹理层surface,render target surface 以及图片surface。Direct3D 使用IDirect3DSurface9接口表示一个surface,CreateOffscreenPlainsurface方法可以创建一个图片surface,它能存在于scrath内存池,系统内存池和设备内存池。CreateDepthStencilSurface和CreateRenderTarget分别返回depth/stencil的surface和render target的surface。一个plain surface可能不是3D 渲染的目标,但是你能在plain surface和其他surface之间进行数据拷贝。HRESULT CreateOffscreenPlainSurface(UINT width,

基于三维全景技术的动态虚拟漫游系统

基于三维全景技术的动态虚拟漫游系统 摘要针对当前全景漫游系统存在的问题,自主研发一种基于三维全景技术的动态虚拟漫游系统。该系统利用先进的网络、数据库技术,提出一系列改进算法,建立动态数据模块,并对数据流程图中的各个模块进行描述;利用HTML5框架上开源的WebGL库文件,构建Ajax模式下的MVC设计模型;借助SqlServer 数据库,增加后台管理平台,从而能对本系统不断更新、维护。 关键词全景漫游;动态数据模块;MVC设计模型;SqlServer数据库 近年来,虚拟现实技术一直是计算机应用领域的研究热点,其特点是利用计算机多媒体技术系统中创建真实世界的仿真环境,通过计算机的硬件设备来模拟人体的视觉、听觉、味觉和触觉等真实感知,使参与者在其中产生与在真实环境中相同或相似的体验。根据人体的生理特点,在各种感知中视觉感知占80%,因此在虚拟现实技术的研究中,视觉的模拟占有十分重要的地位。 1 研究背景 基于视觉的虚拟现实技术主要分为两种:一种是基于三维几何模型建模技术(VRM),另一种是基于图像的全景绘制技术(IBR)。VRM在实时绘制时显然计算量大、制作周期长,再加上互联网网速的延迟,以及计算机本身硬件条件的限制,显得无能为力。IBR提供了较好的方法来解决这些难题,利用真实场景的图像作为虚拟场景的表示形式,真实地再现了真实场景的视觉信息,生成的场景视图的质量远远优于VRM。 目前,国内许多全景数字史馆建设往往采用特制的软件来实现,比较常用的国外软件有MGI photo suite、Pano2VR、Panorama Maker、Virtools、Ulead Cool 360等,国内也有一些比较好的全景处理软件,比如杰图的“造景师”、彩影以及中视典的vrp系列软件。 虽然直接使用商业软件能够比较简单、快速地制作出基于IBR的360全景,但是它们没有考虑现实情况中不断增长、实时更新的动态性问题。所以,本项目自主研发一种基于三维全景技术的动态虚拟漫游系统。 2 关键技术 全景漫游技术可以实现网络上的虚拟场景漫游,因其具有良好的交互性、沉浸性而受到众多用户的青睐。传统漫游技术如VRML、QuickTime、Flash等大多存在标准不一、插件依赖、封闭性、集成性差等问题,新兴的基于HTML5的全景漫游方案可以对以上问题进行缓解。 2.1 基于HTML5的全景漫游技术的实现原理

Direct3D 10系统

摘要 本文描述了第四代PC平台上图形图像单元(GPU)的系统构架。与上一代图形管道相比,新的管道有了重大改变,引入了一个新的可编程阶段(stage)用于生产额外的图元,并把图元流保存到内存中;扩展了所有可编程阶段的功能,涉及到顶点、图片内存资源,以及新的储存格式。此外,我们还描述了API、运行时以及实现新管道的着色语言的结构性改变。解决当前系统中的缺陷,是我们设计的基本思想。文章不但描述了重要设计抉择背后的原理,同时也描述了那些最终被否决的方案。 1.前言 过去10年,OpenGL和Direct3D所依赖的渲染管道构架已经取得了重大发展。最近5年中,随着从固定管道到可编程管道的过渡,发生了许多戏剧性的变化。虽然变化的进程很快,但每一步都反映出了设计者在通用性、性能以及成本上所做出的妥协。 我们一直在努力了解以及构建一个系统,来解决许多程序中对图形加速器的需求(呈现图形、CAD、多媒体处理,等等)。但是,我们更想把注意力集中在交互式娱乐应用中。这些程序需要管理数十亿字节的艺术品,包括几何体、纹理、动画数据以及着色程序,占用大量系统资源(CPU、内存、带宽),以可交互的速率渲染丰富的、充满细节的图片。在处理海量数据的同时,保证渲染的灵活性,是对设计者的重大挑战之一。在系统设计的方方面面,都可以反映出我们对这个问题的解决方案。 与上个版本的Direct3D一样,Direct3D 10同样是在应用程序开发者、硬件设计师以及API/运行时构架师三方的合作下设计的。在三年多的设计过程中,合作者之间详细的交流是无价的,让我们更深入了软硬件部署的代价,以及在大量不同硬件进行权衡。在开发Direct3D 10的过程中,调查显示应用程序开发者通常受以下限制的困扰,以及用来缓解这些问题的策略: 1. 状态(state)改变的代价过高。改变任何类型的状态(顶点格式、纹理、shader、shader参数、混合模式,等等)都会付出很大代价。优化方法通常是通过查询对象状态来排序,减少API状态改变次数;减少外观的改变;或者使用基于shader的技术,使用shader来决定状态。对于后者,例子之一就是把多张纹理打包为一张纹理地图(texture map)(也称为纹理地图集),通过纹理坐标变换,来索引相应的子纹理。 2. 硬件加速器性能变化太多。应用程序不得不编写一系列分支语句,以保证在不同硬件上都能正常运行。这些问题会影响到程序的特性设置,资源管理,算法精度,以及储存格式。 3. CPU和GPU之间频繁的同步。传统的图形管道允许有限制的重新使用管道当前产生的数据,作为下一个处理步骤的输入数据。Render-to-texture就是这种机制的最好例子之一,所渲染的图片接下来能被当作纹理使用,最小化CPU的干涉。但是,产生新顶点数据,或者创建立方贴图就需要CPU与GPU进行更多的协调和通信,降低了效率。 4. 指令以及数据类型的限制。通常都以精度和所支持的流程控制指令来衡量vertex shader,同样的方法也用来衡量pixel shader,但是,无论是pixel还是vertex shader都不支持整数指令。此外,出于对pixel shader精确性的要求,还指定了浮点算法。应用程序要么不使用这些额外的功能,要么模仿他们的使用。基于表格功能的计算就是例子之一。 5. 资源限制。纹理读取的次数、纹理范围、程序指令,等等,都受到限制。应用程序不得不压缩算法,或者把它们分为多个shader pass。因此,还出现了对自动划分shader程序的研究。 2.背景 我们的系统建立于PC,工作站以及游戏机平台上的应用程序可编程渲染管道。当前的图形管道分为两个编程阶段,一个用于处理顶点数据(vertex shader),一个用来处理像素或片断(fragment or pixel shader)。在Lindholm2001里描述了设计早期vertex shader的思想和折中。除了细小的差别以外,pixel shader也是按这样的轨迹来设计的。可以把顶点以及像素着色器的发展分为4代(包括Direct3D 10),如表一所示:

三维虚拟校园漫游系统设计

Scientific Journal of Information Engineering June 2013, Volume 3, Issue 3, PP.50-55 Design of 3D Virtual Campus Roaming System Hongyan Yang, Zhuo Shi, Yanru Zhong# College of Computer science and engineer, Guilin University of Electronic Technology, Guilin Guangxi 541004, China #Email: rosezhong@https://www.360docs.net/doc/ce17853287.html, Abstract With the growing sophistication of virtual reality technology, 3D virtual campus roaming system as effective platform for school propaganda outside, the campus planning and management decision will provide a strongly support. Taking the campus of Guilin University of Electronic Technology as prototype, combing with the software of 3Ds Max and using VR-Platorm development platform connections with the backend database and virtual building and live Imaging shooting, a real-time roaming system of virtual campus has been designed and implemented. In this paper, the main aim is to explore a new idea for digital campus construction. Keywords: Virtual Reality; VR-Platform; Digital Campus 三维虚拟校园漫游系统设计* 杨宏艳,史卓,钟艳如 桂林电子科技大学计算机科学与工程学院,广西桂林 541004 摘要:随着虚拟技术的日益成熟,三维虚拟校园漫游系统作为学校对外宣传的有效平台是数字化校园建设的核心。以桂林电子科技大学东校区为例,结合三维仿真技术3DS max实现了虚拟校园的三维模型。运用VR-Platorm开发引擎,结合SQL Server数据库连接设计并实现了三维虚拟校园漫游系统。实现了自主漫游、按目的地自动生成漫游路径、定位鸟瞰等功能。实验结果表明:经过改进的场景优化技术,系统在普通PC机上运行稳定、流畅、高效。 关键词:虚拟现实;VR-Platform;数字校园 引言 20世纪80年代美国人Jaron Lanier首次正式提出了虚拟现实[1](Virtual Reality)概念。自此,这种利用计算机模拟虚拟世界,提供用户身临其境的视觉、听觉、触觉的感官模拟技术,因其具有感知性、沉浸性、交互性和构想性的特点,如今已广泛应用于城市规划、文物保护、交通模拟、虚拟现实游戏及远程教育等领域。“虚拟校园”是随因特网、虚拟现实技术、网络虚拟小区等的发展而产生,是基于现实校园对三维景观和教学环境数字化模拟的产物。数字化校园虚拟漫游系统是数字校园建设计划的核心平台。当前浙大率先开发展示了虚拟校园之后,国内众多高校如清华、南京大学、北航、香港中文大学等高等院校纷纷建立自己的虚拟校园[2-3] 。 通常,三维虚拟校园开发的主要方法是用ArcGis,SuperMap和其它具有三维功能的软件进行二次开发。但这些方法明显的缺点是对开发者的编程水平要求较高,建模代码太长,开发系统不能独立于运行环境。考虑到以上情况,本文选择VR-Platform为开发环境,提出了一种简单实现虚拟校园的方法。这种方法一方面能利用专业的建模工具3DS MAX软件很快实现三维场景模型的建立。另一方面,通过运用VRP引擎高效的模块化的编程能力,能够进行实时渲染和交互控制,减少了建模时间加速了系统开发的进程。另 *本文受国家自然科学基金(NO.50865003)和广西科学制造系统和先进制造技术开放基金资助(No.K090014)以及新世纪广西高等教育教改工程项目(No. 2011JGB048)“以工程应用能力为导向的数字媒体技术人才培养模式的探索与实践”基金资助。

三维地形漫游系统的OPENGL实现

三维地形漫游系统的OPENGL实现 引言 (2) 1地形可视化的概念: (2) 2 三维地形的生成技术: (3) 2.1 基于真实数据的地形生成 (3) 2.2 基于分形技术的地形生成 (3) 2.3 Diamond一Square算法: (4) 3基于OpenGL的地形渲染: (5) 3.1:OpenGL的基本操作 (6) 4 三维地形的简化技术: (7) 4.1四叉树的LOD简化算法 (7) 4.2自适应实时网格优化算法(ROAM) (9) 5三维地形的漫游系统: (10) 5.1各个类之间的类视图,如图所示: (10) 5.2各个类的具体实现: (11) 5.2.1数据采集和处理 (11) 5.2.2Lod 类,封装LOD技术 (11) 5.3系统实现 (12)

引言 本系统是基于OpenGL的三维地形漫游,系统主要包括三个方面: 地形数据的采集与计算,由于本系统是采用随机中点位移法得到地形高度图数据。采用Diamond一Square算法得到原始数据。地形渲染,采用基于OpenGL的环境,在地形中加入光照,雾,天空,以及纹理等效果对地形进行模拟,使其更接近真实。采用LOD技术对地形进行简化和管理。 1地形可视化的概念: 地理信息系统技术从60年代以来,经过40多年的发展,现逐步向三维化、可视化和网络化等方面发展,GIS软件平台不断推陈出新。传统的2D-GIS 软件通过矢量或栅格的方法完成二维地表的成图和分析,多年来,一直用二维地图产品表示三维地物,包括地质图、横断面图、示意图以及专门的几何结构图如立体网等。但在某些领域,人们需要分析具有三维坐标的地表面以下的状况,这种空间关系时常为判断和评价矿产资源、石油资源和污染状况提供重要的信息。因此人们在2D-GIS软件的基础上研究和开发了一些适合实际需要的3D-GIS产品。“数字地球”强调对地球的真三维的描述,中国政府将“数字地球”列为21世纪的战略目标之一,使得3D-GIS的理论研究和软件开发又掀起了一次高峰。所有的GIS系统都带有包括空间数据、拓扑关系及属性数据在内的地理数据库,或者能与外部数据库管理系统直接进行连接。GIS所处理的空间数据按其处理方式不同,可分为:栅格数据、2D拓扑矢量数据、数字高程模型(DEM)、三角形不规则网格(TIN)、三维模型、时间模型等,而所有这些都是以2D或2.5D(准三维)为主的。2D-GIS用点、线和面来表示地理实体,许多3D地理实体被简化为2D形式,得到的是二维地图、图像产品,其分析功能也是在二维基础上进行的。2.5D或称准3D意思是它不具备真正的Z坐标,而是将Z值作为某一位置上的属性变量,它并不是空间坐标值。在真3D-GIS中,可用表达式a=f(x,y,z)来表示,a为点(x,y,z)对应的属性值,z是独立于x,y的自变量,即三维空间中的z坐标值。3D-GIS 具有连续的数据结构和与之相应的分析功能,由此带来的好处是可以从空间的角度分析和显示物体。地形的可视化是一门以研究数字地面模型(Digital Terrain Model,DTM)或数字高程域(Digital Height Field)的显示、简化、仿真为内容的学科,它属于计算机图形学的一个分支。除了计算机图形学之外,计算几何也是它的重要基础知识。它的应用涉及地理信息系统(GIS)、虚拟现实(VR)技术、战场环境仿真、娱乐与游戏、飞行穿越(Flythrough)、土地管理与利用、气象数据的可视化等各个领域。 常用的地形可视化方法大致有写景法、等高线法、分层设色法、晕渲法、拍摄实地景观照片、建立三维几何相似的实物模型、产生三维线框透视投影图和逼真地形显示等多种方法。随着光栅图形显示硬件的发展,以真实感图形为代表的光栅图形技术日益成为计算机图形发展的主流,基于计算机图形学理论的三维地形逼真显示逐渐成为地形可视化发展的主流。产生逼真地形

Win7系统Direct3d功能不可用的解决方法

Win7系统Direct3d功能不可用的解决方法 DirectX加速不可用或者被禁用,直接导致我们大型游戏玩不,这对于爱玩游戏的人来说是个麻烦。最近,使用Win7系统的用户,发现Direct3d功能不可用,是由于DirectX组件出现问题,才导致Direct3d功能不可用。那要如何解决这个问题呢?今天,小编就和大家介绍一下Win7系统Direct3d功能不可用的解决方法。 推荐更快速解决方法:系统重装 步骤如下: 1、首先,点开开始按钮,在搜索框里输入“dxdiag”。 2、会搜索出一大堆东西,没关系的,只要打开最上边的“dxdiag.exe”这个程序就行了。 3、Dxdiag的中文名叫做DirectX诊断工具,打开后界面如下图: 4、这时我们在主界面上点击“显示”选项卡(如上图红圈所示),就能看到关于系统中所有与图形有关的内容了(如下图):

5、正常的话,下面“DirectX功能”框里的DirectDraw加速、Direct3D 加速、AGP纹理加速应该都是“已启用”状态,这时你的电脑的显示系统没有问题,玩大型游戏、用CAD软件等,应该都可以正常使用。 6、但是有一部分人的DirectX加速功能是不可用状态,怎么修复呢?确定你的显卡驱动是否正常。

7、注意到画红框的部分了吗?这里就会显示你的显卡驱动是否正常。第一张图为一个显卡驱动正常的系统截图,第二张图为一个显卡驱动有问题的系统截图。通过两张图的对比,各位其实很好看出什么样的叫正常,什么样的叫异常。为了严谨,我还是把驱动中每项参数都简单介绍一下。 8、参数中主程序驱动里面会写着驱动的文件名,如果写的是一大堆文件名(如nvd3dumx.dll,nvwgf2umx.dll等等,不同的显卡品牌这里显示的文件名会不一样,这个无所谓的),就是正常状态,如果只写了vga,则100%是显卡驱动有问题。 9、下面是版本信息,如果是以6.1.7600开头的,那么就是显卡驱动有问题,如果是其他的,就是显卡驱动正常。其实这个6.1.7600指的是Windows 7的版本号,系统只能用自己的版本号填在这,说明显卡驱动就是缺失的。 接下来是日期,如果是2009/7/14 7:25:51,那么就是显卡驱动有问题,如果是其他的,就是显卡驱动正常。其实这个2009/7/14 7:25:51,指的是Windo ws 7系统编译完成的时间。 然后是WHQL签名,这个签名无所谓,不管有还是没有都不影响使用。

基于Unity3D的三维数字校园漫游系统

龙源期刊网 https://www.360docs.net/doc/ce17853287.html, 基于Unity3D的三维数字校园漫游系统 作者:宋姗姗 来源:《中国科技博览》2016年第21期 [摘要]在数字校园建设中应用虚拟现实技术,是进行校园规划和设计的新趋势。本文以某大学校园环境为虚拟空间,以Unity3D为开发平台,采用场景建模软件,结合使用编程语言进行交互,并与HTML进行整合,共同开发完成虚拟校园。 [关键词]Unity3D;三维;数字校园;漫游系统 中图分类号:TP391.41 文献标识码:A 文章编号:1009-914X(2016)21-0245-01 1 前言 虚拟现实技术可以利用计算机生成比较真实的模拟环境,用户仿佛置身于真实的环境中,用户通过接口与虚拟环境进行交互,具有用户渲染感、交互性以及实时性。虚拟现实技术是信息科学的一门新的技术,广泛应用于军事、娱乐、医学等各个领域。三维数字校园漫游系统具有强大的功能,可以直观地展现校园全景,用户产生置身于真实校园的感觉,对学校的规划和设计具有指导意义。现在很多高等院校都在利用不同的软件来进行数字校园建设。本文介绍了Unity3D游戏开发技术在三维数字校园漫游系统中的应用情况,校园漫游系统可以让用户对学校有更形象直观的了解。 2 系统简介 三维数字校园漫游系统是三维形式的校园系统,主要是将校园的信息进行三维形式的展示。该系统采用三维可视化技术和虚拟现实技术,并借助三维建模软件模拟现实环境,使系统实时可交互。Unity3D是实现校园漫游系统的游戏型软件,系统可以在网页上直接运行,用户的体验比较直观。 现在实现校园漫游的系统软件很多,最早的语言是VRML语言,以后又出现VRP,这是一款国内国内顶尖的虚拟漫游引擎,在设计虚拟产品方面Cult3D非常的便捷,在国内外享有盛誉的是Unity3D软件。 3 Unity3D平台介绍 Unity3D是一款跨平台游戏开发软件,可以直观的对游戏进行编辑。Unity3D由Unity?Technologies进行系统开发开发,可以轻松创建三维视频游戏、建筑可视化、实时三维动画等类型的互动内容,是一个多平台的综合型游戏开发工具,可以进行全面的游戏引擎。其优势在于性价比高,用户不用下载客户端,直接进行网页效果浏览进行体验。Unity3D支持各类脚本

三维虚拟校园的漫游系统实现

2015.09 主要通过VR-Platform 平台编辑器中对已建立的校园模型交互功能实时设置,同时进行系统优化及设置、编译、发布等系统生成。交互功能设置是通过虚拟相机生成、光照、云彩效果生成、消隐、碰撞检测功能,为校园模型增加场景的逼真度;经过系统优化工作以提高系统交互感,最后对系统添加背景音乐、编译测试、发布运行。 1场景合成导入 首先运用3DS Max 软件进行场景合成,然后将场景导入 到VR-Platform 平台中,通过VRP 平台进行交互处理后,最终生成三维虚拟校园漫游系统。 2交互功能设置 运用VR-Platform 平台编辑器可实现场景模型的交互处 理,包括虚拟相机生成、场景真实化处理、优化处理以及设置背景音乐等。 2.1虚拟相机生成 在三维虚拟校园系统中漫游,其实质是以某一点为基础 点进行观看游览,随着基础点的移动而变换场景,因此在系统开发时需要生成虚拟相机,用以模拟用户在虚拟校园中漫游的视角。 VRP-BUILDER 中内置了多种样式的相机,开发者可以自 由选择,如定点观察相机、行走相机、飞行相机等。其中:定点相机主要用于拍摄虚拟场景;行走相机主要用于模拟人的第一视角进行漫游交互,开发者可自主选择观看位置和观看角度,视线可实现360度调整,可提高虚拟校园的交互性和逼真度,因此行走相机对系统交互性的影响最大;动画相机用于创建自由漫游的路径,并可按此路径进行游览;飞行相机则是通过创建一个较高的视点,实现用户在高空俯瞰校园虚拟场。灵活运用以上多种虚拟相机,系统开发者可设计出不同模式、不同视角的用户自主控制漫游路径。 2.2光照效果 在3DS Max 中,可使用天空盒模型生成辽阔的天空场景, 但实现天空场景的逼真感,还需要有云朵、光照等与真实校园上的天空相似的景观和气候,其中光照就是必不可少的模块。在VR-Platform 平台中,生成光照对象后调整光线方向,使其投射去向和场景投影方向相同。同时还可进一步添加光晕效果,选择合适的光晕加入到虚拟校园系统中,调整其高 度和角度参数,使其与光照方向相吻合,结合天空盒中的光线方向,即可生成美丽的光圈。 2.3云彩效果 云彩是实现虚拟校园系统逼真性不可缺少的道具之一。 为实现更加逼真的云彩效果,建议在天空中对云彩效果进行随机布置,并设置好云彩的浓淡效果,从蓝天到白云应有一个由淡转浓的渐变过程,才可实现云彩效果的逼真性。 2.4消隐 各种三维模型绘制的先后顺序不一样,在整个虚拟场景 中,经常会出现某些模型的一部分被其他部分遮盖住的情况。用户漫游虚拟校园时,随着视点和视角的变化,有些场景对用户来说是不可见的,不可见的场景是随着视点和视角的变化而变化的。为实现这种变化,使三维场景的立体观感更强烈,应对不可见的场景进行隐藏,即进行图形的消隐处理,经过消隐处理的图像视觉观感更为真实。 2.5碰撞检测 真实世界中,人体是无法穿过固态物体的;而在虚拟校 园系统中,大部分的模型为三维模型,这些三维模型在用户的视点发生变化时,可能会出现视点和物体交接穿越的现象。为了更加真实地模拟校园,需要对这类碰撞进行检测。碰撞检测可判定视点与模型之间是否会发生碰撞,增强虚拟系统的交互感与真实感,从而让用户产生身临其境的逼真感。因此,一个逼真的虚拟系统需要高效的碰撞检测算法。 内置物理引擎系统的碰撞检测算法具有非常高的效率是 VR-Platform 平台的显著优势之一,VR-Platform 平台在进行物 理模拟之前,先重组三维场景中所有模型的片和面,使其格式最优化并进行存储,后续的模拟将不需要进行再次计算。为排除碰撞检测时可能出现的计算冗余,在碰撞检测前,VR- Platform 平台会进行多次过滤,包括场景过滤、碰撞组过滤、 包围盒过滤以及动、静物体过滤。 3系统优化 在信息收集和模块建模之后需要对模型进行优化,以确 保虚拟校园系统不仅可以保证良好的沉浸感、交互性和仿真感,还能高效、快速和流畅地运行,这种优化需要在整个项 三维虚拟校园的漫游系统实现 徐飞 (安徽理工学校,安徽安庆246002) 摘 要:虚拟校园系统是虚拟现实技术在教育领域的一个重要应用,可服务于学校的宣传展示、资源管理、规划设 计、远程访问等,也是校园管理信息化的一个重要应用,对学校的数字化管理具有较重要的积极影响。 关键词:三维虚拟校园漫游系统;虚拟现实;VR-Platform 平台;碰撞检测;交互功能;漫游功能 收稿日期: 2015-01-12 91 DOI:10.16184/https://www.360docs.net/doc/ce17853287.html,prg.2015.09.040

Direct 2D与Direct 3D 11协同工作时遇到的一些问题

Direct 2D与Direct 3D 11协同工作时遇到的一些问题 Direct 2D与Direct 3D 11协同工作时遇到的一些问题 1、前言 最近在把游戏引擎的API从DirectX 9升级到DirectX 11,因为两套API之间存在巨大的差异,因此在升级迁移的过程中撞了不少坑,现在主要把Direct 2D和Direct3D 11协同工作时遇到的问题总结一下。 原来的游戏引擎对纹理做处理的时候(如写字、绘制简单图形等)用的都是GDI+这套API,使用的方法也比较傻,就是在内存中存两套完全相同的图片,一套交给Direct 3D作为纹理,一套作为Bitmap保留在GDI+中,当需要对纹理做一些处理的时候,首先在Bitmap中用GDI+来处理,然后把Direct 3D中的纹理Lock住,然后往里面逐个拷贝像素。 在打算升级到DirectX 11的时候,就已经打算不再使用GDI+了,改为使用Direct 2D,毕竟Direct 2D有硬件加速并且更加底层,而且能够直接和Direct 3D交互。 2、思路 对于Direct 2D和Direct 3D的交互,我的主要思路是在Direct 2D中绘制图片,然后作为纹理让Direct 3D使用,中途参考了MSDN上的文档: Direct2D and Direct3D Interoperability Overview 我一开始是按照这篇文章中Using Direct2D Content as a Texture这一小节的说明为指导来进行编写的,但是在前面的工作都顺利完成的时候,最后卡在了这里: hr = m_pD2DFactory->CreateDxgiSurfaceRenderTarget( pDxgiSurface, &props, &m_pRenderTarget );

开题报告-基于虚拟现实技术的三维校园漫游系统的设计与实现

梧州学院 毕业设计(论文)任务书 课题名称基于虚拟现实技术的三维校园 漫游系统的设计与实现 系部计算机科学系 专业计算机科学与技术 班级07计本5班 学号0700608118 姓名王荣华 指导教师(签名)年月日教研室主任(签名)年月日

一、课题的内容和要求: 本课题从3D MAX的建模和渲染烘焙技术着手,采用成熟VRP-BUILDER虚拟现实编辑器模块进行二次开发来构建的三维校园漫游系统。基于3D和VRP技术的三维仿真漫游系统的开发方法,以梧州学院(北区)建立虚拟场景,实现了自动漫游、手动漫游、校园路径导航、校园景物的查看、校园信息查询、各种气候效果、各种实体的动态效果,并根据路线做了详细的碰撞检测。同时根据三维仿真漫游的特点,在自动漫游和手动漫游过程中,以现有场景为基础,通过视频、图片、音乐对虚拟现实系统做了补;给需要了解梧州学院校园地理信息的用户提供了极大方便。 二、设计的技术要求与数据(或论文主要内容): 采用Polygon+NURBS高级建模的建模方法,各个模型采用简体模型来对整个校园建筑进行立体虚拟;用Bitmap位图+UVW Mapping坐标贴图、VRAY渲染方法还原校园的真实景象;采用Max-for-VRP导出插件将模型导入VRP-BUILDER虚拟现实编辑器模块,加入碰撞检测算法、VRP命令行脚本实现人机交互功能,保证系统的实用性;运用行走相机、动态漫游增加三维实景表现力,多角度查看学校环境;调试运行后由虚拟现实编辑器模块导出为EXE可执行文件实现系统的可移植运行。 三、设计(论文)工作起始日期: 自2011 年1 月10 日起,至2011 年4 月10 日止。 四、进度计划与应完成的工作: 1.收集资料进行需求分析时间:2011年1月 2.实时数据采集,建立三维模型时间:2011年2月初-----2011年2月底 3.运行和调试,系统设计及实现时间:2010年3月初-----2011年3月底 4.论文撰写时间:2011年4月 五、主要参考文献、资料: [1]陈珍.虚拟现实技术的教育应用初探.中小学电教.2009,7.8-9 [2]申蔚,曾文琪.虚拟现实技术(21世纪计算机科学与技术实践型教程).北京:清华大学出版社.2009.3-20 [3]数字仿真与虚拟现实技术概述.https://www.360docs.net/doc/ce17853287.html,/showthread.php?t=3340700 [4]姜学智,李忠华.国内外虚拟现实技术的研究现状.辽宁工程技术大学学报.2004,23(2):238-240 [5]杨爱良等.反走样技术在计算机图形仿真中的运用.计算机仿真.2005,22(4):124-125

关于Direct3D驱动流程的大致描述

关于Direct3D驱动流程的大致描述 作者: 谢克香 1.首先总体上的认识如下图所示:

由上图的流程可以知道, 任何一个有界面的程序, 如果要显示在具备独立显卡的显示 器上, 首先第一步要做的就是在显存中分配空间, 此内核函数DxgkDdiCreateDevice(DirectX graphic kernel driver device interface create deivce的缩写)是 由显卡厂商提供的, 在display miniport driver中, 主要起到在显存中分配空间的作用, 注 意这个分配的空间放的是GPU可执行代码, 分配空间的名字叫DMA buffer, DMA 是Direct Memory Access的缩写, 是计算机中的硬件, DMA buffer是DMA可以访问的buffer, 通过DMA硬件, 可以大大提到向DMA buffer写入数据的能力. 上面进行的操作都是在内 核态下, 所以上面的DMA buffer, 和函数,在用户态下都访问不了, 要访问的话, 必须通 过系统提供给用户层的api. 当用户调用DirectX3D Run Time提供的CreateDevice时, CreateDeivce其实是一个虚 函数, 当编译器工作时, CreateDevice形成的代码其实是一个在虚拟表中的偏移量, 虚拟 表是一个放函数地址地方. 然后直接Call这个地址, 经过Direc3D Runtime的一序列函 数的处理, 最终调用use‐mode display drive(用户态显示驱动)中的CreateDeivce函数, 而 这个函数调用Direct3D runtime中提供的pfnCreateContextCb(point function create context call back) 这个函数主要的作用是在系统内存或者AGP内存中分配command buffer, command buffer就是放GPU执行指令的地方, 通常这个command buffer的大小是固定的,,返回一个主要是command buffer的结构(此结构描述context, 也就是主要描述command buffer, 比如它的地址, 当然此结构还描述了其它东西), 到画图的最后阶段, command buffer最终会被GPU处理 当用户调用Direct3D Run time中分配资源的函数时, 比如类似于CreateResource的函 数, 然后Direct3D run time调用use‐mode driver中的CreateResource, 而use‐mode driver 中的函数最终调回Direct3D run time中的分配资源的函数, 通过回调函数pfnAllocationCb, 此函数最终通过DirectX Graphics kernel subystem调用display miniport driver中的DxgkDdiCreateAllocation函数, 此函数主要是在显存或者AGP内存或 者 系统内存中分配资源空间 由此可见 use‐mode display driver主要起到钩子的作用, 也就是截获Direct3D的执行 流程, 然后执行自己的处理, 然后又回调回去, Direct3D Run time应该是指d3d9.dll, 等其 它文件 Direct3D run time中画图操作函数最终调用use‐mode display driver中的draw图函数, 联想一下刚才的command buffer, 由此可见此函数就是把draw图函数转化为GPU能够 识别的command, 并把这些command 放到command buffer 当用户调用present时, Direct3D run time调用use‐mode display driver中的present的 函数, 而这个函数的执行又通过回调函数pfnPresentCB, 返回Direct3D run time执行, 有另一种情况, 也就是command buffer满了的时候, Direct3D run time会自动调用 use‐mode display driver中的flush函数, 此函数也一样通过pfRenderCb回调给Direct3D run time执行. 现在已经分为两种不同的执行流程, 一个present, 一个是flush, 两者执行的操作是不一 样的, present描述如下: Direct3D run time通过系统api, 进入到内核态中的directx graphic kernel subsytem中执行, 然后 graphic kernel紧接着调用显卡驱动中的

directx从入门到精通(direct简介)

返回总目录 第一篇 DirectX

目录 第一章 DirectX简介 1.1 DOS已经过时 1.2 加速DirectX 1.3 加速计算机工业 1.4 Directness原理 1.5 Direct结构 1.6 DirectX组件 1.7 小结 第二章基础 2.1 期望什么 2.2 COM(对象组件模型)入门 2.3 编程经验 24 2.4 调试DirectX 2.5 总结 第三章开始使用DirectX 3.1 安装 3.2 文档

3.3 例子程序源代码3.4 其他有用的信息3.5 使DirectX开始工作3.6 总结

第一章 DirectX简介 到目前为止,Microsoft Windows下的计算机游戏还没有一个辉煌的历史──它的成功还受到多媒体技术方面的限制。Windows所提供的应用程序和PC平台之间的设备独立性使得游戏和多媒体开发者备受压力,这是因为设备独立性技术使得软件和硬件之间增添了许多中间层次,因此要想在Windows平台上生成平滑、快速的动画和紧凑、实时的输入和声音是非常困难的。Windows的中心思想就是要把开发者和应用程序从硬件中分离出来,但这一点对于那些想直接操作硬件而获得最大速度的游戏开发者来说是致命的。市场需要的是高性能的游戏,因此,对于那些想把Windows作为计算机游戏平台的推广者来说,“DOS!DOS!DOS!”是他们经常遇到的对DOS游戏的赞歌! 1.1 DOS已经过时 然而,MS-DOS也有它自已的问题,其中最棘手的是硬件设备的支持。PC机的游戏开发者是不能享受到游戏机开发者的那种平台一致性的。对于游戏机软件开发者,他们晚上可以睡得很香,因为白天所写的代码将在上百万台同样的机器上运行。而PC机的开发者却不能这样,他们老是梦见新

Direct3D场景中3D模型的处理方法

万方数据

万方数据

万方数据

万方数据

辽宁石油化工大学学报第28卷 NORMALIZENORMALS渲染状态。 pD3DDevice一>SetRenderState(D3DRS—NoRMALIZENORMALS,TRUE); 下面是通过程序实现的真实场景。网1是未经添加实体的空旷房间, 图l 未经添加实体的空旷房间 图2是通过加载.x文件(会议桌,椅子,植物, 沙发),确定不同实体的位置或相同实体的不同位置,把它们放在了合理的伉置。 图2加载.x文件后的房间 通过3DSMAX建造的3D模型得到的.x文 件,经过一系列的转换正确加载后可以得到十分逼 真的动画效果,可以很好的应用于虚拟场景,例如三维建筑系统,仓库管理系统等。 参考文献 于忠德.DirectX实时渲染技术详解VM].重庆:重庆出版社,2006. 童晓然,昊晟.用DirectX实现地图3D展示及模拟行走[J].科技广场,2007(1):117--119. 任咏林,任伟林,秦魁.基于MicrosoftDirectX浅析COM组件与多媒体游戏的开发[J].北京工商大学学报,2005,23 (6):38—4Z. JimAdams.AdvancedanimationwithdirectX[M].Thomson:Publishedbythomsnlearning,2002. 叶至军,于忠德.DireetX宾时渲染技术详解EM].重庆:重庆大学出版社,2006.王德才.精通DireetX3D图形与动画程序设计EM].北京:人民邮电出版社,2007.金纯..x文件的解读和处理[J].福建电脑,2005(9):68—69. 金采工作室.3D游戏程序设计基础EM3.北京;北京希望电子出版社,2006. 王德才,张安慧.Direct3D中的三维坐标变换[J].电脑编程技巧与维护,2007(5):4—6. (Ed.:ZW,Z) 叫跚嘲 刚嘲网吲嘲嘲 万方数据 万方数据

Direct3D11教程1Direct3D11基础

Direct3D 11 教程1:Direct3D 11基础 原文地址:。 概览 在第一个教程中,我们学习了创建一个最小Direct3D 11应用程序所需的元素,每个Direct3D 11应用程序必须包含这些元素才能正常工作,这些元素包括创建一个窗口和设备对象,然后才能在窗口中显示颜色。 源代码 (SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial01。 创建Direct3D 11设备 第一个步骤中的创建窗口和消息循环在Direct3D 9、Direct3D 10、Direct3D 11都是相同的,可参见Direct3D 10教程0:Win32编程基础理解这个过程。当显示了一个窗口后,下面继续创建一个Direct3D 11设备,这个设备用于绘制3D场景。首先必须创建三个对象:一个设备(device)、一个立即执行上下文(immediate context)和一个交换链(Swap Chain),立即执行上下文对象是Direct3D 11中新添加的。 在Direct3D 10中,设备同时用来绘制和资源的创建。在Direct3D 11中,立即执行上下文用于将内容绘制到缓存,而设备用于创建资源。 交换链即表示对缓冲的操作,这些缓冲就是设备绘制的和显示在屏幕上的内容。交换链包含两个或两个以上的缓冲,主要是前缓冲和后备缓冲,它们就是设备绘制形成的纹理,用于显示在屏幕上。前缓冲(front buffer)就是当前显示在屏幕上的内容,这个缓冲是只读的,无法修改。后备缓冲(back buffer)是设备将要绘制的渲染目标,一旦它完成了绘制操作,交换链就会通过交换前缓冲和后备缓冲,将后备缓冲的内容显示在屏幕上,此时后备缓冲就变成了前缓冲。 要创建交换链,我们需要设置一个DXGI_SWAPCHAIN_DESC结构体说明将要创建的交换链。此结构体的几个字段需要说明一下:BackBufferUsage标志告诉程序我们使用后备缓冲的方式。本例中我们想绘制到后备缓冲,所以将BackBufferUsage设置为

directx direct3d 的第八章的内容详细注释说明

Checker brick0 Ice d3dUtility.cpp ////////////////////////////////////////////////////////////////////////////////////////////////// // // File: d3dUtility.cpp // // Author: Frank Luna (C) All Rights Reserved //

// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 // // Desc: Provides utility functions for simplifying common tasks. // ////////////////////////////////////////////////////////////////////////////////////////////////// #include "d3dUtility.h" bool d3d::InitD3D( HINSTANCE hInstance, int width, int height, bool windowed, D3DDEVTYPE deviceType, IDirect3DDevice9** device) { // // Create the main application window. // WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)d3d::WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = 0; wc.lpszClassName = "Direct3D9App"; if( !RegisterClass(&wc) ) { ::MessageBox(0, "RegisterClass() - FAILED", 0, 0); return false; } HWND hwnd = 0; hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App", WS_EX_TOPMOST, 0, 0, width, height, 0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);

相关文档
最新文档