MOGRE, MOIS and embeded OGRE Window

feanor91

21-07-2008 20:19:48

Hello

I manage to embeded ogre in a picturebox under vb.net using MOGREFORM example. But, by now, I want to move my camera into OGRE render window. So, I use framelistener and exemple of mogre tutorial. All works fine if OGRE is embeded in the main form but if I embeded it in picture box, It throw an exeption here :

myKeyboard = myInputManager.CreateInputObject(MOIS.Type.OISKeyboard, true)


I can't see what exeption because this
OgreException.LastException.FullDescription
equal nothing....

By intercepting event into mousemove picturebox event, i can move the mouse but, I cant tune movement for I haven't same fonction than listener.

How can achive working with MOIS in an embede control.

Thanks

feanor91

22-07-2008 06:23:26

Forget it, I found how to achieve that. I use classic windows event and a timer.

paddy3k

26-07-2008 10:26:06

could you post how you do that ?

I have problems with embedded Windows.Forms too. My events are never
fired and I don't know why :(

I'm using the exact code from the MogreFramework (DefaultInputHandler) but the events are never raised.

feanor91

26-07-2008 11:24:10

ello

I turn around this a bit, I must say....

In fact you can't use MOIS because, if I have understood well, it uses Direct Input and, after a lot of searching, It apears that direct input needs that the window which handle is passed mus be a top level window, so, if you embeded ogre in a control into a window, this control will never be top level so, to turn around that problem, I use classic window control manager, ie for mouse input, I use myconttrol mousedown, mouseup, en mousemove event and for keyboard, I use a timer window with GetAsyncKeyState API. A side problem is that I think using a timer control make FPS be down cause we can only fired timer_tick onl every 1 millisecond. I think that framelistener must be fired more than this because with classic system from WIKI, my little scenes are render at more than 800FPS and with timer I never be avay from 64 FPS....So, it's suffisant, but I will lokk if ther is an ogre timer that I can use....

To post, my code, well, It's a whole program, in fact, To play with MOGRE and to see how it works, I have planing to do an oFusion scene loader with some control on objects as moving, rolling, hiding, switch camera, play with light, shadows....So, I can't post only a few lines, meanwhile, if you want, PM me, and I will be glad to give you my source to take in whatever you want.

paddy3k

27-07-2008 12:42:34

thanks for your reply ! I will try that soon and post my results if I succeed :)

edit: Ok it works now and i managed without using a Timer.

I set KeyPreview = true (of the Main Form) and catch the KeyDown and KeyUp from there.

For the mouse movement I'm using panel.MouseMove, MouseDown & MouseUp.

Just one problem left.... You cannot turn around continuous, cause if the cursor reaches the left or right of the screen there is no delta location if you keep moving left or right (hope you understand what I mean :). Any suggestions how to solve that ?

greets !
paddy

feanor91

27-07-2008 14:44:23

Hi

I try to use keypreview to, but can't mangae to work with it so I abandon it.

To overshoot mouse movement when cursor reach side of control, well, I don't know how to achive that. If you find something, let me know.

I will retempt to use keypreview....

Edit :

When I move out my picture box, I continu to rotate Mouse....

Here my code :


'Les deux variables suivantes servent à déterminer le sens de déplacement de la souris (cf picMogre.MouseMove)
Private xOrig As Integer = 0
Private yOrig As Integer = 0


Private Sub picMogre_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picMogre.MouseDown

'Quand on clique dans la picture box, on récuère les coordonnées pour le calcul de l'ofset de déplacement de la souris
xOrig = e.X
yOrig = e.Y
End Sub

Private Sub picMogre_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picMogre.MouseMove

'Si le bouton gauche est cliqué, on tourne la caméra
If e.Button = Windows.Forms.MouseButtons.Left Then
If xOrig - e.X <> 0 Then 'déplacement horizontal
If xOrig - e.X < 0 Then 'souris déplacée vers la droite
myCamera.Yaw(-ROTATE * timeSinceLastFrame)
Else
myCamera.Yaw(ROTATE * timeSinceLastFrame)
End If
End If
If yOrig - e.Y <> 0 Then 'déplacement vertical
If yOrig - e.Y < 0 Then 'souris déplacée vers le bas
myCamera.Pitch(-ROTATE * timeSinceLastFrame)
Else
myCamera.Pitch(ROTATE * timeSinceLastFrame)
End If
End If
ElseIf e.Button = Windows.Forms.MouseButtons.Right Then 'on zoom/dézoom
If yOrig - e.Y <> 0 Then
If myCamera.FOVy.ValueRadians + ((e.Y - yOrig) * timeSinceLastFrame) >= 0 And myCamera.FOVy.ValueRadians + ((yOrig - e.Y) * timeSinceLastFrame) <= 3 Then
myCamera.FOVy = myCamera.FOVy.ValueRadians + ((e.Y - yOrig) * timeSinceLastFrame)
End If
End If
txtFOV.Text = myCamera.FOVy.ValueRadians
ElseIf e.Button = Windows.Forms.MouseButtons.Middle Then 'on fait rouler la caméra
If xOrig - e.X <> 0 Then
If xOrig - e.X < 0 Then
myCamera.Roll(-ROTATE * timeSinceLastFrame)
Else
myCamera.Roll(ROTATE * timeSinceLastFrame)
End If
End If
End If

