PDA

View Full Version : Fast image scaling



Randel
10-04-2010, 06:16 AM
Hi!
I try to use OpenGL for quick image scaling. I have an array of bytes in memory (image), want to scale it and write to another array.
I wrote two variants:


glClear(GL_DEPTH_BUFFER_BIT ^ GL_COLOR_BUFFER_BIT);
glPixelZoom(1.05,1.05);
glDrawPixels(256,256,GL_RGB,GL_UNSIGNED_BYTE,Bits1 );
glReadPixels(0,0,256,256,GL_RGB,GL_UNSIGNED_BYTE,B its2);

or


glClear(GL_DEPTH_BUFFER_BIT ^ GL_COLOR_BUFFER_BIT);
glScaled(1.05,1.05,1);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,256,256,
0,GL_RGBA,GL_UNSIGNED_BYTE,Bits1);

glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0); glVertex3f(-1.0,-1.0,0.0);
glTexCoord2f(0.0,1.0); glVertex3f(-1.0,1.0,0.0);
glTexCoord2f(1.0,1.0); glVertex3f(1.0,1.0,0.0);
glTexCoord2f(1.0,0.0); glVertex3f(1.0,-1.0,0.0);
glEnd();
glReadPixels(0,0,256,256,GL_RGB,GL_UNSIGNED_BYTE,B its2);


All works correct, but with bad performance. The GDI method StretchBlt - works a little faster...but StretchBlt is not accelerated. How can I scale image with high performance? Thank You!

mhagain
10-04-2010, 06:59 AM
None of them are going to be fast because glReadPixels needs to stall the pipeline and read back from framebuffer memory in order to do it's thing. The formats you're using aren't exactly conducive to fast transfers either - you should be using GL_BGRA instead of GL_RGB here (it's also worth trying GL_UNSIGNED_INT_8_8_8_8_REV as the type, but only with GL_BGRA and it might make no difference at all).

http://www.opengl.org/resources/faq/technical/performance.htm (see 22.070 Why are glDrawPixels() and glReadPixels() so slow?)

An option is to use glReadPixels in combination with a Pixel Buffer Object, but your mileage may vary. If you don't need the image data back in system memory you could try glCopyTexSubImage2D with your method 2.

ZbuffeR
10-04-2010, 07:57 AM
You can also render several images in parallel, and do async readpixels with a PBO. But this will not help for a single image.

Advantage of hardware scaling is that you get trilinear filter for free.

Randel
10-04-2010, 12:02 PM
GL_BGRA_EXT + GL_UNSIGNED_INT_8_8_8_8_REV works fine. Twice faster then GDI`s StretchBlt.

But my array of image bits is BGR (8,8,8) without alpha. The image is grayscale B=G=R.

Are this settings best for me? If im understood, i can`t use GL_BGRA_EXT + GL_UNSIGNED_INT_8_8_8_8_REV...without conversion


////Buffer Settings//////////
PIXELFORMATDESCRIPTOR pfd, *ppfd;
int pixelformat;
ppfd = &pfd;
ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
ppfd->nVersion = 1;
ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
ppfd->dwLayerMask = PFD_MAIN_PLANE;
ppfd->iPixelType = PFD_TYPE_RGBA;
ppfd->cColorBits = 24;
ppfd->cDepthBits = 24;
ppfd->cAccumBits = 0;
ppfd->cStencilBits = 0;
////////////////////////////
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glDrawPixels(256,256,GL_RGB,GL_UNSIGNED_BYTE,Bits1 );
glReadPixels(6,6,256,256,GL_RGB,GL_UNSIGNED_BYTE,B its2);


Please, help with this settings...Thank You!