Input problems with MOGRE [solved]

marc_antoine

21-01-2007 09:48:26

hey guys, i have some troubles handling the user inout throught the mouse and keyboard, i completed the tutorials showing the way to start making our own apps without the help of the ExampleApplication, but the input is no handled but the next tutorials do hndle the input subject but using the ExampleApplication, y kept reading and at the end ther is a note saying:

You should probably use something like DirectInput (using Managed DirectX), XNA's input system, SDL's input system (Tao.SDL for C#), or some other input system which has been wrapped/ported to .Net. In fact, as you will see in a later tutorial, you do not have to host Ogre in Windows.Forms...and probably shouldn't if you are making a game

i do agree with tht, so first i tryed embedding Mogre in a .NET Form, but just when everything seems to be working suddenly an exception pops, telling a corrupt memory exception ocurred.. then i tried with directinput, or sdl with the same results so maybe some could post the code for a small simple application tht implements an input system. that would be great.

thanks in advance.

Bekas

22-01-2007 00:01:22

maybe some could post the code for a small simple application tht implements an input system. that would be great.
The ExampleApplication framework does exactly that; it uses DirectInput (by Axiom.Input).

CK_MACK

22-01-2007 01:48:34

My problem with exampleApplication is that there is no .sln file for it, and when I try to load some of the examples using MS C# 2005 Express by clicking on csproj, I get errors.

Bekas

22-01-2007 01:55:58

@CK_MACK:
Create a new project, add the files from "AxiomInput" folder and Example.cs, add references

Microsoft.DirectX (from Managed DirectX 1.1)
Microsoft.DirectX.DirectInput
System.Windows.Forms
Mogre

and you should be ok.

CK_MACK

22-01-2007 02:01:18

Thanks.

Marc

marc_antoine

22-01-2007 03:31:45

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:36:23

Here is the full code of the program, i'm using AXIOM here


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 06:25:40

ok, taking a look to the root instance i created, i found method called

AutoCreatedWindow.GetCustomAttribute(), so thought that method could get me the handle to the window, and since it has some overloads i decided to try, but i didn't know what prametrs to pass so i tried to look at the ogre API reference but not luck.....googling the MOGRE forum i found this.


http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=3057&highlight=autocreatedwindow+getcustomattribute

so seems the method 'll be useful fter all but wht other parameter does it accepts? where can i consult other methods, cose i hve the same doubts about the compositor and how to use it.

so anybody could bring knowledge to this newbie i will be thankful :D

still have the problem with the corrupt memory problem.

CK_MACK

22-01-2007 07:54:31

I had seen some code in the MogreFramework... about getting the RenderWindow... not exactly sure if that's what you are looking for, but you might be able to use it.

namespace MogreFramework
{
public partial class OgreWindow : Form
{
#region Fields
Root mRoot = null;
RenderWindow mWindow = null;
Camera mCamera = null;
Viewport mViewport = null;
SceneManager mSceneMgr = null;
#endregion

#region Properties
public Root Root
{
get
{
return mRoot;
}
}

public RenderWindow RenderWindow
{
get
{
return mWindow;
}

protected set
{
mWindow = value;
}
}


Also I saw this code for creating your own window and once you HAD the handle from tutorial # 5:
Creating the Render Window

Ogre can create the window in which we are rendering for us, or we can do it manually. Find the CreateRenderWindow function and add the following code:

mRoot.Initialise(true, "Main Ogre Window");

The Initialise function is actually a misnomer. This function creates a window to render Ogre in with the second parameter setting the window text. If we are trying to embed Ogre into a window which has already been created, we need to use the windows handle which contains it. Assuming the handle was stored in the variable "handle", this would be how you create the RenderWindow (do not add this code to the project):

NameValuePairList misc = new NameValuePairList();
misc["externalWindowHandle"] = handle.ToString();
RenderWindow win = mRoot.CreateRenderWindow("Main RenderWindow", 800, 600, false, misc);


But, that won't help you until you actually GET the handle.
I was hoping that RenderWindow returned the window handle, but I am still very much a beginner.

There is also this bit of code from Win32InputReader.cs (in exampleApplication ) that I have been looking at, that seems to get the window handle:

unsafe
{
fixed (void* p = &this.handle)
{
window.GetCustomAttribute("HWND", p);
}
}




I am still trying to figure it all out so, I can do it as well.

CK_MACK

22-01-2007 08:05:25

Oh bugger, I just got finished posting and found this topic, which answers the question:
http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=3057

marc_antoine

22-01-2007 16:56:24

yeah same happened to me, i found the same post hehehe well at least it is solved :) i finally got directinput to work withoout problems :) i will write it in a more readable way and post a final code that can be used as an example...
for newcomers.