I am a trying to learn C# .Net.
I had written small (hobby) Analog Clock application in VB sometime ago(edit: VB6, to be precise), and I thought I will rewrite in C#.NET, as part of my learning process.
In the VB application, I drew the hands of the clock in XOR Drawmode, so that I have to move the second hand, I just had to redraw it in the previous position and then draw the current position - I need not refresh the whole Form. All I did was
Me.DrawMode = vbNotXorPen
and then
Me.Line...
on a VB Form
In C# I don't find an equivalent Xor Pen Draw mode.
I found
ControlPaint.DrawReversibleLine
somewhere on the net, but I am not sure whether ControlPaint is meant for such purposes (and I don't understand based on what co-ordinate system ControlPaint is drawing)
Is there an equivalent to XOR drawing in C#.NET?
Or is there a better way to do what I am doing (with the best performance)
(Both VB and C# are my hobbies. So feel free to correct me wherever I am wrong)
.NET/GDI+ does not support XOR drawing. You'll have to workaround it by using p/invoke calls of several native functions.
See the link below for more information
http://www.vbaccelerator.com/home/net/code/libraries/Graphics/ZoomIn/article.asp
IMHO, until and unless you are targeting some really slow computers, you don't need to optimize performance by using XOR technique.
Since you'd be drawing the second hand only once in a second, a complete redraw of the clock would be much better. Also, the second hand will "look" good if drawn directly, and use smoothing mode set to Anti alias for a more cleaner look.
To optimize performance, you can create a bmp for clock every one minute and then draw the second hand upon it.
Related
Right now I'm copying window graphics from one window to another via BitBlt from WinApi. I wonder if there is any other fast / faster way to do the same in C#.
Keyword is performance here. If I should stay with WinApi I would hold HDC in memory for quick drawing and if .NET Framework has other possibilities I would probably hold Graphics objects. Right now I'm something to slow when I have to copy ~ 1920x1080 windows.
So how can I boost performance of gui copying in C# ?
I just want to know if I can get better than this. Explicit hardware acceleration (OpenGL, DirectX) is out of my interest here. I decided to stay pure .NET + WinApi.
// example to copy desktop to window
Graphics g = Graphics.FromHwnd(Handle);
IntPtr dc = g.GetHdc();
IntPtr dc0 = Windows.GetWindowDC(Windows.GetDesktopWindow());
Windows.BitBlt(dc, 0, 0, Width, Height, dc0, 0, 0, Windows.SRCCOPY);
// clean up of DCs and Graphics left out
Hans's questions:
How slow is it?
Too slow. Feels (very) stiff.
How fast does it need to be?
The software mustn't feel slow.
Why is it important?
User friendliness of software.
What does the hardware look like?
Any random PC.
Why can't you solve it with better hardware?
It's just software that runs on Windows machines. You won't goy and buy a new PC for a random software that runs slow on your old ?
Get a better video card!
The whole point of the GDI, whether you access it from native code or via .Net, is that it abstracts the details of the graphics subsystem. The downside being that the low level operations such as blitting are in the hands of the graphic driver writers. You can safely assume that these are as optimised as it's possible to get (after all, a video card manufacturer wants to make their card look the best).
The overhead of using the .Net wrappers instead of using the native calls directly pale into insignificance compared to the time spent doing the operation itself, so you're not going to gain much really.
Your code is doing a non-scaling, no blending copy which is possibly the fastest way to copy images.
Of course, you should be profiling the code to see what effect any changes you do to the code is having.
The question then is why are you copying such large images from one window to another? Do you control the contents of both windows?
Update
If you control both windows, why not draw to a single surface and then blit that to both windows? This should replace the often costly operation of reading data from the video card (i.e. blitting from one window to another) with two write operations. It's just a thought and might not work but you'd need timing data to see if it makes any difference.
I've implemented a custom control in C#/Winforms which does things like syntax highlighting & autocomplete. I'm using AutoScroll to manage scrolling and it works nicely.
Currently I have not optimized at all (sure optimization is important, but I'm doing that last; functionality is what I'm after first), I am rendering huge documents, and each keypress will re-parse the affected line to make sure syntax highlighting is consistent.
Right now in my big meaty paint method, I am painting every string, keyword, etc, even if it is outside of the clip region. But regardless of how big the document is & how many combinations of keywords/highlighted bits & pieces I have, it still runs bloody fast with not much memory & CPU overhead.
So my question - do the Graphics.Draw* methods do any kind of culling? Eg: If the AutoScrollPosition is way down the document & I Graphics.DrawString(insert some coordinates outside the draw region), is any actual work being done? Also note I'm running VS on Win 7 inside a VM, and it is still running fast. Not that it's an issue now, but it would be nice to keep in mind for later when it comes to the optimization phase. :D
Cheers,
Aaron
From personal experience writing games that use Graphics.Draw* methods, you will notice a speed increase if you perform your own bounds checking before calling the drawing methods.
Attempting to draw things offscreen is faster than drawing things onscreen, but its still noticeably slower than not drawing them at all.
I've taken on quite a daunting challenge for myself. In my XNA game, I want to implement Blargg's NTSC filter. This is a C library that transforms a bitmap to make it look like it was output on a CRT TV with the NTSC standard. It's quite accurate, really.
The first thing I tried, a while back, was to just use the C library itself by calling it as a dll. Here I had two problems, 1. I couldn't get some of the data to copy correctly so the image was messed up, but more importantly, 2. it was extremely slow. It required getting the XNA Texture2D bitmap data, passing it through the filter, and then setting the data again to the texture. The framerate was ruined, so I couldn't go down this route.
Now I'm trying to translate the filter into a pixel shader. The problem here (if you're adventurous to look at the code - I'm using the SNES one because it's simplest) is that it handles very large arrays, and relies on interesting pointer operations. I've done a lot of work rewriting the algorithm to work independently per pixel, as a pixel shader will require. But I don't know if this will ever work. I've come to you to see if finishing this is even possible.
There's precalculated array involved containing 1,048,576 integers. Is this alone beyond any limits for the pixel shader? It only needs to be set once, not once per frame.
Even if that's ok, I know that HLSL cannot index arrays by a variable. It has to unroll it into a million if statements to get the correct array element. Will this kill the performance and make it a fruitless endeavor again? There are multiple array accesses per pixel.
Is there any chance that my original plan to use the library as is could work? I just need it to be fast.
I've never written a shader before. Is there anything else I should be aware of?
edit: Addendum to #2. I just read somewhere that not only can hlsl not access arrays by variable, but even to unroll it, the index has to be calculable at compile time. Is this true, or does the "unrolling" solve this? If it's true I think I'm screwed. Any way around that? My algorithm is basically a glorified version of "the input pixel is this color, so look up my output pixel values in this giant array."
From my limited understanding of Shader languages, your problem can easily be solved by using texture instead of array.
Pregenerate it on CPU and then save as texture. 1024x1024 in your case.
Use standard texture access functions as if texture was the array. Posibly using nearest-neighbor to limit blendinding of individual pixels.
I dont think this is possible if you want speed.
hello i m using c# and suffering with delay problem. i want to change the technique for handling the graphics before this i want to know what will be the most efficient method for implementing heavy graphics,
i started making bmp files for each dynamic and static module and at the end i updates the whole GUI by pasting this bmps as layers after this i do double buffering but still not getting the required results i am thinking for using Direct-X ??
help required thanx in advance
Microsoft XNA is a managed environment for doing extensive graphics. It's mainly used for Game development.
IMHO. Worth a look in your case.
What exactly are you trying to draw? DirectX may be a good solution but it does depend on what you want to draw.
I've done some quite heavy updating of windows by doing the updates inside a thread. Once the thread has finished doing its processing then the window gets updated. This gives good results for my case (calculating and drawing a spectrogram that can be moved around). It would, however, depend on how heavy what you want to draw is.
I am writing a C# control that wraps DirectX 9 and provides a simplified interface to perform 2D pixel level drawing. .NET requires that I wrap this code in an unsafe code block and compile with the allow unsafe code option.
I'm locking the entire surface which then returns a pointer to the locked area of memory. I can then write pixel data directly using "simple" pointer arithmetic. I have performance tested this and found a substantial speed improvement over other "safe" methods I know of.
Is this the fastest way to manipulate individual pixels in a C# .NET application? Is there a better, safer way? If there was an equally fast approach that does not require pointer manipulation it would be my preference to use that.
(I know this is 2008 and we should all be using DirectX 3D, OpenGL, etc., however this control is to be used exclusively for 2D pixel rendering and simply does not require 3D rendering.)
Using unsafe pointers is the fastest way to do direct memory manipulation in C# (definitely faster than using the Marshal wrapper functions).
Just out of curiosity, what sort of 2D drawing operations are you trying to perform?
I ask because locking a DirectX surface to do pixel level manipulations will defeat most of the hardware acceleration benefits that you would hope to gain from using DirectX. Also, the DirectX device will fail to initialize when used over terminal services (remote desktop), so the control will be unusable in that scenario (this may not matter to you).
DirectX will be a big win when drawing large triangles and transforming images (texture mapped onto a quad), but it won't really perform that great with single pixel manipulation.
Staying in .NET land, one alternative is to keep around a Bitmap object to act as your surface, using LockBits and directly accessing the pixels through the unsafe pointer in the returned BitmapData object.
Yes, that is probably the fastest way.
A few years ago I had to compare two 1024x1024 images at the pixel level; the get-pixel methods took 2 minutes, and the unsafe scan took 0.01 seconds.
I have also used unsafe to speed up things of that nature. The performance improvements are dramatic, to say the least. The point here is that unsafe turns off a bunch of things that you might not need as long as you know what you're doing.
Also, check out DirectDraw. It is the 2D graphics component of DirectX. It is really fast.
I recently was tasked with creating a simple histogram control for one of our thin client apps (C#). The images that I was analyzing were about 1200x1200 and I had to go the same route. I could make the thing draw itself once with no problem, but the control needed to be re-sizable. I tried to avoid it, but I had to get at the raw memory itself.
I'm not saying it is impossible using the standard .NET classes, but I couldn't get it too work in the end.