Smoothing edges

Anything libgdx related goes here!

Smoothing edges

Postby Mercury » Thu Mar 03, 2011 6:56 pm

Hello everybody !

I'm making a port of my game that I created as a final exam at College of Electrical Engineering and Computer Science (here's link :http://www.youtube.com/watch?v=n4oQr7E1bpU&feature=channel_video_title) . It's a physics game something like Crash the Castle game. Everything is working fine and porting game is going smooth and I'm having a blast with this libreary.

So I have a question regarding smoothing edges. Because It's a 2d game, I'm using spritebatch and orthographic camera for matrix manipulation. When I zoom the camrea out the sharp edges appear. Is there any solution ? :(

Image

It's really important for me, because I want the game to have smooth look, and this will probably ruin it. Thanks in advance. Lingdx rocks ! :D

Mercury :ugeek:
Mercury
 
Posts: 27
Joined: Sat Oct 23, 2010 10:03 am
Location: Serbia and Montenegro, Budva

Re: Smoothing edges

Postby mzechner » Fri Mar 04, 2011 2:34 am

try this on your texture(s)

Code: Select all
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);


this might have an impact on performance on older devices like the Hero, but probably not much in your case. The background doesn't need that filter necessarily imo.
mzechner
Site Admin
 
Posts: 4598
Joined: Sat Jul 10, 2010 3:50 pm

Re: Smoothing edges

Postby Mercury » Fri Mar 04, 2011 7:02 am

mzechner wrote:try this on your texture(s)

Code: Select all
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);


this might have an impact on performance on older devices like the Hero, but probably not much in your case. The background doesn't need that filter necessarily imo.


For asset loading I'm using TextureAtlass, and as you said, it's filter is set to linear ( I reed your article about texture filters on badlogic blog) :
Code: Select all
materials.png
format: RGBA8888
filter: Linear, Linear
repeat: none
wood
  rotate: false
  xy: 32, 160
  size: 32, 32
  orig: 32, 32
  offset: 0, 0
  index: 1
wood
  rotate: false
  xy: 0, 128
  size: 64, 32
  orig: 64, 32
  offset: 0, 0
  index: 2
stone
  rotate: true
  xy: 0, 96
  size: 32, 128
  orig: 32, 128
  offset: 0, 0
  index: 4
wood
  rotate: false
  xy: 0, 160
  size: 32, 64
  orig: 32, 64
  offset: 0, 0
  index: 3
wood
  rotate: false
  xy: 0, 0
  size: 128, 32
  orig: 128, 32
  offset: 0, 0
  index: 4
stone
  rotate: false
  xy: 64, 128
  size: 64, 32
  orig: 64, 32
  offset: 0, 0
  index: 2
wood
  rotate: true
  xy: 0, 64
  size: 32, 128
  orig: 32, 128
  offset: 0, 0
  index: 5
stone
  rotate: false
  xy: 32, 192
  size: 32, 32
  orig: 32, 32
  offset: 0, 0
  index: -1
stone
  rotate: false
  xy: 0, 32
  size: 128, 32
  orig: 128, 32
  offset: 0, 0
  index: 5
stone
  rotate: true
  xy: 0, 224
  size: 32, 64
  orig: 32, 64
  offset: 0, 0
  index: 3


shootCastleSmashers2.png
shootCastleSmashers2.png (56.54 KiB) Viewed 5673 times


Here's my code if you can find something that is not right :

Code: Select all
package me.mercury;

import java.util.ArrayList;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

import me.mercury.utils.AssetManager;
import me.mercury.utils.InputManager;
import me.mercury.utils.Screen;
import me.mercury.utils.ScreenManager;

public class TitleScreen extends Screen {

   enum Side
   {
      left,
      right
   }
   
   private Sprite s;
   private Side side;
   private Body groundBody;
   private final int RATIO = 30;
   private ArrayList<Body> boxes = new ArrayList<Body>();
   private Box2DDebugRenderer renderer;
   private World world;
   
   public TitleScreen(String name) {
      super(name);
   }
   
   @Override
   public Boolean Init() {

      side = Side.left;
      cam = new OrthographicCamera(480, 320);
      cam.position.x = 240;
      cam.position.y = 160;
      s = AssetManager.backgrounds.createSprite("background");
      renderer = new Box2DDebugRenderer();
      InitializePhysics();
      
      return super.Init();
   }
   
   private void InitializePhysics() {
      
      world = new World(new Vector2(0,-200),true);
      world.setContactListener(new BoxContactListener());
      PolygonShape groundPoly = new PolygonShape();
      groundPoly.setAsBox(1024, 100);
      BodyDef groundBodyDef = new BodyDef();
      groundBodyDef.type = BodyType.StaticBody;
      groundBody = world.createBody(groundBodyDef);
      groundBodyDef.position.set(0,0);
      FixtureDef fixtureDef = new FixtureDef();
      fixtureDef.shape = groundPoly;
      fixtureDef.filter.groupIndex = 0;
      groundBody.createFixture(fixtureDef);
      groundPoly.dispose();
      
      createBoxes();
   }
   
