views:

53

answers:

1

I have an application that creates 3D motion on a TPaintBox Canvas using native Delphi code. In the old code I rendered the 3D image to a temporary TBitmap on a Timer event. In the TPaintBox OnPaint() event I would BitBlt() the temporary TBitmap the TPaintBox's Canvas. This approach worked fine but the motion was jerky.

Because I was not happy with the smoothness of the motion I decided to try "rendering" instead to a very large workspace bitmap and then down-sample it to the TPaintBox Canvas. To do the re-sampling I used the Graphics32 library which I read about here:

http://stackoverflow.com/questions/1976116/scale-an-image-nicely-in-delphi

I changed my code to render to a large TBitmap32 (1100w x 1100h) and then when I down-sample it I use a Graphics TKernelResampler object with a TLanczosKernel kernel to do the down-sampling to another TBitmap32 that is the exact same size as the TPaintBox Canvas and call the TPaintBox's Refresh method. In the TPaintBox OnPaint event I BitBlt() the down-sampled TBitmap32 to the TPaintBox Canvas.

This works but the problem is I only see repaints when the Form that owns the TPaintBox requires a repaint, a problem I did not have with the old code despite the face that I call the Refresh method on the TPaintBox right after I'm done rendering to it, as I said. As a validity test I called SaveToFile() on both the large hi-res TBitmap32 object and the smaller TBitmap32 object I use for pre-rendering. The bitmaps showed that indeed the frame had not changed in content at all between Timer events so it's not a weird Repaint related issue, at least not with the TPaintBox component.

If I invalidate the Form's Canvas by moving the Form or overlaying any part of it's client area with another form, then the content of the TBitmap32 objects do update and so do the bitmap images I save to disk as a check.

It's as if the Graphics32 TBitmap object's themselves need to be invalidated so that the new content I rendered to the large hi-res workspace is updated. However, TBitmap32 has no such invalidate/refresh call.

If anyone out there is experienced with the Graphics32 library and can tell me why I'm only seeing the images change when the Form requires a repaint or has it's client area invalidated then I would appreciate that.

A: 

This ended up being a prime example of how somehow the symptoms can look like a problem that is completely different than the one you are actually having. Despite the fact that the CPU utilization on my quad core and on only one processor never exceeded 25%, it turned out that the lack of updating was due to a processing (not processor) overload somewhere in the graphics handling chain. I still don't know exactly where, perhaps something in the dark recesses of the Windows graphics libraries. But once I eased up the processing load everything started updating perfectly. It turned out that trying to run the Graphics32 library TLanczos kernel resampler 20 times a second on a large bitmap was too much for the windows graphics system to handle. If I slowed the frame rate (renders per second) down to 4 times a second than suddenly updates started happening normally. By swapping out the TLanczos kernel resampler for the much faster draft resampler, I was able to go back to updating 20 times a second with excellent visual aesthetic quality. I guess when I moved or resized the host window, that gave the graphics sub-system enough time to catch up and update properly so that's why I saw the updates after doing that.

Robert Oschler