Direct video buffer access - c#

when I comes to rendering things on screen using video card, only three options are available, if I understand correctly. These are
DirectX (or XNA)
OpenGL
Windows Driver Kit and creating minimal implementation of graphics driver
I have very little experience with DirectX or OpenGL, but from what I know you have to write a pixel shader program that tells rendering pipeline what to do with each pixel. These shaders are programmed in HLSL. But as far as I know, neither DirectX, nor OpenGL is able to return a pointer to a memory that I could write some byte[] buffer to from my C# program and get it rendered. Or am I mistaken here?
WDK might be a better choice, because it would be possible to implement absolutely minimal implementation of graphics driver that does nothing but returns pointer to a memory where I could write RGB data. So at one hand I could get rid of all the abstraction DirectX or OpenGL provides (and which I don't need), but at the other complexity of driver development is not exactly a time-saver.
Also, from what I have found while searching more information on this, in the old days of DOS there was an address 0B00 or similar that allowed developers to draw directly onto screen buffer. It's gone of course and no longer usable I guess, but I have read for compatibility reasons this memory spaces are still reserved. Is it possible to utilize this somehow?
What is the easiest way to get access to video memory from C# so I can write directly onto screen? Does DirectX or OpenGL provide such functionality, that would enable me to directly copy and array of bytes somewhere and get it rendered?

By using OpenGL's or Direct3D's built-in texture rendering capabilities, you can copy the pixel data from client side memory to server side memory and then have it render the texture on screen.
Note: With client side memory I mean the memory accessible from the program (on the CPU and in the RAM) and with server side memory I mean the memory on the graphics card. This has nothing to do with networking

Related

D3DImage: display bitmap from byte array

I have raw bitmap data (pixel colors, 32 bit) in an array.
Is there a simple way to display such a "sprite" on a D3DImage?
Preferably without use of thirdparty libs (such as SharpDX).
Background:
I have raw bitmap frames coming from unmanaged DLL and I need to display them with high framerate/low CPU usage in WPF. So far I've tried WriteableBitmap and InteropBitmap, but they are too slow (I get ~110 fps on maximized window (1680x1050 display), Core i5; and this is just a simple test with filling the memory. I believe that modern computers should do this much faster without using 100% CPU core time).
I'm also looking at VideoRendererElement (Displaying live video from a raw uncompressed byte source in C#: WPF vs. Win forms), but this is a bit overcomplicated (involves unmanaged dlls, regsvr32 registration, etc).
As I see from D3DImage samples, it achieves good framerates without stressing the CPU. I wonder if it is possible to use it for bitmap display.
UPD:
I've found this: http://www.codeproject.com/Articles/113991/Using-Direct2D-with-WPF
Which is basically what I was looking for. I've plugged it into my project, and it is on par with InteropBitmap, even a little bit slower. Looks like memory performance is a bottleneck in my case. In both cases most time is spent on copying bitmap (I use unmanaged memcpy).

Make entire screen monochrome and other full screen effects

Does anyone know how to apply effects to the entire screen, in c# or any programming language.
I'm mostly interested in making the screen monochrome (specifically green-white instead of black white).
I know a cross-graphic card solution is possible because I found a program that can do it:
http://www.freedomscientific.com/products/lv/magic-bl-product-page.asp
Anyone knows how to accomplish something this or where to look?
Thanks !!
There is no easy Windows API to modify the entire screen contents. But this could be done at the device driver level.
Otherwise you have to resort to some Windows API tricks: place a "fake" window over the entire desktop, in a loop: grab the entire screen contents without grabbing fake window contents, do your processing to get the monochrome effect, then display that on the fake window. Yes, it's hacky and slow, but possible. Even more hacky, when you get mouse clicks to "go through" the fake window (lots of SetWindowsRgn calls).
So cross-platform here means using GDI, though some older DirectDraw APIs might work, in that case, you have a much easier time with hardware overlays (and better performance). Though I'm not sure how many cards actually support hardware overlays, and if newer versions of windows support the older DirectDraw APIs.
One more possibility is if the video card has a C# or C++ or C API, then you can do whatever you want with the card without writing device driver code.
Then there's CUDA, but I haven't yet tried that out. I know it's for stream processing on nVidia boards, but I wonder if it could get you an easy backdoor into the video display stuff.
To help people in the future who are interested in this:
This is possible with the Magnification API's color effect method. This allows one to use a matrix that can be applied to the whole screen.
NegativeScreen is an open source project that implements the feature you are describing in C#.
Unfortunately, this only works with affine transformations, as the API takes only an augmented matrices rather than a delegate or something.

video scaling using C#

I need to perform video scaling in my C++ app. I know I can use COM to communicate to C#, and I know C# can perform video scaling, so I am thinking of bridging the two worlds.
How can I, using C#, scale a video image which is in memory, and then get the video data after the image is scaled?
This question seems similar but how do I get the data after scaling instead of showing it to screen?
High Quality Image Scaling Library
C# (using GDI+ a.k.a. System.Drawing) can scale individual images, but it has no built-in way of scaling full videos (like MPEGs or AVIs).
Assuming that you actually only need to scale individual images (i.e. not full videos), then you would be better off doing this from C++ (StretchBlt would be the main API method that you would use for this.

Is it smart building an OpenGL C# application to replace GDI

I have developed a quite large application using MFC. Naturaly, I used GDI for drawing, CCmdTarget for event routing, and the document-view architecture.
It was a convenient development path.
Now, the client is interested in converting this application to .Net.
I would prefer (and they too) writing the new product in C#.
The application displays and interacts with thousands of graphic objects, so
I figured going with GDI+, although seems natuaral, can cause performance issues,
So I am thinking of using OpenGL, specifically - OpenTK - as the graphics library (it's 2D).
I know that OpenGL works differently that these Windows APIs, which rely on Invalidation of portion of the screen. OpenGL has a rendering loop which constantly draws to the screen.
My question is:
Is this an acceptable way to go, thinking of:
performance - will the users need special graphics cards (hardware?). It is graphics intensive, but it's not a high-end game
printing and print preview - are these things complex to achienve?
multiple selection and context menus
Is this library goes well inside windows forms?
I don't think so. Use WPF if you can or DirectX if you can't.
I know it might not be fair but if I'm programming on .NET (microsoft) on windows (microsoft) I'd rather use DirectX ... which is also from microsoft.
As a side note: don't reinvent the wheel. Recoding user controls in open-gl can be very time consuming, if you do make sure you have a good reason.
In my experience developing CAD-like software, the benefits of OpenGL and DirectX are fast depth testing, smooth rotation and panning, lighting and powerful texture capabilities. Obviously there are other benefits but, despite what most tutorials would lead you to believe, implementing a rendering system using either of these APIs is a significant undertaking and should not be taken lightly.
Specifically:
If it is a 2D app and you already have it implemented in GDI then switching to GDI+ will be much easier. Additionally, on modern hardware, 2D GDI or GDI+ can be about as fast as 2D OpenGL or DirectX. And ultimately, the end-user probably won't notice the difference, especially with double buffered support in GDI+.
You do not need (and probably don't want) a continuous rendering loop for your app. In OpenGL and DirectX you can explicitly invalidate the window when your scene changes.
If you go with OpenGL or DirectX you will need to consider putting your objects into display lists or vertex arrays (buffers) for fast drawing. This is not difficult but managing objects in this way adds complexity to the system and will most likely significantly change the architecture of your rendering system.
Printing in either OpenGL or DirectX can also be tedious. On the one hand you can render to a bitmap and print that out. However, for high quality images you may want vectorized images instead, which are difficult to produce with either of these rendering frameworks.
I would also stay away from writing GUIs in OpenGL or DirectX...unless you're really looking for a challenge ;~)
Finally, and this is just an annoyance from an install perspective, the Managed DirectX run-time library that must be installed on the user's machine is around 100 MB.
I have no experience with C#, but I have once built a layer system for a drawing program that used openGL for rendering.
To make this layer I asked openGL for the current framebuffer and converted it to an image to use as a texture under the current canvas. So I guess from there its pretty easy to go to printing and print preview.
Direct X and Open GL much faster than GDI+.
You can also use an TAO framework as an alternative to OpenTK.

Rendering graphics in C#

Is there another way to render graphics in C# beyond GDI+ and XNA?
(For the development of a tile map editor.)
SDL.NET is the solution I've come to love. If you need 3D on top of it, you can use Tao.OpenGL to render inside it. It's fast, industry standard (SDL, that is), and cross-platform.
Yes, I have written a Windows Forms control that wraps DirectX 9.0 and provides direct pixel level manipulation of the video surface.
I actually wrote another post on Stack Overflow asking if there are other better approaches: Unsafe C# and pointers for 2D rendering, good or bad?
While it is relatively high performance, it requires the unsafe compiler option as it uses pointers to access the memory efficiently. Hence the reason for this earlier post.
This is a high level of the required steps:
Download the DirectX SDK.
Create a new C# Windows Forms project and reference the installed
Microsoft DirectX assembly.
Initialize a new DirectX Device object with Presentation Parameters
(windowed, back buffering, etc.) you require.
Create the Device, taking care to record the surface "Pitch" and
current display mode (bits per pixel).
When you need to display something, Lock the backbuffer
surface and store the returned pointer to the start of surface
memory.
Use pointer arithmetic, calculate the actual pixel position in the
data based on the surface pitch,
bits per pixel and the actual x/y pixel coordinate.
In my case for simplicity I am sticking to 32 bpp, meaning setting a pixel is as simple as: *(surfacePointer + (y * pitch + x))=Color.FromARGB(255,0,0);
When finished drawing, Unlock the back buffer surface. Present the surface.
Repeat from step 5 as required.
Be aware that taking this approach you need to be very careful about checking the current display mode (pitch and bits per pxiel) of the target surface. Also you will need to have a strategy in place to deal with window resizing or changes of screen format while your program is running.
Managed DirectX (Microsoft.DirectX namespace) for faster 3D graphics. It's a solid .NET wrapper over DirectX API, which comes with a bit of performance hit for creating .NET objects and marshalling. Unless you are writing a full featured modern 3D engine, it will work fine.
Window Presentation Foundation (WPF) (Windows.Media namespace) - best choice for 2D graphics. Also has limited 3D abilities. Aimed to replace Windows Forms with vector, hardware accelerated resolution-independent framework. Very convenient, supports several flavours of custom controls, resources, data binding, events and commands... also has a few WTFs. Speed is usually faster than GDI and slower than DirectX, and depends greatly on how you do things (seen something to work 60 times faster after rewriting in a sensible way). We had a success implementing 3 1280x1024 screens full of real-time indicators, graphs and plots on a single (and not the best) PC.
You could try looking into WPF, using Visual Studio and/or Expression Blend. I'm not sure how sophisticated you're trying to get, but it should be able to handle a simple editor. Check out this MSDN Article for more info.
You might look into the Cairo graphics library. The Mono project has bindings for C#.
Cairo is an option. I'm currently rewriting my mapping software using both GDI+ and Cairo. It has a tile map generator, among other features.

Categories