Design and Implementation of multiple Renderer in Game Engine (1)-Ogre

Source: Internet
Author: User

Http://blog.csdn.net/zdl1016/article/details/1612647

Many game engines provide a variety of Renderer (DirectX, OpenGL, software), and even a variety of platforms (Windows, Linux, Mac ), this is a great challenge for the design and implementation of the engine, especially the multi-Renderer, but also the efficiency, the general purpose, and the characteristics of each Renderer, this is indeed a tiangu. The principles discussed here are simple: 1. Keep it simple; 2. Make it work first.

Let's take a look at the Ogre method. Each module in ogre is a plug-in Design "combined". You can add your own Renderer on the basis of ogre without starting otherCode(Even the code of the main part of the ogremain engine ). Many software architectures use similar plug-ins. The most famous ones are ide eclipse, and the engine is like unreal 2 and unreal 3. Writing a Renderer plug-in is not very difficult, but it is very difficult to design a non-plug-in engine kernel. If the engine kernel is not well designed in the early stage, there will be no way to make too many modifications in the later stage. Of course, if it is well designed, it is very convenient to expand or modify the functions of the engine (unreal 2 is a plug-in-style design, and after the development to the middle of the development, it has changed the original physical module, instead, use novodex ).

Another method is to take the Renderer type as the parameter of the main module constructor of the engine (or the related initialization function. For example, this method is used in irrilicht. In irrilicht, there is a cvideonull pure virtual class, and different Renderer inherits from this class. The main module of the engine has a class cirrdevicewin32, its constructor is:

Cirrdevicewin32 (Video: e_driver_type devicetype, const core: dimension2d <s32> & windowsize, u32 bits, bool fullscreen, bool stencilbuffer, bool vsync, ieventreceiver * receiver, const wchar_t * version );

E_driver_type indicates the Renderer type. Then, in the implementation of the constructor, use the switch to initialize the base class Renderer. The disadvantage of this method is that the engine framework physically and logically has circular dependencies (here it refers to the Code layer, that is, the dependencies at the compilation layer ), the main engine depends on each Renderer, and each Renderer depends on other parts of the main engine. During compilation, the cost of this design is huge.

Using the dynamic link library is one of the solutions to this problem, and it is also the implementation method of plug-in design (in Linux, there is a corresponding mechanism shared object, since I have never been familiar with programming on Linux, the discussion here is limited to Windows ). Change the code in the constructor of the original main engine. Switch is still used to select different Renderer, but different. dll is called to construct the base class function. For example, in ogre, each Renderer has a module definition file (. Def file) exported to. dll. For example, the definition of the. Def file in the DirectX Renderer is as follows:

Library rendersystem_direct3d9exports dllstartplugin @ 1 dllstopplugin @ 2

dllstartplugin and dllstopplugin is the function for creating and destructor Renderer respectively. The specific definition is as follows:
dllstartplugin, and dllstopplugin are two functions that must be implemented by every system that wants to act as the Ogre plug-in !!

namespace ogre {
d3d9rendersystem * d3drendplugin;
d3d9hlslprogramfactory * hlslprogramfactory;
extern "C" Void dllstartplugin (void) Throw ()
{// create the DirectX 8 rendering API
hinstance hinst = getmodulehandle (" rendersystem_direct3d9.dll ");
d3drendplugin = new d3d9rendersystem (hinst );
// register the Render system root: getsingleton (). addrendersystem (d3drendplugin);
// create & register
HLSL factory hlslprogramfactory = new d3d9hlslprogramfactory (); highlevelgpuprogrammanager: getsingleton (). addfactory (hlslprogramfactory) ;}< br> extern "C" Void dllstopplugin (void)
{ Delete d3drendplugin; Delete hlslprogramfactory ;}

Root: getsingleton (). addrendersystem (d3drendplugin) is to insert the generated Renderer into the main engine as a plug-in. In the main engine, the corresponding part is:

Void root: loadplugin (const string & pluginname ){
// Load plugin Library
Dynlib * Lib = dynlibmanager: getsingleton (). Load (pluginname );

// Store for later unload
Mpluginlibs. push_back (LIB );

// Call startup Function
Dll_start_plugin pfunc = (dll_start_plugin) Lib-> getsymbol ("dllstartplugin ");
If (! Pfunc)
Ogre_effect (exception: err_item_not_found, "cannot find symbol dllstartplugin library" + pluginname, "root: loadplugins ");
Pfunc ();
If (misinitialised)
{// Initialise too dll_init_plugin pfunc = (dll_init_plugin) Lib-> getsymbol ("dllinitialiseplugin ");
If (pfunc)
{Pfunc ();}
}
}

In this way, the root: getsingleton (). addrendersystem (d3drendplugin) is completed ).

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.