Slow drawing when using many controls in C# - c#

I've been trying to create a roll-playing game for a little over a year now, and I thought a good way to test it and flesh it out a bit would be to turn it into a Dungeons and Dragons variant. However, the inherent problem with using a DnD setup is that there's a lot to keep track of, to the point where it becomes impossible for a single person to do by themselves. As such, I thought of writing a C# program to help.
I ran into this problem when I tried using a series of PictureBox objects to represent the spaces on the map where characters can move. I wanted to use PictureBoxes because that would allow me to use images to represent terrain and characters occupying the given space. However, the map I am using is roughly 46 x 75 1-inch squares, totaling 3450 PictureBoxes. This, understandably, slows the application down so much that it actually freezes for minutes at a time while it redraws the map every so often.
I tried two solutions. First, I tried using a Panel object for its free scrolling capabilities in the hopes that the application wouldn't have to redraw the whole map, but rather only the subset of PictureBoxes visible at that time. This helped only a little, and not enough to make the application usable. Second, I looked online, including this forum, and found people having similar problems. However, the problems they were having were entirely unrelated to mine (aside from the whole slow redraw thing) and thus the solutions didn't really apply to me. I did see a few recurring lines that I tried:
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
I'm not really sure what they do, but they did help a bit. I am still seeing way too much lag, though.
I'm out of ideas at the moment. Is there a better control I could use or a different way of drawing? Thanks in advance for your help!

I would try to develop a solution that only renders the images that are visible on the screen at any given time. Images should only be rendered when you scroll them into focus.
This is a common technique since rendering UI is usually the slowest operation by far. I would bind a view model object to the visible objects, which means you only have to render a subset of the images instead of the entire screen.
Grids with endless scroll sometimes use this approach.

Related

How to prevent the rendering of unseen triangle in Unity3D?

In Unity3D the logic dictates that objects are not to be rendered unless in the field of view. This is obviously the way to go for optimization purposes. However, it still renders meshes that can not be seen by a player due to being occluded. I would like to solve this and was wondering if there was already a method to do so or if I had to do it myself.
Here's a picture to help illustrate my point.
So far my only real ideas are using the culling, but that still would be in a range not necessarily visible.
https://docs.unity3d.com/ScriptReference/Camera-layerCullDistances.html
I guess essentially what I need to know is how to do occlusion culling after a scene starts because the scene is generated, it's not premade.
For anyone who's interested, I asked the unity community
Answer by Bunny83 · 4 hours ago
No, that's not possible. At least not with the occlusion culling
system that Unity uses. The calculation which parts are visible from
which points is quite complicated and has to be precomputed in the
editor. So it won't work for procedurally generated levels.
You have to roll your own solution if you need something like that.
Just a few weeks (or month?) ago i implemented a VisPortals solution
similar to those used by Doom3 (basically how most ID Tech engines
work). It's more a prove of concept than a ready-to-use solution.
Usually i upload a webplayer demo onto my dropbox, however i just
realised that Dropbox finally prevented to directly view HTML pages
off my public folder. They now force a download of the page which
breaks everything. So if you want to try it, you have to download the
project.
Of course vis portals doesn't work in all situations. They are perfect
for closed environments which can be split nicely into seperate areas.
Of course this splitting into areas and the creation of the visportals
currently is done by hand. So you would need to automate this
yourself.
Be careful with static batching, it might break the system as each
area has to be seperate so it can be enabled / disabled seperately.

Is a single pass dropshadow pixel shader possible?

I've been working on a project, in WPF/C#, at work which uses quite a few animations. As a whole the project is going very well, and we've managed to make the animations efficient and impressive.
The problem is, we had to remove drop shadows to make that a reality. This has been met with a bit of resistance, as drop shadows on our title text generally look nicer. Now that we are getting close to the wrap-up stage I was asked to take another look at drop shadows and see if I can't make a workable solution. I tried the standard drop shadow effect, which is notoriously bad, and the Windows.Themes.x.DropShadowChrome effect which is more lightweight but still not great.
I am currently approaching the issue by trying to make a custom control which is using a template selector to basically remove the drop shadows during animation, and things are going well enough but I was curious about making my own pixel shader. Once upon a time I learned HLSL, and I have made a few shaders before but try as I might I cannot seem to make a single pass (a requirement of wpf) drop shadow.
I'm honestly not even sure such a shader is possible and I couldn't find a definitive yes or no online. Anyone have any insight to the possibility/method of doing something like this?

Rotate Windows form upside down

I have a C# application that has an existing WinForm that I now need to display upside down.
The application will be displayed on a touchscreen Windows 7 device. If two people are using the device, one person is viewing it right-side-up while another user will be simultaneously viewing it upside-down. I will need to have one control displayed right-side-up while another control is displayed upside-down, each duplicate forms. Both need to be functional. It is not necessary for the title bar and Windows close, maximize, and minimize to be rotated.
Is there a way to easily rotate this Form and all of its contents without having to rewrite it from scratch?
Unfortunately, rotating controls is not directly possible in WinForms.
At least, not if you want them to retain their functionality. It would be relatively simple to draw the control into a bitmap, rotate the bitmap, and then draw that back to the desired location on the form. But you would obviously lose the ability to interact with the controls. They would just be static representatives of their original selves.
But making functional upside-down controls just isn't going to happen. I mean, you could try to write a bunch of custom drawing code for owner-drawn controls, but you'll still run into a bunch of bugs, corner cases, and compatibility problems. The Win32 controls that WinForms is based on just don't support this. No big surprise, really, considering they were invented some 20–25 years before anyone thought of computer screens that you could carry around in your pocket and rotate in any direction. There is a good reason that UI technologies like WPF came out around the time that touch screens and tablets did.
There are some possibilities that can be explored when it comes to flipping the entire screen, but that's not going to help when you want different controls going different directions. (And I guess it betrays my vantage point as a desktop app guy when I say this, but that just sounds like an incredibly confusing UI.)
If you absolutely have to have this, someone else is going to have to give you another route to hack it, perhaps along the lines of Dhawalk's comment: hosting the WinForms control inside of a WPF app that does provide built-in support for rotated controls. I don't know enough about this to make any concrete suggestions down that path. From a few minutes of searching, it appears that WindowsFormsHost does not actually support rotation transforms, so this may be a non-starter anyway.

