Fading my screen

I’ve made a software rendering class that seems to work pretty well for fading my screens in Rimscape at a decent speed. However, it DOES take up a heck of a lot of memory. I’m gonna post here what I’m doing so you guys can see it and see if I can get any suggestions to improve upon it :slight_smile:


public void addScreen() {
      background = new BufferedImage();
      //draw what's is currently on the screen

      foreground = new BufferedImage();
      //draw what it will look like when done fading on this one

      sf.setBackground(background);
      sf.setForeGround(foreground);
}
ScreenFader: public void setBackground(BufferedImage image) {
      
      w = image.getWidth(); 
      h = image.getHeight(); 
      
      xOffset = (width - w)/2;
      yOffset = (height - h)/2;
      pixels = null;
      
      pixels = image.getRaster().getPixels(0, 0, w-1, h-1, pixels);
      PixelGrabber pg = new PixelGrabber(image, 0, 0, w-1, h-1, pixels, 0, w);
      try {
       pg.grabPixels();
    } catch (InterruptedException e) {
    }
}
ScreenFader: public void setForeGround(BufferedImage image) {
      w = image.getWidth();
      h = image.getHeight();
      
      try {
            pixelsToAdd = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
            
            xOffset = (width - w)/2;
            yOffset = (height - h)/2;
            
            totalAlpha = 0;
            currentTicks = 0;
            currentAlpha = 0;
      }
      catch (NullPointerException e) {
            System.out.println("null");
      }
}
public void run(double ticks) {
    currentTicks += ticks;
    currentAlpha = 255d*currentTicks/MAX_TICKS - currentAlpha;
    totalAlpha += currentAlpha;
      
      int start = yOffset*width + xOffset; 
      int start_end = start + width*h;
      int sp = 0; 
      
      for (; start < start_end; start += width) { 
            int end = start + w; 
            for (int curr = start; curr < end; curr++, sp++) {
                  pixels[curr] = blend(pixels[curr], pixelsToAdd[sp]); 
            } 
      }
      
      if (!isActive()) {
            pixels = null;
            pixelsToAdd = null;                  
      }
}
private int blend(int bg, int fg) {
      int bg_r = bg & 0xff;
    int bg_g = bg & 0xff00;
    int bg_b = bg & 0xff0000;
    
    // Blend values 
    bg_r += (int)( ((fg & 0xff)            - bg_r) * currentAlpha) >> 8;
    bg_g += (int)( ((fg & 0xff00)      - bg_g) * currentAlpha) >> 8;
    bg_b += (int)( ((fg & 0xff0000)      - bg_b) * currentAlpha) >> 8;
    
    // Mask channels back to 8 bit and
    // Return combined RGB values, with 255 as the alpha
    return ( 0xff000000 + (bg_r & 0xff) + (bg_g & 0xff00) + (bg_b & 0xff0000));
}
public synchronized void render(Graphics2D g2d) {
      // copy integer pixel data to image consumer
      consumer.setPixels(0, 0, width, height, model, pixels, 0, width);

      // notify image consumer that the frame is done
      consumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
      
      g2d.drawImage(image, 0, 0, width, height, null);
}

There’s the main meat of it. As you can see, I create those two big fat images to fade the screens and draw on them… it’s a memory hog. However, setting an AlphaComposite and just rendering stuff on the fly is MUCH slower. Does anyone see anything about it that could be changed to make things much nicer?

Why don’t you use a simple rectangle that cover the entire screen and fade it ? Should be easier and very fast :slight_smile:

Chman

edit: sorry, I think I’ve misanderstood your post… You’re fading two images… It’s not just a “fade in” / “fade out” effect :stuck_out_tongue:

How fast it is compare to AlphaComposite Malohkan?
I’d like to know is it worth for me to change my AlphaComposite to it?
I haven’t try it, seen the ScreenFader class that I don’t have, don’t know how to test it (which one the fading start point?), and I’m a bit lazy to screw with the code atm. :slight_smile:
So far I use AlphaComposite and it works pretty well on my game intro, haven’t try it at when running the game though.

Yeah I’m fading between two images. Role, the difference is such that I’m not willing to switch back even if I do need like 30 megs of RAM set aside just for it :slight_smile: I could get like 2 fps before. Now I get like 20. However the initial creation of the images causes significant lag.

O_o

I presume the 2 images you are fading between are no larger than the screen size.
I also assume neither of the images are VolatileImages.

If both these are true, software AlphaCompositing of 2 fullscreen images shouldn’t be prohibitively slow - if it is, you are doing something wrong.

On the other hand, if you can be sure the operation will be hardware accelerated (either with the transaccel flag, or the opengl pipeline enabled), you can quite comfortably AlphaComposite dozens of fullscreen images without risk of it ever being the bottleneck.

:edit:

A quick note on the above code, you shouldn’t ever need to use pixel grabber its horribly slow and inefficient, the only excuse for its use is if you are limited to Java1.1 (which you obviously are not).

You know… the funny thing is… I started with rendering everything in the background, then rendering everything in the foreground, both with different AlphaComposites blending them. I was like, man this is slow. So then I thought, I bet I could do it faster using some custom rendering. So I set that up, and in realizing I had to have two images already created, I made them and passed them to my fader class. It worked much better. However, the thought never crossed my mind to just AlphaComposite the two images. Its like I skipped that step :wink:

Thanks for that Abuse, it’s definitely faster. Wanna look at the rest of my game code and find other stupid things I’m doing? :smiley:

On that subject… scaling, rotating, and translating translucent images on the fly sucks. I have a warp/jump effect thing that scales out to a pretty serious size, then scales back down. It makes for a nice warp effect, but it suuurree drags things to a crawl while it goes. Any ideas on how to manage it other than using AffineTransform to just throw it out there?

On top of that, pretty much everything drawn in the game is being rotated (sometimes scaled) with AffineTransform, all of my images being translucent. While the beam weapons and jump effects are the only ones that make my game lag, they’re definitely the memory and processor bottleneck. JProfiler says that Graphics2D.drawImage() both takes the most processor time and the most memory time. My >= $150 offer for someone to help me port to LWJGL is still open ;D

Next runner up is my AI routines… your 4KShooter AI seems pretty smart, but it’s very concise and I can’t figure out a dern thing that it’s doing :slight_smile: Perhaps you could look at my post in the AI forum and give me some pointers?

New news. The changes I was comparing to was in my Applet. In the Applet, it’s faster. In a JFrame using BufferStrategy (both in windowed and fullscreen mode) it’s MUCH slower.

My original code is at least 5 times faster than using AlphaComposite. When I run with AlphaComposite I only see maybe 3 frames of animation. When I run with my code I see about 20.

Why would the Applet be so much faster than the JFrame?

Here are the flags I’m running with the JFrame version:
System.setProperty(“sun.java2d.translaccel”,“true”);
System.setProperty(“sun.java2d.accthreshold”, “1”);
System.setProperty(“sun.java2d.ddscale”,“true”);