Using another GameComponent to measure the elapsed times - c#

Okay, so I started developing a game. The first thing I wanted to set up was an extensive Debug viewer, which can ultimately show things like buttons pressed (only those that I want to listen to of course) and a graph containing information about frametime, a histogram of sorts. However, I wanted to do this the correct way. It occurred to me that I wanted to use the DrawableGameComponent class for the debugviewer, and draw the debug information there. However it seems that it can't measure the Update and Draw times correctly, as I start the update timer at the beginning of the update and end the update at the beginning of the draw. However, I shortly thereafter realized that first the main game is executed (update - draw - wait) and then are all the other components executed (update component 1, draw component 1), so they aren't intertwined. This means that I can't calculate the elapsedtime (for both Update, Draw and overhead). As we can read in this blog it's better to measure frametime as opposed to frames per seconds.
So enough with the back story and on to my main question: How do I measure the frametimes needed for both the Update, the Draw and the overhead from the main game in another DrawableGameComponent, or should I just use a class and update that in the game?
I hope that everything is clear, have a great day.

i found this http://gamedevwithoutacause.com/?p=876 which explaines exactly what you need.

If you can't measure the Update and Draw times correctly, using the update timer, can't you simply use DateTime.Now? You get it at the beginning of your Update, then every next cycle (after Update, Draw and overhead) you just subtract the DateTime.Now measured previously.

Related

Delay between on screen display and parallel port trigger

I am working on a research project which needs precise timing/synchronize between the on screen display and a trigger from parallel port in Unity.
What I am trying to do is to flash the screen to white while sending a trigger to the parellel port at the same time (desired difference is within 10ms).
I mesured the screen flash with a photodiode to determine the exact time it turns white, and synchronize it with the trigger from parellel port. I always observed a delay of 40 - 70ms between the trigger and the flash (the flash arrived slower) which is my main problem.
What I have tried so far:
- Update the flash and send the trigger in the same frame (bigger delay)
- Update the flash -> WaitForEndOfFrame() -> send trigger (lower delay but still big). Below is a sample code:
IEnumerator UpdateParallelPort()
{
while (true)
{
yield return new WaitForEndOfFrame();
if (flashed == FlashState.ToWhite)
{
parallelPort.SendTrigger();
}
}
}
I also tested if the flash take multiple frames to be rendered by using ReadPixels to determine at what frame the screen turn white, but it was not the case, it was in the same frame when I issued the command. So I guess the delay comes from the time the buffer being sent to screen ? If that is the case, is there anyway to determine/synchronize the exact timing, or to minimize it ?
This is my first post in Stackoverflow, hope that I explained it clear enough. Thank you in advance for your help!
which needs precise timing
I have bad news, completely forget it.
Unity is a game engine through-and-through.
The whole entire raison d'etre, the most fundamental aspects of it, is that it lets you render mesh of dinosaurs etc, with "total compromise" of granular time, and reasonable overall perceptive time.
Unfortunately, you literally could not choose a worse milieu for the project! Sorry! :O

How do I add a new image to the window of an already running game in XNA C# using an if statement in the Update method?

I am pretty sure something like this has been asked before, but I haven't been able to find it. Anyway, I am making a simple game animation with two moving objects (halloween themed). The objects bounce off the walls when they hit them, but I also need an image to be displayed when the two objects hit eachother. I have tried multiple ways, but none of them work. They either have no effect or raise an error. Anyway, here is the last thing I tried:
public PumpkinCheckCollisionPumpkin(GameTime gameTime)
{
if (pumpkin1.BoundingBox.Intersects(pumpkin2.BoundingBox))
{
pumpkinCollide = True;
Draw(gameTime);
}
I then tried passing the that bool (which I set to false earlier) to the draw section, but it did not work. The above method is called within the Update method.
I tried having the draw method invoked in the Update (GameTime gameTime) part, but that didn't work either. How do I trigger another image to be displayed in addition to what is already is displayed when my two objects collide? (also, that public method was originally private but made it public so another tactic I tried might work(didn't work)).
The answer is pretty simple, never directly call the Draw function.
In this case, I would set a class level state variable that holds the fact that a collision graphic should be drawn on the next draw call, which can then happen.
You erase every time you draw anyways, so even if the call did work correctly, the next Draw call (which will happen really soon) would erase it. For the same reason, don't unset the flag after the Draw call happens, because it will get erased faster than your players can see it. You need to keep it on the screen for some time.
You could do this by setting a variable that holds the time when the flag was set, then checking it against the current time until enough "visible" time has passed. This would then clear the "show collision" flag, and the graphic would no longer draw.
Just let the framework handle the timing of that call, and let the state you set drive what is drawn.

