From 069eca7d9c51b22cff5239eb2f0b6ccc7c432b94 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 30 Jun 2018 16:47:22 +0900 Subject: [PATCH] IngameRenderer: damned thing finally works somewhat --- assets/aaaxmul.frag | 5 +- assets/aonly.frag | 4 +- assets/crt.frag | 2 +- assets/rgbxmul.frag | 8 +- src/net/torvald/terrarum/AppLoader.java | 20 +- ...erer.kt => FuckingWorldRenderer.kt.unused} | 2 +- src/net/torvald/terrarum/PostProcessor.kt | 25 +- src/net/torvald/terrarum/Terrarum.kt | 41 +- src/net/torvald/terrarum/TitleScreen.kt | 25 +- .../terrarum/blockproperties/BlockProp.kt | 2 +- .../torvald/terrarum/modulebasegame/Ingame.kt | 552 +----------------- .../terrarum/modulebasegame/IngameRenderer.kt | 520 +++++++++++++++++ .../gameactors/PlayerBuilderSigrid.kt | 2 +- .../torvald/terrarum/weather/WeatherMixer.kt | 2 +- .../terrarum/worlddrawer/BlocksDrawerNew.kt | 16 +- .../terrarum/worlddrawer/LightmapRenderer.kt | 3 +- .../worlddrawer/LightmapRendererNew.kt | 45 +- 17 files changed, 628 insertions(+), 646 deletions(-) rename src/net/torvald/terrarum/{FuckingWorldRenderer.kt => FuckingWorldRenderer.kt.unused} (99%) create mode 100644 src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt diff --git a/assets/aaaxmul.frag b/assets/aaaxmul.frag index 6a67d5b99..b19cf7fa5 100644 --- a/assets/aaaxmul.frag +++ b/assets/aaaxmul.frag @@ -8,10 +8,13 @@ varying vec2 v_texCoords; uniform sampler2D u_texture; // world texture, has alpha value that is meaningful uniform sampler2D tex1; // lightmap texture +uniform vec2 tex1Offset; void main() { vec4 colorTex0 = texture2D(u_texture, v_texCoords); // world texture vec4 colorTex1 = texture2D(tex1, v_texCoords); // lightmap (RGBA) - gl_FragColor = colorTex0 * vec4(colorTex1.aaa, 1.0); + colorTex1 = vec4(colorTex1.www, 1.0); + + gl_FragColor = colorTex0 * colorTex1; } diff --git a/assets/aonly.frag b/assets/aonly.frag index 14809ad4d..49e3089db 100644 --- a/assets/aonly.frag +++ b/assets/aonly.frag @@ -3,6 +3,6 @@ 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); + vec3 alpha = texture2D(u_texture, v_texCoords).aaa; + gl_FragColor = vec4(alpha, 1.0); } \ No newline at end of file diff --git a/assets/crt.frag b/assets/crt.frag index 5ca822771..daf862511 100644 --- a/assets/crt.frag +++ b/assets/crt.frag @@ -40,6 +40,6 @@ void main(void) { out_color = out_color * scanline_darkening; } - gl_FragColor = vec4(out_color, 0.5); + gl_FragColor = vec4(out_color, 1); } \ No newline at end of file diff --git a/assets/rgbxmul.frag b/assets/rgbxmul.frag index 39b28b186..0776232df 100644 --- a/assets/rgbxmul.frag +++ b/assets/rgbxmul.frag @@ -8,10 +8,14 @@ varying vec2 v_texCoords; uniform sampler2D u_texture; // world texture, has alpha value that is meaningful uniform sampler2D tex1; // lightmap texture +uniform vec2 tex1Offset; +uniform vec2 tex1Resolution; void main() { - vec4 colorTex0 = texture2D(u_texture, v_texCoords); // world texture + vec4 colorTex0 = texture2D(u_texture, v_texCoords + vec2(0.5, 0.5)); // world texture vec4 colorTex1 = texture2D(tex1, v_texCoords); // lightmap (RGBA) - gl_FragColor = colorTex0 * vec4(colorTex1.rgb, 1.0); + colorTex1 = vec4(colorTex1.xyz, 1.0); + + gl_FragColor = colorTex0 * colorTex1; } diff --git a/src/net/torvald/terrarum/AppLoader.java b/src/net/torvald/terrarum/AppLoader.java index 6104e9f96..008ca23ec 100644 --- a/src/net/torvald/terrarum/AppLoader.java +++ b/src/net/torvald/terrarum/AppLoader.java @@ -216,11 +216,11 @@ public class AppLoader implements ApplicationListener { - //Gdx.gl.glClearColor(.094f, .094f, .094f, 0f); - //Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); - //Gdx.gl.glEnable(GL20.GL_TEXTURE_2D); - //Gdx.gl.glEnable(GL20.GL_BLEND); - //Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); + Gdx.gl.glClearColor(.094f, .094f, .094f, 0f); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + Gdx.gl.glEnable(GL20.GL_TEXTURE_2D); + Gdx.gl.glEnable(GL20.GL_BLEND); + Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); screen.render(Gdx.graphics.getDeltaTime()); @@ -292,4 +292,14 @@ public class AppLoader implements ApplicationListener { camera.update(); logoBatch.setProjectionMatrix(camera.combined); } + + private void updateFullscreenQuad(int WIDTH, int HEIGHT) { + fullscreenQuad.setVertices(new float[]{ + 0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f, 1f, + WIDTH, 0f, 0f, 1f, 1f, 1f, 1f, 1f, 1f, + WIDTH, HEIGHT, 0f, 1f, 1f, 1f, 1f, 1f, 0f, + 0f, HEIGHT, 0f, 1f, 1f, 1f, 1f, 0f, 0f + }); + fullscreenQuad.setIndices(new short[]{0, 1, 2, 2, 3, 0}); + } } diff --git a/src/net/torvald/terrarum/FuckingWorldRenderer.kt b/src/net/torvald/terrarum/FuckingWorldRenderer.kt.unused similarity index 99% rename from src/net/torvald/terrarum/FuckingWorldRenderer.kt rename to src/net/torvald/terrarum/FuckingWorldRenderer.kt.unused index 3c12bfab6..9f1f9999d 100644 --- a/src/net/torvald/terrarum/FuckingWorldRenderer.kt +++ b/src/net/torvald/terrarum/FuckingWorldRenderer.kt.unused @@ -270,7 +270,7 @@ class FuckingWorldRenderer(val batch: SpriteBatch) : Screen { BlocksDrawer.renderTerrain(batch) - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // don't know why it is needed; it really depresses me + Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it FeaturesDrawer.drawEnvOverlay(batch) diff --git a/src/net/torvald/terrarum/PostProcessor.kt b/src/net/torvald/terrarum/PostProcessor.kt index 33542abac..2baf9aa5e 100644 --- a/src/net/torvald/terrarum/PostProcessor.kt +++ b/src/net/torvald/terrarum/PostProcessor.kt @@ -25,12 +25,6 @@ object PostProcessor { } fun draw(fbo: FrameBuffer) { - //Gdx.gl.glClearColor(.094f, .094f, .094f, 0f) - //Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - //Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) - //Gdx.gl.glEnable(GL20.GL_BLEND) - //Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - if (textureRegion == null) { textureRegion = TextureRegion(fbo.colorBufferTexture) @@ -49,20 +43,23 @@ object PostProcessor { Terrarum.debugTimers["GFX.PostProcessor"] = measureNanoTime { + //Gdx.gl.glClearColor(.094f, .094f, .094f, 0f) + //Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + //Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) + //Gdx.gl.glEnable(GL20.GL_BLEND) + //Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) + val shader = AppLoader.shader18Bit // no-screen screen renders but the game don't? wtf? - batch.inUse { - - batch.shader = shader - shader.setUniformf("resolution", AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat()) - batch.draw(textureRegion, 0f, 0f) - - } + shader.begin() + shader.setUniformf("resolution", AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat()) + AppLoader.fullscreenQuad.render(shader, GL20.GL_TRIANGLES) + shader.end() - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // don't know why it is needed; it really depresses me + Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it } diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index ecbcfbbb8..1ac5338f3 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -15,6 +15,7 @@ import com.jme3.math.FastMath import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.imagefont.TinyAlphNum import net.torvald.terrarum.itemproperties.ItemCodex +import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.ui.ConsoleWindow import net.torvald.terrarum.utils.JsonFetcher import net.torvald.terrarum.utils.JsonWriter @@ -193,8 +194,6 @@ object Terrarum : Screen { lateinit var shaderBlendGlow: ShaderProgram lateinit var shaderRGBOnly: ShaderProgram lateinit var shaderAtoGrey: ShaderProgram - lateinit var shaderMulRGBX: ShaderProgram - lateinit var shaderMulAAAX: ShaderProgram lateinit var textureWhiteSquare: Texture @@ -204,8 +203,7 @@ object Terrarum : Screen { /** Actually just a mesh of four vertices, two triangles -- not a literal glQuad */ - lateinit var fullscreenQuad: Mesh; private set - private var fullscreenQuadInit = false + val fullscreenQuad = AppLoader.fullscreenQuad val deltaTime: Float; get() = Gdx.graphics.rawDeltaTime @@ -283,28 +281,6 @@ object Terrarum : Screen { } val MINIMAL_GL_MAX_TEXTURE_SIZE = 4096 - private fun initFullscreenQuad() { - if (!fullscreenQuadInit) { - fullscreenQuad = Mesh( - true, 4, 6, - VertexAttribute.Position(), - VertexAttribute.ColorUnpacked(), - VertexAttribute.TexCoords(0) - ) - fullscreenQuadInit = true - } - } - private fun updateFullscreenQuad(WIDTH: Int, HEIGHT: Int) { - initFullscreenQuad() - fullscreenQuad.setVertices(floatArrayOf( - 0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f, 1f, - WIDTH.toFloat(), 0f, 0f, 1f, 1f, 1f, 1f, 1f, 1f, - WIDTH.toFloat(), HEIGHT.toFloat(), 0f, 1f, 1f, 1f, 1f, 1f, 0f, - 0f, HEIGHT.toFloat(), 0f, 1f, 1f, 1f, 1f, 0f, 0f - )) - fullscreenQuad.setIndices(shortArrayOf(0, 1, 2, 2, 3, 0)) - } - override fun show() { if (environment != RunningEnvironment.MOBILE) { Gdx.gl.glDisable(GL20.GL_DITHER) @@ -327,9 +303,7 @@ object Terrarum : Screen { throw GdxRuntimeException("Graphics device not capable -- device's GL_VERSION: $GL_VERSION, required: $MINIMAL_GL_VERSION; GL_MAX_TEXTURE_SIZE: $GL_MAX_TEXTURE_SIZE, required: $MINIMAL_GL_MAX_TEXTURE_SIZE") } - - updateFullscreenQuad(WIDTH, HEIGHT) - + // resize fullscreen quad? TextureRegionPack.globalFlipY = true // !! TO MAKE LEGACY CODE RENDER ON ITS POSITION !! @@ -377,9 +351,6 @@ object Terrarum : Screen { shaderRGBOnly = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/rgbonly.frag")) shaderAtoGrey = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/aonly.frag")) - shaderMulRGBX = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/rgbxmul.frag")) - shaderMulAAAX = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/aaaxmul.frag")) - if (!shaderBlendGlow.isCompiled) { Gdx.app.log("shaderBlendGlow", shaderBlendGlow.log) @@ -486,7 +457,7 @@ object Terrarum : Screen { // re-calculate fullscreen quad - updateFullscreenQuad(screenW, screenH) + //updateFullscreenQuad(screenW, screenH) //appLoader.resize(width, height) //Gdx.graphics.setWindowedMode(width, height) @@ -923,6 +894,10 @@ fun blendScreen(batch: SpriteBatch? = null) { Gdx.gl.glBlendEquation(GL20.GL_FUNC_ADD) // batch.flush does not touch blend equation } +fun blendDisable(batch: SpriteBatch? = null) { + (batch ?: Terrarum.batch).disableBlending() +} + object BlendMode { const val SCREEN = "screen" const val MULTIPLY = "multiply" diff --git a/src/net/torvald/terrarum/TitleScreen.kt b/src/net/torvald/terrarum/TitleScreen.kt index d83754386..b30b44a1a 100644 --- a/src/net/torvald/terrarum/TitleScreen.kt +++ b/src/net/torvald/terrarum/TitleScreen.kt @@ -16,6 +16,7 @@ import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.fmod import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.modulebasegame.Ingame +import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.gameactors.* import net.torvald.terrarum.serialise.ReadLayerData import net.torvald.terrarum.ui.UICanvas @@ -104,7 +105,7 @@ class TitleScreen(val batch: SpriteBatch) : Screen { private val gradWhiteTop = Color(0xf8f8f8ff.toInt()) private val gradWhiteBottom = Color(0xd8d8d8ff.toInt()) - private val lightFBOformat = Pixmap.Format.RGB888 + private val lightFBOformat = Pixmap.Format.RGBA8888 lateinit var lightmapFboA: FrameBuffer lateinit var lightmapFboB: FrameBuffer private var lightmapInitialised = false // to avoid nullability of lightmapFBO @@ -278,9 +279,9 @@ class TitleScreen(val batch: SpriteBatch) : Screen { // draw tiles // - BlocksDrawer.renderWall(batch) - BlocksDrawer.renderTerrain(batch) - BlocksDrawer.renderFront(batch, false) + BlocksDrawer.renderWall(batch.projectionMatrix) + BlocksDrawer.renderTerrain(batch.projectionMatrix) + BlocksDrawer.renderFront(batch.projectionMatrix, false) FeaturesDrawer.drawEnvOverlay(batch) @@ -311,7 +312,7 @@ class TitleScreen(val batch: SpriteBatch) : Screen { batch.draw(lightTex, xrem, yrem, - lightTex.width * Ingame.lightmapDownsample, lightTex.height * Ingame.lightmapDownsample + lightTex.width * IngameRenderer.lightmapDownsample, lightTex.height * IngameRenderer.lightmapDownsample //lightTex.width.toFloat(), lightTex.height.toFloat() // for debugging ) @@ -420,7 +421,7 @@ class TitleScreen(val batch: SpriteBatch) : Screen { 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 / Ingame.lightmapDownsample // (5, 4f); using low numbers for pixel-y aesthetics + val blurRadius = 4f / IngameRenderer.lightmapDownsample // (5, 4f); using low numbers for pixel-y aesthetics var blurWriteBuffer = lightmapFboA var blurReadBuffer = lightmapFboB @@ -429,10 +430,12 @@ class TitleScreen(val batch: SpriteBatch) : Screen { lightmapFboA.inAction(null, null) { Gdx.gl.glClearColor(0f, 0f, 0f, 0f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + Gdx.gl.glDisable(GL20.GL_BLEND) } lightmapFboB.inAction(null, null) { Gdx.gl.glClearColor(0f, 0f, 0f, 0f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + Gdx.gl.glDisable(GL20.GL_BLEND) } @@ -440,9 +443,10 @@ class TitleScreen(val batch: SpriteBatch) : Screen { // initialise readBuffer with untreated lightmap blurReadBuffer.inAction(camera, batch) { batch.inUse { - blendNormal(batch) + //blendNormal(batch) + blendDisable(batch) batch.color = Color.WHITE - LightmapRenderer.draw(batch, LightmapRenderer.DRAW_FOR_RGB) + LightmapRenderer.draw(batch) } } } @@ -450,9 +454,10 @@ class TitleScreen(val batch: SpriteBatch) : Screen { // initialise readBuffer with untreated lightmap blurReadBuffer.inAction(camera, batch) { batch.inUse { - blendNormal(batch) + //blendNormal(batch) + blendDisable(batch) batch.color = Color.WHITE - LightmapRenderer.draw(batch, LightmapRenderer.DRAW_FOR_ALPHA) + LightmapRenderer.draw(batch) } } } diff --git a/src/net/torvald/terrarum/blockproperties/BlockProp.kt b/src/net/torvald/terrarum/blockproperties/BlockProp.kt index 379f78106..75481a7c2 100644 --- a/src/net/torvald/terrarum/blockproperties/BlockProp.kt +++ b/src/net/torvald/terrarum/blockproperties/BlockProp.kt @@ -41,7 +41,7 @@ class BlockProp { var lumColA = 0f /** - * @param luminosity Raw RGB value, without alpha + * @param luminosity */ inline val luminosity: Color get() = BlockPropUtil.getDynamicLumFunc(Color(lumColR, lumColG, lumColB, lumColA), dynamicLuminosityFunction) diff --git a/src/net/torvald/terrarum/modulebasegame/Ingame.kt b/src/net/torvald/terrarum/modulebasegame/Ingame.kt index 1777927dc..d4278abd4 100644 --- a/src/net/torvald/terrarum/modulebasegame/Ingame.kt +++ b/src/net/torvald/terrarum/modulebasegame/Ingame.kt @@ -86,7 +86,7 @@ class Ingame(batch: SpriteBatch) : IngameInstance(batch) { //val ZOOM_MINIMUM = 0.5f // definition moved to IngameInstance companion object { - val lightmapDownsample = 4f //2f: still has choppy look when the camera moves but unnoticeable when blurred + //val lightmapDownsample = 4f //2f: still has choppy look when the camera moves but unnoticeable when blurred /** Sets camera position so that (0,0) would be top-left of the screen, (width, height) be bottom-right. */ @@ -128,16 +128,6 @@ class Ingame(batch: SpriteBatch) : IngameInstance(batch) { } - private val worldFBOformat = if (Terrarum.environment == RunningEnvironment.MOBILE) Pixmap.Format.RGBA4444 else Pixmap.Format.RGBA8888 - private val lightFBOformat = Pixmap.Format.RGB888 - - var worldDrawFrameBuffer = FrameBuffer(worldFBOformat, Terrarum.WIDTH, Terrarum.HEIGHT, false) - var worldGlowFrameBuffer = FrameBuffer(worldFBOformat, Terrarum.WIDTH, Terrarum.HEIGHT, false) - var worldBlendFrameBuffer = FrameBuffer(worldFBOformat, Terrarum.WIDTH, Terrarum.HEIGHT, false) - // RGB elements of Lightmap for Color Vec4(R, G, B, 1.0) 24-bit - private lateinit var lightmapFboA: FrameBuffer - private lateinit var lightmapFboB: FrameBuffer - init { } @@ -205,21 +195,6 @@ class Ingame(batch: SpriteBatch) : IngameInstance(batch) { // GDX code // ////////////// - var camera = OrthographicCamera(Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat()) - - - // invert Y - fun initViewPort(width: Int, height: Int) { - // Set Y to point downwards - camera.setToOrtho(true, width.toFloat(), height.toFloat()) - - // Update camera matrix - camera.update() - - // Set viewport to restrict drawing - Gdx.gl20.glViewport(0, 0, width, height) - } - lateinit var gameLoadMode: GameLoadMode lateinit var gameLoadInfoPayload: Any @@ -337,8 +312,6 @@ class Ingame(batch: SpriteBatch) : IngameInstance(batch) { Gdx.input.inputProcessor = ingameController - initViewPort(Terrarum.WIDTH, Terrarum.HEIGHT) - // init console window consoleHandler = ConsoleWindow() @@ -545,7 +518,7 @@ class Ingame(batch: SpriteBatch) : IngameInstance(batch) { /** RENDER CODE GOES HERE */ //renderGame(batch) - Terrarum.debugTimers["Ingame.render"] = measureNanoTime { renderGame(batch) } + Terrarum.debugTimers["Ingame.render"] = measureNanoTime { renderGame() } } protected fun updateGame(delta: Float) { @@ -609,471 +582,18 @@ class Ingame(batch: SpriteBatch) : IngameInstance(batch) { } - private fun renderGame(batch: SpriteBatch) { - Gdx.gl.glClearColor(.094f, .094f, .094f, 0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) - Gdx.gl.glEnable(GL20.GL_BLEND) - Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - - //camera.position.set(-WorldCamera.x.toFloat(), -WorldCamera.y.toFloat(), 0f) // make camara work - //camera.position.set(0f, 0f, 0f) // make camara work - //batch.projectionMatrix = camera.combined - - - - LightmapRenderer.fireRecalculateEvent() - - - - worldBlendFrameBuffer.inAction(null, null) { - Gdx.gl.glClearColor(0f,0f,0f,0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) - Gdx.gl.glEnable(GL20.GL_BLEND) - Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - } - worldDrawFrameBuffer.inAction(null, null) { - Gdx.gl.glClearColor(0f,0f,0f,0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) - Gdx.gl.glEnable(GL20.GL_BLEND) - Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - } - worldGlowFrameBuffer.inAction(null, null) { - Gdx.gl.glClearColor(0f,0f,0f,1f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) - Gdx.gl.glEnable(GL20.GL_BLEND) - Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - } - - - fun moveCameraToWorldCoord() { - // using custom code for camera; this is obscure and tricky - camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work - camera.update() - batch.projectionMatrix = camera.combined - } - - - /////////////////////////// - // draw world to the FBO // - /////////////////////////// - processBlur(lightmapFboA, lightmapFboB, LightmapRenderer.DRAW_FOR_RGB) - - worldDrawFrameBuffer.inAction(camera, batch) { - - - // draw-with-poly doesn't want to co-op with peasant spriteBatch... (it hides sprites) - - batch.inUse { - batch.shader = null - batch.color = Color.WHITE - blendNormal() - } - - - - setCameraPosition(0f, 0f) - BlocksDrawer.renderWall(batch) - - - - batch.inUse { - moveCameraToWorldCoord() - actorsRenderBehind.forEach { it.drawBody(batch) } - particlesContainer.forEach { it.drawBody(batch) } - - } - - - - setCameraPosition(0f, 0f) - BlocksDrawer.renderTerrain(batch) - - - - batch.inUse { - ///////////////// - // draw actors // - ///////////////// - moveCameraToWorldCoord() - actorsRenderMiddle.forEach { it.drawBody(batch) } - actorsRenderMidTop.forEach { it.drawBody(batch) } - player.drawBody(batch) - actorsRenderFront.forEach { it.drawBody(batch) } - // --> Change of blend mode <-- introduced by children of ActorWithBody // - - - ///////////////////////////// - // draw map related stuffs // - ///////////////////////////// - } - - - - setCameraPosition(0f, 0f) - BlocksDrawer.renderFront(batch, false) - - - - batch.inUse { - // --> blendNormal() <-- by BlocksDrawer.renderFront - FeaturesDrawer.drawEnvOverlay(batch) - - - - - // 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 = Terrarum.shaderBayer - batch.shader.setUniformf("rcount", 64f) - batch.shader.setUniformf("gcount", 64f) - batch.shader.setUniformf("bcount", 64f) // de-banding - - val lightTex = lightmapFboB.colorBufferTexture // A or B? flipped in Y means you chose wrong buffer; use one that works correctly - lightTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) // blocky feeling for A E S T H E T I C S - - if (KeyToggler.isOn(KEY_LIGHTMAP_RENDER)) blendNormal() - else blendMul() - - batch.color = Color.WHITE - val xrem = -(WorldCamera.x.toFloat() fmod TILE_SIZEF) - val yrem = -(WorldCamera.y.toFloat() fmod TILE_SIZEF) - batch.draw(lightTex, - xrem, - yrem, - lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample - //lightTex.width.toFloat(), lightTex.height.toFloat() // for debugging - ) - - } - - - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // don't know why it is REALLY needed; it really depresses me - batch.shader = null - - - // move camera back to its former position - // using custom code for camera; this is obscure and tricky - camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work - camera.update() - batch.projectionMatrix = camera.combined - - } - } - - - ////////////////////////// - // draw glow to the FBO // - ////////////////////////// - processBlur(lightmapFboA, lightmapFboB, LightmapRenderer.DRAW_FOR_ALPHA) - - worldGlowFrameBuffer.inAction(camera, batch) { - batch.inUse { - batch.shader = null - - - batch.color = Color.WHITE - blendNormal() - - - - ////////////////////// - // draw actor glows // - ////////////////////// - moveCameraToWorldCoord() - actorsRenderBehind.forEach { it.drawGlow(batch) } - particlesContainer.forEach { it.drawGlow(batch) } - actorsRenderMiddle.forEach { it.drawGlow(batch) } - actorsRenderMidTop.forEach { it.drawGlow(batch) } - player.drawGlow(batch) - actorsRenderFront.forEach { it.drawGlow(batch) } - // --> blendNormal() <-- introduced by childs of ActorWithBody // - - - - // mix lighpmap canvas to this canvas (UV lights -- A channel written on RGB as greyscale image) - if (!KeyToggler.isOn(Input.Keys.F6)) { // F6 to disable lightmap draw - setCameraPosition(0f, 0f) - batch.shader = Terrarum.shaderBayer - batch.shader.setUniformf("rcount", 64f) - batch.shader.setUniformf("gcount", 64f) - batch.shader.setUniformf("bcount", 64f) // de-banding - - val lightTex = lightmapFboB.colorBufferTexture // A or B? flipped in Y means you chose wrong buffer; use one that works correctly - lightTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) // blocky feeling for A E S T H E T I C S - - if (KeyToggler.isOn(KEY_LIGHTMAP_RENDER)) blendNormal() - else blendMul() - - batch.color = Color.WHITE - val xrem = -(WorldCamera.x.toFloat() fmod TILE_SIZEF) - val yrem = -(WorldCamera.y.toFloat() fmod TILE_SIZEF) - batch.draw(lightTex, - xrem, - yrem, - lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample - //lightTex.width.toFloat(), lightTex.height.toFloat() // for debugging - ) - - } - - - blendNormal() - } - } - - - worldBlendFrameBuffer.inAction(camera, batch) { - Gdx.gl.glClearColor(0f, 0f, 0f, 0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - - - // draw blended world - val worldTex = worldDrawFrameBuffer.colorBufferTexture // WORLD: light_color must be applied beforehand - val glowTex = worldGlowFrameBuffer.colorBufferTexture // GLOW: light_uvlight must be applied beforehand - - worldTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - glowTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - - worldTex.bind(0) - glowTex.bind(1) - - - Terrarum.shaderBlendGlow.begin() - Terrarum.shaderBlendGlow.setUniformMatrix("u_projTrans", camera.combined) - Terrarum.shaderBlendGlow.setUniformi("u_texture", 0) - Terrarum.shaderBlendGlow.setUniformi("tex1", 1) - Terrarum.fullscreenQuad.render(Terrarum.shaderBlendGlow, GL20.GL_TRIANGLES) - Terrarum.shaderBlendGlow.end() - - - - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // don't know why it is REALLY needed; it really depresses me - - - batch.inUse { - batch.color = Color.WHITE - blendNormal() - - batch.shader = null - } - } - - - ///////////////////////// - // draw to main screen // - ///////////////////////// - camera.setToOrtho(true, Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat()) - batch.projectionMatrix = camera.combined - batch.inUse { - - batch.shader = null - - setCameraPosition(0f, 0f) - batch.color = Color.WHITE - blendNormal() - - - /////////////////////////// - // draw skybox to screen // - /////////////////////////// - - WeatherMixer.render(camera, world) - - - - - ///////////////////////////////// - // draw framebuffers to screen // - ///////////////////////////////// - - - - val blendedTex = worldBlendFrameBuffer.colorBufferTexture - blendedTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - batch.color = Color.WHITE - batch.shader = null - blendNormal() - batch.draw(blendedTex, 0f, 0f, blendedTex.width.toFloat(), blendedTex.height.toFloat()) - - - - - - // an old code. - /*batch.shader = null - val worldTex = worldDrawFrameBuffer.colorBufferTexture // WORLD: light_color must be applied beforehand - val glowTex = worldGlowFrameBuffer.colorBufferTexture // GLOW: light_uvlight must be applied beforehand - - - batch.draw(worldTex, 0f, 0f, worldTex.width.toFloat(), worldTex.height.toFloat())*/ - - - - batch.shader = null - - //////////////////////// - // debug informations // - //////////////////////// - - blendNormal() - // draw reference ID if debugWindow is open - if (debugWindow.isVisible) { - - actorContainer.forEachIndexed { i, actor -> - if (actor is ActorWithBody) { - batch.color = Color.WHITE - Terrarum.fontSmallNumbers.draw(batch, - actor.referenceID.toString(), - actor.hitbox.startX.toFloat(), - actor.hitbox.canonicalY.toFloat() + 4 - ) - } - } - } - // debug physics - if (KeyToggler.isOn(Input.Keys.F11)) { - actorContainer.forEachIndexed { i, actor -> - if (actor is ActorWithPhysics) { - /*shapeRenderer.inUse(ShapeRenderer.ShapeType.Line) { - shapeRenderer.color = Color(1f, 0f, 1f, 1f) - //shapeRenderer.lineWidth = 1f - shapeRenderer.rect( - actor.hitbox.startX.toFloat(), - actor.hitbox.startY.toFloat(), - actor.hitbox.width.toFloat(), - actor.hitbox.height.toFloat() - ) - }*/ - - // velocity - batch.color = Color.CHARTREUSE//GameFontBase.codeToCol["g"] - Terrarum.fontSmallNumbers.draw(batch, - "${0x7F.toChar()}X ${actor.externalForce.x}", - actor.hitbox.startX.toFloat(), - actor.hitbox.canonicalY.toFloat() + 4 + 8 - ) - Terrarum.fontSmallNumbers.draw(batch, - "${0x7F.toChar()}Y ${actor.externalForce.y}", - actor.hitbox.startX.toFloat(), - actor.hitbox.canonicalY.toFloat() + 4 + 8 * 2 - ) - } - } - } - // fluidmap debug - if (KeyToggler.isOn(Input.Keys.F4)) { - WorldSimulator.drawFluidMapDebug(batch) - } - - - - - ///////////////////////////// - // draw some overlays (UI) // - ///////////////////////////// - - uiContainer.forEach { - if (it != consoleHandler) { - batch.color = Color.WHITE - it.render(batch, camera) - } - } - - debugWindow.render(batch, camera) - // make sure console draws on top of other UIs - consoleHandler.render(batch, camera) - notifier.render(batch, camera) - - - blendNormal() - } - + private fun renderGame() { + IngameRenderer.invoke( + actorsRenderBehind, + actorsRenderMiddle, + actorsRenderMidTop, + actorsRenderFront, + particlesContainer, + player, + uiContainer + ) } - fun processBlur(lightmapFboA: FrameBuffer, lightmapFboB: FrameBuffer, 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 - - var blurWriteBuffer = lightmapFboA - var 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 { - blendNormal(batch) - batch.color = Color.WHITE - LightmapRenderer.draw(batch, LightmapRenderer.DRAW_FOR_RGB) - } - } - } - else { - // initialise readBuffer with untreated lightmap - blurReadBuffer.inAction(camera, batch) { - batch.inUse { - blendNormal(batch) - 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 @@ -1396,9 +916,6 @@ class Ingame(batch: SpriteBatch) : IngameInstance(batch) { } - - private var lightmapInitialised = false // to avoid nullability of lightmapFBO - /** * @param width same as Terrarum.WIDTH * @param height same as Terrarum.HEIGHT @@ -1410,35 +927,8 @@ class Ingame(batch: SpriteBatch) : IngameInstance(batch) { LightmapRenderer.resize(Terrarum.WIDTH, Terrarum.HEIGHT) MegaRainGovernor.resize() - worldDrawFrameBuffer.dispose() - worldDrawFrameBuffer = FrameBuffer(worldFBOformat, Terrarum.WIDTH, Terrarum.HEIGHT, false) - worldGlowFrameBuffer.dispose() - worldGlowFrameBuffer = FrameBuffer(worldFBOformat, Terrarum.WIDTH, Terrarum.HEIGHT, false) - worldBlendFrameBuffer.dispose() - worldBlendFrameBuffer = FrameBuffer(worldFBOformat, Terrarum.WIDTH, Terrarum.HEIGHT, false) - - if (lightmapInitialised) { - lightmapFboA.dispose() - lightmapFboB.dispose() - } - lightmapFboA = FrameBuffer( - lightFBOformat, - LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt(), - LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt(), - false - ) - lightmapFboB = FrameBuffer( - lightFBOformat, - LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt(), - LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt(), - false - ) - lightmapInitialised = true // are you the first time? - - - // Set up viewport when window is resized - initViewPort(Terrarum.WIDTH, Terrarum.HEIGHT) + IngameRenderer.resize(Terrarum.WIDTH, Terrarum.HEIGHT) if (gameInitialised) { @@ -1471,11 +961,7 @@ class Ingame(batch: SpriteBatch) : IngameInstance(batch) { } override fun dispose() { - worldDrawFrameBuffer.dispose() - worldGlowFrameBuffer.dispose() - worldBlendFrameBuffer.dispose() - lightmapFboA.dispose() - lightmapFboB.dispose() + IngameRenderer.dispose() actorsRenderBehind.forEach { it.dispose() } actorsRenderMiddle.forEach { it.dispose() } @@ -1497,14 +983,4 @@ class Ingame(batch: SpriteBatch) : IngameInstance(batch) { } - /** - * WARNING! this function flushes batch; use this sparingly! - * - * Camera will be moved so that (newX, newY) would be sit on the top-left edge. - */ - fun setCameraPosition(newX: Float, newY: Float) { - setCameraPosition(batch, camera, newX, newY) - } - - } diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt new file mode 100644 index 000000000..e3e845bcc --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -0,0 +1,520 @@ +package net.torvald.terrarum.modulebasegame + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.Input +import com.badlogic.gdx.graphics.* +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.glutils.FrameBuffer +import net.torvald.dataclass.CircularArray +import net.torvald.terrarum.* +import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gamecontroller.KeyToggler +import net.torvald.terrarum.gameworld.fmod +import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid +import net.torvald.terrarum.modulebasegame.gameactors.ParticleBase +import net.torvald.terrarum.ui.UICanvas +import net.torvald.terrarum.weather.WeatherMixer +import net.torvald.terrarum.worlddrawer.BlocksDrawer +import net.torvald.terrarum.worlddrawer.FeaturesDrawer +import net.torvald.terrarum.worlddrawer.LightmapRenderer +import net.torvald.terrarum.worlddrawer.WorldCamera + +/** + * This will be rendered to a postprocessor FBO + */ +object IngameRenderer { + + private lateinit var batch: SpriteBatch + private lateinit var camera: OrthographicCamera + + private lateinit var lightmapFboA: FrameBuffer + private lateinit var lightmapFboB: FrameBuffer + private lateinit var fboRGB: FrameBuffer + private lateinit var fboRGB_lightMixed: FrameBuffer + private lateinit var fboA: FrameBuffer + private lateinit var fboA_lightMixed: FrameBuffer + + // you must have lightMixed FBO; otherwise you'll be reading from unbaked FBO and it freaks out GPU + + private val shaderBlur = Terrarum.shaderBlur + private val shaderSkyboxFill = Terrarum.shaderSkyboxFill + private val shaderBlendGlow = Terrarum.shaderBlendGlow + private val shaderRGBOnly = Terrarum.shaderRGBOnly + private val shaderAtoGrey = Terrarum.shaderAtoGrey + + private val width = Terrarum.WIDTH + private val height = Terrarum.HEIGHT + private val widthf = width.toFloat() + private val heightf = height.toFloat() + + private var initDone = false + + private val world = (Terrarum.ingame as Ingame).world + private lateinit var player: ActorHumanoid + + var uiListToDraw = ArrayList() + + const val lightmapDownsample = 4f //2f: still has choppy look when the camera moves but unnoticeable when blurred + + private var debugMode = 0 + + operator fun invoke( + actorsRenderBehind: List, + actorsRenderMiddle: List, + actorsRenderMidTop: List, + actorsRenderFront : List, + particlesContainer: CircularArray, + player: ActorHumanoid, + uisToDraw: ArrayList? = null + ) { + + if (uisToDraw != null) { + uiListToDraw = uisToDraw + } + + init() + this.player = player + + + + + LightmapRenderer.fireRecalculateEvent() + + prepLightmapRGBA() + drawToRGB(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer) + drawToA(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer) + + // clear main or whatever super-FBO being used + clearBuffer() + + /////////////////////////////////////////////////////////////////////// + + // draw sky + WeatherMixer.render(camera, world) + + /////////////////////////////////////////////////////////////////////// + + // use shader to mix RGB and A + setCameraPosition(0f, 0f) + + val rgbTex = fboRGB_lightMixed.colorBufferTexture + val aTex = fboA_lightMixed.colorBufferTexture + + // normal behaviour + if (!KeyToggler.isOn(Input.Keys.F6) && + !KeyToggler.isOn(Input.Keys.F7) + ) { + debugMode = 0 + + aTex.bind(1) + Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it + + batch.inUse { + blendNormal(batch) + batch.shader = shaderBlendGlow + shaderBlendGlow.setUniformi("tex1", 1) + batch.draw(rgbTex, 0f, 0f) + } + + + // definitely something is not blended correctly + } + // something about RGB + else if (KeyToggler.isOn(Input.Keys.F6) && + !KeyToggler.isOn(Input.Keys.F7) + ) { + debugMode = 1 + batch.inUse { + blendNormal(batch) + batch.shader = null + batch.draw(rgbTex, 0f, 0f) + + + // indicator + batch.color = Color.RED + batch.fillRect(0f, 0f, 6f, 10f) + batch.color = Color.LIME + batch.fillRect(6f, 0f, 6f, 10f) + batch.color = Color.BLUE + batch.fillRect(12f, 0f, 6f, 10f) + batch.color = Color.WHITE + } + + // works as intended + } + // something about A + else if (!KeyToggler.isOn(Input.Keys.F6) && + KeyToggler.isOn(Input.Keys.F7) + ) { + debugMode = 2 + batch.inUse { + blendNormal(batch) + batch.shader = null + batch.draw(aTex, 0f, 0f) + + + // indicator + batch.color = Color.WHITE + batch.fillRect(18f, 0f, 18f, 10f) + } + + // works as intended + } + else { + if (debugMode == 1) { + KeyToggler.forceSet(Input.Keys.F6, false) + KeyToggler.forceSet(Input.Keys.F7, true) + } + else if (debugMode == 2) { + KeyToggler.forceSet(Input.Keys.F6, true) + KeyToggler.forceSet(Input.Keys.F7, false) + } + else { + KeyToggler.forceSet(Input.Keys.F6, false) + KeyToggler.forceSet(Input.Keys.F7, false) + } + + // works as intended + } + + + blendNormal(batch) + + + /////////////////////////////////////////////////////////////////////// + + // draw UI + setCameraPosition(0f, 0f) + + batch.inUse { + batch.shader = null + batch.color = Color.WHITE + + uiListToDraw.forEach { + it.render(batch, camera) + } + } + + // works but some UI elements have wrong transparency + blendNormal(batch) + } + + + private fun prepLightmapRGBA() { + lightmapFboA.inAction(null, null) { + clearBuffer() + Gdx.gl.glDisable(GL20.GL_BLEND) + } + lightmapFboB.inAction(null, null) { + clearBuffer() + Gdx.gl.glDisable(GL20.GL_BLEND) + } + + processBlur(lightmapFboA, lightmapFboB) + } + + private fun drawToRGB( + actorsRenderBehind: List, + actorsRenderMiddle: List, + actorsRenderMidTop: List, + actorsRenderFront : List, + particlesContainer: CircularArray + ) { + fboRGB.inAction(null, null) { clearBuffer() } + fboRGB_lightMixed.inAction(null, null) { clearBuffer() } + + fboRGB.inAction(camera, batch) { + + batch.inUse { + batch.shader = null + batch.color = Color.WHITE + } + + setCameraPosition(0f, 0f) + BlocksDrawer.renderWall(batch.projectionMatrix) + + batch.inUse { + moveCameraToWorldCoord() + actorsRenderBehind.forEach { it.drawBody(batch) } + particlesContainer.forEach { it.drawBody(batch) } + } + + setCameraPosition(0f, 0f) + BlocksDrawer.renderTerrain(batch.projectionMatrix) + + batch.inUse { + ///////////////// + // draw actors // + ///////////////// + moveCameraToWorldCoord() + actorsRenderMiddle.forEach { it.drawBody(batch) } + actorsRenderMidTop.forEach { it.drawBody(batch) } + player.drawBody(batch) + actorsRenderFront.forEach { it.drawBody(batch) } + // --> Change of blend mode <-- introduced by children of ActorWithBody // + } + + setCameraPosition(0f, 0f) + BlocksDrawer.renderFront(batch.projectionMatrix, false) // blue coloured filter of water, etc. + + batch.inUse { + FeaturesDrawer.drawEnvOverlay(batch) + } + } + + + fboRGB_lightMixed.inAction(camera, batch) { + + setCameraPosition(0f, 0f) + val xrem = -(WorldCamera.x.toFloat() fmod TILE_SIZEF) + val yrem = -(WorldCamera.y.toFloat() fmod TILE_SIZEF) + + batch.inUse { + // draw world + batch.draw(fboRGB.colorBufferTexture, 0f, 0f) + batch.flush() + + // multiply light on top of it + val lightTex = lightmapFboB.colorBufferTexture + + if (KeyToggler.isOn(Input.Keys.F8)) + blendNormal(batch) + else + blendMul(batch) + + batch.shader = shaderRGBOnly + batch.draw(lightTex, + xrem, yrem, + lightTex.width * lightmapDownsample, + lightTex.height * lightmapDownsample + ) + } + + + // NOTE TO SELF: this works. + } + + + blendNormal(batch) + } + + private fun drawToA( + actorsRenderBehind: List, + actorsRenderMiddle: List, + actorsRenderMidTop: List, + actorsRenderFront : List, + particlesContainer: CircularArray + ) { + fboA.inAction(null, null) { + clearBuffer() + // paint black + Gdx.gl.glClearColor(0f,0f,0f,1f) // solid black: so that unused area will be also black + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + } + fboA_lightMixed.inAction(null, null) { clearBuffer() } + + fboA.inAction(camera, batch) { + + batch.inUse { + batch.shader = null + batch.color = Color.WHITE + } + + setCameraPosition(0f, 0f) + // BlocksDrawer.renderWhateverGlow_WALL + + batch.inUse { + moveCameraToWorldCoord() + actorsRenderBehind.forEach { it.drawGlow(batch) } + particlesContainer.forEach { it.drawGlow(batch) } + } + + setCameraPosition(0f, 0f) + // BlocksDrawer.renderWhateverGlow_TERRAIN + + batch.inUse { + ///////////////// + // draw actors // + ///////////////// + moveCameraToWorldCoord() + actorsRenderMiddle.forEach { it.drawGlow(batch) } + actorsRenderMidTop.forEach { it.drawGlow(batch) } + player.drawGlow(batch) + actorsRenderFront.forEach { it.drawGlow(batch) } + // --> Change of blend mode <-- introduced by children of ActorWithBody // + } + } + + + fboA_lightMixed.inAction(camera, batch) { + + setCameraPosition(0f, 0f) + val xrem = -(WorldCamera.x.toFloat() fmod TILE_SIZEF) + val yrem = -(WorldCamera.y.toFloat() fmod TILE_SIZEF) + + batch.inUse { + // draw world + batch.draw(fboA.colorBufferTexture, 0f, 0f) + batch.flush() + + // multiply light on top of it + val lightTex = lightmapFboB.colorBufferTexture + + if (KeyToggler.isOn(Input.Keys.F8)) + blendNormal(batch) + else + blendMul(batch) + + batch.shader = shaderAtoGrey + batch.draw(lightTex, + xrem, yrem, + lightTex.width * lightmapDownsample, + lightTex.height * lightmapDownsample + ) + } + + + // NOTE TO SELF: this works. + } + + + blendNormal(batch) + } + + + private fun init() { + if (!initDone) { + batch = SpriteBatch() + camera = OrthographicCamera(widthf, heightf) + + camera.setToOrtho(true, widthf, heightf) + camera.update() + Gdx.gl20.glViewport(0, 0, width, height) + + resize(width, height) + + LightmapRenderer.world = world + + + + + initDone = true + } + } + + private fun clearBuffer() { + Gdx.gl.glClearColor(0f,0f,0f,0f) + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) + Gdx.gl.glEnable(GL20.GL_BLEND) + Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) + } + + private fun moveCameraToWorldCoord() { + // using custom code for camera; this is obscure and tricky + camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work + camera.update() + batch.projectionMatrix = camera.combined + } + + /** + * Camera will be moved so that (newX, newY) would be sit on the top-left edge. + */ + private fun setCameraPosition(newX: Float, newY: Float) { + camera.position.set((-newX + Terrarum.HALFW).round(), (-newY + Terrarum.HALFH).round(), 0f) + camera.update() + batch.projectionMatrix = camera.combined + } + + fun processBlur(lightmapFboA: FrameBuffer, lightmapFboB: FrameBuffer) { + 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 + + var blurWriteBuffer = lightmapFboA + var blurReadBuffer = lightmapFboB + + + // buffers must be cleared beforehand + + + // initialise readBuffer with untreated lightmap + blurReadBuffer.inAction(camera, batch) { + batch.inUse { + blendDisable(batch) + batch.color = Color.WHITE + LightmapRenderer.draw(batch) + } + } + + + + + 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 = 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 + } + } + } + + + + blendNormal(batch) + } + + fun resize(width: Int, height: Int) { + fboRGB = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false) + fboRGB_lightMixed = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false) + fboA = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false) + fboA_lightMixed = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false) + lightmapFboA = FrameBuffer( + Pixmap.Format.RGBA8888, + LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt(), + LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt(), + false + ) + lightmapFboB = FrameBuffer( + Pixmap.Format.RGBA8888, + LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt(), + LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt(), + false + ) + + BlocksDrawer.resize(width, height) + LightmapRenderer.resize(width, height) + } + + private val TILE_SIZEF = FeaturesDrawer.TILE_SIZE.toFloat() + + fun dispose() { + fboRGB.dispose() + fboA.dispose() + fboRGB_lightMixed.dispose() + fboA_lightMixed.dispose() + lightmapFboA.dispose() + lightmapFboB.dispose() + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt index bc134cecd..896b15640 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt @@ -53,7 +53,7 @@ object PlayerBuilderSigrid { //p.actorValue[AVKey.LUMR] = 0.84 //p.actorValue[AVKey.LUMG] = 0.93 //p.actorValue[AVKey.LUMB] = 1.37 - p.actorValue[AVKey.LUMA] = 1.93 + //p.actorValue[AVKey.LUMA] = 1.93 p.actorValue[AVKey.BASEDEFENCE] = 141 diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt index 92386611b..2bbfa05f6 100644 --- a/src/net/torvald/terrarum/weather/WeatherMixer.kt +++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt @@ -140,7 +140,7 @@ object WeatherMixer { Terrarum.shaderSkyboxFill.end() - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // don't know why it is needed; it really depresses me + Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it } diff --git a/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt b/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt index 8748b975c..5c4f2a8a9 100644 --- a/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt +++ b/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt @@ -376,27 +376,27 @@ object BlocksDrawer { // NO draw lightmap using colour filter, actors must also be hidden behind the darkness /////////////////////////////////////////// - fun renderWall(batch: SpriteBatch) { + fun renderWall(projectionMatrix: Matrix4) { // blend normal Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) Gdx.gl.glEnable(GL20.GL_BLEND) Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) drawTiles(WALL, false) - renderUsingBuffer(WALL, batch.projectionMatrix) + renderUsingBuffer(WALL, projectionMatrix) } - fun renderTerrain(batch: SpriteBatch) { + fun renderTerrain(projectionMatrix: Matrix4) { // blend normal Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) Gdx.gl.glEnable(GL20.GL_BLEND) Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) drawTiles(TERRAIN, false) // regular tiles - renderUsingBuffer(TERRAIN, batch.projectionMatrix) + renderUsingBuffer(TERRAIN, projectionMatrix) } - fun renderFront(batch: SpriteBatch, drawWires: Boolean) { + fun renderFront(projectionMatrix: Matrix4, drawWires: Boolean) { // blend mul Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) Gdx.gl.glEnable(GL20.GL_BLEND) @@ -404,7 +404,7 @@ object BlocksDrawer { drawTiles(TERRAIN, true) // blendmul tiles - renderUsingBuffer(TERRAIN, batch.projectionMatrix) + renderUsingBuffer(TERRAIN, projectionMatrix) @@ -416,7 +416,7 @@ object BlocksDrawer { if (drawWires) { drawTiles(WIRE, false) - renderUsingBuffer(WIRE, batch.projectionMatrix) + renderUsingBuffer(WIRE, projectionMatrix) } } @@ -757,7 +757,7 @@ object BlocksDrawer { tilesQuad.render(shader, GL20.GL_TRIANGLES) shader.end() - tilesBufferAsTex.dispose() + //tilesBufferAsTex.dispose() } private var oldScreenW = 0 diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt index f5cd785ab..1ac5fda7d 100644 --- a/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt +++ b/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt @@ -12,6 +12,7 @@ import net.torvald.terrarum.fillRect import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.modulebasegame.gameactors.ActorWithPhysics import net.torvald.terrarum.floorInt +import net.torvald.terrarum.modulebasegame.IngameRenderer import java.util.* /** @@ -54,7 +55,7 @@ object LightmapRendererOld { private val AIR = Block.AIR private const val TILE_SIZE = FeaturesDrawer.TILE_SIZE - private val DRAW_TILE_SIZE: Float = FeaturesDrawer.TILE_SIZE / Ingame.lightmapDownsample + private val DRAW_TILE_SIZE: Float = FeaturesDrawer.TILE_SIZE / IngameRenderer.lightmapDownsample // color model related constants const val MUL = 1024 // modify this to 1024 to implement 30-bit RGB diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt index 17c59749c..533eb08a6 100644 --- a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt +++ b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt @@ -16,6 +16,7 @@ import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.modulebasegame.gameactors.ActorWithPhysics import net.torvald.terrarum.ceilInt import net.torvald.terrarum.floorInt +import net.torvald.terrarum.modulebasegame.IngameRenderer import java.util.* /** @@ -58,7 +59,7 @@ object LightmapRenderer { private val AIR = Block.AIR private const val TILE_SIZE = FeaturesDrawer.TILE_SIZE - val DRAW_TILE_SIZE: Float = FeaturesDrawer.TILE_SIZE / Ingame.lightmapDownsample + val DRAW_TILE_SIZE: Float = FeaturesDrawer.TILE_SIZE / IngameRenderer.lightmapDownsample // color model related constants const val MUL = 1024 // modify this to 1024 to implement 30-bit RGB @@ -292,6 +293,7 @@ object LightmapRenderer { val l = getLightInternal(x, y) if (l == null) return null + // brighten if solid if (BlockCodex[world.getTileFromTerrain(x, y)].isSolid) { return Color( (l.r * 1.25f),//.clampOne(), @@ -310,13 +312,20 @@ object LightmapRenderer { lateinit var lightBuffer: Pixmap - fun draw(batch: SpriteBatch, drawMode: Int) { + private val colourNull = Color(0) + + fun draw(batch: SpriteBatch) { 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 val this_y_end = for_y_end// + overscan_open + // wipe out beforehand. You DO need this + lightBuffer.blending = Pixmap.Blending.None // gonna overwrite + lightBuffer.setColor(colourNull) + lightBuffer.fillRectangle(0, 0, lightBuffer.width, lightBuffer.height) + // write to colour buffer for (y in this_y_start..this_y_end) { @@ -327,16 +336,7 @@ object LightmapRenderer { for (x in this_x_start..this_x_end) { - val color = if (drawMode == DRAW_FOR_RGB) { - (getLightForOpaque(x, y) ?: Color(0f,0f,0f,0f)).normaliseToColourHDR() - } - else if (drawMode == DRAW_FOR_ALPHA) { - (getLightForOpaque(x, y) ?: Color(0f,0f,0f,0f)).normaliseToAlphaHDR() - } - else { - throw IllegalArgumentException() - } - + val color = (getLightForOpaque(x, y) ?: Color(0f,0f,0f,0f)).normaliseToHDR() lightBuffer.setColor(color) @@ -366,7 +366,7 @@ object LightmapRenderer { lightBufferAsTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // don't know why it is needed; it really depresses me + Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it // we might not need shader here... //batch.draw(lightBufferAsTex, 0f, 0f, lightBufferAsTex.width.toFloat(), lightBufferAsTex.height.toFloat()) batch.draw(lightBufferAsTex, 0f, 0f, lightBufferAsTex.width * DRAW_TILE_SIZE, lightBufferAsTex.height * DRAW_TILE_SIZE) @@ -375,10 +375,6 @@ object LightmapRenderer { - // TODO: set lightmap BACK TO array - // TODO: re-iterate over the lightmap, applying filters like getLightForOpaque(x, y) and save it to new buffer (pixmap) - // TODO: and THEN draw the map using SHADER - } val lightScalingMagic = 8f @@ -555,11 +551,13 @@ object LightmapRenderer { val intervalPos = (intensity * CHANNEL_MAX) - (intensity * CHANNEL_MAX).toInt() - return interpolateLinear( + val ret = interpolateLinear( intervalPos, rgbHDRLookupTable[intervalStart], rgbHDRLookupTable[intervalEnd] ) + + return ret } @@ -645,18 +643,11 @@ object LightmapRenderer { 1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f // isn't it beautiful? ) /** To eliminated visible edge on the gradient when 255/1023 is exceeded */ - inline fun Color.normaliseToColourHDR() = Color( + inline fun Color.normaliseToHDR() = Color( hdr(this.r), hdr(this.g), hdr(this.b), - 1f - ) - - inline fun Color.normaliseToAlphaHDR() = Color( - hdr(this.a), - hdr(this.a), - hdr(this.a), - 1f + hdr(this.a) ) /**