7

I just started creating a game using libgdx. It is a top down 2d shooter using scene2d ui. Now i thought, that i could add darkness and light to some levels, but i don't want to rewrite everything using box2d. I don't need realistic shadows just some kind of ambient light and a lightcircle arround my character, which is not affected by walls and other obstacles arround him. So i wanted to know if there is any kind of lightsystem in libgdx? Or can i use box2dlights without using box2d bodies/world...? Thanks

Sebastian
  • 4,893
  • 3
  • 40
  • 59
Springrbua
  • 8,377
  • 9
  • 48
  • 92

2 Answers2

27

In my opinion the marked answer is wrong.

Its actually pretty simple to use box2dLights without using box2d if u dont want any shadows. The question was, if its possible to add some kind of circle light around a character.

I used two different approaches, only one using box2dlights.

The article in the marked answer discripes a method using FBO. U dont really need that if u just want to lighten an area. U just need a sprite, like this. Now place it somewhere on ur screen, and when rendering , do the following:

batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_SRC_ALPHA);
theLightSprite.draw(batch, parentAlpha);
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

First the blend function is changed, so we dont just render the sprite, but blend it in a lighting way on the background. After drawing it, reset the blend function to normal, so everything else after this is rendered normally again. Thats it.

Second approach uses box2dlights. Yes, we do need a box2d world object, but we dont need to do something with it. So what we do is:

world = new World(new Vector2(0,0),false);
rayHandler = new RayHandler(world);
rayHandler.setCombinedMatrix(stage.getCamera().combined);
new PointLight(rayHandler,1000, Color.BLUE,radius,x_position,y_position);

First we create our world, thats just doing nothing. We only need it for the second statement, where we create our RayHandler, that calculates our lights. In the third statement we set the matrix of the rayHandler. In this case i use scene2d, and thus using the stages camera combined matrix for it. If u use another camera just use its combined matrix here. The last statement creates a pointlight with the rayHandler, and discribe the number of rays, the lights color, its radius, and its position.

All we have to do now, is draw our stage or sprites in our render() method and call

rayHandler.updateAndRender();

after that in the render method. Pretty easy.

Kedu
  • 1,310
  • 14
  • 25
8

Unfortunately there is nothing like this already provided by LibGDX.

But you can easily do it yourself if you do not want shadows.

Here is a little video of someone who has done it via LibGDX. Here is the article to this video, with code and descriptions and everything provided. You can do it this way with shaders, but you could also do the same by just rendering a lightmap to an FBO (in the given links you can see how to do that) and then just render it the usual way with blending activated on top of your screen. The standard SpriteBatch can do that and you don't need any custom shaders.

If you still want to have real shadows with obstacles, you will probably find this article very useful. But this is a lot slower and needs special shaders.

There is also no way to use Box2dLights without Box2D btw.

noone
  • 18,807
  • 5
  • 58
  • 75
  • Thanks for this realy quick answer. I will go throught this article as soon as possible. Thanks! – Springrbua Jan 22 '14 at 09:02
  • I think i understood how it basicly works. In libgdx i could use the draw method of my stage and overdraw everything with a darkblue, transparent (Alpha = 0.7f or something like that) Color to add ambient light? But how can i then add the bright light to the character? Thanks – Springrbua Jan 22 '14 at 09:33
  • First you render your scene the normal way. Then you create an FBO of the size of your screen, but you set your (background) colour to something like (0.7, 0.7, 0.7, 1.0) for example (ambient lightning). After that you draw all your lights on this FBO, just like you would draw something in your normal scene. They will be white spots on top of a darker background. When you are done with it, you will render that FBO with blending enabled on top of your normal scene. All places without a light will get darker because of the dark ambient colour of the fbo. All others will get more bright (lights). – noone Jan 22 '14 at 09:50
  • So the Background (0.7, 0.7, 0.7, 1.0) and the White spots (lights) have Alpha channel 1 and the transparency is then set to the whole FBO and then drawn over my rendered Scene? – Springrbua Jan 22 '14 at 09:52
  • Yes, before you draw the FBO over your scene, you'd set your batch's colour to something like (1, 1, 1, 0.7f), which applies a global alpha to your lightmap. – noone Jan 22 '14 at 10:06
  • Sounds easy to use (: Hope i am not wrong xD I looked at this https://github.com/mattdesl/lwjgl-basics/wiki/FrameBufferObjects and noticed, that the batch is resized in the FBO. I am using a camera in my game, which makes it possible to use my own Worldunit instead of pixels size. Do i have to resize the FBO only if i just want to add ambient light to a part of screen? And if i do so can i resize it by using my Worldunits? – Springrbua Jan 22 '14 at 10:16
  • I don't get your question actually. Your FBO (in case you go the non-shader/blending way) should be the same size as your window/screen. If you use a camera you have to render your lights to the FBO using that camera as well. Otherwise they will not appear where they are supposed to be. Maybe you should try it and if you run into problems, post a new question and add your code to it. – noone Jan 22 '14 at 11:53
  • So the FBO uses the same spritebatch and so the same camera (i set the spritebatchs projectionMatrix to camera.combined)? So i don't have to resize it right? – Springrbua Jan 22 '14 at 13:00
  • I just noticed, that FBO only works with OpenGL ES 2.0. My game will be desktop only for the moment. Which version of OpenGL (not ES) do i have to use then? And are there some things i have to change then? – Springrbua Jan 27 '14 at 13:17
  • 1
    http://www.opengl.org/wiki/Framebuffer_Object says "since version 3.0". I don't think you have to change anything. Since LibGDX does abstract that anyway. – noone Jan 27 '14 at 14:12
  • Thats great! I just worried cause i read that some Android devices have problems with OpenGl ES 2.0 and FBO is only supported with OpenGl Es 2.0. So i thought it could cause some problems on desktop to. Thanks – Springrbua Jan 27 '14 at 14:14
  • 1
    uumm, ya... some devices have problems with OpenGL ES 2... about 0.1% (http://developer.android.com/about/dashboards/index.html#OpenGL) – noone Jan 27 '14 at 14:26
  • Oh so many... I have read aboud this "issue" many times so 0.1% shock me a little :P – Springrbua Jan 27 '14 at 14:30
  • I have a libgdx stage with its own 50 width and 31 high camera. I set the spritebatchs projection-matrix to camera.combined. If i use the same spritebatch for the FBO do i have to set its width to 50 and hight to 31 and set the light positions in world units (P(50/0) is the bottom right)? Or have i do it in pixels? – Springrbua Feb 04 '14 at 08:15
  • @Springrbua Please stop asking more and more questions in the comments. Open a new question and add the necessary information (code) to it. That way there could also be someone else answering. – noone Feb 04 '14 at 08:23
  • i opened a new question. Just thought that little thing is not worth a new question. But thanks again! – Springrbua Feb 04 '14 at 08:37