WriteWorldInfo: actually working thumbnail export

This commit is contained in:
minjaesong
2019-02-25 02:07:39 +09:00
parent 6afd36db64
commit f12271f087
7 changed files with 78 additions and 13 deletions

View File

@@ -13,6 +13,8 @@ public class PixmapIO2 {
// REMEMBER: to the GL's perspective, this game's FBOs are always Y-flipped. //
public static int HEADER_FOOTER_SIZE = 18 + 26;
public static void writeTGAHappy(FileHandle file, Pixmap pixmap, boolean flipY) throws IOException {
OutputStream output = file.write(false);
@@ -33,7 +35,7 @@ public class PixmapIO2 {
}
}
private static void _writeTGA(OutputStream out, Pixmap pixmap, boolean verbatim, boolean flipY) throws IOException {
public static void _writeTGA(OutputStream out, Pixmap pixmap, boolean verbatim, boolean flipY) throws IOException {
byte[] width = toShortLittle(pixmap.getWidth());
byte[] height = toShortLittle(pixmap.getHeight());
byte[] zero = toShortLittle(0);

View File

@@ -219,7 +219,7 @@ public class AppLoader implements ApplicationListener {
ShaderProgram.pedantic = false;
LwjglApplicationConfiguration appConfig = new LwjglApplicationConfiguration();
//appConfig.useGL30 = true; // used: loads GL 3.2, unused: loads GL 4.6; what the fuck?
appConfig.useGL30 = true; // utilising some GL trickeries, need this to be TRUE
appConfig.vSyncEnabled = getConfigBoolean("usevsync");
appConfig.resizable = false;//true;
//appConfig.width = 1110; // photographic ratio (1.5:1)

View File

@@ -39,7 +39,8 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
/**
* The actual gamer
*/
open var actorGamer: ActorHumanoid? = null
val actorGamer: ActorHumanoid
get() = getActorByID(Terrarum.PLAYER_REF_ID) as ActorHumanoid
open var gameInitialised = false
internal set

View File

@@ -155,12 +155,7 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
lateinit var gameLoadInfoPayload: Any
lateinit var gameworld: GameWorldExtension
lateinit var theRealGamer: IngamePlayer
override var actorGamer: ActorHumanoid?
get() = theRealGamer
set(value) {
throw UnsupportedOperationException()
}
// get() = actorGamer as IngamePlayer
enum class GameLoadMode {
CREATE_NEW, LOAD_FROM
@@ -202,6 +197,10 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
)
private fun setTheRealGamerFirstTime(actor: IngamePlayer) {
if (actor.referenceID != Terrarum.PLAYER_REF_ID) {
throw Error()
}
actorNowPlaying = actor
theRealGamer = actor
addNewActor(actorNowPlaying)

View File

@@ -1,8 +1,18 @@
package net.torvald.terrarum.serialise
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.GL30
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.PixmapIO2
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.badlogic.gdx.utils.ScreenUtils
import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.inAction
import net.torvald.terrarum.inUse
import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
import net.torvald.terrarum.modulebasegame.weather.WeatherMixer
import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser
@@ -10,6 +20,9 @@ import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64GrowableOutputStream
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64InputStream
import org.apache.commons.codec.digest.DigestUtils
import java.io.ByteArrayOutputStream
import java.util.zip.Deflater
import java.util.zip.DeflaterOutputStream
object WriteWorldInfo {
@@ -111,6 +124,55 @@ object WriteWorldInfo {
metaOut.write(it)
}
// thumbnail
val texreg = Terrarum.ingame!!.actorGamer.sprite?.textureRegion
if (texreg != null) {
val batch = SpriteBatch()
val camera = OrthographicCamera(texreg.tileW.toFloat(), texreg.tileH.toFloat())
val fbo = FrameBuffer(Pixmap.Format.RGBA8888, texreg.tileW, texreg.tileH, false)
fbo.inAction(camera, batch) {
batch.inUse {
batch.draw(texreg.get(0, 0), 0f, 0f)
}
}
// bind and unbind the fbo so that I can get the damned Pixmap using ScreenUtils
// NullPointerException if not appconfig.useGL30
Gdx.gl30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, fbo.framebufferHandle)
Gdx.gl30.glReadBuffer(GL30.GL_COLOR_ATTACHMENT0)
val outpixmap = ScreenUtils.getFrameBufferPixmap(0, 0, fbo.width, fbo.height)
Gdx.gl30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, 0)
Gdx.gl30.glReadBuffer(GL30.GL_BACK)
val tgaSize = PixmapIO2.HEADER_FOOTER_SIZE + outpixmap.width * outpixmap.height * 4
val byteArrayOS = ByteArrayOutputStream(tgaSize)
PixmapIO2._writeTGA(byteArrayOS, outpixmap, true, true)
byteArrayOS.flush()
byteArrayOS.close()
//PixmapIO2.writeTGA(Gdx.files.absolute(AppLoader.defaultDir+"/tmp_writeworldinfo+outpixmap.tga"), outpixmap, true)
outpixmap.dispose()
batch.dispose()
fbo.dispose()
// write uncompressed size
metaOut.write(tgaSize.toULittleShort())
// write compressed tga
val deflater = DeflaterOutputStream(metaOut, Deflater(Deflater.BEST_COMPRESSION, true), false)
deflater.write(byteArrayOS.toByteArray())
deflater.flush(); deflater.finish()
// write footer
metaOut.write(-1); metaOut.write(-2)
}
// more data goes here //

View File

@@ -35,7 +35,8 @@ n-1 00 String terminator
72 SHA-256 hash of worldinfo2 (32 bytes)
A4 SHA-256 hash of worldinfo3 (32 bytes)
D6 Compressed size (2 bytes)
D8 Gzipped thumbnail image in TGA format
(it's gzipped so that it saves faster, so no Lzma)
D6 Uncompressed size (2 bytes)
D8 Deflated thumbnail image in TGA format
p-2 (it's deflated so that it saves faster, so no Lzma)
p-2 0xFF
p-1 0xFE