Made dynamic lighting smoother
This commit is contained in:
parent
0ee4243011
commit
a0d6d87dcf
|
|
@ -1,9 +1,5 @@
|
|||
package projectzombie.display;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_FLOAT;
|
||||
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
|
||||
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
|
@ -147,7 +143,7 @@ public class DisplayWindow implements IMainloopTask
|
|||
|
||||
// Bind the lightmap
|
||||
GL33.glActiveTexture(GL33.GL_TEXTURE1);
|
||||
GL33.glBindTexture(GL33.GL_TEXTURE_2D, TileLighting.lightmap_src);
|
||||
GL33.glBindTexture(GL33.GL_TEXTURE_2D, TileLighting.lightmap);
|
||||
|
||||
// Render everything
|
||||
DisplayRender.render(w[0], h[0]);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import bdf.types.BdfNamedList;
|
|||
import bdf.types.BdfObject;
|
||||
import gl_engine.MathHelpers;
|
||||
import gl_engine.range.Range2i;
|
||||
import gl_engine.vec.Vec2d;
|
||||
import gl_engine.vec.Vec2i;
|
||||
import projectzombie.Main;
|
||||
import projectzombie.display.Camera;
|
||||
|
|
@ -22,19 +23,19 @@ import projectzombie.world.layer.Layer;
|
|||
public class TileLighting
|
||||
{
|
||||
private static class Lighting {
|
||||
float[] p_src;
|
||||
float[] p_day;
|
||||
float[] p;
|
||||
int w, h;
|
||||
int x, y;
|
||||
|
||||
private int getID(int x, int y) {
|
||||
return x + y * w;
|
||||
return (x + y * w) * 3 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static int lighting_last_x = 0;
|
||||
private static int lighting_last_y = 0;
|
||||
private static boolean lighting_dirty = false;
|
||||
public static int lightmap_src;
|
||||
public static int lightmap_day;
|
||||
public static int lightmap;
|
||||
|
||||
private static Lighting lighting;
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ public class TileLighting
|
|||
}
|
||||
|
||||
public TileLighting() {
|
||||
lightmap_src = GL33.glGenTextures();
|
||||
lightmap = GL33.glGenTextures();
|
||||
}
|
||||
|
||||
public static void update()
|
||||
|
|
@ -131,7 +132,7 @@ public class TileLighting
|
|||
MathHelpers.floor(player.pos.y / 16) - Chunk.RENDER_DISTANCE);
|
||||
}
|
||||
|
||||
private static void calculateLight(Layer layer, Lighting lighting, float[] pixels, int x, int y, float level, boolean ignore)
|
||||
private static void calculateLight(Layer layer, Lighting lighting, float[] pixels, int x, int y, float level)
|
||||
{
|
||||
if(x < 0 || y < 0 || x >= lighting.w || y >= lighting.h) {
|
||||
return;
|
||||
|
|
@ -143,7 +144,7 @@ public class TileLighting
|
|||
Vec2i tpos = new Vec2i(x + lighting.x * 16, y + lighting.y * 16);
|
||||
int tid = tpos.getId(Chunk.CHUNK_SIZE);
|
||||
|
||||
if(level_current >= level && !ignore) {
|
||||
if(level_current >= level) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +165,64 @@ public class TileLighting
|
|||
};
|
||||
|
||||
for(int i=0;i<8;i+=2) {
|
||||
calculateLight(layer, lighting, pixels, adjacent[i], adjacent[i+1], level_next, false);
|
||||
calculateLight(layer, lighting, pixels, adjacent[i], adjacent[i+1], level_next);
|
||||
}
|
||||
}
|
||||
|
||||
private static void calculateEntityLighting(Layer layer, Lighting lighting, Entity entity, float[] pixels)
|
||||
{
|
||||
if(!entity.emitsLight) {
|
||||
return;
|
||||
}
|
||||
|
||||
double level = entity.getLightLevel();
|
||||
|
||||
if(level <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(level > 1) {
|
||||
level = 1;
|
||||
}
|
||||
|
||||
int[] positions = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
1, 1,
|
||||
0, 1
|
||||
};
|
||||
|
||||
for(int i=0;i<positions.length;i+=2)
|
||||
{
|
||||
int x = (int)Math.round(entity.pos.x) - positions[i+0];
|
||||
int y = (int)Math.round(entity.pos.y) - positions[i+1];
|
||||
|
||||
Vec2i lpos = new Vec2i(x, y).subtract(new Vec2i(lighting.x * 16, lighting.y * 16));
|
||||
|
||||
if(lpos.x < 0 || lpos.y < 0 || lpos.x >= lighting.w || lpos.y >= lighting.h) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int id = lighting.getID(lpos.x, lpos.y);
|
||||
float level_current = pixels[id];
|
||||
|
||||
Vec2i tpos = new Vec2i(x, y);
|
||||
int tid = tpos.getId(Chunk.CHUNK_SIZE);
|
||||
|
||||
if(level_current >= level) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Chunk chunk = layer.getChunk(tpos);
|
||||
TileState ft = chunk.getFrontTile(tid);
|
||||
TileState bt = chunk.getBackTile(tid);
|
||||
|
||||
double dissipation = Math.max(ft.tile.getLightDissipation(ft), bt.tile.getLightDissipation(bt));
|
||||
double level2 = level - dissipation * (Math.abs(x + 0.5 - entity.pos.x) + Math.abs(y + 0.5 - entity.pos.y));
|
||||
|
||||
//pixels[id] = (float)level2;
|
||||
|
||||
calculateLight(layer, lighting, pixels, lpos.x, lpos.y, (float)level2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -173,28 +231,14 @@ public class TileLighting
|
|||
Lighting lighting = getLighting();
|
||||
|
||||
// Copy the pixels
|
||||
float[] pixels = new float[lighting.p_src.length];
|
||||
float[] pixels = new float[lighting.p.length];
|
||||
for(int i=0;i<pixels.length;i++) {
|
||||
pixels[i] = lighting.p_src[i];
|
||||
pixels[i] = lighting.p[i];
|
||||
}
|
||||
|
||||
Layer layer = Main.world.getLayer();
|
||||
|
||||
lighting: {
|
||||
double level = Main.player.getLightLevel();
|
||||
|
||||
if(level <= 0) {
|
||||
break lighting;
|
||||
}
|
||||
|
||||
if(level > 1) {
|
||||
level = 1;
|
||||
}
|
||||
|
||||
Vec2i lpos = Main.player.pos.toInt().subtract(new Vec2i(lighting.x * 16, lighting.y * 16));
|
||||
|
||||
calculateLight(layer, lighting, pixels, lpos.x, lpos.y, (float)level, true);
|
||||
}
|
||||
calculateEntityLighting(layer, lighting, Main.player, pixels);
|
||||
|
||||
for(int cx=-Chunk.RENDER_DISTANCE;cx<=Chunk.RENDER_DISTANCE;cx++) {
|
||||
for(int cy=-Chunk.RENDER_DISTANCE;cy<=Chunk.RENDER_DISTANCE;cy++)
|
||||
|
|
@ -205,37 +249,15 @@ public class TileLighting
|
|||
|
||||
Chunk chunk = layer.chunks.get(cpos);
|
||||
|
||||
for(Entity entity : chunk.entities)
|
||||
{
|
||||
if(!entity.emitsLight) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double level = entity.getLightLevel();
|
||||
|
||||
if(level <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(level > 1) {
|
||||
level = 1;
|
||||
}
|
||||
|
||||
Vec2i lpos = entity.pos.toInt().subtract(new Vec2i(lighting.x * 16, lighting.y * 16));
|
||||
|
||||
calculateLight(layer, lighting, pixels, lpos.x, lpos.y, (float)level, true);
|
||||
for(Entity entity : chunk.entities) {
|
||||
calculateEntityLighting(layer, lighting, entity, pixels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the texture
|
||||
GL33.glBindTexture(GL33.GL_TEXTURE_2D, lightmap_src);
|
||||
|
||||
GL33.glTexImage2D(
|
||||
GL33.GL_TEXTURE_2D, 0, GL33.GL_LUMINANCE,
|
||||
lighting.w, lighting.h, 0, GL33.GL_LUMINANCE,
|
||||
GL33.GL_FLOAT, pixels);
|
||||
|
||||
GL33.glBindTexture(GL33.GL_TEXTURE_2D, lightmap);
|
||||
GL33.glTexImage2D(GL33.GL_TEXTURE_2D, 0, GL33.GL_RGB, lighting.w, lighting.h, 0, GL33.GL_RGB, GL33.GL_FLOAT, pixels);
|
||||
GL33.glGenerateMipmap(GL33.GL_TEXTURE_2D);
|
||||
|
||||
// Set the texture location data
|
||||
|
|
@ -246,7 +268,7 @@ public class TileLighting
|
|||
public static void clearLighting()
|
||||
{
|
||||
Lighting lighting = new Lighting();
|
||||
lighting.p_src = new float[2];
|
||||
lighting.p = new float[3];
|
||||
lighting.w = 1;
|
||||
lighting.h = 1;
|
||||
lighting.x = 0;
|
||||
|
|
@ -264,8 +286,15 @@ public class TileLighting
|
|||
int x = nl.get("x").getInteger();
|
||||
int y = nl.get("y").getInteger();
|
||||
|
||||
float[] pixels = new float[width*height*3];
|
||||
|
||||
for(int i=0;i<width*height;i++) {
|
||||
pixels[i*3+0] = light[i*2+0];
|
||||
pixels[i*3+1] = light[i*2+1];
|
||||
}
|
||||
|
||||
Lighting lighting = new Lighting();
|
||||
lighting.p_src = light;
|
||||
lighting.p = pixels;
|
||||
lighting.w = width;
|
||||
lighting.h = height;
|
||||
lighting.x = x;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import projectzombie.init.Models;
|
|||
import projectzombie.init.Sounds;
|
||||
import projectzombie.init.Tiles;
|
||||
import projectzombie.model.Model;
|
||||
import projectzombie.util.gl.texture.IHasTexture;
|
||||
import projectzombie.util.math.TileState;
|
||||
import projectzombie.world.chunk.Chunk;
|
||||
import projectzombie.world.layer.Layer;
|
||||
|
|
@ -112,14 +111,14 @@ public class EntityExplosion extends Entity
|
|||
// Set the tiles
|
||||
if(!bts.tile.unbreakable) {
|
||||
l.setBackTile(ets, tpos);
|
||||
if(fts.tile instanceof IHasTexture)
|
||||
l.spawnEntity(new ParticleBreak(new Vec2d(tpos.x+rand.nextDouble(), tpos.y+rand.nextDouble()), bts, 1));
|
||||
//if(fts.tile instanceof IHasTexture)
|
||||
//l.spawnEntity(new ParticleBreak(new Vec2d(tpos.x+rand.nextDouble(), tpos.y+rand.nextDouble()), bts, 1));
|
||||
}
|
||||
|
||||
if(!fts.tile.unbreakable) {
|
||||
l.setFrontTile(Tiles.VOID.getDefaultState(), tpos);
|
||||
if(fts.tile instanceof IHasTexture)
|
||||
l.spawnEntity(new ParticleBreak(new Vec2d(tpos.x+rand.nextDouble(), tpos.y+rand.nextDouble()), fts, 1));
|
||||
//if(fts.tile instanceof IHasTexture)
|
||||
//l.spawnEntity(new ParticleBreak(new Vec2d(tpos.x+rand.nextDouble(), tpos.y+rand.nextDouble()), fts, 1));
|
||||
}
|
||||
|
||||
if(upto + multiplier > entities.length) {
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ public class EntityPlayer extends Entity implements EntityAlive, EntityInventory
|
|||
|
||||
// Create the inventory
|
||||
inventory = new Inventory(10);
|
||||
|
||||
inventory.addItem(new ItemStack(Items.LANTERN, 99, (short)0));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
package projectzombie.util.gl.texture;
|
||||
|
||||
public interface IHasTexture
|
||||
{
|
||||
public TextureReference getTexture();
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
package projectzombie.util.gl.texture;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.lwjgl.stb.STBImage;
|
||||
|
||||
import projectzombie.resources.Resource;
|
||||
|
||||
public class Texture
|
||||
{
|
||||
private ByteBuffer texture;
|
||||
private int width;
|
||||
private int height;
|
||||
private int channels;
|
||||
|
||||
public Texture(Resource tex)
|
||||
{
|
||||
// Get the width, height, and channels
|
||||
int width[] = {0};
|
||||
int height[] = {0};
|
||||
int channels[] = {0};
|
||||
|
||||
// Load the texture with STBImage
|
||||
this.texture = STBImage.stbi_load_from_memory(
|
||||
tex.getByteBuffer(),
|
||||
width, height, channels,
|
||||
STBImage.STBI_rgb_alpha);
|
||||
|
||||
// Check for a failure
|
||||
String failure = STBImage.stbi_failure_reason();
|
||||
if(failure != "") {
|
||||
System.out.println("STB: "+failure);
|
||||
}
|
||||
|
||||
// Store the image data
|
||||
this.width = width[0];
|
||||
this.height = height[0];
|
||||
this.channels = channels[0];
|
||||
|
||||
System.out.println("w:"+this.width+" h:"+this.height+" c:"+this.channels);
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public int getChannels() {
|
||||
return this.channels;
|
||||
}
|
||||
|
||||
public ByteBuffer getByteBuffer() {
|
||||
return this.texture;
|
||||
}
|
||||
|
||||
public void free() {
|
||||
//STBImage.stbi_image_free(this.texture);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
package projectzombie.util.gl.texture;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_NEAREST;
|
||||
import static org.lwjgl.opengl.GL11.GL_RGBA;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
|
||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||
import static org.lwjgl.opengl.GL11.glGenTextures;
|
||||
import static org.lwjgl.opengl.GL11.glTexImage2D;
|
||||
import static org.lwjgl.opengl.GL11.glTexParameteri;
|
||||
|
||||
import projectzombie.resources.Resource;
|
||||
|
||||
public class TextureMap
|
||||
{
|
||||
private int texture_gl;
|
||||
private int max_x;
|
||||
private int max_y;
|
||||
private int scale;
|
||||
private Resource resource;
|
||||
|
||||
public TextureMap(int scale, Resource resource) {
|
||||
this.scale = scale;
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
// Generate and bind the texture map
|
||||
this.texture_gl = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D, this.texture_gl);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
// Load the texture into opengl
|
||||
Texture texture = new Texture(resource);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||
texture.getWidth(), texture.getHeight(),
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, texture.getByteBuffer());
|
||||
|
||||
// Store the width and height variables
|
||||
this.max_x = texture.getWidth();
|
||||
this.max_y = texture.getHeight();
|
||||
|
||||
System.out.println("texmap: "+texture_gl);
|
||||
|
||||
// Free the texture
|
||||
//texture.free();
|
||||
}
|
||||
|
||||
public TextureReference getTextureReference(int start_x, int end_x, int start_y, int end_y) {
|
||||
return new TextureReference(start_x * scale, end_x * scale, start_y * scale, end_y * scale)
|
||||
{
|
||||
|
||||
@Override
|
||||
public int getMaxX() {
|
||||
return max_x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return max_y;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public void bindTexture() {
|
||||
glBindTexture(GL_TEXTURE_2D, texture_gl);
|
||||
}
|
||||
|
||||
public void unbindTexture() {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
package projectzombie.util.gl.texture;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.glTexCoord2f;
|
||||
|
||||
import gl_engine.MathHelpers;
|
||||
|
||||
public abstract class TextureReference
|
||||
{
|
||||
public int start_x;
|
||||
public int start_y;
|
||||
public int end_x;
|
||||
public int end_y;
|
||||
|
||||
public static final TextureReference EMPTY = new TextureReferenceEmpty();
|
||||
|
||||
TextureReference() {
|
||||
}
|
||||
|
||||
public TextureReference getTextureReference(int start_x, int end_x, int start_y, int end_y) {
|
||||
TextureReference parent = this;
|
||||
return new TextureReference(start_x, end_x, start_y, end_y)
|
||||
{
|
||||
|
||||
@Override
|
||||
public int getMaxX() {
|
||||
return parent.getMaxX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return parent.getMaxY();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public TextureReference(int start_x, int end_x, int start_y, int end_y)
|
||||
{
|
||||
// Save all the specified values
|
||||
this.start_x = start_x;
|
||||
this.start_y = start_y;
|
||||
this.end_x = end_x;
|
||||
this.end_y = end_y;
|
||||
}
|
||||
|
||||
public void texCoord(double x, double y)
|
||||
{
|
||||
// Create texture coordinates
|
||||
float cx = (float) ( MathHelpers.map(x, 0, 1, start_x, end_x) / (double) this.getMaxX() );
|
||||
float cy = (float) ( MathHelpers.map(y, 0, 1, start_y, end_y) / (double) this.getMaxY() );
|
||||
|
||||
// Send the coordinates from the texture map to opengl
|
||||
glTexCoord2f(cx, cy);
|
||||
}
|
||||
|
||||
public abstract int getMaxX();
|
||||
public abstract int getMaxY();
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
package projectzombie.util.gl.texture;
|
||||
|
||||
class TextureReferenceEmpty extends TextureReference
|
||||
{
|
||||
|
||||
public TextureReferenceEmpty() {
|
||||
super(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void texCoord(double x, double y) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package projectzombie.util.gl.texture;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import projectzombie.util.math.random.RandomHelpers;
|
||||
|
||||
public class TextureReferenceRandom
|
||||
{
|
||||
private static final Random rand = new Random();
|
||||
|
||||
private TextureReference[] textures;
|
||||
|
||||
public TextureReferenceRandom(TextureReference ... textures) {
|
||||
this.textures = textures;
|
||||
}
|
||||
|
||||
public TextureReference getTexture() {
|
||||
return textures[RandomHelpers.randrange(rand, textures.length)];
|
||||
}
|
||||
}
|
||||
|
|
@ -32,14 +32,18 @@ vec3 biggest(vec3 a, vec3 b) {
|
|||
a.z > b.z ? a.z : b.z);
|
||||
}
|
||||
|
||||
float scaleLight(float level) {
|
||||
return pow(level, 1.5);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 light = texture(lightmap, vec2(
|
||||
map(pLightMapPos.x, lightmap_offset.x, lightmap_offset.x + lightmap_size.x, 0, 1),
|
||||
map(pLightMapPos.z, lightmap_offset.y, lightmap_offset.y + lightmap_size.y, 0, 1)));
|
||||
map((pLightMapPos.x), lightmap_offset.x, lightmap_offset.x + lightmap_size.x, 0, 1),
|
||||
map((pLightMapPos.z), lightmap_offset.y, lightmap_offset.y + lightmap_size.y, 0, 1)));
|
||||
|
||||
vec3 light_day = mapVec(light.r, 0, 1, lighting_day_low, lighting_day_high);
|
||||
vec3 light_src = vec3(1, 1, 1) * (light.g - abs(pLightMapPos.y) * 0.1);
|
||||
vec3 light_day = mapVec(scaleLight(light.r), 0, 1, lighting_day_low, lighting_day_high);
|
||||
vec3 light_src = vec3(1, 1, 1) * (scaleLight(light.g) - abs(pLightMapPos.y) * 0.1);
|
||||
|
||||
FragColor = texture(atlas, pTexture) * color * vec4(biggest(light_day, light_src), 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,16 +31,6 @@ mat4 translate(vec3 vec)
|
|||
return result;
|
||||
}
|
||||
|
||||
vec3 mapVec(float x, float in_min, float in_max, vec3 out_min, vec3 out_max) {
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
vec3 biggest(vec3 a, vec3 b) {
|
||||
return vec3(a.x > b.x ? a.x : b.x,
|
||||
a.y > b.y ? a.y : b.y,
|
||||
a.z > b.z ? a.z : b.z);
|
||||
}
|
||||
|
||||
float getTexY()
|
||||
{
|
||||
float animate_count = aFlags.x;
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@ out vec4 FragColor;
|
|||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(texture(lightmap, TexCoord).rgb, 1);
|
||||
FragColor = vec4(texture(lightmap, TexCoord).rg, 0, 1);
|
||||
}
|
||||
Loading…
Reference in New Issue