Trying to use DirectInput with Mogre...

CK_MACK

19-01-2007 05:06:20

Once I hit tutorial #5, there is the problem of not using Ogre's input system.
The problem is handled by asking the "user" to just go find one and implement it. This is not easy for me since, well, I am just trying to learn HOW to use Mogre and I am not familiar enough with it.

Since Tutorial 4 has a working mesh with a camera that moves, I wanted to put Microsoft.DirectX.DirectInput into Tutorial #4 as a kind of proof of concept.

I was looking at a tutorial located here: http://www.riemers.net/eng/Tutorials/Di ... 1/tut9.php

(please take a quick look at that link)

The part where I seem to be running into difficulty is this line:
our_directx_form.InitializeKeyboard();

My question is:
What is the equivalent of "our_directx_form" in Mogre?

An example the code I "flung" together for Tutorial 4 and a DirectInput Tutorial is below:

// Tutorial 4 + DirectInput: Frame Listeners but substitute in DirectInput for the Keyboard
// Try to use J and K, to move the camera left and right.
// requires the following References: Microsoft.DirectX.DirectInput, Mogre, MogreFramework, System, System.Data,
// System.Deployment, System.Drawing, System.Windows.Forms, System.Xml

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using MogreFramework;
using Mogre;
using System.Drawing;
using Microsoft.DirectX.DirectInput;

namespace Tutorial04
{
static class Program
{
[STAThread]
static void Main()
{
try
{
MyOgreWindow win = new MyOgreWindow();
new SceneCreator(win);
// Initialize the keyboard

win.Go();
}
catch (System.Runtime.InteropServices.SEHException)
{
if (OgreException.IsThrown)
MessageBox.Show(OgreException.LastException.FullDescription, "An Ogre exception has occurred!");
else
throw;
}
}
}

class MyOgreWindow : OgreWindow
{
const float TRANSLATE = 400; // 200 for slower camera motion
const float ROTATE = 0.2f;
bool mRotating = false;
Vector3 mTranslation = Vector3.ZERO;
Radian mYaw = 0.0f;
Point mLastPosition;
private Microsoft.DirectX.DirectInput.Device keyb;

protected override void CreateInputHandler() // Allows us to overide the inputhandler

{

keyb = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard);
keyb.SetCooperativeLevel(this, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
keyb.Acquire();

// Here's the line where I don't know what to use for our form name...
win.InitializeKeyboard(); // obviously its not our_directX_form, but what is it? How can I get that info and bring it here?

this.Root.FrameStarted += new FrameListener.FrameStartedHandler(FrameStarted);
this.KeyDown += new KeyEventHandler(ReadKeyboard);

}
void ReadKeyboard(object sender, KeyEventArgs e)
{
KeyboardState keys = keyb.GetCurrentKeyboardState();
if (keys[Key.J])
{ mTranslation.x = -TRANSLATE; }
if (keys[Key.K])
{ mTranslation.x = TRANSLATE; }
}


bool FrameStarted(FrameEvent evt)
{
Camera.Position += Camera.Orientation * mTranslation * evt.timeSinceLastFrame;



return true;
}
}

class SceneCreator
{
public SceneCreator(OgreWindow win)
{
win.SceneCreating += new OgreWindow.SceneEventHandler(SceneCreating);
}

void SceneCreating(OgreWindow win)
{
win.SceneManager.AmbientLight = new ColourValue(0.25f, 0.25f, 0.25f);

Entity ent = win.SceneManager.CreateEntity("Ninja", "ninja.mesh");
win.SceneManager.RootSceneNode.CreateChildSceneNode().AttachObject(ent);

Light light = win.SceneManager.CreateLight("Light");
light.Type = Light.LightTypes.LT_POINT;
light.Position = new Vector3(250, 150, 250);
light.DiffuseColour = ColourValue.White;
light.SpecularColour = ColourValue.White;

win.Camera.Position = new Vector3(0, 200, 400);
win.Camera.LookAt(ent.BoundingBox.Center);
}
}

}


I apologize in advance for asking stupid noob questions, but I don't know where else to ask these questions.

Marc.

linkerro

19-01-2007 17:21:34

Have you taken a look at the examples that come with MOGRE? Last I looked they had input and it worked quite well.

They relay on a modified version of the Axiom DirectInput library. Copy-paste that dir into your own project and I'm sure you can figure out the rest from the examples.

Avictus

19-01-2007 18:46:03

