Guten Tag zusammen! (German: Good Day everyone!)
Please excuse my English, it is not my mother tongue. Since I have already found a lot of good answers to my questions here I would like now to ask you some.
In the last few days I have done a little research to the question "What is the best way to implement a game loop in Windows Forms?". And I have found a good explained solution form the SlimDX team, which it is based on the work of Tom Miller.
My Questions are:
First: We I use this solution for an game loop which is the best way to redraw the From after I have rendered a frame? A way I have often found is to call Invalidete(), but this does not look like a good idea to me. Wouldn't this add a message to the message queue and break the while-loop every frame?
Second: To my understanding this loop will consume an entire CPU-Thread (Core). Is there and good way to slow it down to a recommended frame rate that does not consume an entire CPU-Thread?
Third: Is GDI+ capable of render a simply 2D game?. When did Drawing becomes so complex that it is advisable to use a hardware accelerated drawing whit some DirectX or OpenGL wrappers?
A way I have often found is to call Invalidate(), but this does not look like a good idea to me. Wouldn't this add a message to the message queue and break the while-loop every frame?
Yes, that's a bad idea. You don't control the frequency at which the messages are delivered to your window, which means you shouldn't rely on it.
To my understanding this loop will consume an entire CPU-Thread (Core). Is there and good way to slow it down to a recommended frame rate that does not consume an entire CPU-Thread?
You can use the SpinWait structure (NOT Thread.SpinWait) to wait short amount of times. Base the waiting time on the duration of the curret frame and the desired framerate.
But usually the game loop taking an entire core isn't a problem. It may even be desired if you want to maximize your framerate.
Is GDI+ capable of render a simply 2D game?
Yes, although it'd be a really simple game. GDI is slow. I advise you to go with a hardware-accelerated solution right from the start, that way you won't have to rewrite everything if GDI proves to be a bottleneck.
Related
I've been working on a game in Visual C# (Not the best platform, I know), and, as would perhaps be expected, it has started to run rather slowly. Running some tests has shown that the main hold up is in drawing images. I've been told that Sprite Batching is a good fix for that.
Problem is, I can't find anything on sprite batching that isn't specific to XNA or OpenGL. I know little to nothing about the process, and I was hoping to get some information on whether such a thing can be implemented using Visual Studio's Visual C#, and (if so) where I can go to learn more about it. If not, are there any other useful methods of speeding the process up a bit? Thanks!
It basically comes down to batching together calls to save on state switches (textures, fill rate) and draw calls (sending a draw call 50,000 times isn't as efficient as sending a single draw call, surprisingly enough). You're going to have to check, when calling the equivalent of a SpriteBatch.Draw(...), the following:
An internal 'max size' of your batch
If the texture switches, flush your buffer (i.e. draw whatever you have)
If SpriteBatch.End(...) has been called (you're done; flush the buffer and draw)
If you're still having trouble, feel free to check out MonoGame's implementation.
Edit: found a great gamedev question about this.
I have a lighting system in my xna game that loops through each light, and adds these lights to a final light map, which contains all the lights.
The process to create these lights involves many functions that have to do with the graphics device, such as using effects / shaders and drawing to render targets, and using graphics.device.clear to clear the render target, etc
So my question is, would it be possible to multi thread each light? Or would this not be possible because there is only 1 graphics device, and only 1 thread can use it at a time? If it is possible, would it improve performance?
Basically no. The GraphicsDevice in XNA is single-threaded for rendering. You can send resources (textures, vertex buffers, etc) to the GPU from multiple threads. But you can only call Draw (and other rendering functions like Present) from your main thread.
I have heard of people having success doing rendering-type-things from multiple threads with the appropriate locking in place. But that seems like "bad voodoo". As the linked post says: "the XNA Framework documentation doesn’t make any promises here". Not to mention: even getting the locking right is tricky.
I'm not really sure about making multiple graphics devices - I've not tried it myself. I think that it is possible, but that you can't share resources between the devices - making it fairly useless. Probably not worth the effort.
As jalf mentioned in a comment on your question - once you get to the GPU everything is handled in parallel already. So this would only be useful if you are CPU limited due to hitting the batch limit (because almost everything that isn't your batches can be moved to another thread). And in that case there are many optimisations to consider first to reduce the number of batches - before trying a crazy scheme like this. (And you have measured your performance, right?)
It sounds like what you might be trying to do is render a fairly complicated scene to a render target in the background, and spreading the load across many frames. In that case - if performance requirements dictate it - you could perhaps render across multiple frames, on the main thread, scheduling it manually. Don't forget to set RenderTargetUsage.PreserveContents so it doesn't get cleared each time you put it on the graphics device.
We're going to do some experiments on perceptual thresholds and want to show an image for a very short time. I'm speaking about less then 10 ms (our screen supports 144 Hz, that is a new image every 6.94 ms).
But all our approaches until now failed. We tried it with C#: WinForms were much too slow, WPF was faster, but we were still able to see the image, and even showing a texture with XNA framework did not work for us.
Do you have any suggestions for us? We're allowed to use C++ too, but we prefer using C#, so if your suggestions works with C# we would really much appreciate.
I would highly recommend using the XNA Framework for this. Some might consider it overkill but the fact is it is first of all designed to handle high throughput of frames and secondly has a relatively small learning curve.
I'm not a game developer but started by reading an article, modifying a simple project and creating one from scratch.
This would probably be your best bet in terms of the technologies you mentioned in your question.
UPDATE: Regarding measuring the actual time an image is shown, XNA would again be your closest guess short of dealing with specialized hardware and resorting to low-level programming.
I'm writing an application for a touch table using WPF and C#. (And, I'm not terribly familiar with WPF. At all.) We suspect we're not getting the framerate we're "requesting" from the API so I'm trying to write my own FPS calculator. I'm aware of the math to calculate it based on the internal clock, I just don't know how to access a timer within the Windows/WPF API.
What library/commands do I need to get access to a timer?
Although you could use a DispatcherTimer (which marshalls its ticks onto the ui thread, causing relativity problems), or a System.Threading.Timer (which might throw an exception if you try to touch any UI controls), i'd recommend you just use the WPF profiling tools :)
I think you're looking for the StopWatch. Just initialize it and reset it with each start of your iteration. At the end of an iteration, do your calculation.
First of all, are you aware that Microsoft provides a free diagnostic tool that will tell you the frame rate at which WPF is updating the screen? I guess if you're not convinced you're getting the framerate you're asking for, then perhaps you might not trust it, but I've found it to be a reliable tool. It's called Perforator, and it's part of the WPF Performance Suite, which you can get by following the instructions here: http://msdn.microsoft.com/library/aa969767
That's probably simpler than writing your own.
Also, how exactly are you "requesting" a frame rate? What API are you using? Are you using the Timeline's DesiredFrameRate property? If so, this is more commonly used to reduce the frame rate than increase it. (The docs also talk about increasing the frame rate to avoid tearing, but that doesn't really make sense - tearing is caused by presenting frames out of sync with the monitor, and isn't an artifact of slow frame rates. In any case, on Vista or Windows 7, you won't get tearing with the DWM enabled.) It's only a hint, and WPF does not promise to match the suggested frame rate.
As for the measurement technique, there are a number of ways you could go. If you're just trying to work out whether the frame rate is in the right ballpark, you could just increment a counter once per frame (which you'd typically do in an event handler for CompositionTarget.Rendering), and set up a DispatcherTimer to fire once a second, and have it show the value in the UI, and then reset the counter. It'll be somewhat rough and ready as DispatcherTimer isn't totally accurate, but it'll show you whether you've got 15fps when you were expecting 30fps, for example.
If you're trying to get a more precise view (e.g., you want to try to work out whether frames are being rendered constantly, or if you seem to be getting lost frames from time to time), then that gets a bit more complex. But I'll wait to see if Perforator does the trick for you before making more suggestions.
You want to either wrap the win32 timing calls you'd normally call (such as QueryPerformanceCounter), by using p/Invoke, or use something in .NET that already wraps them.
You could use DateTime.Ticks, but it's probably not high enough resolution. The Stopwatch class uses QueryPerformanceCounter under the covers.
If you want something that's reusable on a lot of systems, rather than a simple diagnostic, be warned about processor related issues w/ QPC and Stopwatch. See this question: Can the .NET Stopwatch class be THIS terrible?
I develop a utility that behaves like "Adobe photoshop". user can draw rectangle,circle,... with mouse pointer and then move or resize it. for this functionality, I assume each shape is a object that stored in a generic collection in a container object. when user wants to change anything I recognise that where he clicked and in behind of scence I select the target object and so on...
this way have a problem when objects in screen is lot or user loads a picture with high resolution.
What's your opinion?
How can I solve it?
This makes sense because the larger the data set, the more RAM and CPU will be required to handle it.
While performance issues are important to solve, a lot of it may be perceieved performance so something like a threading issue - where you have one thread trying to process the information and you block the UI thread which makes it look like the system is freezing.
There is a lot of information on StackOverflow that you may want to look at
C# Performance Optimization
C# Performance Best Practices
C# Performance Multi threading
C# Performance Collections (Since you said you were using a collection)
Use a profiler such as dotTrace and find out which method is the one most called and the one that takes the most amount of time to process. Those are the ones you want to try to optimize. Other than that, you may have to go down to the GPU to try to speed things up.
About these kind of problem, think about parallel extensions :
http://msdn.microsoft.com/en-us/concurrency/default.aspx
The more cpu you have, the faster your program is running.
The thing is that in hi resolution the computer needs to use more the processor, then this occurs, remember that this also occurs in The Gimp, even in Adobe Photoshop.
Regards.
Look into using a performance analyzing tool (such as ANTS Profiler) to help you pinpoint exactly where the bottle necks are occurring. True graphical computations on a high res photo require alot of resources, but I would assume the logic you are using to manage and find your objects require some tuning up as well.
I high-resolution image takes up a lot of memory (more bits-per-pixel). As such, any operation that you do to it means more bits to manipulate.
Does your program utilise "layers"?
If not, then I'm guessing you are adding components directly to the image - which means each operation has to manipulate the bits. So if you aren't using layers, then you should definitely start. Layers will allow you to draw operations to the screen but only merge them into the base high-resolution image once - when you save!
What library from Windows are you using to open the image?
If you are using System.Drawing then you are actually using GDI+ as it is a wrapper on top of it. GDI+ is nice for a lot of things because it simplies tons of operations, however it isn't the fastest in the world. For example using the [Get|Set]Pixel methods are MUCH slower than working directly on the BitmapData. As there are tons of articles on speeding up operations on top of GDI+ I will not re-iterate them here.
I hope the information I've provided answer some of your questions causes new ones. Good luck!