⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jichu4.txt

📁 本教程假定你已经拥有了c++程序设计的知识
💻 TXT
📖 第 1 页 / 共 2 页
字号:
目录 [隐藏]
1 先决条件 
2 介绍 
3 从这开始 
4 帧监听 
4.1 介绍 
4.2 注册一个帧监听 
5 建立场景 
5.1 介绍 
5.2 代码 
6 帧监听指南 
6.1 变量 
6.2 构造器 
6.3 帧启动方法 
 
[编辑]先决条件 
本教程假定你已经拥有了c++程序设计的知识,并且已经安装和编译了一个Ogre的应用程序(如果你在设置你的应用程序中有困难,请参考this guide获得更详细的编译步骤)。这个教程同时也是建立在上一章基础上的,因此默认你已经了解了上个教程的内容。 

[编辑]介绍 
这一章我们将介绍Ogre中最有用的构造:帧监听(FrameListener)。在本指南最后你将了解帧监听,怎样运用帧监听去实现一些要求每一帧更新的东西,怎样去用Ogre的无缓冲输入系统。 

代码你都可以在这篇指南中找到。当你看完这篇教程以后,你应该试着慢慢的添加一些代码到你自己的工程里,然后看看结果。 

[编辑]从这开始 
像上一个教程一样,我们将使用一个先前建立的代码作为我们出发的起点。在编译器中创建一个工程,添加如下的源代码: 

#include "ExampleApplication.h"
  
class TutorialFrameListener : public ExampleFrameListener
{
public:
    TutorialFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr)
        : ExampleFrameListener(win, cam, false, false)
    {
    }
   
    bool frameStarted(const FrameEvent &evt)
    {
        return ExampleFrameListener::frameStarted(evt);
    }
protected:
    bool mMouseDown;       // Whether or not the left mouse button was down last frame
    Real mToggle;          // The time left until next toggle
    Real mRotate;          // The rotate constant
    Real mMove;            // The movement constant
    SceneManager *mSceneMgr;   // The current SceneManager
    SceneNode *mCamNode;   // The SceneNode the camera is currently attached to
};
  
class TutorialApplication : public ExampleApplication
{
public:
    TutorialApplication()
    {
    }
   
    ~TutorialApplication() 
    {
    }
protected:
    void createCamera(void)
    {
    }
 
    void createScene(void)
    {
    }
 
    void createFrameListener(void)
    {
    }
};

#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
   
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    TutorialApplication app;

    try {
        app.go();
    } catch(Exception& e) {
#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occurred: %s\n",
                e.getFullDescription().c_str());
#endif
    }

    return 0;
}
如果你是在Windows下使用OgreSDK的,请确定添加“"[OgreSDK_DIRECTORY]\samples\include”目录到这个工程(ExampleApplication.h文件所在的位置)除了标准包含以外。如果使用的是Ogre的源代码包,这个文件应该在“"[OgreSource_DIRECTORY]\Samples\Common\include”目录中。不要试着去运行程序,因为我们还没有定义键盘的行为。如果你有问题,请查看这个Wiki页获得设置你编译器的信息,如果仍然有问题请试着去看看帮助栏。 

我们将在这章中定义程序控制器。 

[编辑]帧监听 
[编辑]介绍 
在前面的指南中当我们添加代码到创建场景方法时候,我们仅仅考虑我们可以做什么。在Ogre中我们可以注册一个类去接收消息当一帧被渲染到屏幕之前和之后。FrameListener接口定义两个函数: 

bool frameStarted(const FrameEvent& evt)
bool frameEnded(const FrameEvent& evt)
Ogre的主循环(Root::startRendering)类似这样: 

Root object调用frameStarted方法在所有已经注册的FrameListeners中。 
Root object渲染一帧。 
Root object调用frameEnded方法在所有已经注册的FrameListeners中。 