linkerro is correct. The MOGRE ExampleApplication uses Axiom for input. The source for it is located in MogreInstallDir\Mogre Samples\ExampleApplication. If you copy the AxiomInput directory into your own project, you can use that for input. It is based on DirectInput, so you'll need to add references to Microsoft.DirectX.DirectInput, and possibly Microsoft.DirectX also. Look at Example.cs in the ExampleApplication directory to see how it's implemented.

CK_MACK

19-01-2007 19:06:03

Thanks,
I will take a look at those. Much appreciated.

Marc

marc_antoine

20-01-2007 08:32:03

hey ck_mack i'm new to Mogre to, nd certainly i got to the same point, well sort of the same question first let me answer yours.

"our_directx_form.InitializeKeyboard();" is a way to call the initializekeyboard method you wrote inside your form, "our_directx_form" is the name of the form, but if you call the method when the form loads for example you should rewrite it like this :

"InitializeKeyboard();"


i wrote the code int he page you found in a windows form, this is the code:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX.DirectInput;

namespace DirectInput
{
public partial class Form1 : Form
{
private Microsoft.DirectX.DirectInput.Device keyb;
public Form1()
{
InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)
{
InitializeKeyboard();

}
public void InitializeKeyboard()
{
keyb = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard);
keyb.SetCooperativeLevel(this, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
keyb.Acquire();
}
private void ReadKeyboard()
{
KeyboardState keys = keyb.GetCurrentKeyboardState();
MessageBox.Show(keys.ToString());
if (keys[Key.A])
{
MessageBox.Show("keypressed-->A");
}

}
}
}




as you can see i call the initializekeyboard() when the form loads, good reference is the directX reference documentation that has a step by step tutorial for working with directInput. :)

if you use the axiom code post simple example of how you did that :) that would be helpful for more people in the forum newbies including me :)

hope this helps good luck!

marc_antoine

22-01-2007 03:46:10

indeed bekas i used the Axiom input files that are at the exampleApp, and i got the following error after a while:

"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

i don't know why, but it seems that happens when i move the mouse out of the render window area; so the next thing to try was to make it fullscreen so the mouse is always inside the render window but still got that message.

The same thing happened using directinput or embeding in a window created by the SLD libraries. in a moment i'll post the code so maybe someone could tell me if it is something wrong with the code.


BTW, is there any way that i can retrieve the handle to the window Mogre autocreates like in OGRE? that would be really usefull for not embedding Mogre in a .net Form to get a handle.

marc_antoine

22-01-2007 03:47:04


using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Mogre;
using OSMloader;
using MogreFramework;
using System.Drawing;
using System.IO;
using Axiom.Input;



namespace MOGRE_LV3
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
OgreStartup ogre = new OgreStartup();
ogre.Go();
}
}

}