'et on récupère les valeurs courantes de position pour les futurs calculs.
xOrig = e.X
yOrig = e.Y


End Sub


x and yorig are private to the form.

paddy3k

28-07-2008 09:47:12

yes it does. But it stops rotating if you reach the screen edges, doesn't it ?

I will try that :)

feanor91

28-07-2008 11:32:43

Of course it does....How do you want to continue rotating if you cannot move the mouse? Event is not fired if mouse doesn't move.

Meanwhile, I see what you want to say, but I don't know how you can achieve that behavior....however, it will be intersting to have a such behaviour, I will thinking on my own. If you find a clue, let me know I will do the same.


For the moment, I have trouble with shadows. Yesterday I obtain what I want, my shadow are good, but know, I doesn't work and I don't know why. I oFusion wieport under Max, all is correct, but not in my application though I use scenemanager shadowtechnique property...I didi not undertand what I do not well.

paddy3k

28-07-2008 16:59:09

Hi feanor !

I tried again another way and found a good solution ! I'm using MOIS again now and handle it this way :

The Input Handler :


public class InputHandler
{
// The MOIS input objects
protected MOIS.InputManager inputManager;
protected MOIS.Keyboard inputKeyboard;
protected MOIS.Mouse inputMouse;

// The View3D for accessing the camera
protected IView view;

// Translate & rotate scalars
private float TRANSLATE = 100f;
private Degree ROTATE = 0.2f;

private bool moving;

public bool Moving
{
get
{
return moving;
}
set
{
moving = value;
}
}
#region Constructor

public InputHandler(Form form, IView view)
{
this.view = view;
this.moving = false;

// At first we define the access mode of the mouse
// and pass the windowhandle to the inputManager
MOIS.ParamList param = new MOIS.ParamList();

param.Insert("w32_mouse", "DISCL_NONEXCLUSIVE");
param.Insert("w32_mouse", "DISCL_FOREGROUND");
param.Insert("WINDOW", form.Handle.ToString());

// Hook up the InputManager to the application window
inputManager = MOIS.InputManager.CreateInputSystem(param);

if (inputManager != null)
{
// Create the devices
inputKeyboard = (MOIS.Keyboard)inputManager.CreateInputObject(MOIS.Type.OISKeyboard, false);
inputMouse = (MOIS.Mouse)inputManager.CreateInputObject(MOIS.Type.OISMouse, false);
}

// Subscribe the FrameStarted event
view.Root.FrameStarted += new FrameListener.FrameStartedHandler(FrameStarted);
}

#endregion

#region EventHandlers

private bool FrameStarted(FrameEvent evt)
{
if (moving)
{
Capture();

float moveScale = TRANSLATE * evt.timeSinceLastFrame;
Degree scaleRotate = ROTATE * evt.timeSinceLastFrame;

Camera camera = view.Camera;
Vector3 translateVector = Vector3.ZERO;

if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_A))
{
translateVector.x = -moveScale;
}

if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_D))
{
translateVector.x = moveScale;
}

if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_W))
{
translateVector.z = -moveScale;
}

if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_S))
{
translateVector.z = moveScale;
}

if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_LEFT))
{
camera.Yaw(scaleRotate);
}

if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_RIGHT))
{
camera.Yaw(-scaleRotate);
}

if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_UP))
{
camera.Pitch(scaleRotate);
}

if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_DOWN))
{
camera.Pitch(-scaleRotate);
}

MOIS.MouseState_NativePtr mouseState = inputMouse.MouseState;

Degree cameraYaw = -mouseState.X.rel * .13f;
Degree cameraPitch = -mouseState.Y.rel * .13f;

camera.Yaw(cameraYaw);
camera.Pitch(cameraPitch);

