网页功能: 加入收藏 设为首页 网站搜索  
游戏引擎中多渲染器的设计于实现(2)
发表日期:2007-03-28作者:[转贴] 出处:  

 游戏中的多渲染器的设计与实现

  在了解了其他的引擎的实现方法后,我们可以开始自己写一个这样的框架了。(ps:不要把我写的代码给Hard core C++程序员看,这里暂时只关心原理)

  我现在正在写一个名为Uranus Halo的引擎(以下简称UHE),就以这个为例了。(ps:我用的编译器是VS2005。)

  先建立一个空解决方案,名为Uranus Halo Engine V0,添加工程:动态链接库工程,空项目, 取消“预编译头文件”,名为UHEMain,这是我们的引擎的主部分,是引擎的核心框架,也是多渲染器的入口。在这个工程中,添加新建项:


UHERenderDevice.h
UHERenderer.h
UHEPreriqusites.h
[/code]

  其中,UHERenderDevice.h中定义了渲染器的纯基类,具体的内容如下:
[code]
//file: UHERenderDevice.h
#ifndef _INCLUDE_UHERENDERDEVICE_H
#define _INCLUDE_UHERENDERDEVICE_H

#include "UHEPrerequisites.h"
#include "UHEBasicStruct.h"

namespace UHEngine
{
class _UHE_Export UHERenderDevice
{
public:
UHERenderDevice(void){};
virtual ~UHERenderDevice(void){};

virtual HRESULT Init( HWND hWnd, 
HINSTANCE hInst, 
bool bWindowed,
DWORD dwWidth, 
DWORD dwHeight) = 0;
virtual void ShutDown() = 0;
virtual HRESULT Prepare() = 0;
virtual bool IsRunning() = 0;
virtual void SetClearColor( float fR, float fG, float fB ) = 0;
virtual void Clear() = 0;
virtual void Render() = 0;

//这里我省略了。。。。。。。
};
};
#endif
[/code]

注意到_UHE_Export这个宏,在UHEPreriqusites.h中有定义:
[code]
//file: UHEPrerequisites.h
#ifndef _INCLUDE_UHEPREREQUISITES_H
#define _INCLUDE_UHEPREREQUISITES_H

#include <windows.h>
#define _UHE_Export __declspec( dllexport )
#endif
[/code]

如果想导出某个类的成员函数到.dll文件,就需要在类名前加上&not; _UHE_Export 。

在UHERenderer.h中,我们定义了面向用户的类:
[code]
//file: UHERenderer.h
#ifndef _INCLUDE_UHERENDERER_H
#define _INCLUDE_UHERENDERER_H

#include "UHEPrerequisites.h"
#include "UHERenderDevice.h"
namespace UHEngine
{
class _UHE_Export UHERenderer
{
public:
UHERenderer();
~UHERenderer();

void CreateDevice( int deviceType );
UHERenderDevice *GetRenderDevice(){return this->m_pRenderDevice;}
private:
UHERenderDevice *m_pRenderDevice;
HMODULE m_hDll; 
};
};
#endif
[/code]

  注意,CreateDevice( int deviceType )这个函数是关键,我们先看一下它的实现,在UHERenderer.cpp中:
[code]
void UHERenderer::CreateDevice( int deviceType )
{
if( i )
{
this->m_hDll = LoadLibrary( "UHERenderDX9.dll" );
}
else
{
this->m_hDll = LoadLibrary( "UHERenderGL.dll" );
}
void (*pFun)(UHERenderDevice* &);
pFun = (void (__cdecl *)(UHEngine::UHERenderDevice *&)) GetProcAddress( m_hDll, "dllCreate" );
(*pFun)( this->m_pRenderDevice );
}
[/code]

  这里,我们规定当deviceType 大于0时,是使用的dx的渲染器,即加载的是 UHERenderDX9.dll。然后要注意这个"dllCreate"参数,这是从另一个工程中导出的.dll中的函数名,先放在这里,等一下在讨论。

  这样,UHEMain中的部分的框架就差不多了。我们先写一个dx9的渲染器的实现。

  建立新的项目,依然是.dll的空项目,没有预编译头文件。我们要先写一个dx的渲染器,继承于UHEMain中的渲染器纯虚类:
