0

I am making 3D simulations with C# XNA, I use image\text files to load data.

I want to provide user the option to select a file which then my simulation will load and use. It's not possible with C# XNA.

I was able to embed the 3D XNA App in a WinForm using this tutorial, which worked for me but the problem is after that interaction based on keyboard is not smooth at all. It jut does not respond like a game any more.

How can I achieve file browsing and other things like buttons and and all with in a game?

I could have a logic to monitor the user input and use it to provide functionality like file browsing with in the game but that is too much trouble. Is there an easy was of achieving this. If not with XNA then may be some other way like DirectX

casperOne
  • 73,706
  • 19
  • 184
  • 253
Moon
  • 19,518
  • 56
  • 138
  • 200
  • Without seeing what you are doing is it possible this is an issue where you need to double buffer the winform? – Maynza Jul 05 '11 at 12:27
  • Which input method do you use? The Windows Forms Mouse and Keyboard events, or the XNA Input handling? I guess because of the tutorial you try to use the WinForms events. While it is possible to make it smooth. You can also use the input handling of XNA. Maybe you can provide more code, for your actual input handling. – dowhilefor Jul 05 '11 at 11:19

1 Answers1

2

In regular XNA the Game class calls your Draw and Update functions regularly (usually at 60 frames per second).

The XNA WinForms samples work slightly differently. There is no update/draw loop. Instead all you get is a Draw function. And that is only called when the control needs redrawing. This means that:

  1. You're not given a chance to regularly call Keyboard.GetState(), if that is how you are doing keyboard input.

  2. Even if you are using event-driven (non-XNA) input, your window won't be redrawn regularly so you might not actually see the results of your input until the XNA control is eventually redrawn much later.

Fortunately there is a way to force the control to redraw rapidly. Take a look at the second of those WinForms samples. You will find it is animating (in other words: it is updating frequently). How does it do it? Take a look at this code from ModelViewerControl.cs:

protected override void Initialize()
{
    // Start the animation timer.
    timer = Stopwatch.StartNew();

    // Hook the idle event to constantly redraw our animation.
    Application.Idle += delegate { Invalidate(); };
}

It uses a Stopwatch to track how much time has elapsed (because there's no Game class to do it for you). And it invalidates on the Application.Idle event - in other words, whenever it's not busy processing something, it asks to be redrawn.

(Of course, this is already explained in the documentation for that first WinForms sample. At the bottom, under "Animation".)

Alternative bonus answer: There is nothing stopping you from making use of OpenFileDialog from WinForms within a regular XNA game. Just add a reference to System.Windows.Forms, create an instance of the object, set the appropriate properties on it, and call ShowDialog().

Community
  • 1
  • 1
Andrew Russell
  • 26,924
  • 7
  • 58
  • 104
  • am i Stupid or what.. "Alternative bonus answer" why am i not doing that.. lols thanks a lot – Moon Jul 05 '11 at 14:31
  • this means i can also add Menu Strip etcetera – Moon Jul 05 '11 at 14:33
  • I'd take care with anything that requires you to extract a `Form` object from the XNA `Game`. The file dialogs don't, but I imagine adding menu strips, etc, does. – Andrew Russell Jul 06 '11 at 03:08
  • i am sorry, i don't get your point, may be its because English is not my first language.. sorry. Could you rephrase your last comment – Moon Jul 06 '11 at 19:54
  • To add a `MenuStrip` you generally set `Form.MainMenuStrip`. But getting a `Form` object from an XNA window is something you generally shouldn't do (even though you can). – Andrew Russell Jul 07 '11 at 04:38
  • why not, there's gotta be a reason – Moon Jul 07 '11 at 14:29
  • Because it's not part of the public XNA API - hence you *shouldn't* do it, and there are no guarantees as to whether or not it will always work. Additionally, doing so is bad software engineering practice. If you write the form code yourself (as per the XNA WinForms samples), then *you* are responsible for *all* the code that manages the form's state. The alternative - injecting things into XNA's own window code - you are simply *hoping* that what you inject always interacts correctly with the XNA code (which you can't see and which may change at any time in the future). – Andrew Russell Jul 07 '11 at 15:38
  • first of all. with C# future is not an issue because every new .NET FW that comes shows the finger to previous ones. and second can you please suggest what should i do.. i need to have 3D graphics for simulations with normal Form\Window UI controls. What should i do. For example let say i need to make Google Earth with a slight change that the Globe is an actual 3D object and that Sphere has real topographic height map. Please suggest. – Moon Jul 08 '11 at 04:30
  • I would suggest you use the XNA WinForms approach as demonstrated by the samples. If you are having problems with interaction latency, then diagnose and solve the problems (as per my answer), rather than giving up and doing something hacky. – Andrew Russell Jul 08 '11 at 06:13
  • i got it working... In XNA WinForms case there comes a ambiguity. When you try to check keyboard input it asks to specify from which one System.Forms.Input or Microsoft.Xna.Framework.Input, so you need to be explicit about it. I think this is also gonna happen for mouse as well. – Moon Jul 09 '11 at 06:20
  • Quick tip: you can do things like this: `using Mouse=Microsoft.Xna.Framework.Input.Mouse;`. – Andrew Russell Jul 10 '11 at 01:37
  • yes i did that already. thats why i said i need to be explicit about it. Now i just need to figure out whether loading XNA with in a Form is going to reduce its efficiency or not.. – Moon Jul 11 '11 at 01:53
  • When running in windowed mode, XNA runs on a WinForm (hence you can sneak out a `Form` object and start playing with it, but shouldn't, as we discussed). So there's nothing about using a `Form` that reduces efficiency. – Andrew Russell Jul 11 '11 at 03:00
  • well that's awesome than. Thanks a lot for all the help – Moon Jul 11 '11 at 15:01
  • This may be a little late, but did you get the mouse to work? I've got the keyboard to work moving a camera within my XNA/WinForm, but the mouse is not updating whatsoever. –  Aug 19 '13 at 08:21
  • I've answered your question [here](http://stackoverflow.com/a/18381796/165500). Basically you must set `Mouse.WindowHandle` correctly. – Andrew Russell Aug 22 '13 at 13:27