Slick Forums

Discuss the Slick 2D Library
It is currently Sat Feb 23, 2019 1:02 am

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: FrameBuffer
PostPosted: Sat Mar 10, 2012 4:33 pm 
Offline
Oldbie
User avatar

Joined: Thu Jan 13, 2011 4:42 pm
Posts: 349
I recently found out that my game's fps would increase by 50% if I didn't render a background tilemap. I figured it would be best to render the relatively small tiled map to a texture instead, and render that texture.

Unfortunately, this would not work by traditional means, so I did some research, and it turns out that libgdx has a Framebuffer class that allows me to render to a libgdx texture. however, I don't know how to get a libgdx texture to be used by a slick.

Does anybody know how I can create an image in Slick-AE?

_________________
"Artificial intelligence will never be a match for human stupidity" - "Jamos Kennedynos"


Top
 Profile  
 
 Post subject: Re: FrameBuffer
PostPosted: Sat Mar 10, 2012 8:33 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
You shouldn't need to do much hacking since both Slick and LibGDX use glBindTexture. It would look like this:
Code:
      .. inside init ..
   
         //you should first check to see if FBOs are supported
         //then you create an FBO with a particular size and internal format
         fbo = new FrameBuffer(Format.RGB565, 256, 256, false);

      .. inside render ..
   
         //begin the FBO
         fbo.begin();
   
         // ... render slick graphics, it will go to FBO tex ... //
   
         //end the FBO
         fbo.end();
   
         //then you have to render the FBO texture to the screen..
   
         //rather than bindNone (which disables textures altogether),
         //we just want to clear the last bind
         TextureImpl.unbind();

         //bind the texture (will call glBindTexture)
         fbo.getColorBufferTexture().bind();

         //bind a color filter for the image
         Color.white.bind();

         SGL GL = Renderer.get();
         //you may need to flip the texture -- if so use ty = 1, th = -1
         float ty = 0;
         float th = 1;
         GL.glBegin(SGL.GL_QUADS);
            GL.glTexCoord2f(0, ty); // top left vert
            GL.glVertex3f(x, y, 0);
            GL.glTexCoord2f(1, ty); // top right vert
            GL.glVertex3f(x + fbo.getWidth(), y, 0);
            GL.glTexCoord2f(1, ty+th); // bottom right vert
            GL.glVertex3f(x + fbo.getWidth(), y + fbo.getHeight(), 0);
            GL.glTexCoord2f(0, ty+th); // bottom left vert
            GL.glVertex3f(x, y + fbo.getHeight(), 0);
         GL.glEnd();


If Slick's Image was able to be created without a org.newdawn.slick.Texture (or if you extended TextureImpl to use LibGDX's Texture) then you could also get rid of the ugly glBegin/glEnd stuff.


(note -- this is all untested and theoretical so it might not work at all)


Top
 Profile  
 
 Post subject: Re: FrameBuffer
PostPosted: Mon Mar 12, 2012 4:37 pm 
Offline
Oldbie
User avatar

Joined: Thu Jan 13, 2011 4:42 pm
Posts: 349
Sorry, I meant to reply to myself earlier.

First off, thankyou for the detailed explanation. You show an understanding of OpenGL that I do not have. But unfortunately, there are some problems. I don't know how to use your code to create an image in the enter() method of a basicGameState, and then re-use it throughout the render method. However, even if I did know how to do this, there would e a separate problem because I am using android, detailed here http://www.badlogicgames.com/wordpress/?p=1073. Basically, if the user switches to the homescreen, and then tries to resume the game, all of the gl context is lost, along with any dynamic textures.

I decided to use a workaround. Essentially, I decided to manually add images of the tiled maps that I would use, and render those instead of the actual tiled map.

_________________
"Artificial intelligence will never be a match for human stupidity" - "Jamos Kennedynos"


Top
 Profile  
 
 Post subject: Re: FrameBuffer
PostPosted: Mon Mar 12, 2012 5:28 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
Quote:
I don't know how to use your code to create an image in the enter() method of a basicGameState, and then re-use it throughout the render method.

Maybe something like this: (pseudo code)
Code:
enter {
    if (fbo != null) {
        fbo = new FrameBuffer(Format.RGB565, 256, 256, false);
        updateOffscreen();
    }
}


For context changes, you would have to take that into account. I'm fairly certain LibGDX will re-create the FrameBuffer and its texture on context switching, so all you need to do is update the offscreen image on context loss. You would do something like this:
Code:
MyClass implements RenderListener {
    @Override
    surfaceCreated(Application app) {
        if (fbo != null) { //don't bother updating it if we haven't entered the state
            updateOffscreen();
        }
    }
}


Where updateOffscreen looks pretty much like this:
Code:
updateOffscreen {
    fbo.begin();
    ...render slick graphics here...
    fbo.end();
}


Then in your render() method you would render the FBO texture to the screen using the code I posted earlier (starting at the line TextureImpl.unbind).

FrameBuffer works like so:
  • When you create a new frame buffer, LibGDX tells OpenGL to allocate a texture of the given size. In slick terms, this is the same as using InternalTextureLoader to create an OpenGL texture (although LibGDX supports non-power-of-two size). Preferably you aren't doing this more than once.
  • Calling begin() on FrameBuffer means that anything you render (even if you render it with Slick) will now be rendered to your off-screen texture instead of being rendered to the screen.
  • Calling end() on FrameBuffer returns things to normal, so that rendering goes to the screen
  • Once you're done modifying your texture, you need to render it to the screen in order for it to be visible.


Top
 Profile  
 
 Post subject: Re: FrameBuffer
PostPosted: Mon Mar 19, 2012 7:45 pm 
Offline
Oldbie
User avatar

Joined: Thu Jan 13, 2011 4:42 pm
Posts: 349
Okay, I think I understand now. However, I am still stopped by the fact that the graphics are all destroyed if the user views the homescreen. I will just continue to prerender my maps. Thankyou for the explanation.

_________________
"Artificial intelligence will never be a match for human stupidity" - "Jamos Kennedynos"


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


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:  
cron
Powered by phpBB® Forum Software © phpBB Group