學習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; //} } }
總結:雖然是一個很小很小的項目,仍是有一點體悟:
一、紙上得來終覺淺,絕知此事要躬行。事前感受到很簡單的事,作起來可能製造點麻煩。
二、理解需求很重要。深刻、正確的理解需求,後來編寫代碼事半功倍。
三、思路。思路很重要,若是思路不對,問題永遠是不可能解決的。