camera.MoveRelative(translateVector);
}

return true;
}

private void Capture()
{
inputKeyboard.Capture();
inputMouse.Capture();
}

#endregion
}


Ok, so the FrameStarted code will be only processed if "moved" is set to true. This is done in the MainForm class, simply by subscribing the MouseUp / MouseDown Events of the panel where Ogre renders in :


First the Setup :



private void Setup()
{
view.InitializeOgre(this.renderPanel.Handle);

inputHandler = new InputHandler(this, view);

this.renderPanel.MouseDown += new MouseEventHandler(renderPanel_MouseDown);
this.renderPanel.MouseUp += new MouseEventHandler(renderPanel_MouseUp);
}



And the Handlers :


private void renderPanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
Cursor.Hide();

inputHandler.Moving = true;
}
}

private void renderPanel_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
Cursor.Show();

inputHandler.Moving = false;
}
}


This works very well. The problem with the screen edges is no more and the movement is generally "smoother" like before with Forms Events :)

Hope it will be useful for your project too. :-)

Greets !
paddy

feanor91

28-07-2008 17:45:29

Hi

Well fine, I will try this as soon as possible. But I must see how to interface in VB..

Therefore, I resolve my shadow problem, It was the exporting from max...I mush check "export edges" in oFusion exporter or shadow will not works.

paddy3k

28-07-2008 18:58:59

ah right, your coding in VB.

You don't need to use interfaces. The "IView" is just my Ogre "Core Class",
my application design is orientated by Dependency-Injection pattern, therefore I'm using interfaces.

You can also only pass the Camera instance from Ogre to the input handler :)

greets !

feanor91

06-08-2008 09:37:52

Hi

I finaly have time (and needs) to implement your solustion in my application, but I have a problem...Here my code :

Private Sub InitInputHandler()

'Définition du mode d'accès de la souris et du handle de fenêtre à gérer (ici la picture box)
Dim param As MOIS.ParamList = New MOIS.ParamList()

param.Insert("w32_mouse", "DISCL_NONEXCLUSIVE")
param.Insert("w32_mouse", "DISCL_FOREGROUND")
param.Insert("WINDOW", picMogre.Handle.ToString)

'Hook de l'input manager à la fenêtre
inputManager = MOIS.InputManager.CreateInputSystem(param)
If Not inputManager Is Nothing Then

'Create the devices
inputMouse = CType(inputManager.CreateInputObject(MOIS.Type.OISMouse, False), MOIS.Mouse)
inputKeyboard = CType(inputManager.CreateInputObject(MOIS.Type.OISKeyboard, False), MOIS.Keyboard)
End If

' Subscribe the FrameStarted event
AddHandler myRoot.FrameStarted, AddressOf FrameStarted

End Sub


Here :
inputMouse = CType(inputManager.CreateInputObject(MOIS.Type.OISMouse, False), MOIS.Mouse)
inputKeyboard = CType(inputManager.CreateInputObject(MOIS.Type.OISKeyboard, False), MOIS.Keyboard)


I have an error : External exeption, with no more detail, nothing more in ogre log....Not cool. In fact, it is the same problem that I have at starting with Mois....

Any idea?

Edit :

Finaly, I manage to catch OIS exeption when I see there is an OISException class...And it says :

Win32Keyboard::Win32Keyboard>> coop error!

and for the mouse :

Win32Mouse::Win32Mouse>>Failed to set coop level

What about this?

Bekas

06-08-2008 09:51:26

@feanor91, these are OIS (not Ogre) exceptions that you are getting.
Try to use MOIS.OISException for more details.

feanor91

06-08-2008 10:01:00

@feanor91, these are OIS (not Ogre) exceptions that you are getting.
Try to use MOIS.OISException for more details.


Well, just edited my message in same time you are posting,....I think.

feanor91

06-08-2008 10:09:29

Perhaps a clue, if i comment my paramlist array, I have the same behaviour, so, i think that my paramlist is not well initialised, i seek in this way, posting if i found something.

Edit :

OK, I think that I have found what happend. If I pass handle of my main window in place of my picturebox handle, it works (always the story about the topform window of directX I think) So, I will advance and see if my camera is moving with new events.

paddy3k

06-08-2008 10:42:57

Yes thats right! You have to pass the main window handle... i was intially fooled by the same error because I was using the panel handle :)

feanor91

06-08-2008 10:48:54

OK, all works fine.

Just one question Paddy3K : where did you put your renderoneframe call? For my part, I put it in timer. and you?