namespace MOGRE_LV3
{
class OgreStartup
{
Form ventana=new Form();
Root mRoot = null;
SceneManager mgr = null;
RenderWindow rw = null;
Camera cam = null;
const float TRANSLATE = 10;
const float ROTATE = 0.2f;
float camSpeed = 100f;
Degree rotateSpeed = 36;
float toggleDelay = 1.0f;
Axiom.InputReader input;
//bool mRotating = false;
Mogre.Vector3 mTranslation = Mogre.Vector3.ZERO;
//Point mLastPosition;



public void Go()
{
CreateRoot();
DefineResources();
SetupRenderSystem();
CreateRenderWindow();
InitializeResourceGroups();
CreateScene();
CreateInputHandler();
StartRenderLoop();

}
void CreateRoot()
{
mRoot = new Root();

}
void DefineResources()
{
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);
}
}
}
void SetupRenderSystem()
{
if (!mRoot.ShowConfigDialog())
throw new Exception("The user canceled the configuration dialog.");

//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");

}
void CreateRenderWindow()
{

try
{
rw = mRoot.Initialise(true, "Main Ogre Window");
//Video.SetVideoModeWindow(800, 600);
//Video.WindowCaption = "Hello World!";
//NameValuePairList misc = new NameValuePairList();
//misc["externalWindowHandle"] = Video.WindowHandle.ToString();
//rw = mRoot.CreateRenderWindow("Main RenderWindow", 800, 600, false, misc);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);

}



}
void InitializeResourceGroups()
{
TextureManager.Singleton.DefaultNumMipmaps = 5;
ResourceGroupManager.Singleton.InitialiseAllResourceGroups();
}
private void CreateScene()
{
mgr = mRoot.CreateSceneManager(SceneType.ST_EXTERIOR_CLOSE);
cam = mgr.CreateCamera("Camera");
cam.NearClipDistance = 10;
rw.AddViewport(cam);






//////////////////////////////////////////////////////////////////////
//Establecemos el color de la luz mbiental
mgr.AmbientLight = new ColourValue(1, 1, 1);
//Establecemos el tipo de sombra
mgr.ShadowTechnique = ShadowTechnique.SHADOWTYPE_STENCIL_MODULATIVE;
//Establecemos la imagen del cielo
mgr.SetSkyBox(true, "Examples/SpaceSkyBox");
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
OSMLoader loader = new OSMLoader(mgr, rw);
loader.Initialize("meshlv.osm");
loader.CreateScene(mgr.RootSceneNode.CreateChildSceneNode());
Entity ent = mgr.GetEntity("Poste Nuevo (poste 2)");
////////////////////////////////////////////////////////////////////

cam.Position = new Mogre.Vector3(0, 200, 500);
cam.LookAt(ent.BoundingBox.Center);


mRoot.FrameEnded += new FrameListener.FrameEndedHandler(FrameEnded);
//ticks = Environment.TickCount;

}
public void CreateInputHandler()
{
input = new Axiom.Platforms.Win32.Win32InputReader();
input.Initialize(rw, true, true, false, true);

}
void StartRenderLoop()
{
mRoot.StartRendering();

}
bool FrameEnded(FrameEvent evt)
{
//(Environment.TickCount - ticks > 5000)
//return false;
if (mRoot == null || rw.IsClosed)
{

return false;
}
else
{
HandleInput(evt);
//cam.Position += cam.Orientation * mTranslation * evt.timeSinceLastFrame;
return true;
}
}
protected virtual void HandleInput(FrameEvent evt)
{
// Move about 100 units per second,
float moveScale = camSpeed * evt.timeSinceLastFrame;
// Take about 10 seconds for full rotation
Degree rotScale = rotateSpeed * evt.timeSinceLastFrame;

Vector3 translateVector = Vector3.ZERO;


// set the scaling of camera motion
Degree scaleRotate = rotateSpeed * evt.timeSinceLastFrame;

Vector3 camVelocity = Vector3.ZERO;

// TODO Move this into an event queueing mechanism that is processed every frame
input.Capture();

if (input.IsKeyPressed(KeyCodes.Escape))
{
// stop rendering loop
//shutDown = true;
mRoot = null;
}

if (input.IsKeyPressed(KeyCodes.A))
{
translateVector.x = -moveScale;
}

if (input.IsKeyPressed(KeyCodes.D))
{
translateVector.x = moveScale;
}

if (input.IsKeyPressed(KeyCodes.W))
{
translateVector.z = -moveScale;
}

if (input.IsKeyPressed(KeyCodes.S))
{
translateVector.z = moveScale;
}

if (input.IsKeyPressed(KeyCodes.Left))
{
cam.Yaw(scaleRotate);
}

if (input.IsKeyPressed(KeyCodes.Right))
{
cam.Yaw(-scaleRotate);
}

if (input.IsKeyPressed(KeyCodes.Up))
{
cam.Pitch(scaleRotate);
}

if (input.IsKeyPressed(KeyCodes.Down))
{
cam.Pitch(-scaleRotate);
}

// subtract the time since last frame to delay specific key presses
toggleDelay -= evt.timeSinceLastFrame;

// toggle rendering mode
if (input.IsKeyPressed(KeyCodes.R) && toggleDelay < 0)
{
if (cam.PolygonMode == PolygonMode.PM_POINTS)
{
cam.PolygonMode = PolygonMode.PM_SOLID;
}
else if (cam.PolygonMode == PolygonMode.PM_SOLID)
{
cam.PolygonMode = PolygonMode.PM_WIREFRAME;
}
else
{
cam.PolygonMode = PolygonMode.PM_POINTS;
}

Console.WriteLine("Rendering mode changed to '{0}'.", cam.PolygonMode);

toggleDelay = 1;
}





if (input.IsKeyPressed(KeyCodes.B))
{
mgr.ShowBoundingBoxes = !mgr.ShowBoundingBoxes;
}



if (!input.IsMousePressed(Axiom.Input.MouseButtons.Button0))
{
Degree cameraYaw = -input.RelativeMouseX * .13f;
Degree cameraPitch = -input.RelativeMouseY * .13f;

cam.Yaw(cameraYaw);
cam.Pitch(cameraPitch);
}
else
{
translateVector.x += input.RelativeMouseX * 0.13f;
}


// move the camera based on the accumulated movement vector
cam.MoveRelative(translateVector);


}

}
}

marc_antoine

22-01-2007 17:05:35

hey marc seems we found the link at the same time hehehehe, this will help us alot since we won't have to embed Mogre in a .Net Form.. i will post in a moment a sample code using the handle we got from


[url=http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=3057


to help newcomers :)