前面我们已经学会了如何使用Mogre来建立一个3D游戏,但是那是建立在一个叫做MogreFramework.dll的基础上。如果我们想直接利用Ogre的封装API来创建游戏,又是如何做到呢?
1.首先需要遵循一定的创建顺序。具体来说,包括一下步骤:
CreateRoot();
DefineResources();
SetupRenderSystem();
CreateRenderWindow();
InitResources();
CreateScene();
StartRenderLoop();
下面我们分别解释。
1)CreateRoot
还记得我们之前说的,在Ogre的世界里面,对象的组织是按照node的方式来建立的,因此,一开始我们需要建立一个root node。例如:
mRoot = new Root();
2) DefineResources
创建完root node之后,我们需要加载游戏中所用到的资源。我们一般将资源路径信息存放在config文件中。因此需要先解析config文件的内容,例如:
ConfigFile cf = new ConfigFile();
cf.Load("resources.cfg", "/t:=", true);
ConfigFile.SectionIterator seci = cf.GetSectionIterator();
String secName, typeName, archName;
while (seci.MoveNext())
{
secName = seci.CurrentKey;
ConfigFile.SettingsMultiMap settings = seci.Current;
foreach (KeyValuePair<string, string> pair in settings)
{
typeName = pair.Key;
archName = pair.Value;
ResourceGroupManager.Singleton.AddResourceLocation(archName, typeName, secName);
}
}
注意,上面的代码只是解析了资源文件的路径和类别,但是并没有将资源加载到内存中。
3)SetupRenderSystem
之后我们需要设置Render System。例如究竟是使用DirectX3D还是OpenGL,是否全屏和显示模式等。例如:
RenderSystem rs = mRoot.GetRenderSystemByName("Direct3D9 Rendering Subsystem"); // or use "OpenGL Rendering Subsystem"
mRoot.RenderSystem = rs;
rs.SetConfigOption("Full Screen", "No");
rs.SetConfigOption("Video Mode", "800 x 600 @ 32-bit colour");
4)CreateRenderWindow
设置完RenderSystem之后,我们需要创建RenderWindow,就是用来显示我们以后创建游戏对象的视窗。例如:
mRoot.Initialise(true, "Main Ogre Window");
如果我们想要将RenderWindow嵌在Windows Form里面,代码如下:
NameValuePairList misc = new NameValuePairList();
misc["externalWindowHandle"] = handle.ToString();
RenderWindow win = mRoot.CreateRenderWindow("Main RenderWindow", 800, 600, false, misc);
5)InitializeResourceGroups
在2)中我们制定了资源的路径和group信息,但是我们并没有将资源加载到内存中。为了实现资源加载,我们需要调用:
ResourceGroupManager.Singleton.InitialiseAllResourceGroups();
这样,我们在游戏中需要的纹理和贴图就可以使用了,否则就会看到一个没有白色的空壳。(如果是一个3D物体的话)
6)CreateScene
准备工作已经就绪,我们可以开始创建游戏场景了。包括SceneManager, Entity, SceneNode, Camera, Light, Viewport等。具体内容可以查看学习系列的(1)-(4)节。
7)StartRenderingLoop
游戏场景已经建立完毕,之后我们可以启动Rendering了。通过功能,游戏场景会被渲染和显示出来。
mRoot.StartRendering();
当然了,如果我们希望每次渲染frame的时候都能够添加自己的控制逻辑,可以使用
while (mRoot.RenderOneFrame())
{
// Do other things here, such as sleep for a short period of time
}
注意,这里面有一个重要的topic没有涵盖,就是Game Input System。通常我们可以使用DirectX Input System.
示例代码:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Mogre;
using System.Drawing;
namespace Tutorial05
{
static class Program
{
[STAThread]
static void Main()
{
OgreStartup ogre = new OgreStartup();
ogre.Go();
}
}
class OgreStartup
{
Root mRoot = null;
float ticks = 0;
public void Go()
{
CreateRoot();
DefineResources();
SetupRenderSystem();
CreateRenderWindow();
InitResources();
CreateScene();
StartRenderLoop();
}
void CreateRoot()
{
mRoot = new Root();
}
void DefineResources()
{
ConfigFile cf = new ConfigFile();
cf.Load("resources.cfg", "/t:=", true);
ConfigFile.SectionIterator seci = cf.GetSectionIterator();
String secName, typeName, archName;
while (seci.MoveNext())
{
secName = seci.CurrentKey;
ConfigFile.SettingsMultiMap settings = seci.Current;
foreach (KeyValuePair<string, string> pair in settings)
{
typeName = pair.Key;
archName = pair.Value;
ResourceGroupManager.Singleton.AddResourceLocation(archName, typeName, secName);
}
}
}
void SetupRenderSystem()
{
if (!mRoot.ShowConfigDialog())
throw new Exception("The user canceled the configuration dialog.");
Setting up the RenderSystem manually.
//RenderSystem rs = mRoot.GetRenderSystemByName("Direct3D9 Rendering Subsystem");
// // or use "OpenGL Rendering Subsystem"
//mRoot.RenderSystem = rs;
//rs.SetConfigOption("Full Screen", "No");
//rs.SetConfigOption("Video Mode", "800 x 600 @ 32-bit colour");
}
void CreateRenderWindow()
{
mRoot.Initialise(true, "Main Ogre Window");
Embedding ogre in a windows hWnd. The "handle" variable holds the hWnd.
//NameValuePairList misc = new NameValuePairList();
//misc["externalWindowHandle"] = handle.ToString();
//mWindow = mRoot.CreateRenderWindow("Main RenderWindow", 800, 600, false, misc);
}
void InitResources()
{
TextureManager.Singleton.DefaultNumMipmaps = 5;
ResourceGroupManager.Singleton.InitialiseAllResourceGroups();
}
void CreateScene()
{
SceneManager mgr = mRoot.CreateSceneManager(SceneType.ST_GENERIC);
Camera cam = mgr.CreateCamera("Camera");
mRoot.AutoCreatedWindow.AddViewport(cam);
Entity ent = mgr.CreateEntity("ninja", "ninja.mesh");
mgr.RootSceneNode.CreateChildSceneNode().AttachObject(ent);
cam.Position = new Vector3(0, 200, -400);
cam.LookAt(ent.BoundingBox.Center);
mRoot.FrameEnded += new FrameListener.FrameEndedHandler(FrameEnded);
ticks = Environment.TickCount;
}
void StartRenderLoop()
{
mRoot.StartRendering();
Alternate Rendering Loop
//while (mRoot.RenderOneFrame())
//{
// // Do other things here, such as sleep for a short period of time
//}
}
bool FrameEnded(FrameEvent evt)
{
if (Environment.TickCount - ticks > 5000)
return false;
return true;
}
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tanliyoung/archive/2009/02/24/3931713.aspx