Slick Forums

Discuss the Slick 2D Library
It is currently Thu Jun 20, 2013 6:22 am

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Images in TWL
PostPosted: Sun Oct 30, 2011 12:38 am 
Offline

Joined: Sun Aug 28, 2011 1:58 am
Posts: 41
Hi.

I'd like to be able to simply store and render an image. How would I do this in TWL? It seems that no image class is designed simply for rendering images, and there exists no documentation for the constructors of the classes that do exist - which is fine, since I can look at the source code. I can't/don't want to use:

  • GridImage (it seems to store an array of images- overkill)
  • TextureArea (there is no documentation whatsoever on how to instantiate a TextureArea object - one of the parameters LWJGLTexture itself requires another LWJGL object as a parameter)
  • AnimatedImage (I want a static image)


I tried creating my own class:
Code:
package gui;

import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;

import de.matthiasmann.twl.Color;
import de.matthiasmann.twl.Widget;
import de.matthiasmann.twl.renderer.AnimationState;

public class SimpleImage extends Widget implements de.matthiasmann.twl.renderer.Image {
    private Image slickImage;
   
    SimpleImage(String fileName) throws SlickException {
        this(fileName, null, false);
    }
   
    SimpleImage(SimpleImage rhs) {
        super(rhs.getAnimationState(), false); // Should this be true or false?
        slickImage = rhs.slickImage.copy();
        setInnerSize(slickImage.getWidth(), slickImage.getHeight());
    }
   
    SimpleImage(String fileName, de.matthiasmann.twl.AnimationState animState, boolean inherit) throws SlickException {
        super(animState, inherit);
        slickImage = new Image(fileName);
        setInnerSize(slickImage.getWidth(), slickImage.getHeight());
    }

    @Override
    public void draw(AnimationState as, int x, int y) {
        draw(x, y);
    }
   
    @Override
    public void draw(AnimationState as, int x, int y, int width, int height) {
        slickImage.draw(x, y, 0, 0, width, height);
    }
   
    public void draw(int x, int y) {
        slickImage.draw(x, y);
    }

    @Override
    public de.matthiasmann.twl.renderer.Image createTintedVersion(Color color) {
        // Do nothing for now...
        return new SimpleImage(this);
    }
}


But I get some error regarding recursively adding widgets to the GUI:

Quote:
Sun Oct 30 10:54:38 CST 2011 ERROR:null
java.lang.NullPointerException
at de.matthiasmann.twl.Widget.recursivelyAddToGUI(Widget.java:2341)
at de.matthiasmann.twl.Widget.recursivelyAddToGUI(Widget.java:2350)
at de.matthiasmann.twl.Widget.recursivelyAddToGUI(Widget.java:2350)
at de.matthiasmann.twl.Widget.insertChild(Widget.java:1214)
at de.matthiasmann.twl.GUI.setRootPane(GUI.java:247)
at twlslick.TWLStateBasedGame.setRootPane(TWLStateBasedGame.java:128)
at twlslick.BasicTWLGameState.enter(BasicTWLGameState.java:80)
at org.newdawn.slick.state.StateBasedGame.update(StateBasedGame.java:261)
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:663)
at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
at poo.Application.main(Application.java:32)
Sun Oct 30 10:54:38 CST 2011 ERROR:Game.update() failure - check the game code.
org.newdawn.slick.SlickException: Game.update() failure - check the game code.
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:669)
at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
at poo.Application.main(Application.java:32)


Cheers.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 30, 2011 6:15 am 
Offline
Slick Zombie

Joined: Fri Jan 29, 2010 7:02 pm
Posts: 1190
Ok, first it's not really clear what you want to do so I'll explain how the system works.

Image is a class which is responsible for rendering an image like object - it doesn't say how the image is stored or generated - that is the job of one of the sub classes.

You can obtain an Image instance by loading a Texture and retrieving a rectangular (sub)area from it:
Code:
   Renderer renderer = gui.getRenderer();
   Texture texture = renderer.loadTexture(url, "COLOR", "LINEAR");
   Image img = texture.getImage(0, 0, texture.getWidth(), texture.getHeight(), Color.WHITE, false, Texture.Rotation.NONE);

