MOGRE學習筆記(3)--MOGRE小項目練習

學習OGRE有一段時間了,領導爲了檢測學習效果,根據已有C++項目,弄一個相似的用c#語言編寫的小項目。node

配置:win7,DirectX2009,vs2010.c#

 

項目要求:ide

1.有Ogre窗口(尺寸1600*900),周圍有導航按鈕(分別進行旋轉拉伸平移操做)
2.導入VIV手臂模型(左右手),默認只顯示左手,經過按鈕能夠進行模型切換顯示
3.模型上有完整貼圖,點光源綁在照相機上
4.Ogre窗口中開小Viewport,從正上方俯視整條手臂
5.導入消毒動畫,並實現手背上消毒效果(原本就是對齊的)
6.導入小墊枕模型,能夠經過wasd按鍵控制其之後
7.經過點擊按鈕能實現手臂更換貼圖oop

編寫時遇到的問題:學習

一、在新建完項目工程winform後,須要對winform進行配置,此過程當中原本是想走捷徑, 使用之前拷貝的cfg文件直接添加到項目中(半個月前使用過此方法成功建立項目),致使有錯誤出現。動畫

二、在設置手臂材料時,最好是新建一個material文件夾。 (設置左手臂時,在之前練習文件的基礎上添加左臂材質,始終沒有成功, 緣由多是後來的材質帶有片斷和頂點着色器,而本次沒有設置)this

 

實現過程:spa

1導航按鈕 code

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

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

 

總結:雖然是一個很小很小的項目,仍是有一點體悟:

一、紙上得來終覺淺,絕知此事要躬行。事前感受到很簡單的事,作起來可能製造點麻煩。

二、理解需求很重要。深刻、正確的理解需求,後來編寫代碼事半功倍。

三、思路。思路很重要,若是思路不對,問題永遠是不可能解決的。

相關文章
相關標籤/搜索