I wrote an application to draw graphs on bitmaps and bitblit them to the window when necessary. Drawing on bitmaps proved to be slower than i expected. If I draw on Direct Draw surface in memory, using Surface DC and GDI functions, will it be faster? What is the fastest way to draw? Should I use OpenGl? The Program should run on slow video hardware as well.
Posted on 2004-03-31 03:48:39 by Vaxon
I have to say that using DD or OpenGl for making graphs is stupid idea i dont know exactly what you mean by drawing on bitmaps, but maby you should use CreateDIBSection and obtain pointer to image bits.
Posted on 2004-03-31 07:29:18 by AceEmbler
Hm, with CreateDIBSection I haven't had any speed problems. DirectDraw seems a bit faster, especially fullscreen, but I haven't had any problems getting even realtime (>24fps) screen updates when drawing manually to a DIB section and using BitBlt - on NT I generally get speed of my monitor refresh rate, 85fps. 9x is somewhat worse, but should still be plenty fast for graph drawing.

How are you drawing to the bitmaps? If it's anything involving SetPixel, you're attacking the problem quite wrong :).
Posted on 2004-03-31 08:17:32 by f0dder
I create compatible DC and bitmaps and draw on them using standard GDI functions LineTo, PolyLine and so on. What is the better way? Will it be faster to write my own drawing functions for DIB? Or what do I have to do? Using standard GDI functions I can manage line styles, widths and background colors easily.
Posted on 2004-03-31 13:48:50 by Vaxon
By the way, using OpenGL or DD is not that stupid. I know that Borland's CHART components make use of all that stuff, which helps to draw even 3d graphs the fastest way. I attached an image of what I do.
Posted on 2004-03-31 13:59:15 by Vaxon
Is there a way to optain a "pointer to image bits" without copying them into a memory buffer first? I mean, can I get a pointer to the original RGB values?
Posted on 2004-03-31 17:32:57 by SubEvil
Vaxon: I believe writing your own "optimized" routines will kick GDI functions ass! If written properly! I re-wrote GetPixel function and increased it's performance by 25 times.
Posted on 2004-03-31 17:35:38 by SubEvil
Writing custom GetPixel or SetPixel functions is not that hard, but I don't really wanna mess around with line drawing functions, because I'll have to mange clipping, line widths, styles and colors myself. Not mentioning text output functions here.
Posted on 2004-04-01 01:59:09 by Vaxon

Is there a way to optain a "pointer to image bits" without copying them into a memory buffer first? I mean, can I get a pointer to the original RGB values?

Indeed there is, SubEvil. Try having a look at the final code I posted in the "20x faster GetPixel" thread :). I believe you can even do it by GetObject'ing a HBITMAP, getting the BITMAP structure, and accessing bmBits.

Yes Vaxon, there's a whole lot of stuff you need re-implement if you draw directly, that's the price you pay for speed. Using DirectDraw wouldn't really be different, it's a very low-level library. OpenGL has a bunch of high-level stuff, but come on - using that bulky 3D library for graphs? :/

Have you tried running the app through a profiler, to see where the bottlenecks are? If you don't have a profiler, send me a release-mode executables with the linker option /FIXED:NO (ie, containing relocations), debug info enabled and put in a .pdb.

Oh, and one last thing: No matter how much you optimize Get/SetPixel, it's wrong to use them :p
Posted on 2004-04-01 03:38:57 by f0dder
Thank you, f0dder. I haven't tested it in a profiler, but I know that the drawing itself blocks my app most. I just disabled drawing and the whole thing speeded up. I write it in plain C. (VC with no MFC). It's neither finished nor optimized yet. The archive weights 357kb (debug project) and they did not let me to attach it, cause it exceeds the maximum allowed size, so I attached it with no .pdb files (about 123kb), in case you still want to test it. But it's OK if you decide not to mess with that piece of sh.....code.
Posted on 2004-04-01 09:33:13 by Vaxon
Hm, it runs very well here - win2ksp4 with a GeForce4 card and semi-recent video drivers. If I go to properties and select "double line width" and hit apply, the sinewave disappears until I restart the app.

Profiling won't be too meaningful without the .pdb, but you can send it to my oldhttp://www.asmcommunity.net/board/cryptmail.php?tauntspiders=in.your.face@nomail.for.you&id=198d0f25e6880ad053d4a088ff388a82 dump address, I think they allow attachments. (Btw, you can create .pdb file in release as well, this is most useful when profiling).

Which OS gives you the speed problems? 9x sucks at GDI compared to NT, even though early NT versions had some problems.
Posted on 2004-04-01 10:10:28 by f0dder
Thank you for taking time to help me. I've made a release version with .pdb files here (260kb). I have w2k4 and quite recent drivers on my cel400MHz, 256MB RAM, Geforce 4 and it slows down dramatically with double line width. BTW what profiler do you use? Intel?
Posted on 2004-04-01 12:39:46 by Vaxon
You still didn't tell which version of windows you use, I think.

When I enable double line width, the output disappears - so I think you have some sort of bug that needs to be fixed, which may also fix the very slow speed.

Yup, some intel vtune version.
Posted on 2004-04-01 12:49:36 by f0dder
I was editing the post to tell you my windows version when you read it :) I have w2ksp4. There's no bug. It's just wrong axis limits. With this release version it should work fine.
Posted on 2004-04-01 12:53:27 by Vaxon