diff --git a/assets/aonly.frag b/assets/aonly.frag new file mode 100644 index 000000000..14809ad4d --- /dev/null +++ b/assets/aonly.frag @@ -0,0 +1,8 @@ +varying vec4 v_color; +varying vec2 v_texCoords; +uniform sampler2D u_texture; + +void main(void) { + float alpha = texture2D(u_texture, v_texCoords).a; + gl_FragColor = vec4(alpha, alpha, alpha, 1.0); +} \ No newline at end of file diff --git a/assets/blendGlow.frag b/assets/blendGlow.frag new file mode 100644 index 000000000..e69de29bb diff --git a/assets/rgbonly.frag b/assets/rgbonly.frag new file mode 100644 index 000000000..fed6005ff --- /dev/null +++ b/assets/rgbonly.frag @@ -0,0 +1,8 @@ +varying vec4 v_color; +varying vec2 v_texCoords; +uniform sampler2D u_texture; + +void main(void) { + vec3 color = texture2D(u_texture, v_texCoords).rgb; + gl_FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/DefaultConfig.kt b/src/net/torvald/terrarum/DefaultConfig.kt index f9adfb2ce..63e7cf522 100644 --- a/src/net/torvald/terrarum/DefaultConfig.kt +++ b/src/net/torvald/terrarum/DefaultConfig.kt @@ -14,7 +14,7 @@ object DefaultConfig { val jsonObject = JsonObject() jsonObject.addProperty("displayfps", 0) // 0: no limit, non-zero: limit - jsonObject.addProperty("usevsync", false) + jsonObject.addProperty("usevsync", true) jsonObject.addProperty("imtooyoungtodie", false) // no perma-death diff --git a/src/net/torvald/terrarum/Ingame.kt b/src/net/torvald/terrarum/Ingame.kt index 239f414e4..5ffdc2564 100644 --- a/src/net/torvald/terrarum/Ingame.kt +++ b/src/net/torvald/terrarum/Ingame.kt @@ -79,11 +79,17 @@ class Ingame(val batch: SpriteBatch) : Screen { private val worldFBOformat = if (Terrarum.environment == RunningEnvironment.MOBILE) Pixmap.Format.RGBA4444 else Pixmap.Format.RGBA8888 - private val lightFBOformat = Pixmap.Format.RGBA8888 + private val lightFBOformat = Pixmap.Format.RGB888 + private val lightUvFBOformat = Pixmap.Format.Intensity var worldDrawFrameBuffer = FrameBuffer(worldFBOformat, Terrarum.WIDTH, Terrarum.HEIGHT, true) + var worldGlowFrameBuffer = FrameBuffer(worldFBOformat, Terrarum.WIDTH, Terrarum.HEIGHT, true) + // RGB elements of Lightmap for Color Vec4(R, G, B, 1.0) 24-bit var lightmapFboA = FrameBuffer(lightFBOformat, Terrarum.WIDTH.div(lightmapDownsample.toInt()), Terrarum.HEIGHT.div(lightmapDownsample.toInt()), true) var lightmapFboB = FrameBuffer(lightFBOformat, Terrarum.WIDTH.div(lightmapDownsample.toInt()), Terrarum.HEIGHT.div(lightmapDownsample.toInt()), true) + // A elements of Lightmap for UV Light Vec4(A, A, A, A) 8-bit + //var lightmapUvFboA = FrameBuffer(lightUvFBOformat, Terrarum.WIDTH.div(lightmapDownsample.toInt()), Terrarum.HEIGHT.div(lightmapDownsample.toInt()), true) + //var lightmapUvFboB = FrameBuffer(lightUvFBOformat, Terrarum.WIDTH.div(lightmapDownsample.toInt()), Terrarum.HEIGHT.div(lightmapDownsample.toInt()), true) init { @@ -92,8 +98,6 @@ class Ingame(val batch: SpriteBatch) : Screen { } - //private lateinit var shader12BitCol: Shader // grab LibGDX if you want some shader - //private lateinit var shaderBlur: Shader private val useShader: Boolean = false private val shaderProgram = 0 @@ -190,10 +194,6 @@ class Ingame(val batch: SpriteBatch) : Screen { * Create new world */ fun enter() { - // load things when the game entered this "state" - // load necessary shaders - //shader12BitCol = Shader.makeShader("./assets/4096.vert", "./assets/4096.frag") - //shaderBlur = Shader.makeShader("./assets/blur.vert", "./assets/blur.frag") // init map as chosen size world = GameWorld(8192, 2048) @@ -445,6 +445,10 @@ class Ingame(val batch: SpriteBatch) : Screen { } } + + private var blurWriteBuffer = lightmapFboA + private var blurReadBuffer = lightmapFboB + private fun renderGame(batch: SpriteBatch) { Gdx.gl.glClearColor(.157f, .157f, .157f, 0f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) @@ -469,97 +473,24 @@ class Ingame(val batch: SpriteBatch) : Screen { /////////////////// // blur lightmap // /////////////////// - val blurIterations = 5 // ideally, 4 * radius; must be even/odd number -- odd/even number will flip the image - val blurRadius = 4f / lightmapDownsample // (5, 4f); using low numbers for pixel-y aesthetics - - - - lightmapFboA.inAction(null, null) { - Gdx.gl.glClearColor(0f, 0f, 0f, 0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - } - - lightmapFboB.inAction(null, null) { - Gdx.gl.glClearColor(0f, 0f, 0f, 0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - } - worldDrawFrameBuffer.inAction(null, null) { Gdx.gl.glClearColor(0f,0f,0f,0f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) } + worldGlowFrameBuffer.inAction(null, null) { + Gdx.gl.glClearColor(0f,0f,0f,0f) + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + } - var blurWriteBuffer = lightmapFboA - var blurReadBuffer = lightmapFboB - - - - - // initialise readBuffer with untreated lightmap - blurReadBuffer.inAction(camera, batch) { - batch.inUse { - // using custom code for camera; this is obscure and tricky - camera.position.set( - (WorldCamera.gdxCamX / lightmapDownsample).round(), - (WorldCamera.gdxCamY / lightmapDownsample).round(), - 0f - ) // make camara work - camera.update() - batch.projectionMatrix = camera.combined - - - blendNormal() - batch.color = Color.WHITE - LightmapRenderer.draw(batch) - } - } - - if (!KeyToggler.isOn(Input.Keys.F8)) { - for (i in 0..blurIterations - 1) { - blurWriteBuffer.inAction(camera, batch) { - - batch.inUse { - val texture = blurReadBuffer.colorBufferTexture - - texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - - - batch.shader = Terrarum.shaderBlur - batch.shader.setUniformf("iResolution", - blurWriteBuffer.width.toFloat(), blurWriteBuffer.height.toFloat()) - batch.shader.setUniformf("flip", 1f) - if (i % 2 == 0) - batch.shader.setUniformf("direction", blurRadius, 0f) - else - batch.shader.setUniformf("direction", 0f, blurRadius) - - - batch.color = Color.WHITE - batch.draw(texture, 0f, 0f) - - - // swap - val t = blurWriteBuffer - blurWriteBuffer = blurReadBuffer - blurReadBuffer = t - } - } - } - } - else { - blurWriteBuffer = blurReadBuffer - } - - /////////////////////////// // draw world to the FBO // /////////////////////////// + processBlur(LightmapRenderer.DRAW_FOR_RGB) worldDrawFrameBuffer.inAction(camera, batch) { - batch.inUse { batch.shader = null @@ -598,7 +529,7 @@ class Ingame(val batch: SpriteBatch) : Screen { FeaturesDrawer.drawEnvOverlay(batch) - // mix lighpmap canvas to this canvas + // mix lighpmap canvas to this canvas (Colors -- RGB channel) if (!KeyToggler.isOn(Input.Keys.F6)) { // F6 to disable lightmap draw setCameraPosition(0f, 0f) batch.shader = null @@ -626,18 +557,50 @@ class Ingame(val batch: SpriteBatch) : Screen { camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work camera.update() batch.projectionMatrix = camera.combined + } + } + ////////////////////////// + // draw glow to the FBO // + ////////////////////////// + processBlur(LightmapRenderer.DRAW_FOR_ALPHA) + + worldGlowFrameBuffer.inAction(camera, batch) { + batch.inUse { + batch.shader = null + ////////////////////// // draw actor glows // ////////////////////// // FIXME needs some new blending/shader for glow... - //actorsRenderMiddle.forEach { it.drawGlow(batch) } - //actorsRenderMidTop.forEach { it.drawGlow(batch) } - //player?.drawGlow(batch) - //actorsRenderFront.forEach { it.drawGlow(batch) } + + actorsRenderMiddle.forEach { it.drawGlow(batch) } + actorsRenderMidTop.forEach { it.drawGlow(batch) } + player?.drawGlow(batch) + actorsRenderFront.forEach { it.drawGlow(batch) } // --> blendLightenOnly() <-- introduced by childs of ActorWithBody // + + + // mix lighpmap canvas to this canvas (UV lights -- A channel) + if (!KeyToggler.isOn(Input.Keys.F6)) { // F6 to disable lightmap draw + setCameraPosition(0f, 0f) + batch.shader = null + + val lightTex = blurWriteBuffer.colorBufferTexture // TODO zoom! + + lightTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) + + if (KeyToggler.isOn(KEY_LIGHTMAP_RENDER)) blendNormal() + else blendMul() + + batch.color = Color.WHITE + batch.draw(lightTex, + 0f, 0f, + lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample + ) + } } } @@ -661,12 +624,28 @@ class Ingame(val batch: SpriteBatch) : Screen { ///////////////////////////////// WeatherMixer.render(batch) - batch.flush() - batch.shader = null batch.color = Color.WHITE - val worldTex = worldDrawFrameBuffer.colorBufferTexture // TODO zoom! + + // blend world_normal and world_glow + batch.shader = null + + val worldTex = worldDrawFrameBuffer.colorBufferTexture // WORLD: light_color must be applied beforehand worldTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) + + /*val glowTex = worldGlowFrameBuffer.colorBufferTexture // GLOW: light_uvlight must be applied beforehand + glowTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) + + Gdx.graphics.gL20.glActiveTexture(GL20.GL_TEXTURE0) + worldTex.bind(GL20.GL_TEXTURE0) + + Gdx.graphics.gL20.glActiveTexture(GL20.GL_TEXTURE1) + glowTex.bind(GL20.GL_TEXTURE1) + + // setup shader params...*/ + + + // an old code. batch.draw(worldTex, 0f, 0f, worldTex.width.toFloat(), worldTex.height.toFloat()) @@ -913,6 +892,105 @@ class Ingame(val batch: SpriteBatch) : Screen { gwin.drawLine(0f, Terrarum.HEIGHT / 2f, Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT / 2f)*/ } + private fun processBlur(mode: Int) { + val blurIterations = 5 // ideally, 4 * radius; must be even/odd number -- odd/even number will flip the image + val blurRadius = 4f / lightmapDownsample // (5, 4f); using low numbers for pixel-y aesthetics + + blurWriteBuffer = lightmapFboA + blurReadBuffer = lightmapFboB + + + lightmapFboA.inAction(null, null) { + Gdx.gl.glClearColor(0f, 0f, 0f, 0f) + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + } + lightmapFboB.inAction(null, null) { + Gdx.gl.glClearColor(0f, 0f, 0f, 0f) + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + } + + + if (mode == LightmapRenderer.DRAW_FOR_RGB) { + // initialise readBuffer with untreated lightmap + blurReadBuffer.inAction(camera, batch) { + batch.inUse { + // using custom code for camera; this is obscure and tricky + camera.position.set( + (WorldCamera.gdxCamX / lightmapDownsample).round(), + (WorldCamera.gdxCamY / lightmapDownsample).round(), + 0f + ) // make camara work + camera.update() + batch.projectionMatrix = camera.combined + + + blendNormal() + batch.color = Color.WHITE + LightmapRenderer.draw(batch, LightmapRenderer.DRAW_FOR_RGB) + } + } + } + else { + // initialise readBuffer with untreated lightmap + blurReadBuffer.inAction(camera, batch) { + batch.inUse { + // using custom code for camera; this is obscure and tricky + camera.position.set( + (WorldCamera.gdxCamX / lightmapDownsample).round(), + (WorldCamera.gdxCamY / lightmapDownsample).round(), + 0f + ) // make camara work + camera.update() + batch.projectionMatrix = camera.combined + + + blendNormal() + batch.color = Color.WHITE + LightmapRenderer.draw(batch, LightmapRenderer.DRAW_FOR_ALPHA) + } + } + } + + + + if (!KeyToggler.isOn(Input.Keys.F8)) { + for (i in 0 until blurIterations) { + blurWriteBuffer.inAction(camera, batch) { + + batch.inUse { + val texture = blurReadBuffer.colorBufferTexture + + texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + + + batch.shader = Terrarum.shaderBlur + batch.shader.setUniformf("iResolution", + blurWriteBuffer.width.toFloat(), blurWriteBuffer.height.toFloat()) + batch.shader.setUniformf("flip", 1f) + if (i % 2 == 0) + batch.shader.setUniformf("direction", blurRadius, 0f) + else + batch.shader.setUniformf("direction", 0f, blurRadius) + + + batch.color = Color.WHITE + batch.draw(texture, 0f, 0f) + + + // swap + val t = blurWriteBuffer + blurWriteBuffer = blurReadBuffer + blurReadBuffer = t + } + } + } + } + else { + blurWriteBuffer = blurReadBuffer + } + } + + private fun repossessActor() { // check if currently pocessed actor is removed from game @@ -1314,6 +1392,10 @@ class Ingame(val batch: SpriteBatch) : Screen { lightmapFboA = FrameBuffer(lightFBOformat, width.div(lightmapDownsample.toInt()), height.div(lightmapDownsample.toInt()), true) lightmapFboB.dispose() lightmapFboB = FrameBuffer(lightFBOformat, width.div(lightmapDownsample.toInt()), height.div(lightmapDownsample.toInt()), true) + //lightmapUvFboA.dispose() + //lightmapUvFboA = FrameBuffer(lightUvFBOformat, Terrarum.WIDTH.div(lightmapDownsample.toInt()), Terrarum.HEIGHT.div(lightmapDownsample.toInt()), true) + //lightmapUvFboB.dispose() + //lightmapUvFboB = FrameBuffer(lightUvFBOformat, Terrarum.WIDTH.div(lightmapDownsample.toInt()), Terrarum.HEIGHT.div(lightmapDownsample.toInt()), true) // Set up viewport when window is resized diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 51212faea..76344ca16 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -34,6 +34,8 @@ import java.util.* const val GAME_NAME = "Terrarum" fun main(args: Array) { + Terrarum // invoke + val config = LwjglApplicationConfiguration() config.foregroundFPS = Terrarum.RENDER_FPS config.backgroundFPS = Terrarum.RENDER_FPS @@ -45,6 +47,8 @@ fun main(args: Array) { config.foregroundFPS = RENDER_FPS config.title = GAME_NAME + println("usevsync = ${Terrarum.USE_VSYNC}") + // the game must run on same speed regardless of the display FPS; // "Terrarum.TARGET_INTERNAL_FPS" denotes "execute as if FPS was set to this value" @@ -234,6 +238,8 @@ object Terrarum : ApplicationAdapter() { lateinit var shaderBlur: ShaderProgram + lateinit var shaderRGBOnly: ShaderProgram + lateinit var shaderAOnly: ShaderProgram lateinit var shader4096: ShaderProgram lateinit var shader4096Bayer: ShaderProgram @@ -304,6 +310,11 @@ object Terrarum : ApplicationAdapter() { shader4096Bayer.end() + shaderRGBOnly = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/rgbonly.frag")) + shaderAOnly = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/aonly.frag")) + + + ModMgr // invoke Module Manager, will also invoke BlockCodex ItemCodex // invoke Item Codex @@ -583,12 +594,6 @@ fun blendNormal() { Gdx.gl.glBlendEquation(GL20.GL_FUNC_ADD) // batch.flush does not touch blend equation } -fun blendLightenOnly() { - Terrarum.batch.enableBlending() - Terrarum.batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE) - Gdx.gl.glBlendEquation(GL30.GL_MAX) // batch.flush does not touch blend equation -} - fun blendScreen() { Terrarum.batch.enableBlending() Terrarum.batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_COLOR) @@ -599,14 +604,14 @@ object BlendMode { const val SCREEN = "GL_BLEND screen" const val MULTIPLY = "GL_BLEND multiply" const val NORMAL = "GL_BLEND normal" - const val MAX = "GL_MAX" + //const val MAX = "GL_MAX" fun resolve(mode: String) { when (mode) { SCREEN -> blendScreen() MULTIPLY -> blendMul() NORMAL -> blendNormal() - MAX -> blendLightenOnly() + //MAX -> blendLightenOnly() else -> throw Error("Unknown blend mode: $mode") } } diff --git a/src/net/torvald/terrarum/gameactors/ActorWithPhysics.kt b/src/net/torvald/terrarum/gameactors/ActorWithPhysics.kt index 8c9e01810..c9a80c3da 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithPhysics.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithPhysics.kt @@ -1150,7 +1150,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean override fun drawGlow(batch: SpriteBatch) { if (isVisible && spriteGlow != null) { - blendLightenOnly() + blendNormal() val offsetX = hitboxTranslateX * scale val offsetY = spriteGlow!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1 diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt index c759624f9..d295b3066 100644 --- a/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt +++ b/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt @@ -43,7 +43,8 @@ object LightmapRenderer { /** * Float value, 1.0 for 1023 */ - private val lightmap: Array> = Array(LIGHTMAP_HEIGHT) { Array(LIGHTMAP_WIDTH, { Color(0f,0f,0f,1f) }) } // TODO framebuffer? + // TODO utilise alpha channel to determine brightness of "glow" sprites (so that alpha channel works like UV light) + private val lightmap: Array> = Array(LIGHTMAP_HEIGHT) { Array(LIGHTMAP_WIDTH, { Color(0f,0f,0f,0f) }) } // TODO framebuffer? private val lanternMap = ArrayList(Terrarum.ingame!!.ACTORCONTAINER_INITIAL_SIZE * 4) private val AIR = Block.AIR @@ -260,9 +261,9 @@ object LightmapRenderer { // O(9n) == O(n) where n is a size of the map // TODO devise multithreading on this - var ambientAccumulator = Color(0f,0f,0f,1f) + var ambientAccumulator = Color(0f,0f,0f,0f) - var lightLevelThis: Color = Color(0f,0f,0f,1f) + var lightLevelThis: Color = Color(0f,0f,0f,0f) val thisTerrain = Terrarum.ingame!!.world.getTileFromTerrain(x, y) val thisWall = Terrarum.ingame!!.world.getTileFromWall(x, y) val thisTileLuminosity = BlockCodex[thisTerrain].luminosity // already been div by four @@ -299,15 +300,15 @@ object LightmapRenderer { * sample ambient for eight points and apply attenuation for those * maxblend eight values and use it */ - /* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y - 1) ?: Color(0f,0f,0f,1f), scaleSqrt2(thisTileOpacity)) - /* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y - 1) ?: Color(0f,0f,0f,1f), scaleSqrt2(thisTileOpacity)) - /* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y + 1) ?: Color(0f,0f,0f,1f), scaleSqrt2(thisTileOpacity)) - /* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y + 1) ?: Color(0f,0f,0f,1f), scaleSqrt2(thisTileOpacity)) + /* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y - 1) ?: Color(0f,0f,0f,0f), scaleSqrt2(thisTileOpacity)) + /* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y - 1) ?: Color(0f,0f,0f,0f), scaleSqrt2(thisTileOpacity)) + /* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y + 1) ?: Color(0f,0f,0f,0f), scaleSqrt2(thisTileOpacity)) + /* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y + 1) ?: Color(0f,0f,0f,0f), scaleSqrt2(thisTileOpacity)) - /* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x , y - 1) ?: Color(0f,0f,0f,1f), thisTileOpacity) - /* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x , y + 1) ?: Color(0f,0f,0f,1f), thisTileOpacity) - /* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y ) ?: Color(0f,0f,0f,1f), thisTileOpacity) - /* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y ) ?: Color(0f,0f,0f,1f), thisTileOpacity) + /* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x , y - 1) ?: Color(0f,0f,0f,0f), thisTileOpacity) + /* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x , y + 1) ?: Color(0f,0f,0f,0f), thisTileOpacity) + /* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y ) ?: Color(0f,0f,0f,0f), thisTileOpacity) + /* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y ) ?: Color(0f,0f,0f,0f), thisTileOpacity) return lightLevelThis maxBlend ambientAccumulator } @@ -325,7 +326,7 @@ object LightmapRenderer { (l.r * 1.25f),//.clampOne(), (l.g * 1.25f),//.clampOne(), (l.b * 1.25f),//.clampOne() - 1f + (l.a * 1.25f) ) } else { @@ -333,7 +334,10 @@ object LightmapRenderer { } } - fun draw(batch: SpriteBatch) { + const val DRAW_FOR_RGB = 0xFFF0 + const val DRAW_FOR_ALPHA = 0x000F + + fun draw(batch: SpriteBatch, drawMode: Int) { val this_x_start = for_x_start// + overscan_open val this_x_end = for_x_end// + overscan_open val this_y_start = for_y_start// + overscan_open @@ -360,7 +364,14 @@ object LightmapRenderer { if (x + sameLevelCounter >= this_x_end) break } - batch.color = (getLightForOpaque(x, y) ?: Color(0f,0f,0f,1f)).normaliseToColourHDR() + + if (drawMode == DRAW_FOR_RGB) { + batch.color = (getLightForOpaque(x, y) ?: Color(0f,0f,0f,0f)).normaliseToColourHDR() + } + else if (drawMode == DRAW_FOR_ALPHA) { + batch.color = (getLightForOpaque(x, y) ?: Color(0f,0f,0f,0f)).normaliseToAlphaHDR() + } + batch.fillRect( (x * DRAW_TILE_SIZE).round().toFloat(), (y * DRAW_TILE_SIZE).round().toFloat(), @@ -404,7 +415,7 @@ object LightmapRenderer { data.r * (1f - darken.r * lightScalingMagic),//.clampZero(), data.g * (1f - darken.g * lightScalingMagic),//.clampZero(), data.b * (1f - darken.b * lightScalingMagic),//.clampZero(), - 1f) + data.a * (1f - darken.b * lightScalingMagic)) } private fun scaleSqrt2(data: Color): Color { @@ -412,7 +423,7 @@ object LightmapRenderer { data.r * 1.41421356f, data.g * 1.41421356f, data.b * 1.41421356f, - 1f) + data.a * 1.41421356f) } /** @@ -427,7 +438,7 @@ object LightmapRenderer { data.r * (1f + brighten.r * lightScalingMagic), data.g * (1f + brighten.g * lightScalingMagic), data.b * (1f + brighten.b * lightScalingMagic), - 1f + data.a * (1f + brighten.b * lightScalingMagic) ) } @@ -458,7 +469,7 @@ object LightmapRenderer { data.r + brighten, data.g + brighten, data.b + brighten, - 1f + data.a + brighten ) } @@ -472,7 +483,8 @@ object LightmapRenderer { if (this.r > other.r) this.r else other.r, if (this.g > other.g) this.g else other.g, if (this.b > other.b) this.b else other.b, - 1f) + if (this.a > other.a) this.a else other.a + ) } @@ -520,6 +532,14 @@ object LightmapRenderer { return FastMath.max(value.r, value.g, value.b) } + fun getHighestRGBA(x: Int, y: Int): Float? { + val value = getLightInternal(x, y) + if (value == null) + return null + else + return FastMath.max(value.r, value.g, value.b, value.a) + } + private fun purgeLightmap() { for (y in 0..LIGHTMAP_HEIGHT - 1) { for (x in 0..LIGHTMAP_WIDTH - 1) { @@ -638,9 +658,16 @@ object LightmapRenderer { 1f ) + inline fun Color.normaliseToAlphaHDR() = Color( + hdr(this.a), + hdr(this.a), + hdr(this.a), + 1f + ) + data class Lantern(val posX: Int, val posY: Int, val luminosity: Color) - private fun Color.nonZero() = this.r != 0f || this.g != 0f || this.b != 0f + private fun Color.nonZero() = this.r != 0f || this.g != 0f || this.b != 0f || this.a != 0f val histogram: Histogram get() {