这个循环直到有任意一个FrameListener的frameStarted或者frameEnded函数返回false时终止。这些函数返回值的主要意思是“保持渲染”。如果你返回否,这个程序将退出。FrameEvent实体包含两个参数,但是只有timeSinceLastFrame在帧监听中是有用的。这个变量了解frameStarted或者frameEnded最近被激活时间。注意在frameStarted方法中,FrameEvent::timeSinceLastFrame将包含frameStarted时间最近被激活的时间(而不是最近被激活的frameEnded方法)。 

一个重要的概念你不能决定那个FrameListener被调用的次序。如果你需要确定FrameListeners被调用的准确顺序,你应该只注册一个FrameListener,然后用适当的顺序来调用所有的物体。 

你应该也会注意到主循环事实上做了三件事,在frameEnded方法和frameStarted方法被调用中间什么都没有发生,你甚至可以换着用。你的代码也可以随你放哪。你可以放到一个大的frameStarted或者frameStarted方法中,也可以插到两者之间。 

[编辑]注册一个帧监听 
现在上面的代码是可以编译通过的,但是因为我们没有考虑在ExampleApplication和createCamera中创建帧监听,因此如果你运行这个程序你就无法结束她。在继续本指南其他内容之前我们将先解决这个问题。 

找到TutorialApplication::createCamera方法添加如下代码: 

       // create camera, but leave at default position
       mCamera = mSceneMgr->createCamera("PlayerCam"); 
       mCamera->setNearClipDistance(5);

除了最基本的之外我们什么都没有做。之所以我们要用ExampleApplication中的createCamera方法是因为createCamera方法可以用来移动相机和改变相机位置,这里我们详细讨论这个。 

因为Root类是要每帧更新的,他也了解FrameListeners。我们首先要创建TutorialFrameListener的实例,然后把他注册到Root对象中。代码如下: 

       // Create the FrameListener
       mFrameListener = new TutorialFrameListener(mWindow, mCamera, mSceneMgr);
       mRoot->addFrameListener(mFrameListener);
mRoot和mFrameListener变量是在ExampleApplication类中定义的。addFrameListener方法添加一个帧监听者,removeFrameListener方法移除帧监听者(也就是说FrameListener就不用在更新了)。注意add|removeFrameListener方法仅仅是得到一个指向FrameListener的指针(也就是说FrameListener并没有一个名字你可以移除她)。这就意味着你需要对每一个FrameListener持有一个指针,让你随后可以移除他们。 

这个ExampleFrameListener(我们的TutorialFrameListener是从它继承来的),还提供了一个showDebugOverlay(bool)方法,用来告诉ExampleApplication是否要在左下角显示帧率的提示框。我们会把它打开: 

       // Show the frame stats overlay
       mFrameListener->showDebugOverlay(true);
确定你可以编译和运行这个应用程序再继续。 

[编辑]建立场景 
[编辑]介绍 
在我们对代码的深入研究之前,我将简单介绍一下我将做什么,这样你可以了解当我们创建和添加一些东西到场景中去的目的。 

我们将把一个物体(一个忍者)放到屏幕中,并在场景中加上点光源。当你点击鼠标左键,灯光会打开或关闭。按住鼠标右键,则开启“鼠标观察”模式(也就是你用摄像机四处观望)。我们将在场景里放置场景节点,来让作用于不同视口的摄像机附在上面。按下1、2键,以选择从哪一个视口来观看场景。 

[编辑]代码 
找到TutorialApplication::createScene方法。首先我们需要把场景的环境光设置的很低。我们想要场景中物体在灯光关闭情况下仍然可见,而且我们仍然想做到在灯光开关时场景有所变化: 

       mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));
现在把一个忍者加到屏幕中去: 

       Entity *ent = mSceneMgr->createEntity("Ninja", "ninja.mesh");
       SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("NinjaNode");
       node->attachObject(ent);
现在我们创建一个白色灯让后放到场景中,和忍者有一个相对小距离: 

       Light *light = mSceneMgr->createLight("Light1");
       light->setType(Light::LT_POINT);
       light->setPosition(Vector3(250, 150, 250));
       light->setDiffuseColour(ColourValue::White);
       light->setSpecularColour(ColourValue::White);
现在需要创建场景节点供摄像机绑定: 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -