3
\$\begingroup\$

I have black and white SDL_Surface and I'm trying to change colors, such as from black to white and from white to red. I did it, but it is taking too long to work.

SDL_Surface* tempSurface = SDL_DisplayFormat(textSurface);
for(int i=0;i<256;i++){
    SDL_SetColorKey(textSurface,SDL_SRCCOLORKEY,SDL_MapRGB(textSurface->format,i,i,i));
    SDL_FillRect(tempSurface, 0, SDL_MapRGB(tempSurface->format, 255, i, i));
    SDL_BlitSurface(textSurface,0,tempSurface,0);
    SDL_FreeSurface(textSurface);
    textSurface=tempSurface;
    tempSurface = SDL_DisplayFormat(textSurface);
}
SDL_FreeSurface(tempSurface);

It works for a few seconds, but it needs to run very fast. It is C code, but it is not important. SDL is compatible with both languages.

How can I optimize this algorithm? Or can you suggest another way?

\$\endgroup\$

migrated from stackoverflow.com Mar 20 '12 at 19:05

This question came from our site for professional and enthusiast programmers.

  • 1
    \$\begingroup\$ C? C++? So this is working but not fast enough? \$\endgroup\$ – talnicolas Mar 20 '12 at 19:03
  • \$\begingroup\$ Yes, it works for a few seconds, but it needs to run very fast. It is C code, but it is not important. SDL is compatible with both languages. \$\endgroup\$ – cattail Mar 20 '12 at 19:43
1
\$\begingroup\$

It would be helpful to know how textSurface is created. There may be a performance win to be had by using, say, a hardware surface instead of a software surface.

If you are using a surface that supports double buffering I would reccomend using SDL_FLip rather than flipping the buffers yourself using 2 surfaces.

E.g:

SDL_Surface* textSurface;
if(!(textSurface = SDL_SetVideoMode(600, 400, 32, SDL_HWSURFACE)))
    SDL_Quit();

SDL_SetColorKey(textSurface, SDL_SRCCOLORKEY, SDL_MapRGB(textSurface->format, 255, 0, 255)); //typically we use magenta
for(auto i=0; i<256; i++){
    auto col = SDL_MapRGB(textSurface->format, i, i, i);
    std::cout << col << "," << SDL_FillRect(textSurface, 0, col) << std::endl;
    SDL_Flip(textSurface);
}

Note that for your current goal, there is no need to reset the ColorKey each time around the loop.

If you want to run faster than "a few seconds" you certainly won't need to display all 256 intermediate colours to achieve the desired effect.

SDL_Surface* textSurface;
if(!(textSurface = SDL_SetVideoMode(600, 400, 32, SDL_HWSURFACE)))
    SDL_Quit();

SDL_SetColorKey(textSurface, SDL_SRCCOLORKEY, SDL_MapRGB(textSurface->format, 255, 0, 255)); //typically we use magenta
auto frame_increment = 4;
for(auto i=0; i<256; i += frame_increment){
    auto col = SDL_MapRGB(textSurface->format, i, i, i);
    std::cout << col << "," << SDL_FillRect(textSurface, 0, col) << std::endl;
    SDL_Flip(textSurface);
}

You should determine frame_increment based on your desired time and hardware capabilities.

\$\endgroup\$
  • \$\begingroup\$ This routine fills screen with white color only. It draws 256 filled rectangles on surface. I can't receive the result using this code. Or, may be, I not understand something in this algorithm? \$\endgroup\$ – cattail Apr 16 '12 at 8:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.