Fade-In / Fade-Out Revisited

Okay guys, after finding out that the fading stuff that's in jME currently doesn't work, I wrote my own simple implementation:


/*
 * Created on Jan 16, 2006
 */
import com.jme.renderer.*;
import com.jme.scene.*;
import com.jme.scene.shape.*;
import com.jme.scene.state.*;
import com.jme.system.*;

/**
 * @author Matthew D. Hicks
 */
public class FadeController extends Controller {
    public static final int DISABLED = 0;
    public static final int FADE_IN = 1;
    public static final int FADE_OUT = 2;
   
    private float fadeTime;
    private Node rootNode;
    private float width;
    private float height;
    private float alpha;
    private int mode;
    private ColorRGBA color;
   
    private Quad quad;
    private AlphaState alphaState;
    private boolean ignoreUntilStable;
   
    public FadeController(float fadeTime, Node rootNode, float width, float height) {
        this.fadeTime = fadeTime;
        this.rootNode = rootNode;
        this.width = width;
        this.height = height;
       
        init();
    }
   
    private void init() {
        quad = new Quad("FadeQuad", width, height);
        quad.getLocalRotation().set(0.0f, 0.0f, 0.0f, 1.0f);
        quad.getLocalTranslation().set(DisplaySystem.getDisplaySystem().getWidth() / 2, DisplaySystem.getDisplaySystem().getHeight() / 2, 0.0f);
        quad.getLocalScale().set(1.0f, 1.0f, 1.0f);
        quad.setRenderQueueMode(Renderer.QUEUE_ORTHO);
        quad.setLightCombineMode(LightState.OFF);
        rootNode.attachChild(quad);
       
        alphaState = DisplaySystem.getDisplaySystem().getRenderer().createAlphaState();
        alphaState.setBlendEnabled(true);
        alphaState.setSrcFunction(AlphaState.SB_SRC_ALPHA);
        alphaState.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
        alphaState.setTestEnabled(true);
        alphaState.setTestFunction(AlphaState.TF_GREATER);
        alphaState.setEnabled(true);
        quad.setRenderState(alphaState);
       
        quad.setColorBuffer(null);
        color = new ColorRGBA(0.0f, 0.0f, 0.0f, 0.0f);
        quad.setDefaultColor(color);
       
        rootNode.addController(this);
    }
   
    public void update(float time) {
        // Fix for lagged startups
        if (ignoreUntilStable) {
            if (time < 0.1f) {
                ignoreUntilStable = false;
            }
            return;
        }
        if ((mode == FADE_IN) && (alpha > 0.0f)) {
            alpha -= 1 / (fadeTime / time);
            if (alpha < 0.0f) alpha = 0.0f;
            color.a = alpha;
        } else if ((mode == FADE_OUT) && (alpha < 1.0f)) {
            alpha += 1 / (fadeTime / time);
            if (alpha > 1.0f) alpha = 1.0f;
            color.a = alpha;
        } else if ((mode == DISABLED) && (color.a != 0.0f)) {
            color.a = 0.0f;
        }
    }
   
    public void setMode(int mode) {
        this.mode = mode;
        ignoreUntilStable = true;
    }
   
    public void setAlpha(float alpha) {
        this.alpha = alpha;
        color.a = alpha;
    }
}



Personally I'd like to see this available in jME, but otherwise it's freely available for anyone to use in their games.  I added a little hack in there to resolve a problem I was having with going from a "loading" screen that locked the update method for like a minute to the fade controller.  It waits until the tpf stabalizes before starting the fade-in or fade-out after a mode change.

Hope this is useful to someone other than myself.

darkfrog

Okay, Irrisor, this should reflect all the changes you requested for the FadeController:


/*
 * Created on Jan 26, 2006
 */
package com.captiveimagination.jme;

import com.jme.renderer.*;
import com.jme.scene.*;
import com.jme.scene.shape.*;
import com.jme.scene.state.*;
import com.jme.system.*;

/**
 * @author Matthew D. Hicks
 */
public class Fader extends Quad {
    private static final long serialVersionUID = 1L;
   
    public static final int DISABLED = 0;
    public static final int FADE_IN = 1;
    public static final int FADE_OUT = 2;
   
    private float fadeTimeInSeconds;
    private ColorRGBA color;
    private boolean ignoreUntilStable;
    private int mode;
    private float alpha;
    private AlphaState alphaState;
    private Controller fadeController;
   
    public Fader(String name, float width, float height, float fadeTimeInSeconds) {
        super(name, width, height);
        this.fadeTimeInSeconds = fadeTimeInSeconds;
        initQuad();
        initAlphaState();
        initController();
    }
   