morbidel

18-01-2010 10:40:33

Hi,
I overridden the Run and OnIdle in WinApp, check http://www.gamedev.net/reference/articl ... le2204.asp

eddy

19-07-2011 11:51:40

Hello.

Sorry for the bump. How do you pass the main window handle? Is there a chance you could post your source code?

Thank you in advance

smiley80

19-07-2011 12:32:56

Form.Handle
of the form that contains Mogre control.

eddy

21-07-2011 20:46:50

Thank you, i will try.

If i understood correctly, then the bold line is causing the problem?


public OgreForm()
{

try
{

InitializeComponent();
//this.Disposed += new EventHandler(MogreForm_Disposed);
this.Disposed+=new EventHandler(OgreForm_Disposed);

mogreWin = new OgreWindow(new Point(200, 50), mogrePanel.Handle); //<---
//pass the handle to OgreForm.Handle
mogreWin.InitMogre();

//OgreWindow(OgreForm.FromChildHandle());

//mogreWin.CreateInput();

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



}


EDIT:

Or the passing should be done when initializing MOIS, in the following code:


MOIS.ParamList pl = new MOIS.ParamList();
IntPtr windowHnd; //<--from this?
//IntPtr windowHnd = OgreForm.FromHandle(IntPtr hWnd); //I dont have OgreForm.Handle

window.GetCustomAttribute("WINDOW", out windowHnd); // window is your RenderWindow!
pl.Insert("w32_mouse", "DISCL_NONEXCLUSIVE");
pl.Insert("w32_mouse", "DISCL_FOREGROUND");
pl.Insert("WINDOW", windowHnd.ToString());
this.inputManager = MOIS.InputManager.CreateInputSystem(pl);
this.inputManager = MOIS.InputManager.CreateInputSystem(pl);

smiley80

22-07-2011 05:06:14

Pass the handle of OgreForm to OgreWindow:
mogreWin = new OgreWindow(new Point(200, 50), mogrePanel.Handle, this.Handle);

and use it to initialise MOIS:

public OgreWindow(Point p, IntPtr ogreWindowHandle, IntPtr moisWindowHandle)
{
...
pl.Insert("WINDOW", moisWindowHandle.ToString());
...
}

eddy

22-07-2011 10:21:50

Thank you very much. I tried the suggested and i get en exception (but i am happy about the progress):
At the line window.GetCustomAttribute("WINDOW", out moisWindowHandle);



In public void InitMogre(){} i have window = root.CreateRenderWindow("Simple Mogre Form Window", 0, 0, false, misc);, is it possible the upper statement cannot access this one?


root.RenderSystem.SetConfigOption("Full Screen", "No");
root.RenderSystem.SetConfigOption("Video Mode", "640 x 480 @ 32-bit colour");

root.Initialise(false);
NameValuePairList misc = new NameValuePairList();
misc["externalWindowHandle"] = ogreWindowHandle.ToString();
//misc["externalWindowHandle"] = moisWindowHandle.ToString();
misc["vsync"] = "true";

//test kine from forums
//window = root.Initialise(true, "Application");
//^not working
window = root.CreateRenderWindow("Simple Mogre Form Window", 0, 0, false, misc); //*********
//RenderWindow panelMogre = root.CreateRenderWindow("panelMogre", 0, 0, false, misc);

smiley80

22-07-2011 11:43:57

You get the NRE because 'window' is null, but luckily you don't need that line anyway.

window.GetCustomAttribute("WINDOW", out moisWindowHandle);
would set 'moisWindowHandle' to Ogre's window handle (which will be the one of the panel not the form).

Also make sure you uncomment 'this.ogreWindowHandle = ogreWindowHandle;'.

eddy

22-07-2011 12:31:20

It compiled!


public OgreWindow(Point origin, IntPtr ogreWindowHandle, IntPtr moisWindowHandle)
{
position = origin;
this.ogreWindowHandle = ogreWindowHandle;

MOIS.ParamList pl = new MOIS.ParamList();
//IntPtr windowHnd;
//window.GetCustomAttribute("WINDOW", out moisWindowHandle); // window is your RenderWindow!

pl.Insert("w32_mouse", "DISCL_NONEXCLUSIVE");
pl.Insert("w32_mouse", "DISCL_FOREGROUND");

// pl.Insert("WINDOW", windowHnd.ToString());
pl.Insert("WINDOW", moisWindowHandle.ToString());

//this.inputManager = MOIS.InputManager.CreateInputSystem(pl);
inputManager = MOIS.InputManager.CreateInputSystem(pl);

// Create all devices (except joystick, as most people have Keyboard/Mouse) using unbuffered input.
// Create the devices
this.inputKeyboard = (MOIS.Keyboard)this.inputManager.CreateInputObject(MOIS.Type.OISKeyboard, false);
this.inputMouse = (MOIS.Mouse)this.inputManager.CreateInputObject(MOIS.Type.OISMouse, false);

}


Before your last reply i tried it couple of ways (thats when this.ogreWindowHandle = ogreWindowHandle; got left commented). I was also trying to find data about the GetCustomAttribute. But your suggestion worked. I owe you a beer! Now to see if I can really use mois, and if frame listeners can be implemented now (I had an issue with them as well), and then I can transfer the learned stuff from this tutorial file to my project.

EDIT:Ok, the frame listener implementation problem is still a go. I tried by implementing the following code to public class OgreWindow:


I see that it cannot connect, i tried to tie it up looking through intellisense, but nothing came to me. (if I put the code in Tutorial.cs, then there are no compile errors, but I don't think it belongs there)

These are the *.cs files:

OgreForm.cs:

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 Mogre.TutorialFramework;
using MOIS;




namespace Tutorial //nesto razmisljam, da li je uredu sto ti oba namespace nose ime tutorial
{



public partial class OgreForm : Form
{


protected OgreWindow mogreWin;

private static InputManager input = new InputManager();


public OgreForm()
{

try
{

InitializeComponent();
//this.Disposed += new EventHandler(MogreForm_Disposed);
this.Disposed+=new EventHandler(OgreForm_Disposed);

mogreWin = new OgreWindow(new Point(200, 50), mogrePanel.Handle, this.Handle); //ovo proveri

mogreWin.InitMogre();



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


private void OgreForm_Paint(object sender, PaintEventArgs e)
{
mogreWin.Paint();
}

void OgreForm_Disposed(object sender, EventArgs e)
{
mogreWin.Dispose();
//mogreWin=null;

}

private void OgreForm_Load(object sender, EventArgs e)
{

}

private void mogrePanel_Paint(object sender, PaintEventArgs e)
{
mogreWin.Paint(); //ovo je falilo!!!!!!!!

}

private void mogrePanel_Click(object sender, MouseEventArgs e)
{


switch(e.Clicks)
{
case 1:
MessageBox.Show("Single Click");
break;
case 2:
MessageBox.Show( "Double Click!");
break;
default:
MessageBox.Show( "Many clicks!");
break;
}
}


private void button1_Click(object sender, EventArgs e)
{


MessageBox.Show("xcdxc");

}

private void mogrePanel_Click(object sender, EventArgs e)
{
//MessageBox.Show("panel click");

// mogreWin.camera.Position = new Mogre.Vector3(100f, 150f, 340f);
}

private void mogrePanel_MouseDown(object sender, MouseEventArgs e)
{
int initPosX;
initPosX = MousePosition.X;
int initPosY;
initPosY = MousePosition.Y;

if (e.Button==MouseButtons.Left)
mogreWin.nodePublic.Yaw(new Degree(15));
else if (e.Button==MouseButtons.Right)
mogreWin.nodePublic.Yaw(new Degree(-15));

}



}





public class OgreWindow
{



public Root root;
public SceneManager sceneMgr;

//protected Camera camera;
public Camera camera;

protected Viewport viewport;
protected RenderWindow window;
protected Point position;
protected IntPtr hWnd;
protected IntPtr ogreWindowHandle;
protected IntPtr moisWindowHandle;

public SceneNode nodePublic;

protected MOIS.InputManager inputManager;
protected MOIS.Keyboard inputKeyboard;
protected MOIS.Mouse inputMouse;

bool ProcessUnbufferedInput(FrameEvent evt)
{


inputKeyboard.Capture();
inputMouse.Capture();


if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_SPACE))
{
//mLight.Visible = !mLight.Visible;
//mLightToggleTimeout = 0.2f;

nodePublic.Pitch(new Degree(45));

}

return true;

}


protected override void CreateFrameListeners()
{

base.CreateFrameListeners();

//seApplication.
root.FrameRenderingQueued += new FrameListener.FrameRenderingQueuedHandler(ProcessUnbufferedInput);
}

//public OgreWindow(Point origin, IntPtr hWnd) //dodao IntPtr moisWindowHandle
public OgreWindow(Point origin, IntPtr ogreWindowHandle, IntPtr moisWindowHandle)
{
position = origin;
this.ogreWindowHandle = ogreWindowHandle;

//*********************************************************************************************************
MOIS.ParamList pl = new MOIS.ParamList();
//IntPtr windowHnd;

//window.GetCustomAttribute("WINDOW", out moisWindowHandle); // window is your RenderWindow!

pl.Insert("w32_mouse", "DISCL_NONEXCLUSIVE");
pl.Insert("w32_mouse", "DISCL_FOREGROUND");

// pl.Insert("WINDOW", windowHnd.ToString());
pl.Insert("WINDOW", moisWindowHandle.ToString());

//this.inputManager = MOIS.InputManager.CreateInputSystem(pl);
inputManager = MOIS.InputManager.CreateInputSystem(pl);

// Create all devices (except joystick, as most people have Keyboard/Mouse) using unbuffered input.

// Create the devices
this.inputKeyboard = (MOIS.Keyboard)this.inputManager.CreateInputObject(MOIS.Type.OISKeyboard, false);
this.inputMouse = (MOIS.Mouse)this.inputManager.CreateInputObject(MOIS.Type.OISMouse, false);

}


public void InitMogre()
{

//-----------------------------------------------------
// 1 enter ogre
//-----------------------------------------------------
root = new Root();

//-----------------------------------------------------
// 2 configure resource paths
//-----------------------------------------------------
ConfigFile cf = new ConfigFile();
cf.Load("resources.cfg", "\t:=", true);

// Go through all sections & settings in the file
ConfigFile.SectionIterator seci = cf.GetSectionIterator();

String secName, typeName, archName;

// Normally we would use the foreach syntax, which enumerates the values, but in this case we need CurrentKey too;
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);
}
}

//-----------------------------------------------------
// 3 Configures the application and creates the window
//-----------------------------------------------------
bool foundit = false;
foreach (RenderSystem rs in root.GetAvailableRenderers())
{
root.RenderSystem = rs;
String rname = root.RenderSystem.Name;
if (rname == "Direct3D9 Rendering Subsystem")
{
foundit = true;
break;
}
}

if (!foundit)
return; //we didn't find it... Raise exception?

////RenderSystem rs = root.GetRenderSystemByName("Direct3D9 Rendering Subsystem");
////// or use "OpenGL Rendering Subsystem"
////root.RenderSystem = rs;

//we found it, we might as well use it!
root.RenderSystem.SetConfigOption("Full Screen", "No");
root.RenderSystem.SetConfigOption("Video Mode", "640 x 480 @ 32-bit colour");

root.Initialise(false);
NameValuePairList misc = new NameValuePairList();
misc["externalWindowHandle"] = ogreWindowHandle.ToString();
//misc["externalWindowHandle"] = moisWindowHandle.ToString();
misc["vsync"] = "true";

//test kine from forums
//window = root.Initialise(true, "Application");
//^not working
window = root.CreateRenderWindow("Simple Mogre Form Window", 0, 0, false, misc); //*********
//RenderWindow panelMogre = root.CreateRenderWindow("panelMogre", 0, 0, false, misc);
//*********************************************
//*********************************************
//*********************************************


////ne znam da li ovo ispod treba:
//TextureManager.Singleton.DefaultNumMipmaps = 5;
////ali sam dodao iz drugog programa
ResourceGroupManager.Singleton.InitialiseAllResourceGroups();

//-----------------------------------------------------
// 4 Create the SceneManager
//
// ST_GENERIC = octree
// ST_EXTERIOR_CLOSE = simple terrain
// ST_EXTERIOR_FAR = nature terrain (depreciated)
// ST_EXTERIOR_REAL_FAR = paging landscape
// ST_INTERIOR = Quake3 BSP
//-----------------------------------------------------
sceneMgr = root.CreateSceneManager(SceneType.ST_GENERIC, "SceneMgr");
//sceneMgr.AmbientLight = new ColourValue(0.5f, 0.5f, 0.5f);
sceneMgr.AmbientLight = new ColourValue(1, 1, 1);
//-----------------------------------------------------
// 5 Create the camera
//-----------------------------------------------------
camera = sceneMgr.CreateCamera("SimpleCamera");

// da li ovo treba:
//cam.AutoAspectRatio = true;
camera.Position = new Mogre.Vector3(0f, 150f, 340f);
// Look back along -Z
//camera.LookAt(new Vector3(0f, 0f, -300f));
camera.LookAt(new Mogre.Vector3(0f,50f,0f));
camera.NearClipDistance = 5;
camera.FarClipDistance = 1500;

viewport = window.AddViewport(camera);
//viewport.BackgroundColour = new ColourValue(0.0f, 0.0f, 0.0f, 1.0f);
viewport.BackgroundColour = new ColourValue(0.25f, 0.25f, 0.25f, 1.0f);
//prvi
//Entity ent = sceneMgr.CreateEntity("ogre", "ogrehead.mesh");
//SceneNode node1 = sceneMgr.RootSceneNode.CreateChildSceneNode("ogreNode");
//node1.AttachObject(ent);
//node1.Position = new Vector3(0f, 22f, 0f);
//drugi
//SceneManager mgr = root.CreateSceneManager(SceneType.ST_GENERIC);
//Entity ent = mgr.CreateEntity("ninja", "ninja.mesh");
//mgr.RootSceneNode.CreateChildSceneNode().AttachObject(ent);

//treci
CreateGrid(26,26,10);
//cetvrti

//OVDE PROVERI DA LI JE OGRE GLAVA PUBLIC
Entity ent = sceneMgr.CreateEntity("ogre", "ogrehead.mesh");
nodePublic = sceneMgr.RootSceneNode.CreateChildSceneNode("ogreNode");
nodePublic.AttachObject(ent);
nodePublic.Position = new Mogre.Vector3(0f, 22f, 0f);


Light light = sceneMgr.CreateLight("Light");
light.Type = Light.LightTypes.LT_DIRECTIONAL;
//Since directional light should come from a far distance, we do not set its position
light.DiffuseColour = ColourValue.White;
light.SpecularColour = ColourValue.White;



}



public void CreateGrid(int numcols, int numrows, float unitsize)
{
ManualObject grid = sceneMgr.CreateManualObject("grid");

grid.Begin("BaseWhiteNoLighting", RenderOperation.OperationTypes.OT_LINE_LIST);

float width = (float)numcols * unitsize;
float depth = (float)numrows * unitsize;
Mogre.Vector3 center = new Mogre.Vector3(-width / 2.0f, 0, -depth / 2.0f);

for (int i = 0; i < numrows; ++i)
{
Mogre.Vector3 s, e;
s.x = 0.0f;
s.z = i * unitsize;
s.y = 0.0f;

e.x = width;
e.z = i * unitsize;
e.y = 0.0f;

grid.Position(s + center);
grid.Position(e + center);
}
grid.Position(new Mogre.Vector3(0.0f, 0.0f, numrows * unitsize) + center);
grid.Position(new Mogre.Vector3(width, 0.0f, numrows * unitsize) + center);

for (int i = 0; i < numcols; ++i)
{
Mogre.Vector3 s, e;
s.x = i * unitsize;
s.z = depth;
s.y = 0.0f;

e.x = i * unitsize;
e.z = 0.0f;
e.y = 0.0f;

grid.Position(s + center);
grid.Position(e + center);
}
grid.Position(new Mogre.Vector3(numcols * unitsize, 0.0f, 0.0f) + center);
grid.Position(new Mogre.Vector3(numcols * unitsize, 0.0f, depth) + center);
grid.End();

sceneMgr.RootSceneNode.AttachObject(grid);

}

public void Paint()
{
//root.RenderOneFrame();
//promenio u:
root.StartRendering();

}

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



Tutorial.cs:

using Mogre;
using Mogre.TutorialFramework;
using System;
using System.Windows.Forms;





namespace Tutorial //ako ostavim ovako namespace Mogre.Tutorials onda ne radi
{
class Tutorial : BaseApplication
{
public static void Main()
{
// new Tutorial().Go();

//OgreForm form = new OgreForm();


Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new OgreForm());


//myGlobalClass.myGlobalFunction();



}

//protected override void CreateFrameListeners()
//{
// base.CreateFrameListeners();
// mRoot.FrameRenderingQueued += new FrameListener.FrameRenderingQueuedHandler(ProcessUnbufferedInput);
//}

//bool ProcessUnbufferedInput(FrameEvent evt)
//{
// return true;
//}
}
}


