Tuesday, March 15, 2011

opengl slow on texture blit

I called this function once per frame and it took my FPS from >400 to 33. Why?

sw blt(const PtRect *dstRect, Texture *src, const PtRect *srcRect, RenderDevice::bltFlags flags=RenderDevice::bltDefault)
{
 assert(src);
 GL_Texture *glsrc = dynamic_cast<GL_Texture*>(src);
 if (glsrc == 0)
  return -1;

 PtRect srcRect2(0, 0, src->width, src->height);
 if (srcRect == 0)
  srcRect = &srcRect2;

 PtRect dstRect2(0, 0, srcRect->makeWidth(), srcRect->makeHeight());
 if (dstRect == 0)
  dstRect = &dstRect2;

 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

 glEnable(GL_TEXTURE_2D);
 glBindTexture(GL_TEXTURE_2D, *glsrc->getTex());

 glBegin( GL_QUADS );
 glNormal3f( 0.0f, 0.0f, 1.0f );
 for (size_t i=0; i<350; i++)
 {
  glTexCoord2f( srcRect->left /src->width, srcRect->top/src->height);    glVertex2f(dstRect->left,  dstRect->top);
  glTexCoord2f( srcRect->right/src->width, srcRect->top/src->height);    glVertex2f(dstRect->right, dstRect->top);
  glTexCoord2f( srcRect->right/src->width, srcRect->bottom/src->height); glVertex2f(dstRect->right, dstRect->bottom);
  glTexCoord2f( srcRect->left /src->width, srcRect->bottom/src->height); glVertex2f(dstRect->left,  dstRect->bottom);
 }
 glEnd();
 return 0;
}
From stackoverflow
  • Hard to say without more details, potential problems could be using a too large texture, causing software fallbacks in your driver. Also you appear to loop 350 times for no obvious reason.

    You may be able to improve performance by building an array of data and then calling glDrawArrays instead of issuing each glTexCoord/glVertex pair individually

  • It looks like you draw the quad onto the screen 350 times for some reason. If this is full screen, then texturing every pixel on the screen 350 times a frame is bound to damage your performance.

  • For performance you should load your textures in an init function and use a list to display then later on the main render function, for example:

    // Generate texture object ID
    glGenTextures(1, img);
    glBindTexture(GL_TEXTURE_2D, img);
    
    // Set Texture mapping parameters
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    LoadBMP("texture.bmp");
    

    Then on the main render function you have something like:

    // Front face of Cube
    glBindTexture(GL_TEXTURE_2D, img);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-fSize, fSize, fSize);
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-fSize, -fSize, fSize);
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(fSize,-fSize, fSize);
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(fSize,fSize, fSize);
    glEnd();
    

    As you can see you can wrap the texture on the parameters instead of repeating it over and over in a loop.

  • Maybe you are not using Textures with of a power of 2 (e.g. 1024x768 instead of 1024x512)?

0 comments:

Post a Comment