PostProcessor working: nested FBO won't work, use FrameBufferManager

This commit is contained in:
minjaesong
2018-07-03 13:48:34 +09:00
parent 108a3e6188
commit 6b929ac107
154 changed files with 929 additions and 67 deletions

View File

@@ -96,7 +96,7 @@ public class AppLoader implements ApplicationListener {
public static void main(String[] args) {
appConfig = new LwjglApplicationConfiguration();
appConfig.vSyncEnabled = false;
appConfig.resizable = true;
appConfig.resizable = false;//true;
appConfig.width = 1072;
appConfig.height = 742;
appConfig.backgroundFPS = 9999;
@@ -146,10 +146,7 @@ public class AppLoader implements ApplicationListener {
shaderBayerSkyboxFill = new ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/4096_bayer_skyboxfill.frag"));
//shader18Bit = new ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/18BitColour.frag"));
// Q & D test for the new post shader
shader18Bit = new ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/crt.frag"));
shader18Bit = new ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/18BitColour.frag"));
@@ -212,24 +209,27 @@ public class AppLoader implements ApplicationListener {
}
}
else {
renderFBO.begin();
FrameBufferManager.begin(renderFBO);
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.glBlendEquation(GL20.GL_FUNC_ADD);
FrameBufferManager.end();
// nested FBOs are just not a thing in GL!
FrameBufferManager.begin(renderFBO);
setCameraPosition(0, 0);
screen.render(Gdx.graphics.getDeltaTime());
FrameBufferManager.end();
renderFBO.end();
//PostProcessor.INSTANCE.draw(renderFBO);
PostProcessor.INSTANCE.draw(camera.combined, renderFBO);
}
@@ -241,7 +241,7 @@ public class AppLoader implements ApplicationListener {
//initViewPort(width, height);
Terrarum.INSTANCE.resize(width, height);
if (screen != null) screen.resize(width, height);
if (screen != null) screen.resize(Terrarum.INSTANCE.getWIDTH(), Terrarum.INSTANCE.getHEIGHT());
if (renderFBO == null ||
@@ -256,6 +256,9 @@ public class AppLoader implements ApplicationListener {
);
}
appConfig.width = Terrarum.INSTANCE.getWIDTH();
appConfig.height = Terrarum.INSTANCE.getHEIGHT();
System.out.println("[AppLoader] Resize event");
}

View File

@@ -0,0 +1,30 @@
package net.torvald.terrarum;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import java.util.Stack;
/**
* Nested FBOs are just not a thing in GL!
*
* Created by minjaesong on 2018-07-03.
*
* @link https://stackoverflow.com/questions/25471727/libgdx-nested-framebuffer
*/
public class FrameBufferManager {
private static Stack<FrameBuffer> stack = new Stack<FrameBuffer>();
public static void begin(FrameBuffer buffer) {
if (!stack.isEmpty()) {
stack.peek().end();
}
stack.push(buffer).begin();
}
public static void end() {
stack.pop().end();
if (!stack.isEmpty()) {
stack.peek().begin();
}
}
}

View File

@@ -24,7 +24,7 @@ import javax.script.Invocable
/**
* Modules Resource Manager
* Modules (or Mods) Resource Manager
*
*
* NOTE!!: Usage of Groovy is only temporary; if Kotlin's "JSR 223" is no longer experimental and
@@ -47,15 +47,17 @@ object ModMgr {
val entryPoint: String,
val releaseDate: String,
val version: String,
val libraries: Array<String>
val libraries: Array<String>,
val dependencies: Array<String>
) {
override fun toString() =
"\tModule #$order -- $properName | $version | $author\n" +
"\t$description | $releaseDate\n" +
"\tEntry point: $entryPoint\n" +
"\tExternal libraries: ${libraries.joinToString(", ")}"
"\tExternal libraries: ${libraries.joinToString(", ")}\n" +
"\tDependencies: ${dependencies.joinToString("\n\t")}"
}
const val modDir = "./assets/modules"
const val modDir = "./assets/mods"
val moduleInfo = HashMap<String, ModuleMetadata>()
@@ -93,9 +95,10 @@ object ModMgr {
val entryPoint = modMetadata.getProperty("entrypoint")
val releaseDate = modMetadata.getProperty("releasedate")
val version = modMetadata.getProperty("version")
val libs = modMetadata.getProperty("libraries").split(';').toTypedArray()
val libs = modMetadata.getProperty("libraries").split(Regex(""";[ ]*""")).toTypedArray()
val dependency = modMetadata.getProperty("dependency").split(Regex(""";[ ]*""")).toTypedArray()
val isDir = FileSystems.getDefault().getPath("$modDir/$moduleName").toFile().isDirectory
moduleInfo[moduleName] = ModuleMetadata(index, isDir, properName, description, author, entryPoint, releaseDate, version, libs)
moduleInfo[moduleName] = ModuleMetadata(index, isDir, properName, description, author, entryPoint, releaseDate, version, libs, dependency)
println(moduleInfo[moduleName])
@@ -107,6 +110,7 @@ object ModMgr {
val newClassInstance = newClassConstructor.newInstance(/* no args defined */)
(newClassInstance as ModuleEntryPoint).invoke()
}
@@ -115,6 +119,9 @@ object ModMgr {
catch (noSuchModule: FileNotFoundException) {
System.err.println("[ModMgr] No such module: $moduleName, skipping...")
}
catch (e: ClassNotFoundException) {
System.err.println("[ModMgr] $moduleName has nonexisting entry point, skipping...")
}
}

