I am testing libgdx with box2dlights for a small 2d game. I got the point light to follow the mouse cursor and have one direction light setup. I also have a .tmx rendered and created some Box2D bodies. The problem is I cant get the shadows working.
Video: https://www.youtube.com/watch?v=Rhjj1TGavDU
Source code: http://pastebin.com/wVZP5WNc
package com.mygdx.game;
import box2dLight.DirectionalLight;
import box2dLight.PointLight;
import box2dLight.RayHandler;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.MapObjects;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
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;
public class LightingTest implements Screen {
final Drop game;
float screenW, screenH;
OrthographicCamera cam;
OrthogonalTiledMapRenderer mapRenderer;
MapObjects mapObjects;
SpriteBatch mapBatch;
World world;
OrthographicCamera boxLightCamera;
RayHandler rayHandler;
Box2DDebugRenderer debugRenderer;
int TILE_SIZE = 64;
float PIXEL_PER_METER = 1 / 64f;
PointLight pl;
DirectionalLight dl;
public LightingTest(final Drop gam) {
this.game = gam;
screenW = Gdx.graphics.getWidth();
screenH = Gdx.graphics.getHeight();
cam = new OrthographicCamera(30, 30 * (screenH / screenW));
cam.position.set(cam.viewportWidth / 2f, cam.viewportHeight / 2f, 0);
cam.update();
TiledMap map = new TmxMapLoader().load("assets/map01.tmx");
mapBatch = new SpriteBatch();
mapRenderer = new OrthogonalTiledMapRenderer(map, PIXEL_PER_METER, mapBatch);
mapRenderer.setView(cam);
mapObjects = map.getLayers().get("objects").getObjects();
debugRenderer = new Box2DDebugRenderer();
boxLightCamera = createBox2DCam();
world = new World(new Vector2(), true);
rayHandler = createRayHandler(boxLightCamera);
createLights();
createWorldScenery(map);
}
private RayHandler createRayHandler(OrthographicCamera boxLightCamera) {
RayHandler.useDiffuseLight(true);
RayHandler rayHandler = new RayHandler(world);
rayHandler.setCombinedMatrix(boxLightCamera.combined);
rayHandler.setShadows(true);
//rayHandler.setAmbientLight(0.2f, 0.2f, 0.2f, 0.1f);
return rayHandler;
}
private void createLights() {
pl = new PointLight(rayHandler, 128);
pl.setDistance(500);
pl.setPosition(150, 150);
pl.setColor(new Color(0.4f, 0.4f, 0f, 1f));
pl.setSoftnessLength(0);
pl.setSoft(true);
dl = new DirectionalLight(rayHandler, 128, new Color(0.3f, 0.3f, 0.3f, 1f), 45);
dl.setSoftnessLength(0);
dl.setSoft(true);
}
private OrthographicCamera createBox2DCam() {
// light camera
OrthographicCamera boxLightCamera = new OrthographicCamera();
float boxLightViewportWidth = cam.viewportWidth / PIXEL_PER_METER;
float boxLightViewportHeight = cam.viewportHeight / PIXEL_PER_METER;
boxLightCamera.setToOrtho(true, boxLightViewportWidth, boxLightViewportHeight);
boxLightCamera.update(true);
return boxLightCamera;
}
protected void createWorldScenery(TiledMap tileMap) {
// build plan for wall bodies
float halfBody = TILE_SIZE / 64f / 2;
PolygonShape tileShape = new PolygonShape();
tileShape.setAsBox(0.5f, 0.5f);
BodyDef tileBodyDef = new BodyDef();
tileBodyDef.type = BodyType.StaticBody;
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = tileShape;
fixtureDef.filter.groupIndex = 0;
// create box2d bodies for all wall tiles
TiledMapTileLayer layer = (TiledMapTileLayer) tileMap.getLayers().get(0);
int cols = layer.getWidth();
int rows = layer.getHeight();
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
if (col == 0 || col == cols - 1 || row == 0 || row == rows - 1) {
continue;
}
int tileId = layer.getCell(col, row).getTile().getId();
if (tileId == 1) {
float bodyX = col + halfBody;
float bodyY = row + halfBody;
tileBodyDef.position.set(bodyX, bodyY);
Body tileBody = world.createBody(tileBodyDef);
tileBody.createFixture(fixtureDef);
}
}
}
tileShape.dispose();
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (Gdx.input.isKeyPressed(Keys.ESCAPE)) {
Gdx.app.exit();
}
pl.setPosition(Gdx.input.getX(), Gdx.input.getY());
mapRenderer.render();
game.batch.begin();
game.batch.end();
boxLightCamera.update();
rayHandler.setCombinedMatrix(boxLightCamera.combined,
boxLightCamera.position.x, boxLightCamera.position.y,
boxLightCamera.viewportWidth * boxLightCamera.zoom,
boxLightCamera.viewportHeight * boxLightCamera.zoom);
rayHandler.updateAndRender();
debugRenderer.render(world, cam.combined);
}
@Override
public void dispose() {
game.dispose();
mapRenderer.dispose();
mapBatch.dispose();
world.dispose();
rayHandler.dispose();
debugRenderer.dispose();
}
@Override
public void resize(int width, int height) {
}
@Override
public void hide() {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void show() {
}
}
I am expecting when I move the Point light for shadows to appear behind/around the collision shapes. Or some shadows behind the collision shapes opposite of where the directional light is placed.