MOGRE学习笔记(3)--MOGRE小项目练习

学习OGRE有一段时间了,领导为了检测学习效果,根据已有C++项目,弄一个类似的用c#语言编写的小项目。

配置:win7,DirectX2009,vs2010.

 

项目要求:

1.有Ogre窗口(尺寸1600*900),周围有导航按钮(分别进行旋转拉伸平移操作)
2.导入VIV手臂模型(左右手),默认只显示左手,通过按钮可以进行模型切换显示
3.模型上有完整贴图,点光源绑在照相机上
4.Ogre窗口中开小Viewport,从正上方俯视整条手臂
5.导入消毒动画,并实现手背上消毒效果(本来就是对齐的)
6.导入小垫枕模型,可以通过wasd按键控制其以后
7.通过点击按钮能实现手臂更换贴图

编写时遇到的问题:

1、在新建完项目工程winform后,需要对winform进行配置,此过程中本来是想走捷径, 使用以前拷贝的cfg文件直接添加到项目中(半个月前使用过此方法成功创建项目),导致有错误出现。

2、在设置手臂材料时,最好是新建一个material文件夹。 (设置左手臂时,在以前练习文件的基础上添加左臂材质,始终没有成功, 原因可能是后来的材质带有片段和顶点着色器,而本次没有设置)

 

实现过程:

1导航按钮

旋转:nodeRoot.Pitch(new Radian(0.5f)); 平移: 左移右移,nodeRoot.Position += new Vector3(-5, 0, 0); nodeRoot.Position += new Vector3(10, 0, 0);

2 导入模型:

将mesh导入到model文件夹中,在代码中引用即可,同时设置材质

entLArm = sceneMgr.CreateEntity("leftArm", "A_N_Y_F_LH_S.mesh");
            SceneNode nodeLArm = sceneMgr.CreateSceneNode("nodelarm");
            nodeRoot.AddChild(nodeLArm);
            nodeLArm.AttachObject(entLArm);
            nodeLArm.SetPosition(0, 0, 0);
            entLArm.SetMaterialName("LArmMaterial");
            entLArm.Visible = showLArm;

3 将点光源绑定到照相机上 定义一个照相机,同时创建一个视口。创建一个节点,将照相机和光源都绑定到此节点即可实现此功能。

SceneNode nodeCam1 = sceneMgr.CreateSceneNode("nodecam");
            nodeCam1.AttachObject(cam1);
            nodeCam1.AttachObject(light1);

 

4 开一小窗口 因为视角不同,所以新建一个照相机和视口,即可实现。

cam1 = sceneMgr.CreateCamera("Camera1");
            cam1.AutoAspectRatio = true;
            cam1.Position = new Vector3(0,0,300);
            cam1.LookAt(0, 0, 0);
            Viewport vp1 = rWindow.AddViewport(cam1,0,0,0,1,1);
            vp1.BackgroundColour = ColourValue.White;
            cam2 = sceneMgr.CreateCamera("Camera2");
            cam2.AutoAspectRatio = true;
            cam2.Position = new Vector3(-50, 300, 0);
            cam2.LookAt(0, 0, 0);
            Viewport vp2 = rWindow.AddViewport(cam2,1,0,0,0.2f,0.3f);
            vp2.BackgroundColour = ColourValue.Black;

5 导入消毒动画 将消毒动画文件skeleton放入项目文件中,并设置动画状态。

entDisinfection = sceneMgr.CreateEntity("disinfection", "Disinfection_big.mesh");
            animaStateDis = entDisinfection.GetAnimationState("Disinfection_big");
            animaStateDis.Enabled = false;
            animaStateDis.Loop = true;

并在帧监听中添加:

if (animaStateDis != null)
            {
                animaStateDis.AddTime(evt.timeSinceLastFrame);
            }

6 加入垫枕模型,并用wasd键移动它 写入键盘事件:

首先设置:

private void Form1_Load(object sender, EventArgs e)
        {
            this.KeyPreview = true;
            this.KeyPress += new KeyPressEventHandler(Form1_KeyPress);
        }

 

void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            this.KeyDown += new KeyEventHandler(Form1_KeyDown);
            this.KeyUp += new KeyEventHandler(Form1_KeyUp);
        }

void Form1_KeyUp(object sender, KeyEventArgs e)
        {
        }