   private void createBoxes () {

      PolygonShape boxPoly = new PolygonShape();
      boxPoly.setAsBox(32/2, 64/2);

      for (int i = 0; i < 20; i++) {
         BodyDef boxBodyDef = new BodyDef();
         boxBodyDef.type = BodyType.DynamicBody;
         boxBodyDef.position.x = (float)(Math.random() * 1000);
         boxBodyDef.position.y = 500 + (float)(Math.random() * 320);
         boxBodyDef.angle = (float) (Math.random() * 360);
         Body boxBody = world.createBody(boxBodyDef);
         boxBody.createFixture(boxPoly, 1);
         boxes.add(boxBody);
      }
      
      boxPoly.dispose();
   }


   @Override
   public void ShutDown() {
      boxes = null;

      super.ShutDown();
   }
   
   @Override
   public void Update(float gameTime) {

      world.step(gameTime, 20, 20);

      if(side == Side.left){
         if(cam.position.x > 550)
         {
            side = Side.right;
         }
         cam.zoom += 0.005;
         cam.translate(2, 1, 0);
      }
      else
      {
         if(cam.zoom < 1.1)
         {
            side = Side.left;
         }
         cam.zoom -= 0.005;
         cam.translate(-2, -1, 0);
      }
      
      if(InputManager.touched)
      {
         ScreenManager.go_back();
      }

      super.Update(gameTime);      
   }

   @Override
   public void Draw(SpriteBatch spriteBatch) {
      
      Gdx.gl.glClearColor(0, 0, 0, 0);
      Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
      cam.update();
      spriteBatch.setProjectionMatrix(cam.combined);
      spriteBatch.begin();
         spriteBatch.disableBlending();
         spriteBatch.draw(s, 0, 0);
         spriteBatch.enableBlending();
         drawBoxes(spriteBatch);
      spriteBatch.end();
      //renderer.render(world);   
      
      super.Draw(spriteBatch);
   }

   private void drawBoxes(SpriteBatch spriteBatch) {

      for (int i = 0; i < boxes.size(); i++) {
         Body b = boxes.get(i);
         
         spriteBatch.draw(AssetManager.materials.getRegions().get(1), b.getPosition().x-16, b.getPosition().y-32, 16, 32, 32, 64, 1, 1, (int)(b.getAngle()*180/Math.PI));
      }
      
   }

}

}


Thanks again for taking time to help me Mario :) You're the best !

Mercury
Mercury
 
Posts: 27
Joined: Sat Oct 23, 2010 10:03 am
Location: Serbia and Montenegro, Budva

Re: Smoothing edges

Postby NateS » Sat Mar 05, 2011 12:45 am

You can try...
AssetManager.materials.getRegions().get(1).getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
...just to make sure there is no bug in TexturePacker/TextureAtlas.

Note that, assuming AssetManager.materials is a TextureAtlas, getting the region by ordinal is not guaranteed to be the same region if you repack (though it will be if no images are added or removed).

You can use b.getAngle()*MathUtils.radiansToDegrees if you want.
NateS
 
Posts: 1942
Joined: Fri Nov 12, 2010 11:08 am

Re: Smoothing edges

Postby mzechner » Sat Mar 05, 2011 2:27 am

Actually, the problem is that there's no anti-aliasing at the borders of the rectangles. Hence the jagged edges. Sadly, there's no AA on Android either, and the texture filter doesn't affect the border regions of the geometry (the outline). Not sure if this can be solved at this point.
mzechner
Site Admin
 
Posts: 4598
Joined: Sat Jul 10, 2010 3:50 pm

Re: Smoothing edges

Postby AramHase » Sun Mar 06, 2011 3:10 am

Okay, maybe I'm complete wrong, but, what about making the borders of your texture with some "alpha"? Maybe it will smooth things out? like, the texture will be bit bigger, but instead of just a black line on the borders, it has some gradient going from black to full transparency...

Never tried it, just an idea ...
AramHase
 
Posts: 12
Joined: Wed Mar 02, 2011 4:53 am

Re: Smoothing edges

Postby mzechner » Sun Mar 06, 2011 4:56 am

that idea sounds about right to me.
mzechner
Site Admin
 
Posts: 4598
Joined: Sat Jul 10, 2010 3:50 pm

Re: Smoothing edges

Postby Mercury » Sun Mar 06, 2011 9:49 am

This is what I done, and It's working :

Image

I created a texture with transparent offset of 2px.
I than recalculate that offset in box2d and everything works.
Because the image is inside a rectangle, there's no jagged lines on the edges,
and the linear filter works his magic on anti aliasing :)

Mission accomplished !

Thanks everybody for help and ideas, I apriciate it :D
Mercury
 
Posts: 27
Joined: Sat Oct 23, 2010 10:03 am
Location: Serbia and Montenegro, Budva

Re: Smoothing edges

Postby mzechner » Sun Mar 06, 2011 2:44 pm

Awesome! Looks great.
mzechner
Site Admin
 
Posts: 4598
Joined: Sat Jul 10, 2010 3:50 pm

Re: Smoothing edges

Postby Obli » Mon Mar 07, 2011 8:49 am

Indeed, for 2D games, never ever rely on openGL to smooth your edges. Anti-aliasing is a complex thing which is very intensive to compute, so do not expect an AA16x on android ;)
For sprites, it's easy, texture filters work like a charm, so this is the way to go !
Obli
 
Posts: 616
Joined: Mon Jan 10, 2011 6:18 pm
Location: Bordeaux, France

Next

Return to Libgdx

Who is online

Users browsing this forum: noone and 6 guests