What's the fastest way to repeatedly fill a window with RGB data from an array?
Asked Answered
R

4

6

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.

Revolver answered 8/11, 2010 at 0:47 Comment(0)
W
4

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.

Wickiup answered 8/11, 2010 at 1:1 Comment(2)
I don't think SetDIBits actually draws direct to the window, I think you need to use BitBlt afterward.Blimey
@Ben Voigt: Oops, I meant SetDIBitsToDevice.Wickiup
B
2

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.

Blimey answered 8/11, 2010 at 1:2 Comment(0)
S
0

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.

Salmanazar answered 8/11, 2010 at 0:57 Comment(1)
"GDI is absolutely not the way to go" - I'm interested to know why you say this. According to my results at stackoverflow.com/questions/4128441, GDI is the fastest approach - it's also the easiest to write.Revolver
N
0

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.

Nettie answered 8/11, 2010 at 1:4 Comment(4)
DirectDraw is deprecated. While the API is still there, its receiving no love.Salmanazar
Interesting - in my tests (stackoverflow.com/questions/4128441), DirectDraw comes out slower than GDI. Were you using a different approach to mine with one or both APIs?Revolver
please note I mentioned not bit bliting, but setpixel calls. I'm surprised to see 2K fps. you sure that the calls don't set short-circuited somehow?Nettie
Looking again, I think some of the calls may indeed be getting short-circuited...Revolver

© 2022 - 2024 — McMap. All rights reserved.