mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
screen blur helper class
This commit is contained in:
@@ -38,6 +38,7 @@ import net.torvald.terrarum.modulebasegame.IngameRenderer;
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame;
|
||||
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory;
|
||||
import net.torvald.terrarum.serialise.WriteConfig;
|
||||
import net.torvald.terrarum.ui.BlurMgr;
|
||||
import net.torvald.terrarum.ui.Toolkit;
|
||||
import net.torvald.terrarum.utils.JsonFetcher;
|
||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas;
|
||||
@@ -52,6 +53,7 @@ import org.apache.commons.csv.CSVParser;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import javax.tools.Tool;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
@@ -1026,6 +1028,9 @@ public class App implements ApplicationListener {
|
||||
|
||||
deleteTempfiles();
|
||||
|
||||
Toolkit.INSTANCE.dispose();
|
||||
BlurMgr.INSTANCE.dispose();
|
||||
|
||||
disposables.forEach((it) -> {
|
||||
try {
|
||||
it.dispose();
|
||||
|
||||
@@ -69,7 +69,7 @@ basegame
|
||||
* e.g. 0x02010034 will be translated as 2.1.52
|
||||
*
|
||||
*/
|
||||
const val VERSION_RAW: Long = 0x0000_000005_000000
|
||||
const val VERSION_RAW: Long = 0x0000_000005_000001
|
||||
// Commit counts up to the Release 0.3.0: 2259
|
||||
// Commit counts up to the Release 0.3.1: 2278
|
||||
// Commit counts up to the Release 0.3.2: 2732
|
||||
|
||||
@@ -95,7 +95,7 @@ class UIFakeBlurOverlay(val blurRadius: Float, val nodarken: Boolean) : UICanvas
|
||||
batchDrawCol.a = openness
|
||||
batch.color = batchDrawCol
|
||||
if (App.getConfigBoolean("fx_backgroundblur")) {
|
||||
Toolkit.blurEntireScreen(batch, camera as OrthographicCamera, blurRadius * openness, 0, 0, width, height)
|
||||
Toolkit.blurEntireScreen(batch, blurRadius * openness, 0, 0, width, height)
|
||||
}
|
||||
|
||||
if (!nodarken) {
|
||||
|
||||
@@ -35,7 +35,7 @@ class UICheatDetected : UICanvas() {
|
||||
Terrarum.ingame?.consoleHandler?.setAsClose()
|
||||
Terrarum.ingame?.consoleHandler?.isVisible = false
|
||||
|
||||
Toolkit.blurEntireScreen(batch, camera as OrthographicCamera, 2f, 0, 0, width, height)
|
||||
Toolkit.blurEntireScreen(batch, 2f, 0, 0, width, height)
|
||||
batch.color = backgroundCol
|
||||
Toolkit.fillArea(batch, 0f, 0f, width.toFloat(), height.toFloat())
|
||||
|
||||
@@ -80,7 +80,7 @@ class UIPauseTheGame : UICanvas() {
|
||||
Terrarum.ingame?.consoleHandler?.setAsClose()
|
||||
Terrarum.ingame?.consoleHandler?.isVisible = false
|
||||
|
||||
Toolkit.blurEntireScreen(batch, camera as OrthographicCamera, 2f, 0, 0, width, height)
|
||||
Toolkit.blurEntireScreen(batch, 2f, 0, 0, width, height)
|
||||
batch.color = backgroundCol
|
||||
Toolkit.fillArea(batch, 0f, 0f, width.toFloat(), height.toFloat())
|
||||
|
||||
|
||||
150
src/net/torvald/terrarum/ui/BlurMgr.kt
Normal file
150
src/net/torvald/terrarum/ui/BlurMgr.kt
Normal file
@@ -0,0 +1,150 @@
|
||||
package net.torvald.terrarum.ui
|
||||
|
||||
import com.badlogic.gdx.graphics.*
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.glutils.Float16FrameBuffer
|
||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.ceilToInt
|
||||
import net.torvald.terrarum.inAction
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-11-23.
|
||||
*/
|
||||
object BlurMgr {
|
||||
|
||||
private class FrameBufferSet(val width: Int, val height: Int) {
|
||||
private val internalWidth = (width.toFloat() / 4f).ceilToInt() * 4
|
||||
private val internalHeight = (height.toFloat() / 4f).ceilToInt() * 4
|
||||
|
||||
val full = Float16FrameBuffer(width, height, false)
|
||||
val half = Float16FrameBuffer(internalWidth / 2, internalHeight / 2, false)
|
||||
val quarter = Float16FrameBuffer(internalWidth / 4, internalHeight / 4, false)
|
||||
val camera = OrthographicCamera(width.toFloat(), height.toFloat())
|
||||
|
||||
val quadFull = Mesh(
|
||||
true, 4, 4,
|
||||
VertexAttribute.Position(),
|
||||
VertexAttribute.ColorUnpacked(),
|
||||
VertexAttribute.TexCoords(0)
|
||||
)
|
||||
val quadHalf = Mesh(
|
||||
true, 4, 4,
|
||||
VertexAttribute.Position(),
|
||||
VertexAttribute.ColorUnpacked(),
|
||||
VertexAttribute.TexCoords(0)
|
||||
)
|
||||
val quadQuarter = Mesh(
|
||||
true, 4, 4,
|
||||
VertexAttribute.Position(),
|
||||
VertexAttribute.ColorUnpacked(),
|
||||
VertexAttribute.TexCoords(0)
|
||||
)
|
||||
|
||||
init {
|
||||
camera.setToOrtho(true)
|
||||
|
||||
quadFull.setVertices(floatArrayOf(
|
||||
0f,0f,0f, 1f,1f,1f,1f, 0f,1f,
|
||||
width.toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f,
|
||||
width.toFloat(), height.toFloat(),0f, 1f,1f,1f,1f, 1f,0f,
|
||||
0f, height.toFloat(),0f, 1f,1f,1f,1f, 0f,0f))
|
||||
quadFull.setIndices(shortArrayOf(0, 1, 2, 3))
|
||||
|
||||
quadHalf.setVertices(floatArrayOf(
|
||||
0f,0f,0f, 1f,1f,1f,1f, 0f,1f,
|
||||
width.div(2).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f,
|
||||
width.div(2).toFloat(), height.div(2).toFloat(),0f, 1f,1f,1f,1f, 1f,0f,
|
||||
0f, height.div(2).toFloat(),0f, 1f,1f,1f,1f, 0f,0f))
|
||||
quadHalf.setIndices(shortArrayOf(0, 1, 2, 3))
|
||||
|
||||
quadQuarter.setVertices(floatArrayOf(
|
||||
0f,0f,0f, 1f,1f,1f,1f, 0f,1f,
|
||||
width.div(4).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f,
|
||||
width.div(4).toFloat(), height.div(4).toFloat(),0f, 1f,1f,1f,1f, 1f,0f,
|
||||
0f, height.div(4).toFloat(),0f, 1f,1f,1f,1f, 0f,0f))
|
||||
quadQuarter.setIndices(shortArrayOf(0, 1, 2, 3))
|
||||
}
|
||||
|
||||
fun dispose() {
|
||||
full.dispose()
|
||||
half.dispose()
|
||||
quarter.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
private val fboDict = HashMap<Long, FrameBufferSet>()
|
||||
|
||||
private lateinit var blurtex0: Texture
|
||||
private lateinit var blurtex1: Texture
|
||||
private lateinit var blurtex2: Texture
|
||||
private lateinit var blurtex3: Texture
|
||||
|
||||
private val shaderKawaseDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawasedown.frag")
|
||||
private val shaderKawaseUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawaseup.frag")
|
||||
|
||||
fun makeBlur(`in`: FrameBuffer, out: FrameBuffer, strength: Float) {
|
||||
assert(`in`.width == out.width && `in`.height == out.height) {
|
||||
"Input and Output dimension mismatch: In(${`in`.width}x${`in`.height}), Out(${out.width}x${out.height})"
|
||||
}
|
||||
|
||||
val fbos = fboDict.getOrPut(`in`.width.toLong().shl(32) or `in`.height.toLong()) {
|
||||
FrameBufferSet(`in`.width, `in`.height)
|
||||
}
|
||||
|
||||
val batch: SpriteBatch? = null // placeholder
|
||||
|
||||
val radius3 = FastMath.pow(strength / 2, 0.5f)//(blurRadius - 3f) / 8f
|
||||
fbos.half.inAction(fbos.camera, batch) {
|
||||
blurtex0 = `in`.colorBufferTexture
|
||||
blurtex0.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||
blurtex0.bind(0)
|
||||
shaderKawaseDown.bind()
|
||||
shaderKawaseDown.setUniformMatrix("u_projTrans", fbos.camera.combined)
|
||||
shaderKawaseDown.setUniformi("u_texture", 0)
|
||||
shaderKawaseDown.setUniformf("halfpixel", radius3 / fbos.half.width, radius3 / fbos.half.height)
|
||||
fbos.quadHalf.render(shaderKawaseDown, GL20.GL_TRIANGLE_FAN)
|
||||
}
|
||||
|
||||
fbos.quarter.inAction(fbos.camera, batch) {
|
||||
blurtex1 = fbos.half.colorBufferTexture
|
||||
blurtex1.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||
blurtex1.bind(0)
|
||||
shaderKawaseDown.bind()
|
||||
shaderKawaseDown.setUniformMatrix("u_projTrans", fbos.camera.combined)
|
||||
shaderKawaseDown.setUniformi("u_texture", 0)
|
||||
shaderKawaseDown.setUniformf("halfpixel", radius3 / fbos.quarter.width, radius3 / fbos.quarter.height)
|
||||
fbos.quadQuarter.render(shaderKawaseDown, GL20.GL_TRIANGLE_FAN)
|
||||
}
|
||||
|
||||
fbos.half.inAction(fbos.camera, batch) {
|
||||
blurtex2 = fbos.quarter.colorBufferTexture
|
||||
blurtex2.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||
blurtex2.bind(0)
|
||||
shaderKawaseUp.bind()
|
||||
shaderKawaseUp.setUniformMatrix("u_projTrans", fbos.camera.combined)
|
||||
shaderKawaseUp.setUniformi("u_texture", 0)
|
||||
shaderKawaseUp.setUniformf("halfpixel", radius3 / fbos.quarter.width, radius3 / fbos.quarter.height)
|
||||
fbos.quadHalf.render(shaderKawaseUp, GL20.GL_TRIANGLE_FAN)
|
||||
}
|
||||
|
||||
out.inAction(fbos.camera, batch) {
|
||||
blurtex3 = fbos.half.colorBufferTexture
|
||||
blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||
blurtex3.bind(0)
|
||||
shaderKawaseUp.bind()
|
||||
shaderKawaseUp.setUniformMatrix("u_projTrans", fbos.camera.combined)
|
||||
shaderKawaseUp.setUniformi("u_texture", 0)
|
||||
shaderKawaseUp.setUniformf("halfpixel", radius3 / fbos.half.width, radius3 / fbos.half.height)
|
||||
fbos.quadFull.render(shaderKawaseUp, GL20.GL_TRIANGLE_FAN)
|
||||
}
|
||||
}
|
||||
|
||||
fun dispose() {
|
||||
fboDict.values.forEach { it.dispose() }
|
||||
shaderKawaseUp.dispose()
|
||||
shaderKawaseDown.dispose()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -44,19 +44,7 @@ object Toolkit : Disposable {
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
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 shadowTile = TextureRegionPack("assets/graphics/gui/blur_shadow.tga", 32, 32)
|
||||
@@ -82,19 +70,6 @@ object Toolkit : Disposable {
|
||||
// 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
|
||||
@@ -201,87 +176,11 @@ object Toolkit : Disposable {
|
||||
pixmap.fillRectangle(x + w, y, 1, h)
|
||||
}
|
||||
|
||||
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) {
|
||||
fun blurEntireScreen(batch: SpriteBatch, 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 = FastMath.pow(blurRadius0 / 2, 0.5f)//(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)
|
||||
}*/
|
||||
|
||||
|
||||
BlurMgr.makeBlur(renderTarget, fboBlur, blurRadius0)
|
||||
|
||||
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it
|
||||
|
||||
@@ -344,33 +243,9 @@ object Toolkit : Disposable {
|
||||
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)
|
||||
|
||||
@@ -379,36 +254,5 @@ object Toolkit : Disposable {
|
||||
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))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user