From b07e7f5fdd0bc6a0d83d2a2fc6f753ba458a3992 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 12 Sep 2020 11:24:32 +0900 Subject: [PATCH] q&d hack for ui opacity control using a shader --- .../modulebasegame/ui/UIQuickslotPie.kt | 2 +- .../modulebasegame/ui/UIScreenZoom.kt | 3 +- src/net/torvald/terrarum/ui/UICanvas.kt | 4 +- src/net/torvald/terrarum/ui/UIHandler.kt | 58 +++++++++++++++++-- .../terrarum/ui/UIItemHorizontalFadeSlide.kt | 4 +- .../terrarum/ui/UIItemTransitionContainer.kt | 2 +- 6 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt index bc7b5ef79..7c0d33ebf 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt @@ -79,7 +79,7 @@ class UIQuickslotPie : UICanvas() { val slotX = slotCentrePoint.x.toInt() val slotY = slotCentrePoint.y.toInt() - drawColor.a = handler.opacity * UIQuickslotBar.DISPLAY_OPACITY + drawColor.a = UIQuickslotBar.DISPLAY_OPACITY batch.color = drawColor image.draw(batch, slotX, slotY) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIScreenZoom.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIScreenZoom.kt index 9f93e343a..3a718e91f 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIScreenZoom.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIScreenZoom.kt @@ -1,6 +1,7 @@ package net.torvald.terrarum.modulebasegame.ui import com.badlogic.gdx.graphics.Camera +import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import net.torvald.EMDASH import net.torvald.terrarum.AppLoader @@ -34,7 +35,7 @@ class UIScreenZoom : UICanvas( } override fun renderUI(batch: SpriteBatch, camera: Camera) { - batch.color = handler.opacityColour + batch.color = Color.WHITE AppLoader.fontGame.draw( batch, zoomText, diff --git a/src/net/torvald/terrarum/ui/UICanvas.kt b/src/net/torvald/terrarum/ui/UICanvas.kt index 29d2ba6d2..93eed3e94 100644 --- a/src/net/torvald/terrarum/ui/UICanvas.kt +++ b/src/net/torvald/terrarum/ui/UICanvas.kt @@ -121,8 +121,8 @@ abstract class UICanvas( * Under normal circumstances, draws are automatically translated as per the handler's X/Y position. * This means, don't write like: ```draw(posX + 4, posY + 32)```, do instead: ```draw(4, 32)``` unless you have a good reason to do so. * - * The transparency of the handler is independent of the draw, you must specified the color yourself - * using handler.opacity or handler.opacityColour + * The transparency of the handler is independent of the draw, you must set the drawing color yourself + * (use handler.opacity or handler.opacityColour) */ abstract fun renderUI(batch: SpriteBatch, camera: Camera) diff --git a/src/net/torvald/terrarum/ui/UIHandler.kt b/src/net/torvald/terrarum/ui/UIHandler.kt index d6899880a..f3ecf7cf6 100644 --- a/src/net/torvald/terrarum/ui/UIHandler.kt +++ b/src/net/torvald/terrarum/ui/UIHandler.kt @@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.utils.Disposable +import net.torvald.terrarum.AppLoader import net.torvald.terrarum.Terrarum import net.torvald.terrarum.gamecontroller.KeyToggler import net.torvald.terrarum.modulebasegame.TerrarumIngame @@ -15,6 +16,9 @@ import net.torvald.terrarum.modulebasegame.TerrarumIngame * to the coordinate of displayed cartesian coords, and update and render the UI. * It also process game inputs and send control events to the UI so that the UI can handle them. * + * The UI is *non-compositing* and thus has no underlying framebuffers, meaning that some of the effects (opacity, scaling) + * must be separately implemented onto the UICanvas (which may cause some artefacts when UI elements are overlapping and they are both semi-transparent) + * * New UIs are NORMALLY HIDDEN; set it visible as you need! * * Created by minjaesong on 2015-12-31. @@ -28,6 +32,44 @@ class UIHandler(//var UI: UICanvas, internal var allowESCtoClose: Boolean = false ): Disposable { + companion object { + private val SHADER_PROG_FRAG = """ +#version 130 +#ifdef GL_ES + precision mediump float; +#endif + +varying vec4 v_color; +varying vec2 v_texCoords; +uniform sampler2D u_texture; + +uniform float opacity; + +void main(void) { + vec4 color = texture2D(u_texture, v_texCoords).rgba; + + gl_FragColor = v_color * vec4(color.rgb, color.a * opacity); +} +""".trimIndent() + + private val SHADER_PROG_VERT = """ +attribute vec4 a_position; +attribute vec4 a_color; +attribute vec2 a_texCoord0; + +uniform mat4 u_projTrans; + +varying vec4 v_color; +varying vec2 v_texCoords; + +void main() { + v_color = a_color; + v_texCoords = a_texCoord0; + gl_Position = u_projTrans * a_position; +} + """.trimIndent() + } + // X/Y Position relative to the game window. var posX: Int = 0 var posY: Int = 0 @@ -63,16 +105,18 @@ class UIHandler(//var UI: UICanvas, var closeFired = false var opacity = 1f - set(value) { + /*set(value) { field = value - opacityColour.set(1f,1f,1f,opacity) - } + opacityColour.a = value + }*/ var scale = 1f - val opacityColour = Color(1f, 1f, 1f, opacity) + //val opacityColour = Color(1f, 1f, 1f, opacity) var openCloseCounter = 0f + private val shader = AppLoader.loadShaderInline(SHADER_PROG_VERT, SHADER_PROG_FRAG) + init { //UI.handler = this } @@ -204,9 +248,12 @@ class UIHandler(//var UI: UICanvas, } batch.color = Color.WHITE - + batch.shader = shader + shader.setUniformf("opacity", opacity) ui.renderUI(batch, camera) //ingameGraphics.flush() + + batch.shader = null batch.color = Color.WHITE @@ -384,5 +431,6 @@ class UIHandler(//var UI: UICanvas, override fun dispose() { toggleKey?.let { KeyToggler.forceSet(it, false) } toggleButton?.let { /* ButtonToggler.forceSet(it, false) */ } + shader.dispose() } } diff --git a/src/net/torvald/terrarum/ui/UIItemHorizontalFadeSlide.kt b/src/net/torvald/terrarum/ui/UIItemHorizontalFadeSlide.kt index 6638aca32..e363a1936 100644 --- a/src/net/torvald/terrarum/ui/UIItemHorizontalFadeSlide.kt +++ b/src/net/torvald/terrarum/ui/UIItemHorizontalFadeSlide.kt @@ -15,10 +15,10 @@ class UIItemHorizontalFadeSlide( //transitionLength: Float, currentPosition: Float, vararg uis: UICanvas -) : UIItemTransitionContainer(parent, initialX, initialY, width, height, 0.212f, currentPosition, uis) { +) : UIItemTransitionContainer(parent, initialX, initialY, width, height, 0.15f, currentPosition, uis) { fun getOffX(index: Int) = ((currentPosition - index) * width / 2f).roundToInt() - fun getOpacity(index: Int) = (currentPosition - index).coerceIn(0f, 1f) + fun getOpacity(index: Int) = 1f - (currentPosition - index).coerceIn(0f, 1f) // fixme make it work for both direction init { // re-position the uis according to the initial choice of currentPosition diff --git a/src/net/torvald/terrarum/ui/UIItemTransitionContainer.kt b/src/net/torvald/terrarum/ui/UIItemTransitionContainer.kt index b907841ce..40107a427 100644 --- a/src/net/torvald/terrarum/ui/UIItemTransitionContainer.kt +++ b/src/net/torvald/terrarum/ui/UIItemTransitionContainer.kt @@ -12,7 +12,7 @@ open class UIItemTransitionContainer( initialY: Int, override val width: Int, override val height: Int, - val transitionLength: Float = 0.212f, + val transitionLength: Float = 0.15f, var currentPosition: Float = 0f, val uis: Array ) : UIItem(parent, initialX, initialY) {