How to select, display and save regions of a graphic?

So here's the situation: I need to take a (user-specified) graphic, and allow the user to define and label regions within that graphic. For example, if you uploaded a picture of a face, you might want to define "right eye", "left eye", "nose" etc. Also, having defined the regions, if I select a previously defined region, it should be highlighted on the image somehow. These regions are (obviously) not necessarily rectangular, and they cannot overlap. And if you click within a defined region in the graphic, I would be able to identify which region was clicked on.
There are a couple ways I can think of for doing this, none of which are quite satisfactory. Another developer before me tried doing it with a transparent grid overlaid on the original graphic, fiddling with the background alpha/color for highlighting regions, but I think they rather kludged it. I could either get my hands really dirty trying to clean up their code, or try a completely new approach.
What would you suggest for maximum speed and user-friendliness?
Bounty added: for the best solution that will get me up and running in the minimum time.
The GraphicsPath class is made to do this. Keep a list of them along with the image. Draw the image first, then Graphics.DrawPath() to draw the regions on top of the image.
Hit testing is simple with GraphicsPath.IsVisible(). Iterate the list in reverse order so overlaps work.
Assuming you haven't decided yet on the technology you'll use, I'd suggest WPF; I find most graphics-related tasks easier with WPF (at least in version 4) and it's specifically geared for interactivity, so creating non-rectangular regions using mouse clicks and hit-testing clicks to select shapes would be pretty easy. Loading images is also easy.
However, if you haven't used WPF or Silverlight until now, there is some overhead in learning the basic concepts and APIs; so I'm afraid there's no real way I can recommend it as a maximum speed solution without knowing your (or whoever's will be working on it) competencies. That said, using MVVM and WPF would be definitely the maximum speed solution for me. Also the maximum user-friendliness since WPF enables quite interesting interaction models out-of-the-box, like multi-touch support (that's the trendy one that should be mentioned, right?) and easy non-standard layout and placement of controls.
You need polygons, saved as list of points. And you need hit testing for them. See the link:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/40ebadc1-6154-4c7c-9cb1-d608a426b29c

.NET C# drawing slowly

I have a problem drawing something quickly in .NET. I don't think that any thing in particular should take much time, but on every machine I've tried it on, I get serious issues. This is implemented in vs2008 .NET, using C# (with some stuff in C++, but nothing relevant to the drawing).
I have three screens, and the user should be able to toggle between them with no lag. On the first screen, there are four buttons, eight user controls consisting of two buttons and 6 labels each, a text field, and a dropdown box. I don't think of it as being that much.
On the second screen, I have four labels, six buttons, and two controls that have six buttons, one opengl drawing context, and about ten labels each.
On the third screen, I have one opengl context and 10 buttons.
Flipping from any screen to any screen takes literally about a second. For instance, if I flip from the second screen to the first, the entire application blanks out, showing the background screen, and then the first screen is drawn. Many times, a screen is drawn piecemeal, as if the machine were deliberately handcrafting delicate and delicious letters in a factory in Sweden and then shipping each one individually to my screen. I exaggerate, and I want to make that clear, because I don't think Swedes are as slow as this redraw.
The first and second screen are drawn in memory, and stored there, with just a '.Hide()' and '.Show()' to make them appear and disappear. Double buffering doesn't seem to matter. The third screen is drawn anew each time, and appears to take the same amount of time to draw as the first and second.
Any thoughts? What could be going on? How can I track it down?
Thanks!
Edit: I should add that any C++ processing and the like happens in its own thread. There is the occasional MethodInvoke to draw the results of the operation to the screen, but this problem happens without calling any functions, just by pressing buttons to go from one screen to the next.
In addition to the profiler that was mentioned, you might also turn off your OpenGL contexts. If you notice a speed-up, then you'll know it's your graphics stuff, and you can focus your optimisations accordingly.
Points awarded for Swedish humour.
How can I track it down?
dotTrace - http://www.jetbrains.com/profiler/
Are you doing any other processing during the "screen flip" event? other than just letting the form be redrawn? If you are processing something between flips (maybe your c++ addition?), and you are not multi-threading, you get that white out effect. The form is probably waiting for CPU time to redraw itself.
I have never used OpenGL in such a way myself, but you might want to look at the way in that the OpenGL contexts are flipped. When switching from one page to another you might be getting a device reset (in DirectX terms), which could be causing the delay.
If at all possible have a device draw to a back System.Drawing.Bitmap, and use that bitmap on the screens. Make your OpenGL code aware of the current page the user is on, and you might get the speed up you seek.
To test this before making huge changes, try removing the OpenGL displays on your form.
This is all a whim.

Categories

Resources