Search code examples
javascreenlwjglslick2dlighting

Slick2d Lighting with multiply


I'm trying to create some 2d lighting in slick2D. However the result is not quite what I'm looking for.

Currently it's working by drawing the light onto a lightmap and then drawing the lightmap to the screen. When drawing the light to the lightmap I'm just using the screen draw mode, and when drawing the lightmap I'm using the multiply draw mode.

The result is this Drawing the lightmap with normal draw mode I get this

I used the Lightmap image in photoshop and changed the blendingmode to multiply and got this.

For some reason the photoshop result is very dark. It looks much better in photoshop before saving, not as dark.

My question now is how do I get closer to the photoshop result?

This is my code:

public class Light 
{

    public Vector2f Pos;
    public static Image light;
    public Image lightCopy;
    public static Image lightmap;

    private float size=256;
    private static float maxSize=1024;
    public Color lightColor = new Color(255,255,255,255);;
    private static Graphics g2;
    private static Graphics g3;

    public static ArrayList<Light> LightList = new ArrayList<Light>();

    public static void init() throws SlickException
    {
        light = new Image("Light.png");

        lightmap = new Image(1920,1080);

        g3=lightmap.getGraphics();
        maxSize=light.getWidth();
    }


    public Light(Vector2f Pos) throws SlickException
    {
        this.Pos=Pos;
        LightList.add(this);
        lightCopy = light.copy();
        g2=lightCopy.getGraphics();
    }

    public void updateSingle(GameContainer gc, ArrayList<Object> BlockingObjects) throws SlickException
    {
        lightCopy = light.copy();
        g2.setDrawMode(Graphics.MODE_NORMAL);
        g2.setColor(Color.black);
        Rectangle lightPosAndSize = new Rectangle(0,0,maxSize,maxSize);
        g2.fill(lightPosAndSize);
        Vector2f pos = new Vector2f((maxSize/2)-(size/2),(maxSize/2)-(size/2));
        g2.drawImage(light.getScaledCopy(size/maxSize),pos.x, pos.y);
        for(int i=0;i!=BlockingObjects.size();i++)
        {
            Object temp = BlockingObjects.get(i);
            String type = temp.getClass().getSimpleName();
            switch(type)
            {
            case "Circle":
            {
                Circle c = (Circle) temp;
                caseCircle(c);
                break;
            }
            default:
            }
        }
        g2.flush();
    }

    public void renderToLightMap(Graphics g) throws SlickException
    {
        g3.setDrawMode(Graphics.MODE_SCREEN);
        g3.drawImage(lightCopy, Pos.x-maxSize/2, Pos.y-maxSize/2,lightColor);
        g3.setDrawMode(Graphics.MODE_NORMAL);
        g3.flush();
    }

    public static void renderLightmap(Graphics g)
    {
        g.setDrawMode(Graphics.MODE_COLOR_MULTIPLY);
        g.drawImage(lightmap, 0, 0);
        g.setDrawMode(Graphics.MODE_NORMAL);
    }

    private void caseCircle(Circle c)
    {

    }



    public static void renderAll(Graphics g, GameContainer gc,ArrayList<Object> BlockingObjects ) throws SlickException 
    {
        g3=lightmap.getGraphics();
        g3.setColor(new Color(0,0,0));
        g3.fill(new Rectangle(0,0,1920,1080));
        g3.flush();
        for(int i=0;i!=LightList.size();i++)
        {
            Light temp = LightList.get(i);
            temp.updateSingle(gc, BlockingObjects);
            temp.renderToLightMap(g);   
        }
        renderLightmap(g);
    }

I was going to post this at the slick2d forum, however I didn't recieve the activation mail so I couldn't create a thread there.

Hopefully you understand my problem and if you need more information I will try to provide you with it. Hopefully the links of my images works as well.


Solution

  • Solved the problem myself.

    I changed the render lightmap method to this

    public static void renderLightmap(Graphics g)
    {
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_ONE_MINUS_SRC_ALPHA);
        g.drawImage(lightmap, 0, 0);
        GL11.glDisable(GL11.GL_BLEND);
        g.setDrawMode(Graphics.MODE_NORMAL);
    }