AGSBloom! Another Speed Test

Started by Calin Leafshade, Tue 03/08/2010 03:41:31

Previous topic - Next topic

Calin Leafshade

ok so i've written a blurring algorithm for an AGS plugin and it works ok on *some* images but not on all.

if the image is square it blurs it 100% fine
if the image is taller than it is wide then it blurs a weird box in the corner with some artifacts
if the image is wider than it is tall it crashes with an access violation (i.e i've accessed a part of the array that i havent allocated)

So theres obviously a pretty elementary error with the way i calculate the array indices but i cant see it.

It's extremely difficult to debug plugins since you cant add breakpoints or watch values or step through code so i need help

heres my algorithm:

(btw i *know* this is not a quick way to do blurring butI'm just getting to grips with the c++ first then i can alter the algorithm however i please.)

Code: ags

int xytolocale(int x, int y, int width){
    
 return (y * width + x);   
    
    
}
int BlurHorizontal (int Sprite, int radius) {
             
    BITMAP* src = engine->GetSpriteGraphic(Sprite);
    long srcWidth, srcHeight;
    
    engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, NULL);

    unsigned char **srccharbuffer = engine->GetRawBitmapSurface (src);
    unsigned long **srclongbuffer = (unsigned long**)srccharbuffer;
    int negrad = -1 * radius;
    
    //use a 1Dimensional array since the array is on the free store, not the stack
    Pixel32 * Pixels = new Pixel32[(srcWidth + (radius * 2)) * (srcHeight + (radius * 2))]; // this defines a copy of the individual channels in class form.
    Pixel32 * Dest = new Pixel32[(srcWidth + (radius * 2)) * (srcHeight + (radius * 2))]; // this is the destination sprite. both have a border all the way round equal to the radius for the blurring.
    

             
    int arraywidth = srcWidth + (radius * 2); //define the array width since its used many times in the algorithm


    for (int y = 0; y<srcHeight; y++){ //copy the sprite to the Pixels class array
         
         for (int x = 0; x<srcWidth; x++){
             
             int locale = xytolocale(x + radius, y + radius, arraywidth);
             
             Pixels[locale].red = getb32(srclongbuffer[x][y]);
             Pixels[locale].green = getg32(srclongbuffer[x][y]);             
             Pixels[locale].blue = getr32(srclongbuffer[x][y]);
             Pixels[locale].alpha = geta32(srclongbuffer[x][y]);  
                                                     

         
         }
         
     }    
            // start of the blurring 
     int numofpixels = (radius * 2 + 1) * (radius * 2 + 1);
         for (int y = 0; y < srcHeight; y++) {
            for (int x = 0; x < srcWidth; x++) {
                int totalr = 0;
                int totalg = 0;
                int totalb = 0;                
                int totala = 0;

                for (int ky = negrad; ky <= radius; ky++){
                    for (int kx = negrad; kx <= radius; kx++){
                        int locale = xytolocale(x + kx + radius, y + ky + radius, arraywidth);
                        totalr += Pixels[locale].red; //add the pixel values for the surrounding pixels to a total
                        totalg += Pixels[locale].green;
                        totalb += Pixels[locale].blue;
                        totala += Pixels[locale].alpha;                                                
                        
                    }
                }
                int locale = xytolocale(x + radius, y + radius, arraywidth);
                Dest[locale].red = totalr / numofpixels; // take an average and assign it to the destination array
                Dest[locale].green = totalg / numofpixels;
                Dest[locale].blue = totalb / numofpixels;
                Dest[locale].alpha = totala / numofpixels;                            
            }
        }
        
         
     
        for (int y = 0; y<srcHeight; y++){
             
             for (int x = 0; x<srcWidth; x++){
                int locale = xytolocale(x + radius, y + radius, arraywidth);
                srclongbuffer[x][y] = makeacol32(Dest[locale].blue, Dest[locale].green, Dest[locale].red, Dest[locale].alpha); //write the destination array to the main buffer

             }
             
         } 
        
        engine->ReleaseBitmapSurface(src);
}


any ideas?

Kweepa

Did you try just indexing
Code: ags

srclongbuffer[y][x]
instead of
Code: ags

srclongbuffer[x][y]

?
Still waiting for Purity of the Surf II

Calin Leafshade

I could try but surely that would just reverse the problem?

Kweepa

Go on, give it a shot.
It sounds to me from the symptoms that this is the cure.
Still waiting for Purity of the Surf II

Calin Leafshade

you are 100% right.... how did i not see this...

Thanks Steve!

Calin Leafshade

would it be possible for people to try out this game and tell me what frame rates they get in both DD and DX9 mode with the default settings.

also your system specs would be greatly appreciated ^_^

http://www.thethoughtradar.com/AGS/Bloomtest4.zip

also, for giggles, you can play with the settings with the 1-8 number keys.

ddq

In both DD and DX9, performance was about the same. No matter what the other settings, I got solid 40 FPS when blur quality was set to 1. Any higher and performance took a big hit. At 2, I was getting mid 30's and when I maxed it out, I was running about 17. The other settings didn't have much effect on the framerate. Honestly, I didn't think higher "quality" blurs looked noticeably better enough to justify the lowed framerate.
Specs:
2.5 GHz Core 2 Duo
4 GB RAM
Nvidia GeForce 8600M GT with 512 MB RAM
Summary: It looked pretty.

Calin Leafshade

That 'quality' setting is a little misleading.

Its really just the number of times the blur function is run on the sprite.
When i was using a different box blur algorithm it needed multiple passes to look good.. now a single pass is pretty much sufficient.

LimpingFish

I got what I suspect will become the norm: 40+ at '1' quality, 30+ at '2', 20+ at '3', etc.

The other settings don't impact on the frame rate.

Nice effect, though. :)