[code]
//file: UHERenderDX9.h
#ifndef _INCLUDE_UHERENDERDX9_H
#define _INCLUDE_UHERENDERDX9_H

#include "UHERenderDX9Base.h"

namespace UHEngine
{
class UHEDX9 : public UHERenderDevice
{
public:
UHEDX9();
UHEDX9( HWND hWnd, 
HINSTANCE hInst, 
bool bWindowed,
DWORD dwWidth, 
DWORD dwHeight);
~UHEDX9();

HRESULT Init( HWND hWnd, 
HINSTANCE hInst, 
bool bWindowed,
DWORD dwWidth, 
DWORD dwHeight);
HRESULT Prepare();
void ShutDown();

bool IsRunning(){ return m_bIsRunning; }
void SetClearColor( float fR, float fG, float fB );
void Clear();
void Render();


//这里我省略了。。。。。


private:
HRESULT BeginRendering( bool bClearPixel,
bool bClearDepth,
bool bClearStencil );
HRESULT EndRendering();
HRESULT Clear( bool bClearPixel,
 bool bClearDepth,
 bool bClearStencil );
D3DXCOLOR m_clearColor;
bool m_bIsRunning;
bool m_bIsSceneRunning;
bool m_bStencil;

HWND m_hWnd;
HINSTANCE m_hInst;
bool m_bWindowed;
DWORD m_dwHeight;
DWORD m_dwWidth;

LPDIRECT3D9 m_pDX9;
LPDIRECT3DDEVICE9 m_pDevice;
D3DPRESENT_PARAMETERS m_d3dpp;

//这里省略了。。。。。
};
};
#endif
[/code]

  完成这个类的实现。这样还不行,应为我们需要导出初始化基类渲染器的函数到UHERenderDX9.dll中。新建一个UHERenderDX9.def文件作为.dll的导出模块文件,文件中的内容如下:
[code]
LIBRARY "UHERenderDX9"
EXPORTS
dllCreate @1
dllRelease @2
;end of file
[/code]

这样编译之后就可以将dllCreate和dllRelease函数导出到.dll中。
dllCreate的定义:
[code]
//file : UHERenderDX9Dll.cpp
#include "UHEDX9.h"
#include "UHERenderer.h"
namespace UHEngine 
{
UHEDX9* pRenderDX9;
extern "C" __declspec( dllexport ) void dllCreate( UHERenderDevice * &pRenderer )
{
pRenderDX9 = new UHEDX9();
pRenderer = pRenderDX9;
}

extern "C" __declspec( dllexport ) void dllRelease(void)
{
delete pRenderDX9;
}
}


  这样就可以了。

其他的问题:
  关于.dll工程的问题,可以google一下相关的文章;关于项目的设置问题,我们这里没有讲到,可以编译一下,就可以发现相关的错误,再设置好路径和输出即可;这里只讲到了DX渲染器的实现,GL的方法一样,新建一个项目,然后实现。

  最后,我们再整理一下思路。在UEHMain中定义渲染的基类,和用户使用的类UHERenderer,在UHERenderDX9中写好DX版本的渲染器(即继承类),导出初始化函数(dllCreate)到.dll中,在UHERenderer中利用参数来判断该加载那个.dll,说穿了,本质就是判断,该调用哪个渲染器的构造函数,DX的还是GL的。。。

  这里的讨论只是框架上的实现,以后我会再写一些具体该注意的问题(也主要是框架和引擎的设计方面)。

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 游戏引擎中多渲染器的设计于实现(2)
本类热点文章
  DDraw和D3D立即模式编程手册
  矩阵求逆的快速算法
  本地化支持:OGRE+CEGUI中文输入:OGRE方..
  Direct3D中实现图元的鼠标拾取
  3D场景中的圆形天空顶
  OpenGL显卡编程
  一种高效的基于大规模地形场景的OCCLUS..
  一个完善的读取3DS文件例子
  如何制作一个可控制的人体骨骼模型
  Direct3D 入门之我见
  Slope(斜坡) 法线生成算法,在地形渲染..
  在Direct3D中渲染文字
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00591