void Form1_KeyDown(object sender, KeyEventArgs e)
        {
        }

7 更换贴图
实际就是更换材质。将其材质放在帧监听中
switch (stateMaterial)
            {
                case 1:
                    entLArm.SetMaterialName("LArmMaterial");
                    break;
                case 2:
                    entLArm.SetMaterialName("BLArmMaterial");
                    break;
                default :
                    entLArm.SetMaterialName("LArmMaterial");
                    break;
            }

完整的代码: 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Mogre;
using MogreFramework;

namespace MOGREWinform
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //release resource
            Disposed += new EventHandler(Form1_Disposed);
        }

        //dispose resource
        void Form1_Disposed(object sender, EventArgs e)
        {
            this.dispose1();
        }

        public void dispose1()
        {
            if (mRoot != null)
            {
                mRoot.Dispose();
                mRoot = null;
            }
        }

        Root mRoot;
        RenderWindow rWindow;
        SceneManager sceneMgr;
        Camera cam1;
        Camera cam2;
        SceneNode nodeRoot;
        SceneNode nodePillow;
        Light light1;

        Entity entLArm;
        Entity entRArm;
        Entity entDisinfection;

        bool showLArm = true;//default show left arm
        bool showRArm = false;//show right arm
        bool mRotating = false;// mouse rotate
        Point mLastPosition;
        float Rotate = 0.2f;

        int stateMaterial = 0;//arm 1:left yellow,2:left black,3:right yellow,4:right black,5:disinfection
        AnimationState animaStateDis;//disinfection animationstate

        //set up initialize
        public void init()
        {
            //create root object
            mRoot = new Root();

            // Define Resources
            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);
                }
            }

            //set up Rendersystem
            RenderSystem rs = mRoot.GetRenderSystemByName("Direct3D9 Rendering Subsystem");
            mRoot.RenderSystem = rs;
            rs.SetConfigOption("Full Screen", "No");
            rs.SetConfigOption("Video Mode", "800 x 600 @ 32-bit colour");

            //create Render Window
            mRoot.Initialise(false, "Main Ogre Window");
            NameValuePairList misc = new NameValuePairList();

            //将panel1作为渲染容器
            misc["externalWindowHandle"] = this.panel1.Handle.ToString();

            rWindow = mRoot.CreateRenderWindow("Main RenderWindow", 800, 600, false, misc);

            //Init resources
            TextureManager.Singleton.DefaultNumMipmaps = 5;
            ResourceGroupManager.Singleton.InitialiseAllResourceGroups();

            //
            sceneMgr = mRoot.CreateSceneManager(SceneType.ST_GENERIC);

            //set nodeRoot
            nodeRoot = sceneMgr.CreateSceneNode("node0");
            sceneMgr.RootSceneNode.AddChild(nodeRoot);//important
            nodeRoot.Position = new Vector3(0, 0, 0);
            //nodeRoot.SetPosition(0, 0, 0);

            //set up camera,viewport
            cam1 = sceneMgr.CreateCamera("Camera1");
            cam1.AutoAspectRatio = true;
            cam1.Position = new Vector3(0,0,300);
            cam1.LookAt(0, 0, 0);

            Viewport vp1 = rWindow.AddViewport(cam1,0,0,0,1,1);
            vp1.BackgroundColour = ColourValue.White;

            cam2 = sceneMgr.CreateCamera("Camera2");
            cam2.AutoAspectRatio = true;
            cam2.Position = new Vector3(-50, 300, 0);
            cam2.LookAt(0, 0, 0);

            Viewport vp2 = rWindow.AddViewport(cam2,1,0,0,0.2f,0.3f);
            vp2.BackgroundColour = ColourValue.Black;

            light1 = sceneMgr.CreateLight("light1");
            light1.Type = Light.LightTypes.LT_POINT;
            light1._setCameraRelative(cam1);
            light1.Position = new Vector3(0, 0, 300);
            light1.SetDiffuseColour(1, 0, 0);

            SceneNode nodeCam1 = sceneMgr.CreateSceneNode("nodecam");
            //nodeRoot.AddChild(nodeCam1);
            nodeCam1.AttachObject(cam1);
            nodeCam1.AttachObject(light1);

            //FrameListener
            mRoot.FrameStarted += new FrameListener.FrameStartedHandler(mRoot_FrameStarted);

            this .panel1 .MouseDown +=new MouseEventHandler(panel1_MouseDown);
            this.panel1.MouseUp += new MouseEventHandler(panel1_MouseUp);
            this.panel1.MouseMove += new MouseEventHandler(panel1_MouseMove);
        }

        void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (mRotating)
            {
                float x = mLastPosition.X - Cursor.Position.X;
                float y = mLastPosition.Y - Cursor.Position.Y;

                cam1.Yaw(new Degree(x * Rotate));
                cam1.Pitch(new Degree(y * Rotate));

                mLastPosition = Cursor.Position;
            }
        }

        void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Cursor.Show();
                mRotating = false;
            }
        }

        void  panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Cursor.Hide();
                mRotating = true;
                mLastPosition = Cursor.Position;
            }
        }

        bool mRoot_FrameStarted(FrameEvent evt)
        {          
            //change arm
            if (showLArm == true)
            {
                entLArm.Visible = true;
                entRArm.Visible = false;
            }
            else
            {
                entRArm.Visible = true;
                entLArm.Visible = false;
            }

            //
            switch (stateMaterial)
            { 
                case 1:
                    entLArm.SetMaterialName("LArmMaterial");
                    break;
                case 2:
                    entLArm.SetMaterialName("BLArmMaterial");
                    break;
                case 3:
                    entRArm.SetMaterialName("RArmMaterial");
                    break;
                case 4:
                    entRArm.SetMaterialName("BRArmMaterial");
                    break;
                case 51:
                    entLArm.SetMaterialName("DisinfectionMaterial");
                    break;
                case 53:
                    entRArm.SetMaterialName("DisinfectionMaterial");
                    break;
                default :
                    entLArm.SetMaterialName("LArmMaterial");
                    break;
            }

            //disinfection animation
            if (animaStateDis != null)
            {
                animaStateDis.AddTime(evt.timeSinceLastFrame);
            }

            return true;
        }

        public void run()
        {
            Show();
            while (mRoot != null && mRoot.RenderOneFrame())
            {
                Application.DoEvents();
            }
        }

        //close the Form1
        private void btClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        //import left arm
        public void importLArm()
        {
            entLArm = sceneMgr.CreateEntity("leftArm", "A_N_Y_F_LH_S.mesh");
            SceneNode nodeLArm = sceneMgr.CreateSceneNode("nodelarm");
            nodeRoot.AddChild(nodeLArm);
            nodeLArm.AttachObject(entLArm);
            nodeLArm.SetPosition(0, 0, 0);
            //entLArm.SetMaterialName("LArmMaterial");
            entLArm.Visible = showLArm;
        }

        //import right arm
        public void importRArm()
        {
            entRArm = sceneMgr.CreateEntity("rightArm", "A_N_Y_F_RH_S.mesh");
            SceneNode nodeRArm = sceneMgr.CreateSceneNode("noderarm");
            nodeRoot.AddChild(nodeRArm);
            nodeRArm.AttachObject(entRArm);
            //entRArm.SetMaterialName("RArmMaterial");
            entRArm.Visible = showRArm;
        }

        //change arm
        private void btChangeArm_Click(object sender, EventArgs e)
        {
            if (showLArm == true)
            {
                showLArm = false;
                showRArm = true;
                stateMaterial = 3;
            }
            else
            {
                showRArm = false;
                showLArm = true;
                stateMaterial = 1;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            importLArm();
            importRArm();
            this.KeyPreview = true;
            this.KeyPress += new KeyPressEventHandler(Form1_KeyPress);
        }

        #region wasd control 
        void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            this.KeyDown += new KeyEventHandler(Form1_KeyDown);
            this.KeyUp += new KeyEventHandler(Form1_KeyUp);
        }

        void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.W:
                case Keys.S:
                case Keys.A:
                case Keys.D:
                    nodePillow.Position += new Vector3(0, 0, 0);
                    break;
            }
        }

        void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (nodePillow != null)
            {
                switch (e.KeyCode)
                {
                    case Keys.W:
                        nodePillow.Position += new Vector3(0, 0, -0.05f);
                        break;
                    case Keys.S:
                        nodePillow.Position += new Vector3(0, 0, 0.02f);
                        break;
                    case Keys.A:
                        nodePillow.Position += new Vector3(-0.02f, 0, 0);
                        break;
                    case Keys.D:
                        nodePillow.Position += new Vector3(0.02f, 0, 0);
                        break;
                }
            }
        }
        #endregion

        //rotate
        private void btRotate_Click(object sender, EventArgs e)
        {
            nodeRoot.Pitch(new Radian(0.5f));
        }

        //stretch
        private void btStretch_Click(object sender, EventArgs e)
        {

        }

        //Translation
        private void btLTranslation_Click(object sender, EventArgs e)
        {
            nodeRoot.Position += new Vector3(-5, 0, 0);
        }

        private void btRTranslation_Click(object sender, EventArgs e)
        {
            nodeRoot.Position += new Vector3(10, 0, 0);
        }

        //add pillow
        private void btAddPillow_Click(object sender, EventArgs e)
        {
            Entity entPillow = sceneMgr.CreateEntity("entpillow", "Pillow2.mesh");
            nodePillow = sceneMgr.CreateSceneNode("nodepillow");
            nodeRoot.AddChild(nodePillow);
            nodePillow.AttachObject(entPillow);
            entPillow.SetMaterialName("Pillow2");
            this.btAddPillow.Enabled = false;
        }

        //change the material
        private void btChangeMap_Click(object sender, EventArgs e)
        {
            if (entLArm.Visible == true)
            {
                if ((stateMaterial == 1)||(stateMaterial == 0))
                {
                    stateMaterial = 2;
                }
                else
                {
                    stateMaterial = 1;
                }
            }
            else
            {
                if (stateMaterial == 3)
                {
                    stateMaterial = 4;
                }
                else
                {
                    stateMaterial = 3;
                }
            }
        }

        //disinfection
        private void cbDisinfection_CheckedChanged(object sender, EventArgs e)
        {
            if (animaStateDis != null)
            {
                if (cbDisinfection.Checked)
                {
                    if (animaStateDis != null)
                    {
                        animaStateDis.Enabled = true;
                    }
                }
                else
                {
                    animaStateDis.Enabled = false;
                    entDisinfection.Visible = false;

                    switch (stateMaterial)
                    {
                        case 1:
                        case 2:
                            stateMaterial = 51;
                            break;
                        case 3:
                        case 4:
                        default:
                            stateMaterial = 53;
                            break;
                    }
                }
            }
            else
            {
                
                MessageBox.Show("没有消毒棒!");
                cbDisinfection.Checked = false;
            }
        }

        //add stick
        private void btAddStick_Click(object sender, EventArgs e)
        {
            entDisinfection = sceneMgr.CreateEntity("disinfection", "Disinfection_big.mesh");
            SceneNode nodeDisifection = sceneMgr.CreateSceneNode("nodedisifection");
            nodeRoot.AddChild(nodeDisifection);
            nodeDisifection.AttachObject(entDisinfection);
            nodeDisifection.Position = new Vector3(100, 18, 0);
            this.btAddStick.Enabled = false;
            animaStateDis = entDisinfection.GetAnimationState("Disinfection_big");
            animaStateDis.Enabled = false;
            animaStateDis.Loop = true;
        }

        private void btTwodisinfection_Click(object sender, EventArgs e)
        {
            entDisinfection.Visible = true;
        }

        //private void btAddBaby_Click(object sender, EventArgs e)
        //{
        //    Entity entBaby = sceneMgr.CreateEntity("baby", "VIV1.1_head_baby.mesh");
        //    SceneNode nodeBaby = sceneMgr.CreateSceneNode("nodebaby");
        //    nodeRoot.AddChild(nodeBaby);
        //    nodeBaby.AttachObject(entBaby);
        //    entBaby.SetMaterialName("VIV1.1_head_baby");
        //   //nodeBaby.Scale(5, 5, 5);
        //    this.btAddBaby.Enabled = false;
        //}


    }
}
View Code

 

总结:虽然是一个很小很小的项目,还是有一点体悟:

1、纸上得来终觉浅,绝知此事要躬行。事前感觉到很简单的事,做起来可能制造点麻烦。

2、理解需求很重要。深入、正确的理解需求,后来编写代码事半功倍。

3、思路。思路很重要,如果思路不对,问题永远是不可能解决的。

posted @ 2013-09-05 17:35  小项目笔记  阅读(779)  评论(4编辑  收藏  举报

更多文章请关注公众号:小项目笔记

小项目笔记