View File

@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.badlogic.gdx.math.Matrix4
import kotlin.system.measureNanoTime
/**
@@ -15,6 +16,7 @@ import kotlin.system.measureNanoTime
object PostProcessor {
private lateinit var batch: SpriteBatch // not nulling to save some lines of code
//private lateinit var camera: OrthographicCamera
private var textureRegion: TextureRegion? = null
@@ -24,37 +26,39 @@ object PostProcessor {
lutTex = Texture(Gdx.files.internal("assets/clut/$filename"))
}
fun draw(fbo: FrameBuffer) {
fun draw(projMat: Matrix4, fbo: FrameBuffer) {
if (textureRegion == null) {
textureRegion = TextureRegion(fbo.colorBufferTexture)
batch = SpriteBatch()
//camera = OrthographicCamera(AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat())
//camera.setToOrtho(true, AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat())
//camera.update()
Gdx.gl20.glViewport(0, 0, AppLoader.appConfig.width, AppLoader.appConfig.height)
}
// FIXME something's really fucked between sky_gradient and the actual_world_render,
// maybe overlaying world over grad
// OR mixing lightmap (less likely?)
// known symptom: when localising the spritebatch, greyscale lightmap and the UI are the
// only thing gets drawn
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)
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?
fbo.colorBufferTexture.bind(0)
shader.begin()
shader.setUniformf("resolution", AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat())
shader.setUniformMatrix("u_projTrans", projMat)
shader.setUniformi("u_texture", 0)
AppLoader.fullscreenQuad.render(shader, GL20.GL_TRIANGLES)
shader.end()
@@ -65,4 +69,13 @@ object PostProcessor {
}
}
/**
* 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
}*/
}

View File

@@ -833,13 +833,19 @@ inline fun ShapeRenderer.inUse(shapeRendererType: ShapeRenderer.ShapeType = Shap
/** Use Batch inside of it! */
inline fun FrameBuffer.inAction(camera: OrthographicCamera?, batch: SpriteBatch?, action: (FrameBuffer) -> Unit) {
this.begin()
//this.begin()
FrameBufferManager.begin(this)
camera?.setToOrtho(true, this.width.toFloat(), this.height.toFloat())
camera?.position?.set((this.width / 2f).round(), (this.height / 2f).round(), 0f) // TODO floor? ceil? round?
camera?.update()
batch?.projectionMatrix = camera?.combined
action(this)
this.end()
//this.end()
FrameBufferManager.end()
camera?.setToOrtho(true, Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat())
camera?.update()
batch?.projectionMatrix = camera?.combined

View File

@@ -86,7 +86,12 @@ object IngameRenderer {
drawToA(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer)
// clear main or whatever super-FBO being used
clearBuffer()
//clearBuffer()
Gdx.gl.glClearColor(.64f, .754f, .84f, 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)
///////////////////////////////////////////////////////////////////////
@@ -277,6 +282,7 @@ object IngameRenderer {
// multiply light on top of it
val lightTex = lightmapFboB.colorBufferTexture
lightTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
if (KeyToggler.isOn(Input.Keys.F8))
blendNormal(batch)
@@ -360,6 +366,7 @@ object IngameRenderer {
// multiply light on top of it
val lightTex = lightmapFboB.colorBufferTexture
lightTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
if (KeyToggler.isOn(Input.Keys.F8))
blendNormal(batch)