Slick Forums

Discuss the Slick 2D Library
It is currently Thu Oct 18, 2018 4:55 am

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Sun Jan 22, 2012 2:52 am 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
When a transparent image is rendered to an empty texture, it will appear less opaque than it would had it been rendered normally to screen. Seems like the problem has to do with OpenGL blending the image to the empty texture's background (i.e. glClearcolor).

Here's a screen shot -- the first image is rendered normally to screen. The second is rendered to a new texture, and that texture is then rendered to screen (the difference is obvious). The third image is the workaround; GL blending is disabled before rendering the sprite to a new texture.
Image

Here's the code:
Code:
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.*;

public class ImageBlendTest extends BasicGame {

    public ImageBlendTest() {
        super("ImageBlendTest");
    }
   
    Image hud, hud2, hud3;
   
    public void init(final GameContainer container) throws SlickException {
        //regular image
        hud = new Image("res/sample.png");
       
        //render-to-texture
        hud2 = new Image(hud.getWidth(), hud.getHeight());
        Graphics g = hud2.getGraphics();
        g.drawImage(hud, 0, 0);
        g.flush();
       
        //workaround
        hud3 = new Image(hud.getWidth(), hud.getHeight());
        g = hud3.getGraphics();
        g.clear(); //this will trigger a "predraw()" on the new graphics
        GL11.glDisable(GL11.GL_BLEND);
        hud.draw();
        GL11.glEnable(GL11.GL_BLEND);
        g.flush();
    }

    public void update(GameContainer container, int delta) throws SlickException {
       
    }
   
    public void render(GameContainer container, Graphics g) throws SlickException {
        hud.draw(20, 50);
        hud2.draw(200, 50);
        hud3.draw(380, 50);
    }
   

    public static void main(String[] argv) {
        try {
            AppGameContainer container = new AppGameContainer(new ImageBlendTest());
            container.setDisplayMode(800, 600, false);
            container.start();
        } catch (SlickException e) {
            e.printStackTrace();
        }
    }
}


sample.png:
Image


Edit: Here is a better workaround; thanks to MatthiasM
Code:
        hud3 = new Image(hud.getWidth(), hud.getHeight());
        g = hud3.getGraphics();
        g.clear();
        GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_SRC_ALPHA);
        hud.draw();
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
        g.flush();


Top
 Profile  
 
PostPosted: Sun Jan 22, 2012 2:37 pm 
Offline
Game Developer
User avatar

Joined: Thu Mar 03, 2011 6:22 pm
Posts: 534
I put it on my list and implement it as soon as our new development team is organized enough :)

_________________
Current Projects:
Image Mr. Hat I
Image Vegan Vs. Zombies
Projects:
RadicalFish Engine - Build on top of Slick2D, Ideas, Bugs? Open an Issue ticket!


Top
 Profile  
 
PostPosted: Fri Feb 17, 2012 2:11 am 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
For those interested, I've looked into this a little more. Thanks to some code from TWL, I might have something working. There are now three ways I render offscreen images:

  • The typical way that Slick does, using standard blending. This results in transparency loss, but if the image doesn't require transparency (or if the offscreen image is being cleared with a solid background color), then it's not a big deal.
  • By disabling blending -- this needs to be done before drawing to the FBO. Using the blendFunc GL_ONE, GL_SRC_ALPHA also works. The downside: I can't draw multiple images inside the FBO that overlap the transparent background and each other.
    Code:
    Graphics g = hud.getGraphics();
    GL11.glDisable(GL11.GL_BLEND);
    hud.draw();
    GL11.glEnable(GL11.GL_BLEND);
    //draw other stuff here...
    g.flush();
  • The third option requires GL 1.4 (which pretty much everybody has) and is a little more complex, but if you need the images to overlap on a transparent background, it works:
    Code:
       if (!GLContext.getCapabilities().OpenGL14)
          throw new RuntimeException("needs OpenGL 1.4 for this type of blending");
       Graphics g = img.getGraphics();
       //clear the background with alpha of 1.0
       GL11.glClearColor(0f, 0f, 0f, 1f);
       g.clear();
       GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA,
             GL11.GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA);
       //render your images to the graphics ....
       g.flush();
       
       ... then, when rendering the image:
       GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_SRC_ALPHA);
       g.drawImage(offscreenImg);
       GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);


Top
 Profile  
 
PostPosted: Thu Sep 20, 2012 9:02 pm 
Offline

Joined: Sat Feb 19, 2011 2:59 pm
Posts: 52
where is this bug in the slick code? is this already clear? i mean it's a very serious bug and i am wondering why slick offers many many features but the most important feature: drawing 2d sprites is buggy ?!

_________________
http://www.p1sim.org - Economy/Logistics simulaton based on Java and Slick2D


Top
 Profile  
 
PostPosted: Fri Sep 21, 2012 8:29 am 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
What you're trying to achieve isn't a common technique, which is why this issue has gone so many years without being noticed. For dynamic lighting, most hardware accelerated games use sprites/polygons, shaders, or vertex coloring, and don't require it all done in off-screen images. Your approach (blending large feathered circles across the screen) will quickly lead to a fill-rate bottleneck.

Unfortunately because Slick2D aims to be "newb-friendly" there is a tradeoff of sorts. For example, things like drawImage and drawString do not map to OpenGL directly; these abstractions come at the cost of performance and other quirks. If Slick's simple interface isn't allowing you to achieve what you need, there is nothing holding you back from learning OpenGL and writing your own rendering code.

I posted a suggestion in your other thread. You could also use a tool like this to help you decide on what kind of blending function you're aiming for. If you need something more specific, e.g. a Photoshop-like blend mode, you may want to look into shaders. If you want to know more about why this bug occurs, you can read up on OpenGL blend modes and frame buffer objects.


Top
 Profile  
 
PostPosted: Fri Sep 21, 2012 9:09 am 
Offline

Joined: Sat Feb 19, 2011 2:59 pm
Posts: 52
davedes wrote:
What you're trying to achieve isn't a common technique, which is why this issue has gone so many years without being noticed. For dynamic lighting, most hardware accelerated games use sprites/polygons, shaders, or vertex coloring, and don't require it all done in off-screen images. Your approach (blending large feathered circles across the screen) will quickly lead to a fill-rate bottleneck.

Unfortunately because Slick2D aims to be "newb-friendly" there is a tradeoff of sorts. For example, things like drawImage and drawString do not map to OpenGL directly; these abstractions come at the cost of performance and other quirks. If Slick's simple interface isn't allowing you to achieve what you need, there is nothing holding you back from learning OpenGL and writing your own rendering code.

I posted a suggestion in your other thread. You could also use a tool like this to help you decide on what kind of blending function you're aiming for. If you need something more specific, e.g. a Photoshop-like blend mode, you may want to look into shaders. If you want to know more about why this bug occurs, you can read up on OpenGL blend modes and frame buffer objects.


Thanks for the info. (I will discuss my specific problem in the other thread.)

_________________
http://www.p1sim.org - Economy/Logistics simulaton based on Java and Slick2D


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group