Display an array of pixels

Started by
9 comments, last by Sparx82 9 years, 3 months ago

I receive an image over network (proprietary protocol) and then I'd like to display this in a window. Actually, it's not only one image, it's more or less a capture of another monitor, so there are (depending on the available bandwith and the resolution) up to 60 images per second.

I'd like to use DirectX for that because I have to resize this image according to the size of the window. So I receive an image with let's say 800x600 pixels. I do have all the RGB values then in an array. What's the best (aka fastest) way to display that using DirectX so the image will be resized according to the window (which is resizeable by the user)?

I'm programming C++ and use the plain WinAPI. I haven't done much using DirectX (and didn't really understand the stuff I did :-) so your help is greatly appreciated.

Thanks!

Advertisement

Using Direct3D? Create a texture using the source bits you have, and render a full-screen quad (or an appropriately-sized quad) with that texture bound to it.

Use DXGI to capture the screen then you can send updates of screen changes as change rectangles.

This is the most efficient way I know of to motion capture a windows desktop. See: https://msdn.microsoft.com/en-gb/library/windows/desktop/hh404487(v=vs.85).aspx

Edit: just thought I'd mention that I'm pointing this out as you seemed like youre sending raw images (correct me if I'm wrong), this will not scale and your connection will quickly be bogged down. Take a look at the link above for an optimal solution for both ends of the connection...

@Josh

Thanks, I'll start as you suggested, more questions will follow for sure :-)

@braindigitalis

Thanks as well but I only need the receiving side, the capture side is hardware and part of a remote desktop system. Normally the receiving side is hardware as well but we need a software client now. We're using different compression algorithms as well but for the beginning I'm happy when I can display the raw image stream.

You don't even need directX, honestly. The plain windows API has StretchDIBits and friends -- It's not super fast, but if all you're doing is rendering one image to scale, it still might be the faster solution since it will avoid all the extra overhead of setting up DirectX and shuffling all those frames one at a time over the PCIe bus, extra kernel-mode switches, etc.

3D APIs are fast, but they have overhead. Its not a given for tiny workloads that the speedup will outpace what it costs you in extra overhead.

throw table_exception("(? ???)? ? ???");

I tried that but it's too slow. I receive up to 60 images per second and that's a lot of calculation.

I would guess that something with that is fishy -- as I said, its not super fast, but I know for certain that it can keep up with 800x600x32bit color at more than 60fps, because I've done it before, circa 2004 on one core with about half the speed of any single core we have today. Unless they've routed GDI et al through DriectX under the hood these days and that's made some use-cases slower (and it may well be), I can't imagine why StretchDIBits would have trouble keeping up. That's my experience at least, you probably know better than I what to expect given the source/destination formats you're dealing with; I just think its suspect that StretchDIBits is the bottleneck from what I know.

throw table_exception("(? ???)? ? ???");

I would guess that something with that is fishy -- as I said, its not super fast, but I know for certain that it can keep up with 800x600x32bit color at more than 60fps, because I've done it before, circa 2004 on one core with about half the speed of any single core we have today. Unless they've routed GDI et al through DriectX under the hood these days and that's made some use-cases slower (and it may well be), I can't imagine why StretchDIBits would have trouble keeping up. That's my experience at least, you probably know better than I what to expect given the source/destination formats you're dealing with; I just think its suspect that StretchDIBits is the bottleneck from what I know.


_All_ rendering on Windows is routed through DirectX, period, without exception. They don't even make non-DirectX graphics drivers anymore.

The GDI functions used to have special drivers that would hand-optimize various calls, possibly using the dedicated 2D render unit on the graphics hardware (which don't exist on most modern hardware anymore).

Since those drivers don't exist for new hardware and aren't supported at all anyway by Windows Vista and up, most of the GDI routines are now just basic no-brain software implementations that only route through DirectX at the lowest levels (e.g. blit to a texture, render quad). The actual scaling and format manipulation is mostly all in software and the actual texture blitting is likely not even close to as fast as a naive hand-written version would be. GDI is dead (and unlike many other such claims that are a bit premature... no, GDI really is completely dead). Don't use it. If you need plain 2D rendering use Direct2D, otherwise use Direct3D. There are a bunch of libraries that provide simple 2D rendering and compositing and use the most appropriate hardware backend for a multiple platforms, like SDL2, SFML, Allegro, etc.

More information on GDI and its dead-ness since Vista
Benchmarks of GDI on Vista and up showing it's far slower now

There's plenty of other easily searchable articles online about this all too, should you care.

Sean Middleditch – Game Systems Engineer – Join my team!

Is it absolutely necessary to recieve and display the images at 60fps? At this rate it's likely that the network itself will become the most significant bottleneck (particularly if you're doing this over a WAN connection), and latency (as opposed to bandwidth) will prevent you ever achieving it. What are your typical worst-case ping times between two machines involved in this? That will give you a solid indication of the absolute best performance you're going to get from the network, and from there you can adjust the method you use to display the images at the recieving side.

Even if you're entirely on a good LAN, 60fps still seems overkill. For example, Microsoft's own RDP limits the frame rate to 30fps (https://support.microsoft.com/kb/2885213) and is perfectly usable.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

I stand corrected. Circa 2004 I would still have been using XP pro, so that must explain our different experiences.

throw table_exception("(? ???)? ? ???");

This topic is closed to new replies.

Advertisement