q&d hack for ui opacity control using a shader

This commit is contained in:
minjaesong
2020-09-12 11:24:32 +09:00
parent ac144da0b4
commit b07e7f5fdd
6 changed files with 61 additions and 12 deletions

View File

@@ -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)

View File

@@ -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,

View File

@@ -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)

View File

@@ -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()
}
}

View File

@@ -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

View File

@@ -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<out UICanvas>
) : UIItem(parent, initialX, initialY) {