人气 213

[游戏程序] 游戏引擎中多渲染器的设计于实现(2) [复制链接]

九艺网 2017-3-10 17:02:14

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
游戏中的多渲染器的设计与实现
  在了解了其他的引擎的实现方法后,我们可以开始自己写一个这样的框架了。(ps:不要把我写的代码给Hard core C++程序员看,这里暂时只关心原理)
  我现在正在写一个名为Uranus Halo的引擎(以下简称UHE),就以这个为例了。(ps:我用的编译器是VS2005。)
  先建立一个空解决方案,名为Uranus Halo Engine V0,添加工程:动态链接库工程,空项目, 取消“预编译头文件”,名为UHEMain,这是我们的引擎的主部分,是引擎的核心框架,也是多渲染器的入口。在这个工程中,添加新建项:

  1.         UHERenderDevice.h        UHERenderer.h        UHEPreriqusites.h
复制代码


  其中,UHERenderDevice.h中定义了渲染器的纯基类,具体的内容如下:

  1. //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){};
  2.                                                                                 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
复制代码


注意到_UHE_Export这个宏,在UHEPreriqusites.h中有定义:

  1. //file: UHEPrerequisites.h#ifndef _INCLUDE_UHEPREREQUISITES_H#define _INCLUDE_UHEPREREQUISITES_H#include #define _UHE_Export __declspec( dllexport )#endif
复制代码


如果想导出某个类的成员函数到.dll文件,就需要在类名前加上¬ _UHE_Export 。
在UHERenderer.h中,我们定义了面向用户的类:

  1. //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
复制代码


  注意,CreateDevice( int deviceType )这个函数是关键,我们先看一下它的实现,在UHERenderer.cpp中:

  1. 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 );}
复制代码


  这里,我们规定当deviceType 大于0时,是使用的dx的渲染器,即加载的是 UHERenderDX9.dll。然后要注意这个"dllCreate"参数,这是从另一个工程中导出的.dll中的函数名,先放在这里,等一下在讨论。
  这样,UHEMain中的部分的框架就差不多了。我们先写一个dx9的渲染器的实现。
  建立新的项目,依然是.dll的空项目,没有预编译头文件。我们要先写一个dx的渲染器,继承于UHEMain中的渲染器纯虚类:

  1. //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();
  2.                                                                                 //这里我省略了。。。。。        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;
  3.                                                                                 LPDIRECT3D9                        m_pDX9;                LPDIRECT3DDEVICE9                m_pDevice;                D3DPRESENT_PARAMETERS        m_d3dpp;                //这里省略了。。。。。        };};#endif
复制代码


  完成这个类的实现。这样还不行,应为我们需要导出初始化基类渲染器的函数到UHERenderDX9.dll中。新建一个UHERenderDX9.def文件作为.dll的导出模块文件,文件中的内容如下:

  1. LIBRARY        "UHERenderDX9"EXPORTS        dllCreate @1        dllRelease @2;end of file
复制代码


这样编译之后就可以将dllCreate和dllRelease函数导出到.dll中。
dllCreate的定义:

  1. //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的。。。
  这里的讨论只是框架上的实现,以后我会再写一些具体该注意的问题(也主要是框架和引擎的设计方面)。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|小黑屋|九艺游戏动画论坛 ( 津ICP备2022000452号-1 )

GMT+8, 2024-4-25 21:35 , Processed in 0.066903 second(s), 23 queries .

Powered by Discuz! X3.4  © 2001-2017 Discuz Team.