    private void initQuad() {
        getLocalRotation().set(0.0f, 0.0f, 0.0f, 1.0f);
        getLocalTranslation().set(DisplaySystem.getDisplaySystem().getWidth() / 2, DisplaySystem.getDisplaySystem().getHeight() / 2, 0.0f);
        getLocalScale().set(1.0f, 1.0f, 1.0f);
        setRenderQueueMode(Renderer.QUEUE_ORTHO);
        setLightCombineMode(LightState.OFF);
        setColorBuffer(null);
        color = new ColorRGBA(0.0f, 0.0f, 0.0f, 0.0f);
        setDefaultColor(color);
    }
   
    private void initAlphaState() {
        alphaState = DisplaySystem.getDisplaySystem().getRenderer().createAlphaState();
        alphaState.setBlendEnabled(true);
        alphaState.setSrcFunction(AlphaState.SB_SRC_ALPHA);
        alphaState.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
        alphaState.setTestEnabled(true);
        alphaState.setTestFunction(AlphaState.TF_GREATER);
        alphaState.setEnabled(true);
        setRenderState(alphaState);
    }
   
    private void initController() {
        fadeController = new Controller() {
            private static final long serialVersionUID = 1L;

            public void update(float time) {
                // Fix for lagged startups
                if (ignoreUntilStable) {
                    if (time < 0.1f) {
                        ignoreUntilStable = false;
                    }
                    return;
                }
                if ((mode == FADE_IN) && (alpha > 0.0f)) {
                    alpha -= 1 / (fadeTimeInSeconds / time);
                    if (alpha < 0.0f) alpha = 0.0f;
                    color.a = alpha;
                } else if ((mode == FADE_OUT) && (alpha < 1.0f)) {
                    alpha += 1 / (fadeTimeInSeconds / time);
                    if (alpha > 1.0f) alpha = 1.0f;
                    color.a = alpha;
                } else if ((mode == DISABLED) && (color.a != 0.0f)) {
                    color.a = 0.0f;
                }
            }
        };
        addController(fadeController);
    }
   
    public void setMode(int mode) {
        this.mode = mode;
        ignoreUntilStable = true;
    }
   
    public int getMode() {
        return mode;
    }
   
    public void setAlpha(float alpha) {
        this.alpha = alpha;
        color.a = alpha;
    }

    public float getAlpha() {
        return alpha;
    }
}



Let me know when this is in the repository so I can switch to using it instead.

darkfrog

Yes, nice - what about a bit of JavaDoc :smiley:



Then, I'd like to remove the following classes in favor of the one you posted here:

com.jmex.effects.transients.FadeInOut

com.jmex.effects.transients.FadeInOutController

com.jmex.effects.transients.Transient

And I'd like to replace TestFadeInOutTransientEffect with a test for the new class. Would you mind to write one / change the old one, darkfrog?



Any objections from people using FadeInOut?

Certainly not from me. It'd be nice if you can set the colour it will fade to though.

You guys sure are picky wanting documentation, tests, and now COLOR? :-p



I'll add that to the TODO and re-post when it's been finished.



darkfrog

hehe

*wonders what happend to this!  XD *



Im trying to use the FadeIn/FadeOut made by Ahmed (if i spelled his name right) but Im having some trouble with it. I tried to use your sample DonkereKikker (actually, DuistereKikker is a better translation XD ) but the fading isnt working rightly here. Is that because the code isnt finished completly or should I spend some more time into looking at it?



Thanks!

Okay, now this is my first commit to CVS so you better not have gotten me in trouble by doing this. :-p



I put Fader into com.jmex.effects.transients.Fader and created com.jmetest.effects.transients.TestFader.  Now temporarily I left all the FadeInOut stuff that DP did alone and simply put this in the same area.  If all the developer's are happy with this I'll go ahead and delete them (or they can).



darkfrog

Thanks! Im going to check it out right away.



And in case you might've broken something, i'd suggest, judging from your signature, to just manically laugh out loudly !  XD

I checked JMEt out in eclipse a couple of times, are you sure you already added it or am I too impatient! :stuck_out_tongue:

I've gone ahead and removed the older code since the newer Fader is more maintainable and straightforward…  :)  Thanks darkfrog.

@Darklord: I heard a rumor that their is a synchronized copy of CVS for the anonymous users for Java.net so it can not be always up-to-date.  I'm not sure if that's true, but that could be the case here if you're not seeing the changes (obviously Renanse is)



@Renanse: Thanks, I was scared you and Mojo would come kill me in my sleep for not adding an issue for it in the tracker first and referencing it in the commit. :stuck_out_tongue:



darkfrog

I got it and it's perfect!



Darkfrog for president!  XD

Darklord said:

Darkfrog for president!  XD


Yes, yes, keep that to yourself. :o  You'll be called upon when the time comes.  :evil:

darkfrog

You just give me a ring when you have elections in your frog empire! :slight_smile:

So long as I keep my one ring to bind them all…



darkfrog