mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-13 23:26:07 +09:00
prep for draw glow
This commit is contained in:
8
assets/aonly.frag
Normal file
8
assets/aonly.frag
Normal file
@@ -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);
|
||||||
|
}
|
||||||
0
assets/blendGlow.frag
Normal file
0
assets/blendGlow.frag
Normal file
8
assets/rgbonly.frag
Normal file
8
assets/rgbonly.frag
Normal file
@@ -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);
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ object DefaultConfig {
|
|||||||
val jsonObject = JsonObject()
|
val jsonObject = JsonObject()
|
||||||
|
|
||||||
jsonObject.addProperty("displayfps", 0) // 0: no limit, non-zero: limit
|
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
|
jsonObject.addProperty("imtooyoungtodie", false) // no perma-death
|
||||||
|
|||||||
@@ -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 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 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 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)
|
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 {
|
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 useShader: Boolean = false
|
||||||
private val shaderProgram = 0
|
private val shaderProgram = 0
|
||||||
@@ -190,10 +194,6 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
|||||||
* Create new world
|
* Create new world
|
||||||
*/
|
*/
|
||||||
fun enter() {
|
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
|
// init map as chosen size
|
||||||
world = GameWorld(8192, 2048)
|
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) {
|
private fun renderGame(batch: SpriteBatch) {
|
||||||
Gdx.gl.glClearColor(.157f, .157f, .157f, 0f)
|
Gdx.gl.glClearColor(.157f, .157f, .157f, 0f)
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
@@ -469,97 +473,24 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
|||||||
///////////////////
|
///////////////////
|
||||||
// blur lightmap //
|
// 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) {
|
worldDrawFrameBuffer.inAction(null, null) {
|
||||||
Gdx.gl.glClearColor(0f,0f,0f,0f)
|
Gdx.gl.glClearColor(0f,0f,0f,0f)
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
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 //
|
// draw world to the FBO //
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
|
processBlur(LightmapRenderer.DRAW_FOR_RGB)
|
||||||
|
|
||||||
worldDrawFrameBuffer.inAction(camera, batch) {
|
worldDrawFrameBuffer.inAction(camera, batch) {
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.shader = null
|
batch.shader = null
|
||||||
|
|
||||||
@@ -598,7 +529,7 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
|||||||
FeaturesDrawer.drawEnvOverlay(batch)
|
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
|
if (!KeyToggler.isOn(Input.Keys.F6)) { // F6 to disable lightmap draw
|
||||||
setCameraPosition(0f, 0f)
|
setCameraPosition(0f, 0f)
|
||||||
batch.shader = null
|
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.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work
|
||||||
camera.update()
|
camera.update()
|
||||||
batch.projectionMatrix = camera.combined
|
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 //
|
// draw actor glows //
|
||||||
//////////////////////
|
//////////////////////
|
||||||
// FIXME needs some new blending/shader for glow...
|
// FIXME needs some new blending/shader for glow...
|
||||||
|
|
||||||
//actorsRenderMiddle.forEach { it.drawGlow(batch) }
|
|
||||||
//actorsRenderMidTop.forEach { it.drawGlow(batch) }
|
actorsRenderMiddle.forEach { it.drawGlow(batch) }
|
||||||
//player?.drawGlow(batch)
|
actorsRenderMidTop.forEach { it.drawGlow(batch) }
|
||||||
//actorsRenderFront.forEach { it.drawGlow(batch) }
|
player?.drawGlow(batch)
|
||||||
|
actorsRenderFront.forEach { it.drawGlow(batch) }
|
||||||
// --> blendLightenOnly() <-- introduced by childs of ActorWithBody //
|
// --> 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)
|
WeatherMixer.render(batch)
|
||||||
|
|
||||||
batch.flush()
|
|
||||||
|
|
||||||
batch.shader = null
|
|
||||||
batch.color = Color.WHITE
|
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)
|
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())
|
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)*/
|
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() {
|
private fun repossessActor() {
|
||||||
// check if currently pocessed actor is removed from game
|
// 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)
|
lightmapFboA = FrameBuffer(lightFBOformat, width.div(lightmapDownsample.toInt()), height.div(lightmapDownsample.toInt()), true)
|
||||||
lightmapFboB.dispose()
|
lightmapFboB.dispose()
|
||||||
lightmapFboB = FrameBuffer(lightFBOformat, width.div(lightmapDownsample.toInt()), height.div(lightmapDownsample.toInt()), true)
|
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
|
// Set up viewport when window is resized
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ import java.util.*
|
|||||||
const val GAME_NAME = "Terrarum"
|
const val GAME_NAME = "Terrarum"
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
|
Terrarum // invoke
|
||||||
|
|
||||||
val config = LwjglApplicationConfiguration()
|
val config = LwjglApplicationConfiguration()
|
||||||
config.foregroundFPS = Terrarum.RENDER_FPS
|
config.foregroundFPS = Terrarum.RENDER_FPS
|
||||||
config.backgroundFPS = Terrarum.RENDER_FPS
|
config.backgroundFPS = Terrarum.RENDER_FPS
|
||||||
@@ -45,6 +47,8 @@ fun main(args: Array<String>) {
|
|||||||
config.foregroundFPS = RENDER_FPS
|
config.foregroundFPS = RENDER_FPS
|
||||||
config.title = GAME_NAME
|
config.title = GAME_NAME
|
||||||
|
|
||||||
|
println("usevsync = ${Terrarum.USE_VSYNC}")
|
||||||
|
|
||||||
// the game must run on same speed regardless of the display FPS;
|
// 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"
|
// "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 shaderBlur: ShaderProgram
|
||||||
|
lateinit var shaderRGBOnly: ShaderProgram
|
||||||
|
lateinit var shaderAOnly: ShaderProgram
|
||||||
lateinit var shader4096: ShaderProgram
|
lateinit var shader4096: ShaderProgram
|
||||||
lateinit var shader4096Bayer: ShaderProgram
|
lateinit var shader4096Bayer: ShaderProgram
|
||||||
|
|
||||||
@@ -304,6 +310,11 @@ object Terrarum : ApplicationAdapter() {
|
|||||||
shader4096Bayer.end()
|
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
|
ModMgr // invoke Module Manager, will also invoke BlockCodex
|
||||||
ItemCodex // invoke Item Codex
|
ItemCodex // invoke Item Codex
|
||||||
|
|
||||||
@@ -583,12 +594,6 @@ fun blendNormal() {
|
|||||||
Gdx.gl.glBlendEquation(GL20.GL_FUNC_ADD) // batch.flush does not touch blend equation
|
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() {
|
fun blendScreen() {
|
||||||
Terrarum.batch.enableBlending()
|
Terrarum.batch.enableBlending()
|
||||||
Terrarum.batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_COLOR)
|
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 SCREEN = "GL_BLEND screen"
|
||||||
const val MULTIPLY = "GL_BLEND multiply"
|
const val MULTIPLY = "GL_BLEND multiply"
|
||||||
const val NORMAL = "GL_BLEND normal"
|
const val NORMAL = "GL_BLEND normal"
|
||||||
const val MAX = "GL_MAX"
|
//const val MAX = "GL_MAX"
|
||||||
|
|
||||||
fun resolve(mode: String) {
|
fun resolve(mode: String) {
|
||||||
when (mode) {
|
when (mode) {
|
||||||
SCREEN -> blendScreen()
|
SCREEN -> blendScreen()
|
||||||
MULTIPLY -> blendMul()
|
MULTIPLY -> blendMul()
|
||||||
NORMAL -> blendNormal()
|
NORMAL -> blendNormal()
|
||||||
MAX -> blendLightenOnly()
|
//MAX -> blendLightenOnly()
|
||||||
else -> throw Error("Unknown blend mode: $mode")
|
else -> throw Error("Unknown blend mode: $mode")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1150,7 +1150,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
|
|
||||||
override fun drawGlow(batch: SpriteBatch) {
|
override fun drawGlow(batch: SpriteBatch) {
|
||||||
if (isVisible && spriteGlow != null) {
|
if (isVisible && spriteGlow != null) {
|
||||||
blendLightenOnly()
|
blendNormal()
|
||||||
|
|
||||||
val offsetX = hitboxTranslateX * scale
|
val offsetX = hitboxTranslateX * scale
|
||||||
val offsetY = spriteGlow!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1
|
val offsetY = spriteGlow!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ object LightmapRenderer {
|
|||||||
/**
|
/**
|
||||||
* Float value, 1.0 for 1023
|
* Float value, 1.0 for 1023
|
||||||
*/
|
*/
|
||||||
private val lightmap: Array<Array<Color>> = 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<Color>> = Array(LIGHTMAP_HEIGHT) { Array(LIGHTMAP_WIDTH, { Color(0f,0f,0f,0f) }) } // TODO framebuffer?
|
||||||
private val lanternMap = ArrayList<Lantern>(Terrarum.ingame!!.ACTORCONTAINER_INITIAL_SIZE * 4)
|
private val lanternMap = ArrayList<Lantern>(Terrarum.ingame!!.ACTORCONTAINER_INITIAL_SIZE * 4)
|
||||||
|
|
||||||
private val AIR = Block.AIR
|
private val AIR = Block.AIR
|
||||||
@@ -260,9 +261,9 @@ object LightmapRenderer {
|
|||||||
// O(9n) == O(n) where n is a size of the map
|
// O(9n) == O(n) where n is a size of the map
|
||||||
// TODO devise multithreading on this
|
// 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 thisTerrain = Terrarum.ingame!!.world.getTileFromTerrain(x, y)
|
||||||
val thisWall = Terrarum.ingame!!.world.getTileFromWall(x, y)
|
val thisWall = Terrarum.ingame!!.world.getTileFromWall(x, y)
|
||||||
val thisTileLuminosity = BlockCodex[thisTerrain].luminosity // already been div by four
|
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
|
* sample ambient for eight points and apply attenuation for those
|
||||||
* maxblend eight values and use it
|
* 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,0f), 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,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,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 , y - 1) ?: 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,1f), 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,1f), 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,1f), thisTileOpacity)
|
/* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y ) ?: Color(0f,0f,0f,0f), thisTileOpacity)
|
||||||
|
|
||||||
return lightLevelThis maxBlend ambientAccumulator
|
return lightLevelThis maxBlend ambientAccumulator
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,7 @@ object LightmapRenderer {
|
|||||||
(l.r * 1.25f),//.clampOne(),
|
(l.r * 1.25f),//.clampOne(),
|
||||||
(l.g * 1.25f),//.clampOne(),
|
(l.g * 1.25f),//.clampOne(),
|
||||||
(l.b * 1.25f),//.clampOne()
|
(l.b * 1.25f),//.clampOne()
|
||||||
1f
|
(l.a * 1.25f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else {
|
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_start = for_x_start// + overscan_open
|
||||||
val this_x_end = for_x_end// + overscan_open
|
val this_x_end = for_x_end// + overscan_open
|
||||||
val this_y_start = for_y_start// + overscan_open
|
val this_y_start = for_y_start// + overscan_open
|
||||||
@@ -360,7 +364,14 @@ object LightmapRenderer {
|
|||||||
if (x + sameLevelCounter >= this_x_end) break
|
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(
|
batch.fillRect(
|
||||||
(x * DRAW_TILE_SIZE).round().toFloat(),
|
(x * DRAW_TILE_SIZE).round().toFloat(),
|
||||||
(y * 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.r * (1f - darken.r * lightScalingMagic),//.clampZero(),
|
||||||
data.g * (1f - darken.g * lightScalingMagic),//.clampZero(),
|
data.g * (1f - darken.g * lightScalingMagic),//.clampZero(),
|
||||||
data.b * (1f - darken.b * lightScalingMagic),//.clampZero(),
|
data.b * (1f - darken.b * lightScalingMagic),//.clampZero(),
|
||||||
1f)
|
data.a * (1f - darken.b * lightScalingMagic))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scaleSqrt2(data: Color): Color {
|
private fun scaleSqrt2(data: Color): Color {
|
||||||
@@ -412,7 +423,7 @@ object LightmapRenderer {
|
|||||||
data.r * 1.41421356f,
|
data.r * 1.41421356f,
|
||||||
data.g * 1.41421356f,
|
data.g * 1.41421356f,
|
||||||
data.b * 1.41421356f,
|
data.b * 1.41421356f,
|
||||||
1f)
|
data.a * 1.41421356f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -427,7 +438,7 @@ object LightmapRenderer {
|
|||||||
data.r * (1f + brighten.r * lightScalingMagic),
|
data.r * (1f + brighten.r * lightScalingMagic),
|
||||||
data.g * (1f + brighten.g * lightScalingMagic),
|
data.g * (1f + brighten.g * lightScalingMagic),
|
||||||
data.b * (1f + brighten.b * lightScalingMagic),
|
data.b * (1f + brighten.b * lightScalingMagic),
|
||||||
1f
|
data.a * (1f + brighten.b * lightScalingMagic)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,7 +469,7 @@ object LightmapRenderer {
|
|||||||
data.r + brighten,
|
data.r + brighten,
|
||||||
data.g + brighten,
|
data.g + brighten,
|
||||||
data.b + 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.r > other.r) this.r else other.r,
|
||||||
if (this.g > other.g) this.g else other.g,
|
if (this.g > other.g) this.g else other.g,
|
||||||
if (this.b > other.b) this.b else other.b,
|
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)
|
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() {
|
private fun purgeLightmap() {
|
||||||
for (y in 0..LIGHTMAP_HEIGHT - 1) {
|
for (y in 0..LIGHTMAP_HEIGHT - 1) {
|
||||||
for (x in 0..LIGHTMAP_WIDTH - 1) {
|
for (x in 0..LIGHTMAP_WIDTH - 1) {
|
||||||
@@ -638,9 +658,16 @@ object LightmapRenderer {
|
|||||||
1f
|
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)
|
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
|
val histogram: Histogram
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
Reference in New Issue
Block a user