From 6b98c2f0e326c942d6e06d2ff53ab7d8108f47e4 Mon Sep 17 00:00:00 2001 From: Edward Peterson Date: Fri, 4 Nov 2016 19:22:19 -0400 Subject: [PATCH] Added capabilities for multiple light sources --- core/assets/Fragment.frag | 37 +++++++++++++++----- core/assets/testmap.tmx | 16 ++++++++- core/src/com/toasted/chuck/ChuckGame.java | 25 ++++++++++---- core/src/com/toasted/chuck/Graphics.java | 42 +++++++++++++++++------ core/src/com/toasted/chuck/Light.java | 17 +++++++++ 5 files changed, 110 insertions(+), 27 deletions(-) create mode 100644 core/src/com/toasted/chuck/Light.java diff --git a/core/assets/Fragment.frag b/core/assets/Fragment.frag index 51f0499..6158404 100644 --- a/core/assets/Fragment.frag +++ b/core/assets/Fragment.frag @@ -1,22 +1,43 @@ +#version 410 core //SpriteBatch will use texture unit 0 uniform sampler2D u_texture; uniform vec2 u_screenResolution; +uniform vec2 u_lightCoord[50]; +uniform float u_lightIntensity[50]; +uniform int u_actualLights; //"in" varyings from our vertex shader varying vec4 vColor; varying vec2 vTexCoord; + +float getDistance(float x1, float y1, float x2, float y2){ + float dx = x2 - x1; + float dy = y2 - y1; + float dis = sqrt(dx * dx + dy * dy); + return dis; +} void main() { + + + //sample the texture vec4 texColor = texture2D(u_texture, vTexCoord); - float dx = u_screenResolution.x / 2.0 - gl_FragCoord.x; - float dy = u_screenResolution.y / 2.0 - gl_FragCoord.y; - float dxi = u_screenResolution.x / 2.0; - float dyi = u_screenResolution.y / 2.0; - float dis = sqrt(dx * dx + dy * dy); - float disFull = sqrt(dxi * dxi + dyi * dyi); + + float dis = getDistance(u_screenResolution.x / 2.0, u_screenResolution.y / 2.0, gl_FragCoord.x, gl_FragCoord.y); + float disFull = getDistance(u_screenResolution.x / 2.0, u_screenResolution.y / 2.0, 0, 0); float disSq = (1-(dis / disFull)); - texColor.rgb = texColor.rgb * disSq * disSq * disSq * disSq * disSq; + + + //Distance is measured in pixels + + float brightest = 0; + for(int i = 0;i < u_actualLights;i++){ + float dis2Light = getDistance(gl_FragCoord.x, gl_FragCoord.y, u_lightCoord[i].x, u_lightCoord[i].y); + float dis2Light2 = (1-(min(dis2Light/(disFull * u_lightIntensity[i]), 1))); + brightest = brightest + dis2Light2 - brightest * dis2Light2; + } + texColor.rgb = texColor.rgb * (pow(brightest, 10)); //final color gl_FragColor = texColor * vColor; -} \ No newline at end of file +} diff --git a/core/assets/testmap.tmx b/core/assets/testmap.tmx index 3609896..2568d93 100644 --- a/core/assets/testmap.tmx +++ b/core/assets/testmap.tmx @@ -1,5 +1,5 @@ - + @@ -112,4 +112,18 @@ + + + + + + + + + + + + + + diff --git a/core/src/com/toasted/chuck/ChuckGame.java b/core/src/com/toasted/chuck/ChuckGame.java index 13ad923..60324e0 100644 --- a/core/src/com/toasted/chuck/ChuckGame.java +++ b/core/src/com/toasted/chuck/ChuckGame.java @@ -12,10 +12,10 @@ import com.badlogic.gdx.maps.MapLayer; import com.badlogic.gdx.maps.MapObject; import com.badlogic.gdx.maps.objects.RectangleMapObject; import com.badlogic.gdx.maps.tiled.TiledMap; -import com.badlogic.gdx.maps.tiled.TiledMapRenderer; import com.badlogic.gdx.maps.tiled.TmxMapLoader; import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer; import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; public class ChuckGame extends ApplicationAdapter implements InputProcessor{ Graphics graphics; @@ -25,6 +25,8 @@ public class ChuckGame extends ApplicationAdapter implements InputProcessor{ TiledMap tiledMap; OrthogonalTiledMapRenderer tmRenderer; ArrayList collisions = new ArrayList(); + ArrayList lights = new ArrayList(); + Light playerLight; @Override public void create () { Gdx.input.setInputProcessor(this); @@ -43,6 +45,9 @@ public class ChuckGame extends ApplicationAdapter implements InputProcessor{ }; tiledMap = new TmxMapLoader().load("testmap.tmx"); tmRenderer = new OrthogonalTiledMapRenderer(tiledMap, graphics.getBatch()); + playerLight = new Light(8, 8, 1); + lights.add(playerLight); + lights.add(new Light( 100, 100, .3f)); MapLayer ml = tiledMap.getLayers().get("collisions"); for(MapObject o: ml.getObjects()){ @@ -51,7 +56,14 @@ public class ChuckGame extends ApplicationAdapter implements InputProcessor{ collisions.add(r); } - + MapLayer lightLayer = tiledMap.getLayers().get("lights"); + Vector2 t = new Vector2(); + for(MapObject o: lightLayer.getObjects()){ + RectangleMapObject rmo = (RectangleMapObject) o; + t = new Rectangle(rmo.getRectangle()).getCenter(t); + lights.add(new Light(t.x, t.y, .3f)); + + } } @@ -59,13 +71,13 @@ public class ChuckGame extends ApplicationAdapter implements InputProcessor{ @Override public void render () { -// player.update(Gdx.graphics.getDeltaTime(), entities); for(Entity e: entities){ e.update(Gdx.graphics.getDeltaTime(), entities, collisions); } Collections.sort(entities, zSorter); + playerLight.position.x = player.position.x + 8; + playerLight.position.y = player.position.y + 8; -// graphics.cam.lookAt(player.position.x, player.position.y, 0); graphics.cam.position.x = player.position.x + 8; graphics.cam.position.y = player.position.y + 8; @@ -73,21 +85,20 @@ public class ChuckGame extends ApplicationAdapter implements InputProcessor{ graphics.prepare(); + graphics.passLightsToShader(lights); Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); tmRenderer.setView(graphics.cam); tmRenderer.render(); graphics.startSprite(); -// tmRenderer.getBatch().setShader(graphics.shader); -// player.draw(graphics); for(Entity e: entities){ if(e.shouldDrawSelf) e.draw(graphics); } graphics.endSprite(); -// graphics.endShapes(); + System.out.println("FPS:" + Gdx.graphics.getFramesPerSecond()); } @Override diff --git a/core/src/com/toasted/chuck/Graphics.java b/core/src/com/toasted/chuck/Graphics.java index b911803..855d7a8 100644 --- a/core/src/com/toasted/chuck/Graphics.java +++ b/core/src/com/toasted/chuck/Graphics.java @@ -1,5 +1,7 @@ package com.toasted.chuck; +import java.util.ArrayList; + import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.OrthographicCamera; @@ -8,6 +10,7 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; public class Graphics { private SpriteBatch spriteBatch; @@ -16,14 +19,18 @@ public class Graphics { final FileHandle VERTEX = Gdx.files.internal("Vertex.vert"); final FileHandle FRAGMENT = Gdx.files.internal("Fragment.frag"); - + final int orthoX = 16 * 28; + final int orthoY = 9 * 28; + final float orthoScale = orthoX / (float)getWidth(); + + ShaderProgram shader = new ShaderProgram(VERTEX, FRAGMENT); public Graphics(){ cam = new OrthographicCamera(); spriteBatch = new SpriteBatch(); shapeRenderer = new ShapeRenderer(); - cam.setToOrtho(false, 16 * 28, 9 * 28); + cam.setToOrtho(false, orthoX, orthoY); } public int getWidth(){ @@ -32,6 +39,7 @@ public class Graphics { public int getHeight(){ return Gdx.graphics.getHeight(); } + public void startShapes(ShapeType shapeType){ shapeRenderer.begin(shapeType); } @@ -54,18 +62,30 @@ public class Graphics { shapeRenderer.setProjectionMatrix(cam.combined); spriteBatch.setProjectionMatrix(cam.combined); - System.out.println(shader.getLog()); spriteBatch.setShader(shader); - System.out.println(shader.getUniforms()); -// for(String s: shader.getUniforms()){ -// System.out.println(s); -// } -// System.out.println(shader.getFragmentShaderSource()); -// shader.begin(); - shader.begin(); -// shader.setUniform2fv("u_resolution", new float[]{(float) getWidth(), (float) getHeight()}, 0, 2); + if(!shader.isCompiled()){ + System.err.println(shader.getLog()); + } + + shader.begin(); shader.setUniformf("u_screenResolution", new Vector2(getWidth(), getHeight())); } + public void passLightsToShader(ArrayList lights){ + if(lights.size() > 50){ // if there are too many to do + + } else { + shader.setUniformi("u_actualLights", lights.size()); + int loc = shader.getUniformLocation("u_lightCoord[" + 0 + "]"); + int locIn = shader.getUniformLocation("u_lightIntensity[0]"); + for(int i = 0;i < lights.size();i++){ + + Vector3 v3 = cam.project(new Vector3(lights.get(i).position.x, lights.get(i).position.y, 0)); + Vector2 v = new Vector2(v3.x, v3.y); + shader.setUniformf(loc + i, v); + shader.setUniformf(locIn + i, lights.get(i).intensity); + } + } + } } diff --git a/core/src/com/toasted/chuck/Light.java b/core/src/com/toasted/chuck/Light.java new file mode 100644 index 0000000..492d101 --- /dev/null +++ b/core/src/com/toasted/chuck/Light.java @@ -0,0 +1,17 @@ +package com.toasted.chuck; + +import com.badlogic.gdx.math.Vector2; + +public class Light { + private static Vector2 tmp = new Vector2(); + Vector2 position; + float intensity = 1; + public Light(float x, float y, float intensity){ + position = new Vector2(x, y); + this.intensity = intensity; + } + public Vector2 getScreenPos(float cx, float cy){ + return tmp.set(position).sub(cx, cy); + } + +}