mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-09 18:14:06 +09:00
380 lines
16 KiB
Kotlin
380 lines
16 KiB
Kotlin
package net.torvald.terrarum.ui
|
|
|
|
import com.badlogic.gdx.Gdx
|
|
import com.badlogic.gdx.graphics.*
|
|
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
|
import com.badlogic.gdx.graphics.glutils.Float16FrameBuffer
|
|
import com.badlogic.gdx.utils.Disposable
|
|
import com.jme3.math.FastMath
|
|
import net.torvald.random.HQRNG
|
|
import net.torvald.terrarum.*
|
|
import net.torvald.terrarum.imagefont.BigAlphNum
|
|
import net.torvald.terrarum.imagefont.TinyAlphNum
|
|
import net.torvald.terrarumsansbitmap.gdx.TerrarumSansBitmap
|
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|
import kotlin.math.roundToInt
|
|
|
|
|
|
/**
|
|
* Created by minjaesong on 2016-08-04.
|
|
*/
|
|
object Toolkit : Disposable {
|
|
|
|
object Theme {
|
|
val COL_INVENTORY_CELL_BORDER = Color(1f, 1f, 1f, 0.25f)
|
|
val COL_CELL_FILL = Color(0x232528C8)
|
|
val COL_CELL_FILL_ALT = Color(0x3c3835C8)
|
|
val COL_CELL_FILL_OPAQUE = Color(0x232528FF)
|
|
|
|
val COL_LIST_DEFAULT = Color.WHITE // white
|
|
val COL_INACTIVE = Color.LIGHT_GRAY
|
|
val COL_SELECTED = Color(0x00f8ff_ff) // cyan, HIGHLY SATURATED
|
|
val COL_MOUSE_UP = Color(0xfff066_ff.toInt()) // yellow (all yellows are of low saturation according to the colour science)
|
|
val COL_DISABLED = Color(0xaaaaaaff.toInt())
|
|
val COL_RED = Color(0xff8888ff.toInt())
|
|
val COL_REDD = Color(0xff4448ff.toInt())
|
|
|
|
/*
|
|
Try this for alt colour set:
|
|
|
|
COL_SELECTED: FFE800 oklch(92% 0.19255 102) saturated yellow
|
|
COL_MOUSE_UP: 55ECFE oklch(87% 0.127 207) whitened and slightly desaturated cyan
|
|
|
|
*/
|
|
}
|
|
|
|
|
|
private val shaderKawaseDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawasedown.frag")
|
|
private val shaderKawaseUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawaseup.frag")
|
|
private val shaderBoxDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/boxdown.frag")
|
|
private val shaderBoxUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/boxup.frag")
|
|
|
|
private lateinit var fboBlur: Float16FrameBuffer
|
|
private lateinit var fboBlurHalf: Float16FrameBuffer
|
|
private lateinit var fboBlurQuarter: Float16FrameBuffer
|
|
private lateinit var blurWriteQuad: Mesh
|
|
private lateinit var blurWriteQuad2: Mesh
|
|
private lateinit var blurWriteQuad4: Mesh
|
|
|
|
// val baloonTile = TextureRegionPack("assets/graphics/gui/message_black_tileable.tga", 36, 36)
|
|
|
|
val textureWhiteSquare = Texture(Gdx.files.internal("assets/graphics/ortho_line_tex_2px.tga"))
|
|
val textureWhiteCircle = Texture(Gdx.files.internal("assets/graphics/circle_512.tga"))
|
|
|
|
init {
|
|
App.disposables.add(this)
|
|
|
|
textureWhiteSquare.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
|
textureWhiteCircle.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
|
|
|
CommonResourcePool.addToLoadingList("toolkit_box_border") {
|
|
TextureRegionPack(Gdx.files.internal("./assets/graphics/gui/box_border_flat_tileable.tga"), 1, 1)
|
|
}
|
|
CommonResourcePool.loadAll()
|
|
}
|
|
|
|
private val rng = HQRNG()
|
|
|
|
override fun dispose() {
|
|
// baloonTile.dispose()
|
|
textureWhiteSquare.dispose()
|
|
textureWhiteCircle.dispose()
|
|
|
|
fboBlur.dispose()
|
|
fboBlurHalf.dispose()
|
|
fboBlurQuarter.dispose()
|
|
|
|
blurWriteQuad.dispose()
|
|
blurWriteQuad2.dispose()
|
|
blurWriteQuad4.dispose()
|
|
|
|
shaderKawaseUp.dispose()
|
|
shaderKawaseDown.dispose()
|
|
shaderBoxDown.dispose()
|
|
shaderBoxUp.dispose()
|
|
}
|
|
|
|
val drawWidth: Int
|
|
get() = App.scr.width - if (App.getConfigBoolean("fx_streamerslayout")) App.scr.chatWidth else 0
|
|
val drawWidthf: Float
|
|
get() = drawWidth.toFloat()
|
|
val hdrawWidth: Int
|
|
get() = drawWidth / 2
|
|
val hdrawWidthf: Float
|
|
get() = hdrawWidth.toFloat()
|
|
|
|
fun drawCentered(batch: SpriteBatch, image: Texture, screenPosY: Int, ui: UICanvas? = null) {
|
|
val imageW = image.width
|
|
val targetW = ui?.width ?: drawWidth
|
|
batch.draw(image, targetW.minus(imageW).ushr(1).toFloat(), screenPosY.toFloat())
|
|
}
|
|
fun drawCentered(batch: SpriteBatch, image: TextureRegion, screenPosY: Int, ui: UICanvas? = null) {
|
|
val imageW = image.regionWidth
|
|
val targetW = ui?.width ?: drawWidth
|
|
batch.draw(image, targetW.minus(imageW).ushr(1).toFloat(), screenPosY.toFloat())
|
|
}
|
|
|
|
fun drawCentered(batch: SpriteBatch, image: Texture, screenPosY: Int, targetW: Int, offsetX: Int = 0, offsetY: Int = 0) {
|
|
val imageW = image.width
|
|
batch.draw(image, targetW.minus(imageW).ushr(1).toFloat() + offsetX, screenPosY.toFloat() + offsetY)
|
|
}
|
|
fun drawCentered(batch: SpriteBatch, image: TextureRegion, screenPosY: Int, targetW: Int, offsetX: Int = 0, offsetY: Int = 0) {
|
|
val imageW = image.regionWidth
|
|
batch.draw(image, targetW.minus(imageW).ushr(1).toFloat() + offsetX, screenPosY.toFloat() + offsetY)
|
|
}
|
|
|
|
fun drawTextCentered(batch: SpriteBatch, font: TerrarumSansBitmap, text: String, tbw: Int, tbx: Int, tby: Int) {
|
|
val tw = font.getWidth(text)
|
|
font.draw(batch, text, tbx + (tbw - tw) / 2, tby)
|
|
}
|
|
fun drawTextCentered(batch: SpriteBatch, font: TinyAlphNum, text: String, tbw: Int, tbx: Int, tby: Int) {
|
|
val tw = font.getWidth(text)
|
|
font.draw(batch, text, (tbx + (tbw - tw) / 2).toFloat(), tby.toFloat())
|
|
}
|
|
fun drawTextCentered(batch: SpriteBatch, font: BigAlphNum, text: String, tbw: Int, tbx: Int, tby: Int) {
|
|
val tw = font.getWidth(text)
|
|
font.draw(batch, text, (tbx + (tbw - tw) / 2).toFloat(), tby.toFloat())
|
|
}
|
|
|
|
fun fillArea(batch: SpriteBatch, x: Int, y: Int, w: Int, h: Int) {
|
|
batch.draw(textureWhiteSquare, x.toFloat(), y.toFloat(), w.toFloat(), h.toFloat())
|
|
}
|
|
fun fillArea(batch: SpriteBatch, x: Float, y: Float, w: Float, h: Float) {
|
|
batch.draw(textureWhiteSquare, x, y, w, h)
|
|
}
|
|
fun fillCircle(batch: SpriteBatch, x: Int, y: Int, w: Int, h: Int) {
|
|
batch.draw(textureWhiteCircle, x.toFloat(), y.toFloat(), w.toFloat(), h.toFloat())
|
|
}
|
|
fun drawStraightLine(batch: SpriteBatch, x: Float, y: Float, otherEnd: Float, thickness: Float, isVertical: Boolean) {
|
|
if (!isVertical)
|
|
fillArea(batch, x, y, otherEnd - x, thickness)
|
|
else
|
|
fillArea(batch, x, y, thickness, otherEnd - y)
|
|
}
|
|
fun drawStraightLine(batch: SpriteBatch, x: Int, y: Int, otherEnd: Int, thickness: Int, isVertical: Boolean) {
|
|
drawStraightLine(batch, x.toFloat(), y.toFloat(), otherEnd.toFloat(), thickness.toFloat(), isVertical)
|
|
}
|
|
|
|
fun drawBoxBorder(batch: SpriteBatch, x: Float, y: Float, w: Float, h: Float) =
|
|
drawBoxBorder(batch, x.roundToInt(), y.roundToInt(), w.roundToInt(), h.roundToInt())
|
|
|
|
/**
|
|
* Parameters are THAT OF THE BOX, the border will be drawn OUTSIDE of the params you specified!
|
|
*/
|
|
fun drawBoxBorder(batch: SpriteBatch, x: Int, y: Int, w: Int, h: Int) {
|
|
val pack = CommonResourcePool.getAsTextureRegionPack("toolkit_box_border")
|
|
val tx = pack.tileW.toFloat()
|
|
val ty = pack.tileH.toFloat()
|
|
|
|
// top edge
|
|
batch.draw(pack.get(1, 0), x.toFloat(), y - ty, w.toFloat(), ty)
|
|
// bottom edge
|
|
batch.draw(pack.get(1, 2), x.toFloat(), y.toFloat() + h, w.toFloat(), ty)
|
|
// left edge
|
|
batch.draw(pack.get(0, 1), x.toFloat() - tx, y.toFloat(), tx, h.toFloat())
|
|
// right edge
|
|
batch.draw(pack.get(2, 1), x.toFloat() + w, y.toFloat(), tx, h.toFloat())
|
|
|
|
// top left point
|
|
/*batch.draw(pack.get(0, 0), x - tx, y - ty)
|
|
// top right point
|
|
batch.draw(pack.get(2, 0), x + tx, y - ty)
|
|
// bottom left point
|
|
batch.draw(pack.get(0, 2), x - tx, y + ty)
|
|
// bottom right point
|
|
batch.draw(pack.get(2, 2), x + tx, y + ty)*/
|
|
|
|
}
|
|
|
|
private lateinit var blurtex0: Texture
|
|
private lateinit var blurtex1: Texture
|
|
private lateinit var blurtex2: Texture
|
|
private lateinit var blurtex3: Texture
|
|
|
|
fun blurEntireScreen(batch: SpriteBatch, camera: OrthographicCamera, blurRadius0: Float, x: Int, y: Int, w: Int, h: Int) {
|
|
batch.end()
|
|
|
|
val blurRadius = FastMath.pow(blurRadius0, 0.5f)
|
|
val renderTarget = FrameBufferManager.peek()
|
|
|
|
/*if (blurRadius > 3f) {
|
|
val radius3 = (blurRadius - 3f) / 8f
|
|
fboBlurHalf.inAction(camera, batch) {
|
|
blurtex0 = renderTarget.colorBufferTexture
|
|
blurtex0.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
|
blurtex0.bind(0)
|
|
shaderKawaseDown.bind()
|
|
shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined)
|
|
shaderKawaseDown.setUniformi("u_texture", 0)
|
|
shaderKawaseDown.setUniformf("halfpixel", radius3 / fboBlurHalf.width, radius3 / fboBlurHalf.height)
|
|
blurWriteQuad2.render(shaderKawaseDown, GL20.GL_TRIANGLE_FAN)
|
|
}
|
|
|
|
fboBlurQuarter.inAction(camera, batch) {
|
|
blurtex1 = fboBlurHalf.colorBufferTexture
|
|
blurtex1.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
|
blurtex1.bind(0)
|
|
shaderKawaseDown.bind()
|
|
shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined)
|
|
shaderKawaseDown.setUniformi("u_texture", 0)
|
|
shaderKawaseDown.setUniformf("halfpixel", radius3 / fboBlurQuarter.width, radius3 / fboBlurQuarter.height)
|
|
blurWriteQuad4.render(shaderKawaseDown, GL20.GL_TRIANGLE_FAN)
|
|
}
|
|
|
|
fboBlurHalf.inAction(camera, batch) {
|
|
blurtex2 = fboBlurQuarter.colorBufferTexture
|
|
blurtex2.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
|
blurtex2.bind(0)
|
|
shaderKawaseUp.bind()
|
|
shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined)
|
|
shaderKawaseUp.setUniformi("u_texture", 0)
|
|
shaderKawaseUp.setUniformf("halfpixel", radius3 / fboBlurQuarter.width, radius3 / fboBlurQuarter.height)
|
|
blurWriteQuad2.render(shaderKawaseUp, GL20.GL_TRIANGLE_FAN)
|
|
}
|
|
|
|
fboBlur.inAction(camera, batch) {
|
|
blurtex3 = fboBlurHalf.colorBufferTexture
|
|
blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
|
blurtex3.bind(0)
|
|
shaderKawaseUp.bind()
|
|
shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined)
|
|
shaderKawaseUp.setUniformi("u_texture", 0)
|
|
shaderKawaseUp.setUniformf("halfpixel", radius3 / fboBlurHalf.width, radius3 / fboBlurHalf.height)
|
|
blurWriteQuad.render(shaderKawaseUp, GL20.GL_TRIANGLE_FAN)
|
|
}
|
|
}*/
|
|
|
|
fboBlurHalf.inAction(camera, batch) {
|
|
blurtex2 = renderTarget.colorBufferTexture
|
|
blurtex2.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
|
blurtex2.bind(0)
|
|
shaderKawaseDown.bind()
|
|
shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined)
|
|
shaderKawaseDown.setUniformi("u_texture", 0)
|
|
shaderKawaseDown.setUniformf("halfpixel", blurRadius / fboBlurHalf.width, blurRadius / fboBlurHalf.height)
|
|
blurWriteQuad2.render(shaderKawaseDown, GL20.GL_TRIANGLE_FAN)
|
|
}
|
|
|
|
fboBlur.inAction(camera, batch) {
|
|
blurtex3 = fboBlurHalf.colorBufferTexture
|
|
blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
|
blurtex3.bind(0)
|
|
shaderKawaseUp.bind()
|
|
shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined)
|
|
shaderKawaseUp.setUniformi("u_texture", 0)
|
|
shaderKawaseUp.setUniformf("halfpixel", blurRadius / fboBlurHalf.width, blurRadius / fboBlurHalf.height)
|
|
blurWriteQuad.render(shaderKawaseUp, GL20.GL_TRIANGLE_FAN)
|
|
}
|
|
|
|
|
|
|
|
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it
|
|
|
|
batch.begin()
|
|
batch.shader = null
|
|
(batch as FlippingSpriteBatch).drawFlipped(fboBlur.colorBufferTexture, x.toFloat(), y.toFloat())
|
|
}
|
|
|
|
fun drawBaloon(batch: SpriteBatch, x: Float, y: Float, w: Float, h: Float, opacity: Float = 1f) {
|
|
// centre area
|
|
/*batch.draw(baloonTile.get(1, 1), x, y, w, h)
|
|
|
|
// edges
|
|
batch.draw(baloonTile.get(1, 0), x, y - baloonTile.tileH, w, baloonTile.tileH.toFloat())
|
|
batch.draw(baloonTile.get(1, 2), x, y + h, w, baloonTile.tileH.toFloat())
|
|
batch.draw(baloonTile.get(0, 1), x - baloonTile.tileW, y, baloonTile.tileW.toFloat(), h)
|
|
batch.draw(baloonTile.get(2, 1), x + w, y, baloonTile.tileW.toFloat(), h)
|
|
|
|
// corners
|
|
batch.draw(baloonTile.get(0, 0), x - baloonTile.tileW, y - baloonTile.tileH)
|
|
batch.draw(baloonTile.get(2, 0), x + w, y - baloonTile.tileH)
|
|
batch.draw(baloonTile.get(2, 2), x + w, y + h)
|
|
batch.draw(baloonTile.get(0, 2), x - baloonTile.tileW, y + h)*/
|
|
|
|
|
|
batch.color = Theme.COL_CELL_FILL_OPAQUE.cpy().mul(1f,1f,1f,opacity)
|
|
fillArea(batch, x - 4, y - 4, w + 8, h + 8)
|
|
batch.color = Theme.COL_INACTIVE.cpy().mul(1f,1f,1f,opacity)
|
|
drawBoxBorder(batch, x - 4, y - 4, w + 8, h + 8)
|
|
}
|
|
|
|
private var init = false
|
|
|
|
/**
|
|
* Make sure App.resize is called first!
|
|
*/
|
|
fun resize() {
|
|
if (!init) {
|
|
init = true
|
|
}
|
|
else {
|
|
blurWriteQuad.dispose()
|
|
blurWriteQuad2.dispose()
|
|
blurWriteQuad4.dispose()
|
|
fboBlur.dispose()
|
|
fboBlurHalf.dispose()
|
|
fboBlurQuarter.dispose()
|
|
}
|
|
|
|
blurWriteQuad = Mesh(
|
|
true, 4, 4,
|
|
VertexAttribute.Position(),
|
|
VertexAttribute.ColorUnpacked(),
|
|
VertexAttribute.TexCoords(0)
|
|
)
|
|
blurWriteQuad2 = Mesh(
|
|
true, 4, 4,
|
|
VertexAttribute.Position(),
|
|
VertexAttribute.ColorUnpacked(),
|
|
VertexAttribute.TexCoords(0)
|
|
)
|
|
blurWriteQuad4 = Mesh(
|
|
true, 4, 4,
|
|
VertexAttribute.Position(),
|
|
VertexAttribute.ColorUnpacked(),
|
|
VertexAttribute.TexCoords(0)
|
|
)
|
|
|
|
val fw = App.scr.width//MathUtils.nextPowerOfTwo(App.scr.width)
|
|
val fh = App.scr.height//MathUtils.nextPowerOfTwo(App.scr.height)
|
|
|
|
fboBlur = Float16FrameBuffer(
|
|
fw,
|
|
fh,
|
|
false
|
|
)
|
|
fboBlurHalf = Float16FrameBuffer(
|
|
fw / 2,
|
|
fh / 2,
|
|
false
|
|
)
|
|
fboBlurQuarter = Float16FrameBuffer(
|
|
fw / 4,
|
|
fh / 4,
|
|
false
|
|
)
|
|
|
|
blurWriteQuad.setVertices(floatArrayOf(
|
|
0f,0f,0f, 1f,1f,1f,1f, 0f,1f,
|
|
fw.toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f,
|
|
fw.toFloat(), fh.toFloat(),0f, 1f,1f,1f,1f, 1f,0f,
|
|
0f, fh.toFloat(),0f, 1f,1f,1f,1f, 0f,0f))
|
|
blurWriteQuad.setIndices(shortArrayOf(0, 1, 2, 3))
|
|
|
|
blurWriteQuad2.setVertices(floatArrayOf(
|
|
0f,0f,0f, 1f,1f,1f,1f, 0f,1f,
|
|
fw.div(2).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f,
|
|
fw.div(2).toFloat(), fh.div(2).toFloat(),0f, 1f,1f,1f,1f, 1f,0f,
|
|
0f, fh.div(2).toFloat(),0f, 1f,1f,1f,1f, 0f,0f))
|
|
blurWriteQuad2.setIndices(shortArrayOf(0, 1, 2, 3))
|
|
|
|
blurWriteQuad4.setVertices(floatArrayOf(
|
|
0f,0f,0f, 1f,1f,1f,1f, 0f,1f,
|
|
fw.div(4).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f,
|
|
fw.div(4).toFloat(), fh.div(4).toFloat(),0f, 1f,1f,1f,1f, 1f,0f,
|
|
0f, fh.div(4).toFloat(),0f, 1f,1f,1f,1f, 0f,0f))
|
|
blurWriteQuad4.setIndices(shortArrayOf(0, 1, 2, 3))
|
|
}
|
|
} |