I'm currently writing a simple game. My graphics code runs once per frame (approximately 30 times per second), and writes RGB data to an array with 640 * 480 = 307200 entries.
I have created a Win32 window with a client area exactly 640 x 480 pixels in size. What's the fastest way to get my RGB data displayed within the otherwise-empty window?
The window will need to be updated every frame, so I need to avoid flickering. Should I use GDI for this? Or is there a faster approach using a different library - say, DirectDraw?
Edit:
Thanks for all the replies. Firstly, let me rule out Direct2D as an option - I need to support Windows XP. Secondly, I have a background in 3D so the method suggested by Yann Ramin and Ben Voigtto - use Direct3D/OpenGL and a single textured quad - is how I've always done this in the past.
However, I was interested to find out whether a 2D API would be a better solution. Since there has been no definite answer, I threw together a test program. The code simply displays a framebuffer on the screen repeatedly, as fast as possible.
I've posted my results as part of this follow-up question.
The best you can do using GDI is use SetDIBitsToDevice
to directly copy the RGB data from your array to the window. Of course, DirectX is the way to go if you need to completely eliminate flickering.
GDI is absolutely not the way to go.
The best cross-windows-version way is to use Direct3D, and simply update the texture on a single full screen quad.
Direct2D is a new API (Win Vista with Service pack and above) which is the preferred mechanism if you do not need to support XP. Direct2d handles fonts and other system level tasks in an accelerated way.
Use DirectDraw. I had a full screen Game of Life which was bottle-necked on pixel drawing when I used GDI and after I switched to DirectDraw I started to pump out 60 fps easily.
The GDI function SetDIBitsToDevice
will work fine.
Texturing a quad as suggested by theatrus will work as well, except it doesn't have to be full-screen and OpenGL is by far the most portable option, to make this happen, see glTexSubImage2D
A much more direct way is glDrawPixels
Ideally, though, your graphics code would use GPU-accelerated rendering directly into GPU memory, then you wouldn't need to worry about moving the bits from system memory into the GPU.