5
\$\begingroup\$

I've been looking for a way to efficiently manage the pixels on a screen, but so far all I've found is along the lines of SetPixel(), in Windows, and drawing a rectangle 1px by 1px, in OpenGL. Both of these methods seem to be too slow, since I'm looking for a way to constantly update the pixels on the screen at at least 30 FPS.

I need a way to do this, so I can make a non-polygon based graphics engine. I'm sure this is possible, since OpenGL and DirectX can do it, but I have a suspicion I'm going to need direct access to the video memory. I just need some direction to work in, since I'm not really sure where to start. This is primarily to see if I can do it, since it seems like a good challenge.

How do I efficiently manage the pixels, on the screen?

\$\endgroup\$

3 Answers 3

3
\$\begingroup\$

What you're running into is that the overhead of calling a Windows API function (SetPixel) for every pixel is huge. Assuming you don't want to use hardware graphics capabilities at all (entirely-software renderer), what you really need to do is compose the frame yourself in your own buffer in application memory - which is really fast since there's no API sitting between you and the memory - and then pass that buffer off to the operating system to display, once per frame.

There's probably no need for OpenGL/DirectX here, as you can likely do it fast enough with the Windows GDI, using SetDIBitsToDevice (which blits pixel data in memory directly to a GDI device context).

Another option is to use SDL, a library that handles all the details of shipping the frame buffer off to the operating system for you. It can use GDI or DirectX on Windows, and supports other platforms as well. It also helps sort out sound, input, etc. so you may find it well worth using.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks, I think SetDIBitsToDevice is what I'm looking for for now, although I'll look into SDL. I've heard people groan about it in the past for some reason or other (there's always something), but I'll see how it works out. \$\endgroup\$
    – Chaos
    Apr 20, 2012 at 1:10
1
\$\begingroup\$

What you want to do is have a dynamic texture in the graphics card that you update very frame, then draw to the screen. Something like:

  1. Declare the texture, using appropriate hints to tell the graphics driver it's dynamic (i.e. D3DUSAGE_DYNAMIC or D3D11_USAGE_DYNAMIC).
  2. Manipulate your pixels using a data buffer stored in RAM.
  3. When it's time to render, copy the buffer data from RAM into your texture.
  4. Draw a rectangle that covers the entire screen with your texture.

There are optimizations for this--I'm pretty sure there's a way to get around copying the ENTIRE texture every time you change a pixel--but this'll get you started. If you aren't doing anything else with graphics card, this will be fine for performance.

edit: Misunderstood the question. Obviously you'd need to copy data to and from the back buffer every frame, which is obviously inefficient. You might be able to get ~30fps out of it though.

\$\endgroup\$
4
  • \$\begingroup\$ Ah, my bad. I'l edit that part out. If the DID have it, why would it be STATIC over DYNAMIC? STATIC is for buffers that aren't written to very often. \$\endgroup\$ Apr 20, 2012 at 0:42
  • \$\begingroup\$ I meant "STREAM", not "STATIC". \$\endgroup\$ Apr 20, 2012 at 0:46
  • \$\begingroup\$ Thanks for the answer, this is pretty much what I want to do, but I'd personally rather do it without DirectX. I'd be interested in if it would be more efficient to check the pixels in the texture for differences, then copy the different ones, rather than copying the whole thing. \$\endgroup\$
    – Chaos
    Apr 20, 2012 at 1:20
  • \$\begingroup\$ I don't know what type of data you're working with, so it'd be up to your code to determine what part of the texture was modified. You can update parts of a texture using glTexSubImage2D. If you don't need to use OpenGL, the other poster's GDI solution sounds good. \$\endgroup\$ Apr 20, 2012 at 2:36
0
\$\begingroup\$

(I encourage others with more historical knowledge to correct anything that may be inaccurate herein.)

The sad truth is you are not going to get the acceleration you want (not under Windows, anyway) without modern, massively parallel GPU technology (in the form of pixel shaders specifically). The last high speed frame-buffer rendering under Microsoft OSes, prior to the advent of consumer-level GPUs, was seen with the demise of the VGA high performance modes such as Mode X and Mode 13h under DOS, modes which allowed the rapid rendering of all high-end PC games in the early-to-mid 90's (Doom, Magic Carpet, Dungeon Keeper, the C&C games and so on ad nauseum). It was the innovative memory-access models in these modes that benefited non-parallelised performance; the low resolutions and consequently comparatively low iteration also certainly contributed (as compared with today high resolutions and highly parallelised GPUs developed to deal with this). Because these modes are no longer supported under Windows, you simply won't get the same sort of performance in the same way as those old games did.

There are some high performance (and not exactly cheap) solutions such as Pixomatic, which may interest you. I am not sure how they are constructed, given that eg. Pixomatic runs under Windows, but I can guarantee you they are highly specialist solutions that are built using extensive knowledge of old school VGA rendering, and more generally the subtle ins and outs of x86 architecture.

In conclusion -- You really should be writing a special-purpose pixel shader, unless is there some very good reason not to do so.

\$\endgroup\$
2
  • \$\begingroup\$ Kind of missing the point IMO; the OP doesn't really want direct video memory access, just a fast way to get pixels to the device (faster than calling SetPixel for every one). \$\endgroup\$ Apr 20, 2012 at 0:31
  • \$\begingroup\$ Thanks for all the information, I'll keep that in mind. Nathan's right, though, I was just looking for a way to generate frames one way or another that I can change the pixels on efficiently. \$\endgroup\$
    – Chaos
    Apr 20, 2012 at 1:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .