Mogre学习系列(5)如何使用Ogre建立游戏程序

来源:互联网 发布:手机电池电量校正软件 编辑:程序博客网 时间:2024/06/04 18:59

 
      前面我们已经学会了如何使用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

原创粉丝点击