• 实验二 建立基本的游戏场景


    实验二 建立基本的游戏场景

    一、实验内容:

    1. 建立一个简单的游戏场景;

    2. 通过摄像机实现场景的切换;

    3. 使用不同的光照实现阴影效果;

    二、实验目的:

    1. 了解Ogre程序的工作方法和Ogre场景的坐标系,掌握场景管理器、场景节点和实体的概念及其具体应用。

    2. 掌握摄像机、视口的概念及其在游戏编程中的具体应用。

    3. 掌握不同类型光源的使用方法和区别,熟悉阴影的产生方法。

    三、实验步骤

    1)、初试

    首先第一步是要做出一个简单的窗口,

    由于Orge现在Sample都使用了插件的机制,调试不方便,

    也不利于理解真正的Orge流程,

    所以翻看了些资料,直接从根本动手,

    1, 首先建立一个新项目

    敲入代码:

    #include <Ogre.h>

    #include <ExampleApplication.h>

    #include <windows.h>

    #include <windowsx.h>

    int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )

    {

    // 执行应用程序初始化:

    Root * g_ogreRoot=new Root("plugins_d.cfg");

    // 显示配置窗口

    bool rtn = g_ogreRoot->showConfigDialog();

    // 如果配置文件已经存在(已经执行过起码一次showConfigDialog ),

    // 那么你可以用下面这句之间读取配置,而不需要显示配置窗口。

    g_ogreRoot->restoreConfig();

    // 创建渲染窗口

    g_ogreRoot->initialise(true, "My Render Window"); // 这里的true 指示ogre 自动创建窗口

    RenderWindow * renderWindow =g_ogreRoot->getAutoCreatedWindow();

    renderWindow->setAutoUpdated(true);

    // 创建场景管理器,这个TerrainSceneManager 是指地形场景管理器

    SceneManager* mSceneMgr = g_ogreRoot->createSceneManager("TerrainSceneManager");

    // 创建摄像机

    Camera* mCamera = mSceneMgr->createCamera("PlayerCam");

    mCamera->setPosition(Vector3(0,0,-300)); // 摄像机位置

    mCamera->lookAt(Vector3(0,0,800)); // 摄像机朝向

    // 设置渲染窗口的视口(和我们的摄像机绑定)

    Viewport *vp = renderWindow->addViewport(mCamera);

    vp->setBackgroundColour(ColourValue(0, 0, 0));

    // 定义资源的读取目录/文件,dragon.zip 放在执行目录,这个文件可以在OgreSDK\media\packs 目录下找到

    ResourceGroupManager::getSingleton().addResourceLocation(

    "dragon.zip", "Zip", "General"

    );

    // 我把script 目录从OgreSDK\media\materials\scripts 复制到执行目录下了,龙的皮肤着色需要用到某个脚本

    ResourceGroupManager::getSingleton().addResourceLocation(

    "scripts", "FileSystem", "General"

    );

    // 初始化资源管理器

    ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    // 读取龙的模型

    Entity * ent = mSceneMgr->createEntity("dragon", "dragon.mesh");

    // 把模型放入场景管理器

    mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);

    // 开始渲染

    g_ogreRoot->startRendering();

    return 0;

    }

    代码不难理解,相比起手动建立一个完整的DX来说已是非常简单了,

    继续,定义好一个plugins_d.cfg文件,作为Orge的初始化配置

    # Defines plugins to load

    # Define plugin folder

    PluginFolder=.

    # Define plugins

    Plugin=RenderSystem_Direct3D9_d

    # Plugin=RenderSystem_Direct3D10_d

    # Plugin=RenderSystem_Direct3D11_d

    Plugin=RenderSystem_GL_d

    # Plugin=RenderSystem_GLES_d

    Plugin=Plugin_ParticleFX_d

    Plugin=Plugin_BSPSceneManager_d

    Plugin=Plugin_CgProgramManager_d

    Plugin=Plugin_PCZSceneManager_d

    Plugin=Plugin_OctreeZone_d

    Plugin=Plugin_OctreeSceneManager_d

    配置文件既是定义了相关的插件配置,咱是xp,跑不了DX10/11,

    貌似CMake也做好了判断,DX10的RenderSystem也找不到。。。

    2,配置项目

    敲好了代码还远远不够,加入Orge的各个配件可是关键,

    DXSDK早已配置完成,这里主要把Orge一个个耐心加入:

    1.包含文件

    \ogre-v1-7-0\Dependencies\include

    \ogre-v1-7-0\Samples\Common\include

    \ogre-v1-7-0\OgreMain\include

    \ogre-v1-7-0\include

    2.库文件

    \ogre-v1-7-0\Dependencies\lib\Release

    \ogre-v1-7-0\Dependencies\lib\Debug

    \ogre-v1-7-0\lib\Release

    \ogre-v1-7-0\lib\Debug

    clip_image002

    clip_image004

    这些可确是重中之重,仔细检查后F7,F5

    3,调试

    编译非常顺利,比起OrgeSDK,这可算是从石器时代回到了现代文明,

    可美好的东西哪有那么容易得来,

    报错了,

    没办法,兵来将挡水来土掩,

    拿起Debug的利器,

    几经跟踪后发现;

    clip_image006

    应该是动态库的问题

    clip_image008

    终于发现了:RenderSystem_Direct3D9_d.dll!!

    clip_image010

    可是一时还搞不明白Orge的复杂读取机制,只好直接暴力破解,

    在Orge下找到DLL

    clip_image012

    直接复制入系统目录

    clip_image014

    问题迎刃而解:

    clip_image016

    4,Debug II

    可现在就庆祝胜利还是太早了些,错误又来了,

    clip_image018

    呵呵,粗枝大叶了,Media忘记拷贝过来,

    clip_image020

    F5,一切搞定:

    clip_image022

    2)、这些都不够,我要动起来

    1,架构

    当前的框架还是十分的稚嫩,

    到Orge官网逛了下后决定使用Ogre Wiki Tutorial Framework来进行接下来的工作

    clip_image024

    一个小插曲,下来的压缩包解压之后竟然是一个无后缀文件,猜测还是一个压缩包,加了个rar,成功

    clip_image026

    一个全新的窗口来到了,呵呵~~~

    2, 主循环

    读懂了

    clip_image028

    的大体结构,

    重写一个

    void TutorialApplication::createScene(void)

    {

    mCamera->setPosition(Vector3(0,30,-300)); // 摄像机位置

    mCamera->lookAt(Vector3(0,0,800)); // 摄像机朝向

    // 定义资源的读取目录/文件,dragon.zip 放在执行目录,这个文件可以在OgreSDK\media\packs 目录下找到

    ResourceGroupManager::getSingleton().addResourceLocation(

    "dragon.zip", "Zip", "General"

    );

    // 我把script 目录从OgreSDK\media\materials\scripts 复制到执行目录下了,龙的皮肤着色需要用到某个脚本

    ResourceGroupManager::getSingleton().addResourceLocation(

    "scripts", "FileSystem", "General"

    );

    // 初始化资源管理器

    ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    // 读取龙的模型

    Entity * ent = mSceneMgr->createEntity("dragon", "dragon.mesh");

    // 把模型放入场景管理器

    mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);

    // 开始渲染

    SceneNode* node=mSceneMgr->getRootSceneNode();

    float scal=1.0f;

    }

    结果非常顺利,整个三维世界已经触手可及:

    (框架封装好了输入控制,可以直接操作摄像机)

    clip_image030

    3, 接下来,那就让飞龙动起来吧:

    结加入代码,获得更多的控制权

    clip_image032

    if(arg.key == OIS::KC_B)

    {

    m_pNode->showBoundingBox(!m_pNode->getShowBoundingBox());

    }

    if(arg.key == OIS::KC_Z)

    {

    m_fScale=1.1f;

    m_pNode->scale(m_fScale,m_fScale,m_fScale);

    }

    else if(arg.key == OIS::KC_X)

    {

    m_fScale=0.9f;

    m_pNode->scale(m_fScale,m_fScale,m_fScale);

    }

    if(arg.key == OIS::KC_W)

    {

    m_pNode->pitch(Radian(0.1f));

    }

    else if(arg.key == OIS::KC_S)

    {

    m_pNode->pitch(Radian(-0.1f));

    }

    if(arg.key == OIS::KC_A)

    {

    m_pNode->yaw(Radian(0.1f));

    }

    else if(arg.key == OIS::KC_D)

    {

    m_pNode->yaw(Radian(-0.1f));

    }

    clip_image034

    4,细节

    一开始,缩放只能一直缩或者一直放,

    看了源代码,发现Orge下的scal的参数传进去是用了个*,

    明白之后,传入1.1/0.9,问题解决

    接下来,旋转始终有问题,

    发现快捷键与现有的摄像机的快捷键有了冲突,

    改正之后,还有个问题就是单帧分离开,就是要一直不停的按才可以,这个很郁闷,

    打算写个状态,来记录下键位。。。

    clip_image036

    clip_image038

    4, 继续改进

    心动不如行动,加入了一个KeyState记录键位信息,

    加入Update作为响应:

    clip_image040

    响应键位变化:

    clip_image042

    整体操作现在终于变得非常流畅了:

    clip_image044

    3)、上帝说,要有光

    基本操作都已经实现,那么接下来就加入光影效果吧:

    建立一个新工程,这回直接改写基类,上回写的架构太过罗嗦了,

    其它基本保持一致,改动createScene,载入模型,加入灯光

    void BasicTutorial2::createScene(void)

    {

    mSceneMgr->setAmbientLight(Ogre::ColourValue(0, 0, 0));

    mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

    Ogre::Entity* entNinja = mSceneMgr->createEntity("Ninja", "ninja.mesh");

    entNinja->setCastShadows(true);

    //mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entNinja);

    m_pNode->attachObject(entNinja);

    Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);

    Ogre::MeshManager::getSingleton().createPlane("ground", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,

    plane, 1500, 1500, 20, 20, true, 1, 5, 5, Ogre::Vector3::UNIT_Z);

    Ogre::Entity* entGround = mSceneMgr->createEntity("GroundEntity", "ground");

    mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entGround);

    entGround->setMaterialName("Examples/Rockwall");

    entGround->setCastShadows(false);

    Ogre::Light* pointLight = mSceneMgr->createLight("pointLight");

    pointLight->setType(Ogre::Light::LT_POINT);

    pointLight->setPosition(Ogre::Vector3(0, 150, 250));

    pointLight->setDiffuseColour(1.0, 0.0, 0.0);

    pointLight->setSpecularColour(1.0, 0.0, 0.0);

    Ogre::Light* directionalLight = mSceneMgr->createLight("directionalLight");

    directionalLight->setType(Ogre::Light::LT_DIRECTIONAL);

    directionalLight->setDiffuseColour(Ogre::ColourValue(.25, .25, 0));

    directionalLight->setSpecularColour(Ogre::ColourValue(.25, .25, 0));

    directionalLight->setDirection(Ogre::Vector3( 0, -1, 1 ));

    Ogre::Light* spotLight = mSceneMgr->createLight("spotLight");

    spotLight->setType(Ogre::Light::LT_SPOTLIGHT);

    spotLight->setDiffuseColour(0, 0, 1.0);

    spotLight->setSpecularColour(0, 0, 1.0);

    spotLight->setDirection(-1, -1, 0);

    spotLight->setPosition(Ogre::Vector3(300, 300, 0));

    spotLight->setSpotlightRange(Ogre::Degree(35), Ogre::Degree(50));

    }

    Debug it ,只要正确地配好SDK就万事大吉了,

    不得不说,Ogre真的是太方便了,想当初自学ShadowVolume和ShadowMap不知死了多少脑细胞,废了多少周折,现在好了,So easy

    clip_image046

    4)、骨骼动画

    四、实验数据及处理结果

    结果均以截图给出,代码,工程附带。。。

    五、思考讨论题或体会或对改进实验的建议

    代码Ogre真的很简单,尤其是有了一定基础之后,看他的代码真的是一种享受,好吧,再接再厉,继续探索吧!

  • 相关阅读:
    Java 基础 ------- 面向对象(三) 继承
    虚拟机安装系统--- 安装VMware Tools(五)
    'sqlplus'不是内部或外部命令,也不是可运行的程序
    点餐系统(java基础、数据库、jsp、servlet)
    jsp页面pageContext.setAttribute报错
    Spring事务管理(编码式、配置文件方式、注解方式)
    并发控制
    Spring整合JDBC(连接池、JDBC模板、Dao配置到Spring容器、配置文件的优化)
    Spring的aop思想(名词、aop的配置)
    spring:spring的核心API
  • 原文地址:https://www.cnblogs.com/Zephyroal/p/1947509.html
Copyright © 2020-2023  润新知