WPF / C#: async load/buffer next movie clip

I need a main 'home' video (full screen HD) running in a loop, and then at some point (say the user presses a key) another short movie plays (one of twelve selected at random), and then back to the home movie loop.
I'm using the mediaElement in WPF from my C# code - Is there a way to load the next movie into memory so that it's ready to play instantly? It currently takes about a second or so...
(I'm actually using two media elements with the triggered movie on top - I was doing a cross fade but have taken that out now until I can buffer the next clip. Not sure if this is the best way of doing this, any ideas? Many Thanks.
I figured out a way in case anyone is interested.
You can just specify a bunch of mediaElements on top of each other (can have different z index but not essential). Then did
video.Opacity = 0.0;
video.Play();
video.Pause();
for all of them, then when you want to play one you just set the opacity to 1 and play it and it'll play instantly.
Don't know if that's the best way, but works well. Now going to implement a cross fade to finish up. Happy days.

I want to force a render, but only draw as fast as possible (InvalidateVisual / CompositionTarget.Rendering)

I'm working on a real-time WPF/Silverlight (and soon WP7) visualization component and I'm looking for the best solution to force a redraw of the entire component in a Game-loop style. Redraw should be on-demand, but I don't want to back up the message pump with re-draw calls. Most of the drawing in my component is done using non-WPF primitives (e.g. Bitmap Interop, Direct2D) so my code does not use InvalidateVisual, and as a result, currently looks like this
// Pseudocode, doesnt compile, just to convey the meaning
public void InvalidateElement()
{
if (CurrentlyDrawing)
return;
Dispatcher.BeginInvoke(() =>
{
CurrentlyDrawing = true;
DoDrawInternal();
CurrentlyDrawing = false;
}
}
Ok so this is great. If I call InvalidateElement lots of times I get good responsiveness. However, what I want to do is ensure I can push data to my visualization component as fast as possible but only draw when the component is able to draw, and not keep drawing to catch up with the data once the input stream completes.
No I can't override OnRender, I'm using non-WPF drawing inside WPF ;-)
Basically what I want is something like the old Invalidate() / OnPaint in WindowsForms, or better yet, a game loop in DirectX.
At the moment I get the situation where if I have an external thread that pushes data to the visualization component at a high rate then if I Stop pushing data I get another 20 seconds worth of refreshes to get through before the component stops drawing. I want to stop drawing as soon as data has gone in.
Another idea I had was to handle CompositionTarget.Rendering in the visualization component then implement some sort of rudimentary Queue to push data to and the Rendering event consumes this data as fast as it can.
In Summary
Given a WPF visualization component, V, and a datasource which pushes it data every 1ms, D, how can I ensure that no matter the datarate of D, V draws data at 30FPS (or whatever it can do) and updates itself in chunks, sort of how a game render loop does in DirectX?
When the data stops, V should redraw everything it has up to now in one go. When the data is too fast, V draws larger chunks at a time to compensate.
If you need more information I'd be happy to share it. Right now I've just posted a synopsis to gauge if there are any quick fixes but a fuller Q with code examples can be provided on request.
Best regards,
You might want to consider rendering on the CompositionTarget.Rendering event and throttling on the invalidated state.
Silverlight game loop example (F#):
/// Run game
let runGame () =
let state = gameState.GetEnumerator()
let rate = TimeSpan.FromSeconds(1.0/50.0)
let lastUpdate = ref DateTime.Now
let residual = ref (TimeSpan())
CompositionTarget.Rendering.Add (fun x ->
let now = DateTime.Now
residual := !residual + (now - !lastUpdate)
while !residual > rate do
state.MoveNext() |> ignore
residual := !residual - rate
lastUpdate := now
)
Play the game: http://trelford.com/blog/post/LightCycles.aspx
Read the source: https://bitbucket.org/ptrelford/lightcycles
You can listen to the CompositionTarget.Rendering event, which is triggered right before WPF renders the UI, and do your drawing in there.
Another tidbit.. InvalidateVisuals() is nothing like Form.Invalidate(), as it also causes re-layout which is expensive. If you want something like Form.Invalidate(), then create a DrawingGroup (or bitmap image) "backingStore", place it in the DrawingContext during OnRender(), and then update it whenever you want. WPF will automatically update and repaint the UI.
Have you thought of using a dispatch timer running at 30FPS, then take a snapshot of the current data and rendering it at each timer tick? If you want to avoid redrawing if nothing has changed, you can simply keep timestamps for LastChanged and LastRendered, only performing an actual redraw if LastChanged > LastRendered. Basically updating the data and rendering the data are decoupled from one-another; the main trick is making sure you can somehow get a coherent snapshot of the data when the rendering thread wants to render it (i.e. you'll need some sort of locking.)
I was recently working with a project that required a game loop like style. Although my example is purely in F#, you can figure it out how you can do that way in C# too, may be use some interop code to initialize the timer and hooking up events as given in this below link,
http://dl.dropbox.com/u/23500975/Demos/loopstate.zip
The sample doesn't show how to redraw, it just updates the underlying stock data for every 500ms, It should pretty much work for any kind of drawing mechanisms with WPF. The core idea is to use composable events, in F# an event is a first-class citizen + an IObservable (reactive extensions for C#), so we can easily compose functions that in-turn return a set of events or a single event. There is a function Observable.await, which takes in an Observable and also has a state to return.
eventSource
|> Observable.await(fun (t:State.t) e ->
// return the modified state back on every check or in the end
match e with
// start button click
| Choice1Of3(_) ->
{t with start=true}
// stop button click
| Choice2Of3(_) ->
{t with start=false}
// timer tick event,
| Choice3Of3(_) ->
if t.start = true then
handleStockUpdate(t)
else t
) (state)
I just used some of FP terms here, but it should work just fine with normal C# (OO) way of doing things here.
Hope this helps!
-Fahad
I'm not sure why you would use WPF for your front-end if you're drawing using non-WPF elements and require the Invalidate() method that was provided by WinForms? Can't you just switch the UI to use WinForms?

Silverlight - Is it possible to create UI elements on a background thread?

I'm building a line chart control in Silverlight using PolyLineSegment and points. It works just as expected, but the application freezes for a long time when there's too much data that needs to be visualized (too many points). I can't move my code on a separate thread for an obvious reason - it deals with UI elements directly, so when I try to call them from a separate thread it results in exception (even if UI elements are not yet rendered).
Is there any way to create UI elements dynamically on a background thread and then pass them to the UI thread to be rendered? And if not, what would be the possible solution? I'm thinking of creating an Bitmap image instead of actual controls, but there won't be much interactivity in this case.
It sounds like you need to get a faster way of rendering your points. If you have 800k samples and only say, 800 pixels to display them in you're wasting 1000 points per pixel of calculations if you just load it into a PolyLineSegment.
I would revisit 'interpolating' the points (this is really coalescing for your large dataset). You want to make sure you capture the dynamic range of the function in each pixel correctly:
Figure out how many pixels wide the graph should be
Determine how many points per pixel in the X direction
For each chunk of points:
Build a histogram of the points
Draw a vertical line from max->min on your graph at the X where these points will map to. This captures the full range represented in the chunk.
If your points/pixel gets close to 1 you'll want to switch to the easy rendering to give better visual results as well.
For displaying a waveform (in your case PCM audio data) with "millions of points" you would be better off writing directly to a WritableBitmap. You then have only one render object.
You have already said there is not much processing in your calculations. Trying to use individual UIElements is way too big an overhead (IMHO). Point display is trivial to a bitmap and there are plenty of line drawing algorithms out there, optimised for speed, to do any line segments.
You can plot your points on a background thread and them update an image's ImageSource at the end of the processing to display it.
You certainly can do your compute work on background thread(s) and pass the finished results up to the UI tread with
Deployment.Current.Dispatcher.BeginInvoke
which is discussed here

Categories

Resources