mirror of
https://github.com/curioustorvald/Terrarum-sans-bitmap.git
synced 2026-03-07 11:51:50 +09:00
wtf with the premultiplying i didn't even told it to do so
This commit is contained in:
@@ -1,11 +1,15 @@
|
|||||||
import com.badlogic.gdx.*
|
import com.badlogic.gdx.*
|
||||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
|
||||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
|
||||||
|
import com.badlogic.gdx.files.FileHandle
|
||||||
import com.badlogic.gdx.graphics.*
|
import com.badlogic.gdx.graphics.*
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.utils.ScreenUtils
|
import com.badlogic.gdx.utils.ScreenUtils
|
||||||
|
import com.badlogic.gdx.utils.StreamUtils
|
||||||
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.OutputStream
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2018-07-26.
|
* Created by minjaesong on 2018-07-26.
|
||||||
@@ -28,7 +32,7 @@ class FontTestGDX : Game() {
|
|||||||
private val outimageName = if (testing) "testing.PNG" else "demo.PNG"
|
private val outimageName = if (testing) "testing.PNG" else "demo.PNG"
|
||||||
|
|
||||||
override fun create() {
|
override fun create() {
|
||||||
font = GameFontBase("./assets", flipY = false, errorOnUnknownChar = false) // must test for two flipY cases
|
font = GameFontBase("./assets", flipY = false, errorOnUnknownChar = false, shadowAlpha = 0.796f) // must test for two flipY cases
|
||||||
|
|
||||||
val inTextFile = Gdx.files.internal("./$demotextName")
|
val inTextFile = Gdx.files.internal("./$demotextName")
|
||||||
val reader = inTextFile.reader("UTF-8")
|
val reader = inTextFile.reader("UTF-8")
|
||||||
@@ -72,16 +76,19 @@ class FontTestGDX : Game() {
|
|||||||
if (tex == null) {
|
if (tex == null) {
|
||||||
frameBuffer.begin()
|
frameBuffer.begin()
|
||||||
|
|
||||||
Gdx.gl.glClearColor(.141f, .141f, .141f, 1f)
|
Gdx.gl.glClearColor(0f,0f,0f,0f)
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D)
|
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D)
|
||||||
Gdx.gl.glEnable(GL20.GL_BLEND)
|
Gdx.gl.glEnable(GL20.GL_BLEND)
|
||||||
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA)
|
Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE)
|
||||||
|
// Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_COLOR, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_SRC_ALPHA, GL20.GL_ONE)
|
||||||
|
|
||||||
|
// Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA)
|
||||||
|
|
||||||
batch.projectionMatrix = camera.combined
|
batch.projectionMatrix = camera.combined
|
||||||
batch.begin()
|
batch.begin()
|
||||||
|
|
||||||
batch.color = Color(0xeeeeeeff.toInt())
|
batch.color = Color(-1)
|
||||||
inputText.forEachIndexed { index, s ->
|
inputText.forEachIndexed { index, s ->
|
||||||
font.draw(batch, s, 10f, TEXH - 30f - index * font.lineHeight)
|
font.draw(batch, s, 10f, TEXH - 30f - index * font.lineHeight)
|
||||||
}
|
}
|
||||||
@@ -94,6 +101,7 @@ class FontTestGDX : Game() {
|
|||||||
val pixmap = ScreenUtils.getFrameBufferPixmap(0, 0, frameBuffer.width, frameBuffer.height)
|
val pixmap = ScreenUtils.getFrameBufferPixmap(0, 0, frameBuffer.width, frameBuffer.height)
|
||||||
|
|
||||||
PixmapIO.writePNG(Gdx.files.local(outimageName), pixmap)
|
PixmapIO.writePNG(Gdx.files.local(outimageName), pixmap)
|
||||||
|
// writeTGA(Gdx.files.local(outimageName), pixmap, false)
|
||||||
pixmap.dispose()
|
pixmap.dispose()
|
||||||
|
|
||||||
screenshotExported = true
|
screenshotExported = true
|
||||||
@@ -107,6 +115,14 @@ class FontTestGDX : Game() {
|
|||||||
tex = frameBuffer.colorBufferTexture
|
tex = frameBuffer.colorBufferTexture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Gdx.gl.glClearColor(.141f, .141f, .141f, 1f)
|
||||||
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
|
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D)
|
||||||
|
Gdx.gl.glEnable(GL20.GL_BLEND)
|
||||||
|
Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE)
|
||||||
|
|
||||||
|
|
||||||
batch.begin()
|
batch.begin()
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
batch.draw(tex, 0f, (TEXH.toFloat()/HEIGHT)*TEXH - scrollOffsetY, TEXW.toFloat(), -(TEXH.toFloat() / HEIGHT) * TEXH.toFloat())
|
batch.draw(tex, 0f, (TEXH.toFloat()/HEIGHT)*TEXH - scrollOffsetY, TEXW.toFloat(), -(TEXH.toFloat() / HEIGHT) * TEXH.toFloat())
|
||||||
@@ -155,6 +171,91 @@ class FontTestGDX : Game() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
private fun writeTGA(file: FileHandle, pixmap: Pixmap, flipY: Boolean) {
|
||||||
|
val output = file.write(false)
|
||||||
|
try {
|
||||||
|
_writeTGA(output, pixmap, true, flipY)
|
||||||
|
} finally {
|
||||||
|
StreamUtils.closeQuietly(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
private fun _writeTGA(out: OutputStream, pixmap: Pixmap, verbatim: Boolean, flipY: Boolean) {
|
||||||
|
val width: ByteArray = toShortLittle(pixmap.width)
|
||||||
|
val height: ByteArray = toShortLittle(pixmap.height)
|
||||||
|
val zero: ByteArray = toShortLittle(0)
|
||||||
|
out.write(0) // ID field: empty
|
||||||
|
out.write(0) // no colour map, but should be ignored anyway as it being unmapped RGB
|
||||||
|
out.write(2) // 2 means unmapped RGB
|
||||||
|
out.write(byteArrayOf(0, 0, 0, 0, 0)) // color map spec: empty
|
||||||
|
out.write(zero) // x origin: 0
|
||||||
|
out.write(zero) // y origin: 0
|
||||||
|
out.write(width) // width
|
||||||
|
out.write(height) // height
|
||||||
|
out.write(32) // image pixel size: we're writing 32-bit image (8bpp BGRA)
|
||||||
|
out.write(8) // image descriptor: dunno, Photoshop writes 8 in there
|
||||||
|
|
||||||
|
// write actual image data
|
||||||
|
// since we're following Photoshop's conventional header, we also follows Photoshop's
|
||||||
|
// TGA saving scheme, that is:
|
||||||
|
// 1. BGRA order
|
||||||
|
// 2. Y-Flipped but not X-Flipped
|
||||||
|
if (!flipY) {
|
||||||
|
for (y in pixmap.height - 1 downTo 0) {
|
||||||
|
for (x in 0 until pixmap.width) {
|
||||||
|
writeTga(x, y, verbatim, pixmap, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (y in 0 until pixmap.height) {
|
||||||
|
for (x in 0 until pixmap.width) {
|
||||||
|
writeTga(x, y, verbatim, pixmap, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// write footer
|
||||||
|
// 00 00 00 00 00 00 00 00 TRUEVISION-XFILE 2E 00
|
||||||
|
out.write(byteArrayOf(0, 0, 0, 0, 0, 0, 0, 0))
|
||||||
|
if (verbatim) out.write("TRUEVISION-XFILE".toByteArray()) else out.write("TerrarumHappyTGA".toByteArray())
|
||||||
|
out.write(byteArrayOf(0x2E, 0))
|
||||||
|
out.flush()
|
||||||
|
out.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val zeroalpha = byteArrayOf(0, 0, 0, 0)
|
||||||
|
@Throws(IOException::class)
|
||||||
|
private fun writeTga(x: Int, y: Int, verbatim: Boolean, pixmap: Pixmap, out: OutputStream) {
|
||||||
|
val color = pixmap.getPixel(x, y)
|
||||||
|
|
||||||
|
// if alpha == 0, write special value instead
|
||||||
|
if (verbatim && color and 0xFF == 0) {
|
||||||
|
out.write(zeroalpha)
|
||||||
|
} else {
|
||||||
|
out.write(RGBAtoBGRA(color))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toShortLittle(i: Int): ByteArray {
|
||||||
|
return byteArrayOf(
|
||||||
|
(i and 0xFF).toByte(),
|
||||||
|
(i ushr 8 and 0xFF).toByte()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun RGBAtoBGRA(rgba: Int): ByteArray {
|
||||||
|
return byteArrayOf(
|
||||||
|
(rgba ushr 8 and 0xFF).toByte(),
|
||||||
|
(rgba ushr 16 and 0xFF).toByte(),
|
||||||
|
(rgba ushr 24 and 0xFF).toByte(),
|
||||||
|
(rgba and 0xFF).toByte()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var appConfig: Lwjgl3ApplicationConfiguration
|
lateinit var appConfig: Lwjgl3ApplicationConfiguration
|
||||||
|
|||||||
@@ -364,6 +364,8 @@ class GameFontBase(
|
|||||||
|
|
||||||
private val pixmapOffsetY = 10
|
private val pixmapOffsetY = 10
|
||||||
|
|
||||||
|
fun draw(batch: Batch, charSeq: CharSequence, x: Int, y: Int) = draw(batch, charSeq, x.toFloat(), y.toFloat())
|
||||||
|
|
||||||
override fun draw(batch: Batch, charSeq: CharSequence, x: Float, y: Float): GlyphLayout? {
|
override fun draw(batch: Batch, charSeq: CharSequence, x: Float, y: Float): GlyphLayout? {
|
||||||
if (debug)
|
if (debug)
|
||||||
println("[TerrarumSansBitmap] max age: $textCacheCap")
|
println("[TerrarumSansBitmap] max age: $textCacheCap")
|
||||||
@@ -1155,27 +1157,23 @@ class GameFontBase(
|
|||||||
)
|
)
|
||||||
|
|
||||||
jobQueue.forEach {
|
jobQueue.forEach {
|
||||||
for (y in 0 until pixmap.height) {
|
for (y in (if (invertShadow) 1 else 0) until (if (invertShadow) pixmap.height else pixmap.height - 1)) {
|
||||||
for (x in 0 until pixmap.width) {
|
for (x in (if (invertShadow) 1 else 0) until (if (invertShadow) pixmap.width else pixmap.width - 1)) {
|
||||||
val pixel = pixmap.getPixel(x, y) // RGBA8888
|
val pixel = pixmap.getPixel(x, y) // RGBA8888
|
||||||
|
val newPixel = pixmap.getPixel(x + it.first, y + it.second)
|
||||||
|
|
||||||
|
val newColor = Color(pixel)
|
||||||
|
newColor.a *= shadowAlpha
|
||||||
|
/*if (shadowAlphaPremultiply) {
|
||||||
|
newColor.r *= shadowAlpha
|
||||||
|
newColor.g *= shadowAlpha
|
||||||
|
newColor.b *= shadowAlpha
|
||||||
|
}*/
|
||||||
|
|
||||||
// in the current version, all colour-coded glyphs are guaranteed
|
// in the current version, all colour-coded glyphs are guaranteed
|
||||||
// to be opaque
|
// to be opaque
|
||||||
if (pixel and 0xFF == 0xFF) {
|
if (pixel and 0xFF == 0xFF && newPixel and 0xFF == 0) {
|
||||||
val newPixel = pixmap.getPixel(x + it.first, y + it.second)
|
pixmap.drawPixel(x + it.first, y + it.second, newColor.toRGBA8888())
|
||||||
val newColour = Color(); Color.rgba8888ToColor(newColour, pixel)
|
|
||||||
newColour.a = shadowAlpha
|
|
||||||
|
|
||||||
if (shadowAlphaPremultiply) {
|
|
||||||
newColour.r *= shadowAlpha
|
|
||||||
newColour.g *= shadowAlpha
|
|
||||||
newColour.b *= shadowAlpha
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newPixel and 0xFF == 0) {
|
|
||||||
pixmap.drawPixel(x + it.first, y + it.second, newColour.toRGBA8888())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user