This is basically what happens when you use an <area> element in the theme,

The other Image instance you can create is a DynamicImage where you can upload your own texel data:
Code:
   Renderer renderer = gui.getRenderer();
   DynamicImage dynImg = renderer.createDynamicImage(256, 256);

This method is used for example in the color chooser to renderer the hue grid and the luminance bar.

The other Image subclasses in the theme package just take existing Image instances and combine / manipulate how they are rendered.

_________________
TWL - The Themable Widget Library


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 30, 2011 8:22 am 
Offline

Joined: Sun Aug 28, 2011 1:58 am
Posts: 41
Ah, thank you for that. Is that on the Wiki anywhere - did I miss it? I couldn't seem to find it anywhere.

What I was trying to do was create a background image. I'd like to add an Image to the root pane, but Image is not a derivative of Widget. What is the proper way to add an image to the root pane?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 30, 2011 8:34 am 
Offline
Slick Zombie

Joined: Fri Jan 29, 2010 7:02 pm
Posts: 1190
Just give your root pane a theme name like this:
Code:
   Widget rootPane = new Widget();
   rootPane.setTheme("rootpane");
   GUI gui = new GUI(rootPane, renderer);

Then you can just theme it via the theme file.

_________________
TWL - The Themable Widget Library


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 30, 2011 10:27 am 
Offline

Joined: Sun Aug 28, 2011 1:58 am
Posts: 41
MatthiasM wrote:
Just give your root pane a theme name like this:
Code:
   Widget rootPane = new Widget();
   rootPane.setTheme("rootpane");
   GUI gui = new GUI(rootPane, renderer);

Then you can just theme it via the theme file.

Ohhh ok. So it's all done through themes. Thanks, I'll try it out.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 03, 2011 4:31 pm 
Offline

Joined: Thu Jul 28, 2011 3:21 pm
Posts: 17
Location: Hungary
If you want dynamic images then you should read them in a different way than slick does. (Search on the twl forums. I posted my png loader somewhere.) Slick images totally diferr from TWL images.

I use labels to show my images. Set the image with setBackground.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 05, 2011 7:41 am 
Offline

Joined: Sun Aug 28, 2011 1:58 am
Posts: 41
laxika wrote:
If you want dynamic images then you should read them in a different way than slick does. (Search on the twl forums. I posted my png loader somewhere.) Slick images totally diferr from TWL images.

I use labels to show my images. Set the image with setBackground.

Thanks for the reply.

I'm trying to create images using your function that I slightly adjusted:
Code:
private DynamicImage loadTWLImage(String fileName) {
        try {
            InputStream stream = StreamUtils.getInputStream(fileName);

            BufferedImage img = ImageIO.read(stream);
            ByteBuffer bb = ByteBuffer.allocateDirect(img.getWidth() * img.getHeight() * 4);

            for(int i = 0; i < img.getHeight(); i++) {
                for(int j = 0; j < img.getWidth(); j++) {
                    int argb = img.getRGB(j, i);
                    byte alpha = (byte) (argb >> 24);
                    byte red = (byte) (argb >> 16);
                    byte green = (byte) (argb >> 8);
                    byte blue = (byte) (argb);

                    bb.put(red);
                    bb.put(green);
                    bb.put(blue);
                    bb.put(alpha);
                }
            }
            bb.flip();

            DynamicImage dynamicImage = twlRenderer.createDynamicImage(img.getWidth(), img.getHeight());
            dynamicImage.update(bb, DynamicImage.Format.RGBA);
            return dynamicImage;
        } catch(IOException e) {
            LoggerFactory.getLogger(ImageCache.class.getName()).debug(e.getMessage());
            return null;
        }
    }


But I can't see ANY way to get the Renderer used by the GUI without causing an exception. I tried instantiating a new LWJGLRenderer, but of cause the images then don't get drawn.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 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