From de15212824d37b17a0e4c117e086b439c9d1b493 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 4 Feb 2022 12:36:39 +0700 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=B3=D1=80=D1=83=D0=B7?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B0=D1=81=D1=81=D0=B5=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B2=D0=BE=20=D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D0=BC=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=82=D0=BE=D0=BA=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/ru/dbotthepony/kstarbound/Main.kt | 104 ++++++++++++------ .../ru/dbotthepony/kstarbound/Starbound.kt | 49 +++++++-- .../ru/dbotthepony/kstarbound/api/Structs.kt | 26 +++++ .../ru/dbotthepony/kstarbound/math/Matrix.kt | 20 +++- .../kstarbound/math/Matrix4fStack.kt | 6 +- .../ru/dbotthepony/kstarbound/math/Vector.kt | 91 +++++++++++++-- .../dbotthepony/kstarbound/render/Camera.kt | 14 ++- .../ru/dbotthepony/kstarbound/render/Font.kt | 19 +++- .../kstarbound/render/TileRenderer.kt | 3 +- .../ru/dbotthepony/kstarbound/util/Color.kt | 9 ++ 10 files changed, 274 insertions(+), 67 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt index 37493a7d..014bb628 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt @@ -1,6 +1,5 @@ package ru.dbotthepony.kstarbound -import com.sun.jna.ptr.LongByReference import org.apache.logging.log4j.LogManager import org.lwjgl.Version import org.lwjgl.glfw.Callbacks.glfwFreeCallbacks @@ -9,25 +8,21 @@ import org.lwjgl.glfw.GLFWErrorCallback import org.lwjgl.opengl.GL46.* import org.lwjgl.system.MemoryStack.stackPush import org.lwjgl.system.MemoryUtil.NULL -import ru.dbotthepony.kstarbound.defs.TileDefinition -import ru.dbotthepony.kstarbound.freetype.FREE_TYPE_JNA -import ru.dbotthepony.kstarbound.freetype.FreeType -import ru.dbotthepony.kstarbound.freetype.LoadFlag import ru.dbotthepony.kstarbound.gl.* import ru.dbotthepony.kstarbound.math.* import ru.dbotthepony.kstarbound.render.* +import ru.dbotthepony.kstarbound.util.Color import ru.dbotthepony.kstarbound.util.formatBytesShort -import ru.dbotthepony.kstarbound.world.CHUNK_SIZE -import ru.dbotthepony.kstarbound.world.CHUNK_SIZE_FF -import ru.dbotthepony.kstarbound.world.ChunkTile import java.io.File -import kotlin.math.PI private val LOGGER = LogManager.getLogger() -private const val TEST = false + +var terminateGame = false + private set var viewportWidth = 800 private set + var viewportHeight = 600 private set @@ -51,25 +46,26 @@ var window = 0L fun main() { LOGGER.info("Running LWJGL ${Version.getVersion()}") - if (!TEST) { - try { - init() - loop() - } finally { - if (window != NULL) { - glfwFreeCallbacks(window) - glfwDestroyWindow(window) - } - - glfwTerminate() - glfwSetErrorCallback(null)?.free() + try { + init() + loop() + } finally { + if (window != NULL) { + glfwFreeCallbacks(window) + glfwDestroyWindow(window) } - } else { - Starbound.addFilePath(File("./unpacked_assets/")) - Starbound.loadTileDefinition("alienrock") + + glfwTerminate() + glfwSetErrorCallback(null)?.free() + + terminateGame = true } } +private var camera: Camera? = null +private val startupTextList = ArrayList() +private var finishStartupRendering = Long.MAX_VALUE + private fun init() { GLFWErrorCallback.create { error, description -> LOGGER.error("LWJGL error {}: {}", error, description) @@ -91,6 +87,8 @@ private fun init() { glfwSetKeyCallback(window) { window, key, scancode, action, mods -> if (key == GLFW_KEY_ESCAPE || key == GLFW_RELEASE) { glfwSetWindowShouldClose(window, true) + } else { + camera?.userInput(key, scancode, action, mods) } } @@ -129,7 +127,21 @@ private fun init() { glfwShowWindow(window) Starbound.addFilePath(File("./unpacked_assets/")) - Starbound.loadTileMaterials() + Starbound.initializeGame { finished, replaceStatus, status -> + if (replaceStatus) { + if (startupTextList.isEmpty()) { + startupTextList.add(status) + } else { + startupTextList[startupTextList.size - 1] = status + } + } else { + startupTextList.add(status) + } + + if (finished) { + finishStartupRendering = System.currentTimeMillis() + 2000L + } + } } var frameRenderTime = 1.0 @@ -139,7 +151,7 @@ val framesPerSecond get() = 1.0 / frameRenderTime private fun loop() { val state = GLStateTracker() - val camera = Camera() + camera = Camera() // Set the clear color glClearColor(0.2f, 0.2f, 0.2f, 0.2f) @@ -147,7 +159,7 @@ private fun loop() { state.blend = true glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - val chunk = Starbound.world.getOrMakeChunk(Vector2i(2, 2)) + /*val chunk = Starbound.world.getOrMakeChunk(Vector2i(2, 2)) var x = 0 var y = 0 @@ -183,7 +195,7 @@ private fun loop() { for (y in 4 .. 8) { chunk.foreground[x, y] = null as TileDefinition? } - } + }*/ /* for (x in 0 .. 24) { @@ -193,9 +205,9 @@ private fun loop() { } */ - val chunkRenderer = ChunkRenderer(state, chunk, Starbound.world) - chunkRenderer.tesselateStatic() - chunkRenderer.uploadStatic() + //val chunkRenderer = ChunkRenderer(state, chunk, Starbound.world) + //chunkRenderer.tesselateStatic() + //chunkRenderer.uploadStatic() val runtime = Runtime.getRuntime() @@ -206,15 +218,41 @@ private fun loop() { glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT) // clear the framebuffer state.matrixStack.clear(viewportMatrixGame.toMutableMatrix()) + camera?.translate(state.matrixStack.last) state.matrixStack.push().scale(x = 20f, y = 20f).translateWithScale(0f, 0f) - chunkRenderer.render() + //chunkRenderer.render() state.matrixStack.clear(viewportMatrixGUI.toMutableMatrix().translate(z = 2f)) state.font.render("FPS: %.2f".format(framesPerSecond), scale = 0.4f) state.font.render("Mem: ${formatBytesShort(runtime.totalMemory() - runtime.freeMemory())}", x = viewportWidth.toFloat(), scale = 0.4f, alignX = TextAlignX.RIGHT) + val thisTime = System.currentTimeMillis() + + if (!startupTextList.isEmpty() && thisTime <= finishStartupRendering) { + var alpha = 1f + + if (finishStartupRendering - thisTime < 1000L) { + alpha = (finishStartupRendering - thisTime) / 1000f + } + + state.matrixStack.push() + state.matrixStack.translateWithScale(y = viewportHeight.toFloat()) + var shade = 255 + + for (i in startupTextList.size - 1 downTo 0) { + val size = state.font.render(startupTextList[i], alignY = TextAlignY.BOTTOM, scale = 0.4f, color = Color.SHADES_OF_GRAY[shade].copy(alpha = alpha)) + state.matrixStack.translateWithScale(y = -size.height * 1.2f) + + if (shade > 120) { + shade -= 10 + } + } + + state.matrixStack.pop() + } + glfwSwapBuffers(window) // swap the color buffers // Poll for window events. The key callback above will only be diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt index 58e374f7..dddac29e 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt @@ -5,20 +5,22 @@ import com.google.gson.JsonObject import com.google.gson.JsonParser import ru.dbotthepony.kstarbound.defs.TileDefinition import ru.dbotthepony.kstarbound.defs.TileDefinitionBuilder -import ru.dbotthepony.kstarbound.defs.TileRenderTemplate import ru.dbotthepony.kstarbound.world.World import java.io.File import java.io.FileNotFoundException -import java.io.FilenameFilter class TileDefLoadingException(message: String, cause: Throwable? = null) : IllegalStateException(message, cause) object Starbound { private val tiles = HashMap() val tilesAccess = object : Map by tiles {} - val world = World() + var initializing = false + private set + var initialized = false + private set + private val _filepath = ArrayList() val filepath = object : List by _filepath {} @@ -51,18 +53,42 @@ object Starbound { return JsonParser.parseReader(findFile(path).bufferedReader()) } - fun loadTileDefinition(name: String): TileDefinition { - return tiles.computeIfAbsent(name) { - val foundPath = findFile("tiles/materials/$name.material") - return@computeIfAbsent TileDefinitionBuilder.fromJson(JsonParser.parseReader(foundPath.bufferedReader()) as JsonObject).build(foundPath.parent) - } - } - fun getTileDefinition(name: String): TileDefinition? { return tiles[name] } - fun loadTileMaterials() { + fun initializeGame(callback: (finished: Boolean, replaceStatus: Boolean, status: String) -> Unit) { + if (initializing) { + throw IllegalStateException("Already initializing!") + } + + if (initialized) { + throw IllegalStateException("Already initialized!") + } + + initializing = true + + Thread { + val time = System.currentTimeMillis() + callback(false, false, "Loading materials...") + + loadTileMaterials { + if (terminateGame) { + throw InterruptedException("Game is terminating") + } + + callback(false, true, it) + } + + callback(false, false, "Loaded materials") + + initializing = false + initialized = true + callback(true, false, "Finished loading in ${System.currentTimeMillis() - time}ms") + }.start() + } + + private fun loadTileMaterials(callback: (String) -> Unit) { for (sPath in _filepath) { val newPath = File(sPath.path, "tiles/materials") @@ -72,6 +98,7 @@ object Starbound { for (listedFile in findFiles) { if (listedFile.path.endsWith(".material")) { try { + callback("Loading ${listedFile.name}") val tileDef = TileDefinitionBuilder.fromJson(JsonParser.parseReader(listedFile.bufferedReader()) as JsonObject).build(listedFile.parent) check(tiles[tileDef.materialName] == null) { "Already has material with ID ${tileDef.materialName} loaded!" } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/api/Structs.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/api/Structs.kt index 4364e7dc..142ffb07 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/api/Structs.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/api/Structs.kt @@ -12,3 +12,29 @@ interface IStruct3f : IStruct2f { interface IStruct4f : IStruct3f { operator fun component4(): Float } + +interface IStruct2d { + operator fun component1(): Double + operator fun component2(): Double +} + +interface IStruct3d : IStruct2d { + operator fun component3(): Double +} + +interface IStruct4d : IStruct3d { + operator fun component4(): Double +} + +interface IStruct2i { + operator fun component1(): Int + operator fun component2(): Int +} + +interface IStruct3i : IStruct2i { + operator fun component3(): Int +} + +interface IStruct4i : IStruct3i { + operator fun component4(): Int +} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/math/Matrix.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/math/Matrix.kt index a01e2f79..94b54c0b 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/math/Matrix.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/math/Matrix.kt @@ -1,5 +1,7 @@ package ru.dbotthepony.kstarbound.math +import ru.dbotthepony.kstarbound.api.IStruct3f +import ru.dbotthepony.kstarbound.api.IStruct4f import java.nio.ByteBuffer import java.nio.ByteOrder import java.nio.FloatBuffer @@ -11,7 +13,7 @@ interface IMatrixLike { val rows: Int } -interface IMatrixLikeGetterI { +interface IMatrixLikeInt { operator fun get(row: Int, column: Int): Int } @@ -39,14 +41,22 @@ interface FloatMatrix> : IMatrix, IMatrixLikeFloat { * Если матрица больше или меньше, считать что всевозможные остальные координаты равны единице (не менять) */ fun scale(x: Float, y: Float = 1f, z: Float = 1f, w: Float = 1f): T - - fun scale(value: Vector4f) = scale(value.x, value.y, value.z, value.w) + fun scale(value: IStruct4f): T { + val (x, y, z, w) = value + return scale(x, y, z, w) + } fun translate(x: Float = 0f, y: Float = 0f, z: Float = 0f): T - fun translate(vector3f: Vector3f) = translate(vector3f.x, vector3f.y, vector3f.z) + fun translate(value: IStruct3f): T { + val (x, y, z) = value + return translate(x, y, z) + } fun translateWithScale(x: Float = 0f, y: Float = 0f, z: Float = 0f): T - fun translateWithScale(vector3f: Vector3f) = translateWithScale(vector3f.x, vector3f.y, vector3f.z) + fun translateWithScale(value: IStruct3f): T { + val (x, y, z) = value + return translateWithScale(x, y, z) + } /** * Выдает массив в готовом для OpenGL виде (строка -> столбец) по умолчанию diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/math/Matrix4fStack.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/math/Matrix4fStack.kt index e769283c..f1e4802e 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/math/Matrix4fStack.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/math/Matrix4fStack.kt @@ -1,5 +1,7 @@ package ru.dbotthepony.kstarbound.math +import ru.dbotthepony.kstarbound.api.IStruct3f + class Matrix4fStack { private val stack = ArrayDeque() @@ -70,12 +72,12 @@ class Matrix4fStack { return this } - fun translate(vec: Vector3f): Matrix4fStack { + fun translate(vec: IStruct3f): Matrix4fStack { last.translate(vec) return this } - fun translateWithScale(vec: Vector3f): Matrix4fStack { + fun translateWithScale(vec: IStruct3f): Matrix4fStack { last.translateWithScale(vec) return this } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/math/Vector.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/math/Vector.kt index 0a7f8b53..4923344e 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/math/Vector.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/math/Vector.kt @@ -1,10 +1,13 @@ package ru.dbotthepony.kstarbound.math import com.google.gson.JsonArray +import ru.dbotthepony.kstarbound.api.IStruct2i +import ru.dbotthepony.kstarbound.api.IStruct3f +import ru.dbotthepony.kstarbound.api.IStruct4f import kotlin.math.cos import kotlin.math.sin -abstract class IVector2i> : IMatrixLike, IMatrixLikeGetterI { +abstract class IVector2i> : IMatrixLike, IMatrixLikeInt, IStruct2i { override val columns = 1 override val rows = 2 @@ -56,10 +59,24 @@ data class Vector2i(override val x: Int = 0, override val y: Int = 0) : IVector2 } } -data class Vector3f(val x: Float = 0f, val y: Float = 0f, val z: Float = 0f) : IMatrixLikeFloat { +abstract class IVector3f> : IMatrixLike, IMatrixLikeFloat, IStruct3f { override val columns = 1 override val rows = 3 + abstract val x: Float + abstract val y: Float + abstract val z: Float + + operator fun plus(other: IVector3f<*>) = make(x + other.x, y + other.y, z + other.z) + operator fun minus(other: IVector3f<*>) = make(x - other.x, y - other.y, z - other.z) + operator fun times(other: IVector3f<*>) = make(x * other.x, y * other.y, z * other.z) + operator fun div(other: IVector3f<*>) = make(x / other.x, y / other.y, z / other.z) + + operator fun plus(other: Float) = make(x + other, y + other, z + other) + operator fun minus(other: Float) = make(x - other, y - other, z - other) + operator fun times(other: Float) = make(x * other, y * other, z * other) + operator fun div(other: Float) = make(x / other, y / other, z / other) + override fun get(row: Int, column: Int): Float { if (column != 0) { throw IndexOutOfBoundsException("Column must be 0 ($column given)") @@ -85,7 +102,7 @@ data class Vector3f(val x: Float = 0f, val y: Float = 0f, val z: Float = 0f) : I ) } - operator fun times(other: IMatrixLikeFloat): Vector3f { + operator fun times(other: IMatrixLikeFloat): T { if (other.rows >= 4 && other.columns >= 4) { val x = this.x * other[0, 0] + this.y * other[0, 1] + @@ -102,7 +119,7 @@ data class Vector3f(val x: Float = 0f, val y: Float = 0f, val z: Float = 0f) : I this.z * other[2, 2] + other[2, 3] - return Vector3f(x, y, z) + return make(x, y, z) } else if (other.rows >= 3 && other.columns >= 3) { val x = this.x * other[0, 0] + this.y * other[0, 1] + @@ -116,12 +133,24 @@ data class Vector3f(val x: Float = 0f, val y: Float = 0f, val z: Float = 0f) : I this.y * other[2, 1] + this.z * other[2, 2] - return Vector3f(x, y, z) + return make(x, y, z) } throw IllegalArgumentException("Incompatible matrix provided: ${other.rows} x ${other.columns}") } + protected abstract fun make(x: Float, y: Float, z: Float): T +} + +data class Vector3f(override val x: Float = 0f, override val y: Float = 0f, override val z: Float = 0f) : IVector3f() { + override fun make(x: Float, y: Float, z: Float): Vector3f { + return Vector3f(x, y, z) + } + + fun toMutableVector(): MutableVector3f { + return MutableVector3f(x, y, z) + } + companion object { val UP = Vector3f(0f, 1f, 0f) val DOWN = Vector3f(0f, -1f, 0f) @@ -132,7 +161,35 @@ data class Vector3f(val x: Float = 0f, val y: Float = 0f, val z: Float = 0f) : I } } -data class Vector4f(val x: Float = 0f, val y: Float = 0f, val z: Float = 0f, val w: Float = 0f) : IMatrixLikeFloat { +data class MutableVector3f(override var x: Float = 0f, override var y: Float = 0f, override var z: Float = 0f) : IVector3f() { + fun toVector(): Vector3f { + return Vector3f(x, y, z) + } + + override fun make(x: Float, y: Float, z: Float): MutableVector3f { + this.x = x + this.y = y + this.z = z + return this + } +} + +abstract class IVector4f> : IMatrixLike, IMatrixLikeFloat, IStruct4f { + abstract val x: Float + abstract val y: Float + abstract val z: Float + abstract val w: Float + + operator fun plus(other: IVector4f<*>) = make(x + other.x, y + other.y, z + other.z, w + other.w) + operator fun minus(other: IVector4f<*>) = make(x - other.x, y - other.y, z - other.z, w + other.w) + operator fun times(other: IVector4f<*>) = make(x * other.x, y * other.y, z * other.z, w + other.w) + operator fun div(other: IVector4f<*>) = make(x / other.x, y / other.y, z / other.z, w + other.w) + + operator fun plus(other: Float) = make(x + other, y + other, z + other, w + other) + operator fun minus(other: Float) = make(x - other, y - other, z - other, w - other) + operator fun times(other: Float) = make(x * other, y * other, z * other, w * other) + operator fun div(other: Float) = make(x / other, y / other, z / other, w / other) + override val columns = 1 override val rows = 4 @@ -150,7 +207,7 @@ data class Vector4f(val x: Float = 0f, val y: Float = 0f, val z: Float = 0f, val } } - operator fun times(other: IMatrixLikeFloat): Vector4f { + operator fun times(other: IMatrixLikeFloat): T { if (other.rows >= 4 && other.columns >= 4) { val x = this.x * other[0, 0] + this.y * other[0, 1] + @@ -172,9 +229,27 @@ data class Vector4f(val x: Float = 0f, val y: Float = 0f, val z: Float = 0f, val this.z * other[3, 2] + this.w * other[3, 3] - return Vector4f(x, y, z, w) + return make(x, y, z, w) } throw IllegalArgumentException("Incompatible matrix provided: ${other.rows} x ${other.columns}") } + + protected abstract fun make(x: Float, y: Float, z: Float, w: Float): T +} + +data class Vector4f(override val x: Float = 0f, override val y: Float = 0f, override val z: Float = 0f, override val w: Float = 0f) : IVector4f() { + override fun make(x: Float, y: Float, z: Float, w: Float): Vector4f { + return Vector4f(x, y, z, w) + } +} + +data class MutableVector4f(override var x: Float = 0f, override var y: Float = 0f, override var z: Float = 0f, override var w: Float = 0f) : IVector4f() { + override fun make(x: Float, y: Float, z: Float, w: Float): MutableVector4f { + this.x = x + this.y = y + this.z = z + this.w = w + return this + } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/render/Camera.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/render/Camera.kt index c4825fa7..d410227d 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/render/Camera.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/render/Camera.kt @@ -1,14 +1,18 @@ package ru.dbotthepony.kstarbound.render -import ru.dbotthepony.kstarbound.math.Matrix4f -import ru.dbotthepony.kstarbound.math.Vector3f +import ru.dbotthepony.kstarbound.math.* class Camera { - var pos = Vector3f(z = 400f) + val pos = MutableVector3f() var zoom = 1f - fun matrix(): Matrix4f { - return Matrix4f.IDENTITY.scale(zoom, zoom, zoom).translate(pos) + fun translate(stack: FloatMatrix<*>) { + stack.translateWithScale(pos) + stack.scale(x = zoom, y = zoom) + } + + fun userInput(key: Int, scancode: Int, action: Int, mods: Int) { + } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/render/Font.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/render/Font.kt index 9699e9ee..ee27ddde 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/render/Font.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/render/Font.kt @@ -8,6 +8,7 @@ import ru.dbotthepony.kstarbound.freetype.LoadFlag import ru.dbotthepony.kstarbound.freetype.struct.FT_Pixel_Mode import ru.dbotthepony.kstarbound.gl.* import ru.dbotthepony.kstarbound.math.Matrix4fStack +import ru.dbotthepony.kstarbound.util.Color private fun breakLines(text: String): List { var nextLineBreak = text.indexOf('\n', 0) @@ -83,6 +84,8 @@ class Font( alignX: TextAlignX = TextAlignX.LEFT, alignY: TextAlignY = TextAlignY.TOP, + color: Color = Color.WHITE, + scale: Float = 1f, stack: Matrix4fStack = state.matrixStack, ): TextSize { @@ -107,6 +110,7 @@ class Font( stack.scale(x = scale, y = scale) state.fontProgram.use() + state.fontProgram.color.set(color) state.activeTexture = 0 val space = getGlyph(' ') @@ -165,7 +169,7 @@ class Font( state.VAO = null stack.pop() - return totalSize + return TextSize(totalX * scale, totalY * scale) } fun render( @@ -177,10 +181,21 @@ class Font( alignX: TextAlignX = TextAlignX.LEFT, alignY: TextAlignY = TextAlignY.TOP, + color: Color = Color.WHITE, + scale: Float = 1f, stack: Matrix4fStack = state.matrixStack, ): TextSize { - return render(breakLines(text), x, y, alignX, alignY, scale, stack) + return render( + breakLines(text), + x = x, + y = y, + alignX = alignX, + alignY = alignY, + scale = scale, + stack = stack, + color = color, + ) } private fun lineWidth(line: String, space: Glyph): Float { diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/render/TileRenderer.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/render/TileRenderer.kt index 1ca2aaeb..cf7a1c0e 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/render/TileRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/render/TileRenderer.kt @@ -59,7 +59,8 @@ class TileRenderers(val state: GLStateTracker) { operator fun get(tile: String): TileRenderer { return tileRenderers.computeIfAbsent(tile) { - return@computeIfAbsent TileRenderer(state, Starbound.loadTileDefinition(tile)) + val def = Starbound.getTileDefinition(tile) // TODO: Пустой рендерер + return@computeIfAbsent TileRenderer(state, def!!) } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/util/Color.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/util/Color.kt index d7ff31bf..03fb6559 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/util/Color.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/util/Color.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.kstarbound.util +import com.google.common.collect.ImmutableList import com.google.gson.JsonArray import ru.dbotthepony.kstarbound.api.IStruct4f @@ -8,5 +9,13 @@ data class Color(val red: Float, val green: Float, val blue: Float, val alpha: F companion object { val WHITE = Color(1f, 1f, 1f) + + val SHADES_OF_GRAY = ArrayList().let { + for (i in 0 .. 256) { + it.add(Color(i / 256f, i / 256f, i / 256f)) + } + + return@let ImmutableList.copyOf(it) as List + } } }