EDIT2: I have been comparing the upper solution with the one created by following basic tutorial 4. I changed the namespace names from Tutorial back to the initial Mogre.Tutorials but it doesn't help. I also tried stuff like Mogre.TutorialFramework.BaseApplication.Base to get here:

But without succes.

{

edoardo

07-09-2011 12:01:54

Hi guys,

sorry to bother again on this topic, but I tried to follow your examples, discussions and example Framework - I got confused more than one time, because I think you used two different tutorials mixed (Mogre Wiki Tutorial Framework http://www.ogre3d.org/tikiwiki/Mogre+Wiki+Tutorial+Framework AND MogreSDK Smiley80's "mogre_basic_tutorials", found under "mogresdk\smiley80\mogre_basic_tutorials"), but I don't think these informations can solve my problem...


|*| In our project we create a mogreUserControl (like the mogrePanel in the examples, but we are forced by user requisites to use this type) inside a Windows Form, we have our EventManager that initializes MOIS input system with the MainWindow (Form) Handle, plus we have the MouseManager and the KeyboardManager (two separate singleton classes that refers to the EventManager) that are initialized passing them the already initialized MOIS input system;
the chain of operations ends up to be like yours, |1| we create a RenderWindow giving it the UserControl Handle, then |2| we initialize MOIS input system with the MainWindowHandle (the Form Handle).

|*| All works fine, except the fact that we got a problem of MOIS mouse coordinates: absolute values in the axis object of the MouseState (AbsX and AbsY) are referred to a "ghost" UserControl that doesn't start from TopLeft corner of the mogreUserControl, but from the TopLeft of the MainWindow (the Windows Form)!

Infact I get values incremented of the mogreUserControl LeftTop offset (in the example (75,50)), so I get a "shadow zone" in the bottom right corner, obviously exactly equal to the TopLeft offset, where the mouse coordinates remains at their maximum possible value, given the Mogre RenderWindow dimensions.

Is there a way to tell MOIS that the RenderWindow has an offset (because incapsulated in other Controls like Groupbox and Tabs) from the MainWindow (Form) LeftTop?
I tried during RenderWindow creation to use the "parentWindowHandle" instead of the "externalWindowHandle", giving to it the mogreUserControl handle and the leftTop offset, but it didn't solved the issue - even if I do a greater RenderWindow there's always the offset in the mouse coordinates, as MOIS "thinks" that Form (0,0) is also RenderWindow (0,0), but it's not...

I need the exact mouse coordinates to do the "picking to the polygon level" (http://www.ogre3d.org/tikiwiki/Raycasting+to+the+polygon+level+-+Mogre) - I already implemented it and it works, but it's shifted of the leftTop offset from the mouse pointer real position; i can correct that subtracting the leftTop amount from Abs mouse positions, but I still get the "shadow zone", i.e. cannot pick the far right, bottom zone.

Anyone have some clues about what I do wrong and/or how could I try to solve it? :idea: Please!!

Thank you so much in advance, really!

smiley80

07-09-2011 20:46:48

MOIS doesn't know about Mogre's RenderWindow, it gets its input from the window you've passed in the initialization.

i can correct that subtracting the leftTop amount from Abs mouse positions, but I still get the "shadow zone", i.e. cannot pick the far right, bottom zone.
When you initialize MOIS set the 'MouseState' size to the form size:
MOIS.MouseState_NativePtr state = this.inputMouse.MouseState;
state.width = myForm.Width;
state.height = myForm.Height;

edoardo

09-09-2011 09:42:10

Thank you very much for your quick and precise reply, smiley80!

Your solution worked partially for my case, because to convert the mouse coordinates in the clip space (that is normalized), the proportions must correspond to the rendering window otherwise they distort the Mouse position, that are correct near TopLeft & BottomDown, but wrong in other positions; i.e. once initialized the input system I must change the MOIS MouseState with the viewport (RenderWindow) real width & height, to mantain correct aspect ratio proportions.

This forces me (in my MouseMoved C# delegate) to do an overwrite of MOIS mouse absolute coordinates (because they are relative to the mainWindow), because otherwise they are shifted from TopLeft or "distorted" if I keep original mainWindow width & height:


// Here we receive from MOIS the MouseState, that we reverse in a very similar custom structure
_MouseState = args;

// "Cursor" is defined in System.Windows.Forms
Point point, correctPoint;
point = Cursor.Position; // C++: GetCursorPos(&point);
correctPoint = _mogreUserControl.PointToClient(point); // C++: ScreenToClient(mHwnd, &point);
_MouseState.AbsX = correctPoint.X;
_MouseState.AbsY = correctPoint.Y;


With the above code the mouse coordinates are correct to the pixel and relative to the UserControl; to achieve that I was forced to redo part of the MOIS task, because evidently he doesn't know my RenderWindow (the mogreUserControl) inside the mainWindowForm.

Do you think this is an acceptable overhead? How would you do it (are there other more efficient ways to achieve that in your opinion)?

Thank you again for the support!