mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
StateBlurTest from blur test (gah)
Former-commit-id: ea7d2b3cd9c5f072846aea102b43f09226f73a57 Former-commit-id: 3d716699cbf6ed344c5e7b2ab5a2f8b121f828a8
This commit is contained in:
@@ -1,5 +1,333 @@
|
||||
package net.torvald.terrarum
|
||||
|
||||
import net.torvald.terrarum.gameactors.floor
|
||||
import net.torvald.terrarum.gameactors.floorInt
|
||||
import net.torvald.terrarum.gameworld.toUint
|
||||
import org.newdawn.slick.*
|
||||
import org.newdawn.slick.state.BasicGameState
|
||||
import org.newdawn.slick.state.StateBasedGame
|
||||
import java.nio.ByteOrder
|
||||
|
||||
|
||||
/**
|
||||
* Software rendering test for blur
|
||||
*
|
||||
* Created by SKYHi14 on 2017-01-12.
|
||||
*/
|
||||
class StateBlurTest : BasicGameState() {
|
||||
|
||||
/** Warning: the image must have a bit depth of 32! (use 32-bit PNG or TGA) */
|
||||
private val testImage = Image("./assets/testimage_resized.png")
|
||||
private val bluredImage = ImageBuffer(testImage.width, testImage.height)
|
||||
|
||||
override fun init(gc: GameContainer, sbg: StateBasedGame) {
|
||||
testImage.flushPixelData()
|
||||
|
||||
System.arraycopy(
|
||||
testImage.texture.textureData, 0,
|
||||
bluredImage.rgba, 0, testImage.texture.textureData.size
|
||||
)
|
||||
kotlin.repeat(3, { fastBoxBlur(bluredImage, 3) })
|
||||
}
|
||||
|
||||
override fun update(gc: GameContainer, sbg: StateBasedGame, delta: Int) {
|
||||
Terrarum.appgc.setTitle("${Terrarum.NAME} — F: ${Terrarum.appgc.fps}")
|
||||
|
||||
/*System.arraycopy(
|
||||
testImage.texture.textureData, 0,
|
||||
bluredImage.rgba, 0, testImage.texture.textureData.size
|
||||
)*/
|
||||
//fastBoxBlur(testImage, bluredImage, 3)
|
||||
//fastBoxBlur(bluredImage, 3)
|
||||
//fastBoxBlur(bluredImage, 3)
|
||||
}
|
||||
|
||||
override fun getID() = Terrarum.STATE_ID_TEST_BLUR
|
||||
|
||||
override fun render(gc: GameContainer, sbg: StateBasedGame, g: Graphics) {
|
||||
g.background = Color(0x404040)
|
||||
g.drawImage(bluredImage.image,
|
||||
Terrarum.WIDTH.minus(testImage.width).div(2f).floor(),
|
||||
Terrarum.HEIGHT.minus(testImage.height).div(2f).floor()
|
||||
)
|
||||
g.flush()
|
||||
}
|
||||
|
||||
/** three iterations of box blur \simeq gaussian blur */
|
||||
fun fastBoxBlur(from: Image, to: ImageBuffer, radius: Int) {
|
||||
|
||||
/** 0xRRGGBBAA */
|
||||
fun getPixelData(index: Int): Int {
|
||||
val r = from.texture.textureData[4 * index].toUint()
|
||||
val g = from.texture.textureData[4 * index + 1].toUint()
|
||||
val b = from.texture.textureData[4 * index + 2].toUint()
|
||||
|
||||
if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
|
||||
return r.shl(16) or g.shl(8) or b
|
||||
}
|
||||
else {
|
||||
return b.shl(16) or g.shl(8) or r
|
||||
}
|
||||
}
|
||||
|
||||
/** alpha will be passed through */
|
||||
fun setPixelData(index: Int, value: Int) {
|
||||
val r = value.ushr(24).and(0xff)
|
||||
val g = value.ushr(16).and(0xff)
|
||||
val b = value.ushr(8).and(0xff)
|
||||
|
||||
to.rgba[4 * index] = r.toByte()
|
||||
to.rgba[4 * index + 1] = g.toByte()
|
||||
to.rgba[4 * index + 2] = b.toByte()
|
||||
}
|
||||
|
||||
if (radius < 1) {
|
||||
return
|
||||
}
|
||||
val w = to.texWidth
|
||||
val h = to.texHeight
|
||||
val wm = w - 1
|
||||
val hm = h - 1
|
||||
val wh = w * h
|
||||
val div = radius + radius + 1
|
||||
val r = IntArray(wh)
|
||||
val g = IntArray(wh)
|
||||
val b = IntArray(wh)
|
||||
var rsum: Int
|
||||
var gsum: Int
|
||||
var bsum: Int
|
||||
var x: Int
|
||||
var y: Int
|
||||
var i: Int
|
||||
var p: Int
|
||||
var p1: Int
|
||||
var p2: Int
|
||||
var yp: Int
|
||||
var yi: Int
|
||||
var yw: Int
|
||||
val vmin = IntArray(Math.max(w, h))
|
||||
val vmax = IntArray(Math.max(w, h))
|
||||
|
||||
//img.getPixels(pix, 0, w, 0, 0, w, h)
|
||||
|
||||
val dv = IntArray(256 * div)
|
||||
i = 0
|
||||
while (i < 256 * div) {
|
||||
dv[i] = i / div
|
||||
i++
|
||||
}
|
||||
|
||||
yi = 0
|
||||
yw = yi
|
||||
|
||||
y = 0
|
||||
while (y < h) {
|
||||
bsum = 0
|
||||
gsum = bsum
|
||||
rsum = gsum
|
||||
i = -radius
|
||||
while (i <= radius) {
|
||||
p = getPixelData(yi + Math.min(wm, Math.max(i, 0)))
|
||||
rsum += p and 0xff0000 shr 16
|
||||
gsum += p and 0x00ff00 shr 8
|
||||
bsum += p and 0x0000ff
|
||||
i++
|
||||
}
|
||||
x = 0
|
||||
while (x < w) {
|
||||
|
||||
r[yi] = dv[rsum]
|
||||
g[yi] = dv[gsum]
|
||||
b[yi] = dv[bsum]
|
||||
|
||||
if (y == 0) {
|
||||
vmin[x] = Math.min(x + radius + 1, wm)
|
||||
vmax[x] = Math.max(x - radius, 0)
|
||||
}
|
||||
p1 = getPixelData(yw + vmin[x])
|
||||
p2 = getPixelData(yw + vmax[x])
|
||||
|
||||
rsum += (p1 and 0xff0000) - (p2 and 0xff0000) shr 16
|
||||
gsum += (p1 and 0x00ff00) - (p2 and 0x00ff00) shr 8
|
||||
bsum += (p1 and 0x0000ff) - (p2 and 0x0000ff)
|
||||
yi++
|
||||
x++
|
||||
}
|
||||
yw += w
|
||||
y++
|
||||
}
|
||||
|
||||
x = 0
|
||||
while (x < w) {
|
||||
bsum = 0
|
||||
gsum = bsum
|
||||
rsum = gsum
|
||||
yp = -radius * w
|
||||
i = -radius
|
||||
while (i <= radius) {
|
||||
yi = Math.max(0, yp) + x
|
||||
rsum += r[yi]
|
||||
gsum += g[yi]
|
||||
bsum += b[yi]
|
||||
yp += w
|
||||
i++
|
||||
}
|
||||
yi = x
|
||||
y = 0
|
||||
while (y < h) {
|
||||
setPixelData(yi, dv[rsum].shl(24) or dv[gsum].shl(16) or dv[bsum].shl(8))
|
||||
|
||||
if (x == 0) {
|
||||
vmin[y] = Math.min(y + radius + 1, hm) * w
|
||||
vmax[y] = Math.max(y - radius, 0) * w
|
||||
}
|
||||
p1 = x + vmin[y]
|
||||
p2 = x + vmax[y]
|
||||
|
||||
rsum += r[p1] - r[p2]
|
||||
gsum += g[p1] - g[p2]
|
||||
bsum += b[p1] - b[p2]
|
||||
|
||||
yi += w
|
||||
y++
|
||||
}
|
||||
x++
|
||||
}
|
||||
}
|
||||
|
||||
fun fastBoxBlur(img: ImageBuffer, radius: Int) {
|
||||
|
||||
/** 0xRRGGBBAA */
|
||||
fun getPixelData(index: Int): Int {
|
||||
val r = img.rgba[4 * index].toUint()
|
||||
val g = img.rgba[4 * index + 1].toUint()
|
||||
val b = img.rgba[4 * index + 2].toUint()
|
||||
|
||||
return r.shl(16) or g.shl(8) or b
|
||||
}
|
||||
|
||||
/** alpha will be passed through */
|
||||
fun setPixelData(index: Int, value: Int) {
|
||||
val r = value.ushr(24).and(0xff)
|
||||
val g = value.ushr(16).and(0xff)
|
||||
val b = value.ushr(8).and(0xff)
|
||||
|
||||
img.rgba[4 * index] = r.toByte()
|
||||
img.rgba[4 * index + 1] = g.toByte()
|
||||
img.rgba[4 * index + 2] = b.toByte()
|
||||
}
|
||||
|
||||
if (radius < 1) {
|
||||
return
|
||||
}
|
||||
val w = img.texWidth
|
||||
val h = img.texHeight
|
||||
val wm = w - 1
|
||||
val hm = h - 1
|
||||
val wh = w * h
|
||||
val div = radius + radius + 1
|
||||
val r = IntArray(wh)
|
||||
val g = IntArray(wh)
|
||||
val b = IntArray(wh)
|
||||
var rsum: Int
|
||||
var gsum: Int
|
||||
var bsum: Int
|
||||
var x: Int
|
||||
var y: Int
|
||||
var i: Int
|
||||
var p: Int
|
||||
var p1: Int
|
||||
var p2: Int
|
||||
var yp: Int
|
||||
var yi: Int
|
||||
var yw: Int
|
||||
val vmin = IntArray(Math.max(w, h))
|
||||
val vmax = IntArray(Math.max(w, h))
|
||||
|
||||
//img.getPixels(pix, 0, w, 0, 0, w, h)
|
||||
|
||||
val dv = IntArray(256 * div)
|
||||
i = 0
|
||||
while (i < 256 * div) {
|
||||
dv[i] = i / div
|
||||
i++
|
||||
}
|
||||
|
||||
yi = 0
|
||||
yw = yi
|
||||
|
||||
y = 0
|
||||
while (y < h) {
|
||||
bsum = 0
|
||||
gsum = bsum
|
||||
rsum = gsum
|
||||
i = -radius
|
||||
while (i <= radius) {
|
||||
p = getPixelData(yi + Math.min(wm, Math.max(i, 0)))
|
||||
rsum += p and 0xff0000 shr 16
|
||||
gsum += p and 0x00ff00 shr 8
|
||||
bsum += p and 0x0000ff
|
||||
i++
|
||||
}
|
||||
x = 0
|
||||
while (x < w) {
|
||||
|
||||
r[yi] = dv[rsum]
|
||||
g[yi] = dv[gsum]
|
||||
b[yi] = dv[bsum]
|
||||
|
||||
if (y == 0) {
|
||||
vmin[x] = Math.min(x + radius + 1, wm)
|
||||
vmax[x] = Math.max(x - radius, 0)
|
||||
}
|
||||
p1 = getPixelData(yw + vmin[x])
|
||||
p2 = getPixelData(yw + vmax[x])
|
||||
|
||||
rsum += (p1 and 0xff0000) - (p2 and 0xff0000) shr 16
|
||||
gsum += (p1 and 0x00ff00) - (p2 and 0x00ff00) shr 8
|
||||
bsum += (p1 and 0x0000ff) - (p2 and 0x0000ff)
|
||||
yi++
|
||||
x++
|
||||
}
|
||||
yw += w
|
||||
y++
|
||||
}
|
||||
|
||||
x = 0
|
||||
while (x < w) {
|
||||
bsum = 0
|
||||
gsum = bsum
|
||||
rsum = gsum
|
||||
yp = -radius * w
|
||||
i = -radius
|
||||
while (i <= radius) {
|
||||
yi = Math.max(0, yp) + x
|
||||
rsum += r[yi]
|
||||
gsum += g[yi]
|
||||
bsum += b[yi]
|
||||
yp += w
|
||||
i++
|
||||
}
|
||||
yi = x
|
||||
y = 0
|
||||
while (y < h) {
|
||||
setPixelData(yi, dv[rsum].shl(24) or dv[gsum].shl(16) or dv[bsum].shl(8))
|
||||
|
||||
if (x == 0) {
|
||||
vmin[y] = Math.min(y + radius + 1, hm) * w
|
||||
vmax[y] = Math.max(y - radius, 0) * w
|
||||
}
|
||||
p1 = x + vmin[y]
|
||||
p2 = x + vmax[y]
|
||||
|
||||
rsum += r[p1] - r[p2]
|
||||
gsum += g[p1] - g[p2]
|
||||
bsum += b[p1] - b[p2]
|
||||
|
||||
yi += w
|
||||
y++
|
||||
}
|
||||
x++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user