Double buffering is your friend http://msdn.microsoft.com/en-us/library/3t7htc9c.aspx
Drawing a single large image with the graphics card in a custom control
-
28-06-2022 - |
Question
Simply put, I'm trying to draw an image (2560x2048) that is supposed to be zoomed / draged and such but the performance is very bad, because it flickers everytime I move it. I use a custom control to be able to drag the image to a new position and zoom in and out, which means it have to be flexible and fast.
So, what is the easiest and best way to just draw a single image with the graphics card? Without having to initialize a thousand directX objects just for one simple purpose.
Overall, the application is a tool - so not a game. But this particular large image is supposed to be drawn effectively.
Solution
OTHER TIPS
Well I am Borland C++ friendly so i would use simple Canvas (simple Windows GDI interface).
No need for GL,GLSL or DX
you need 2 bitmaps.
one as source image (that is your 2560x2048) next is back-buffer of the screen (client size of your view area). Both has to be DIB. I prefer
pf32bit
pixel format (32 bit int as a color so I can useint *p
...)need to write render function (or use GDIs strech draw or CopyRect)
do not use
Set
orPut
orPixels
they are slow (always checking size and color format and many other stuff for each pixel). Instead use bitmaps scan lines (in VCLbmp->ScanLine[y]
).This usually speeds up things about ~1000 times if done properly
put it all together
clear back-buffer with background color. Use your render function to copy viewed area to back-buffer (no need to render whole image). When all rendering is done copy back-buffer to the screen.
when all works you can further speed up things
use array of scan lines pointers instead of calling them in rendering. Addresses of scan lines are changed only after resizing of bitmap so on resize delete all array of pointers and create and fill new one (
int *pyx[ys];
)
This kind of bitmap rendering is fast enough for simple software 3D rendering so for your purpose must be sufficient with high enough framerate (estimate well over 70fps
on average desktop machine)
some code for Borland C++ VCL (just so you know what to look for in your programing languge)
// init
int xs=0,ys=0,*pyx=NULL;
Graphics::TBitmap *bmp=new Graphics::TBitmap;
bmp->HandleType=bmDIB;
bmp->PixelFormat=pf32bit;
// exit
if (bmp) delete bmp; bmp=NULL;
if (pyx) delete pyx; pyx=NULL;
// resize(_xs,_ys)
if (pyx) delete pyx; pyx=NULL;
bmp->Width=_xs;
bmp->Height=_xs;
xs=bmp->Width;
ys=bmp->Height;
pyx=new int*[ys];
if (pyx==NULL) return; // not enough memory
for (int y=0;y<ys;y++) pyx[y]=(int*)bmp->ScanLine[y];
// now pyx[y][x]=0; means setpixel(x,y)=color(0) without any slowing down checks
// now c=pyx[y][x]; means colro(c)=getpixel(x,y) without any slowing down checks
// but beware of accessing x,y, outside <0;xs),<0;ys) !!!