Steam: LimpingFish
PSN: LFishRoller
XB: TheActualLimpingFish
Spotify: LimpingFish

GarageGothic

I had the same experience as LimpingFish, on quality 1 I get 40 fps no matter the other settings, any increase in quality leads to a dramatic drop (but didn't note the exact fps). Looks awesome though, don't see any real need to increase quality.

Kweepa

Q1 = 40
Q2 = 40
Q3 = 33
Q4 = 27
Q5 = 22
Core i7 920 @ 2.67GHz
Still waiting for Purity of the Surf II

Calin Leafshade

the i7 cores are insane at computation like this.

Hardware accelerated version comming soon... I hope..

Wyz


P4 2.8GHz
No difference between DD and DX9
Life is like an adventure without the pixel hunts.

Calin Leafshade

It seems like I do need to hardware accelerate this.. its just too intense to do without shaders.

Crimson Wizard

I tried, but... I see pretty much visual difference between quality 0 and 1,but other quality levels simply lower the effect, as it seems (while downgrading fps). Is this an expected behavior? Sorry, do not know much about Bloom.

Calin Leafshade

Yes, bloom is essentially a 3 part process.

1 - run a high pass filter on the texture
2 - blur the result.
3 - additively blend the result over the original image.

"quality" refers to the number of times step 2 is done and if you continue to blur something you dilute its intensity.

Shane 'ProgZmax' Stevens

It's a bit buggy/crashy (straying too far up on the screen causes a CTD) but so far the performance doesn't drop significantly for me.

With default settings I get 33 fps in DDRAW and 40 in D3D.

With no bloom I get 34/41.

With full (hold down 2 until the whole screen is glowing) I get 30/37.

High quality above about 2 seems to diminish the effect...  on 2 it seems to render the areas as blended squares.

I think the result is pretty neat without a significant performance hit (for me).


Gilbert

With this crappy office computer I got around 14 FPS, without touching any of the in-game settings and using the default configuration (i.e. DX5 and 3X zoom). I got around 15 FPS if I didn't use any zoom for the window though.

This is a bit meaningless anyway, as D3D9 won't work with AGS on this machine, so no comparison can be made.

Anyway, specs:

2.4 GHz P4
1GB RAM
Win XP Professional SP3
Extraordinary Awesome Super Powerful Onboard Intel 82845(something) graphics, stealing some 32MB (I think) of system memory :=
Direct X 9 (yeah...)

SMF spam blocked by CleanTalk