Тест StarboundClient
This commit is contained in:
parent
10fdc34ffd
commit
5b62fe3f09
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
import com.sun.jna.NativeLong;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
import com.sun.jna.NativeLong;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
import com.sun.jna.NativeLong;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
import com.sun.jna.NativeLong;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
import com.sun.jna.NativeLong;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
import com.sun.jna.NativeLong;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
import com.sun.jna.NativeLong;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
public enum FT_Pixel_Mode {
|
public enum FT_Pixel_Mode {
|
||||||
FT_PIXEL_MODE_NONE,
|
FT_PIXEL_MODE_NONE,
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
import com.sun.jna.NativeLong;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype.struct;
|
package ru.dbotthepony.kstarbound.client.freetype.struct;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
import ru.dbotthepony.kstarbound.math.Vector2i;
|
import ru.dbotthepony.kstarbound.math.Vector2i;
|
@ -1,13 +0,0 @@
|
|||||||
package ru.dbotthepony.kstarbound
|
|
||||||
|
|
||||||
class GameRegistry<T> {
|
|
||||||
private val table = HashMap<String, T>()
|
|
||||||
val access: Map<String, T> by table
|
|
||||||
|
|
||||||
var frozen = false
|
|
||||||
private set
|
|
||||||
|
|
||||||
fun freeze() {
|
|
||||||
frozen = true
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,25 +2,20 @@ package ru.dbotthepony.kstarbound
|
|||||||
|
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import org.lwjgl.Version
|
import org.lwjgl.Version
|
||||||
import org.lwjgl.glfw.Callbacks.glfwFreeCallbacks
|
|
||||||
import org.lwjgl.glfw.GLFW.*
|
import org.lwjgl.glfw.GLFW.*
|
||||||
import org.lwjgl.glfw.GLFWErrorCallback
|
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
import org.lwjgl.system.MemoryStack.stackPush
|
import ru.dbotthepony.kstarbound.client.StarboundClient
|
||||||
import org.lwjgl.system.MemoryUtil.NULL
|
import ru.dbotthepony.kstarbound.math.Matrix4f
|
||||||
import ru.dbotthepony.kstarbound.defs.TileDefinition
|
import ru.dbotthepony.kstarbound.client.render.Camera
|
||||||
import ru.dbotthepony.kstarbound.gl.*
|
import ru.dbotthepony.kstarbound.client.render.ChunkRenderer
|
||||||
import ru.dbotthepony.kstarbound.math.*
|
import ru.dbotthepony.kstarbound.client.render.TextAlignX
|
||||||
import ru.dbotthepony.kstarbound.render.*
|
import ru.dbotthepony.kstarbound.client.render.TextAlignY
|
||||||
import ru.dbotthepony.kstarbound.util.Color
|
import ru.dbotthepony.kstarbound.util.Color
|
||||||
import ru.dbotthepony.kstarbound.util.formatBytesShort
|
import ru.dbotthepony.kstarbound.util.formatBytesShort
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
private val LOGGER = LogManager.getLogger()
|
private val LOGGER = LogManager.getLogger()
|
||||||
|
|
||||||
var terminateGame = false
|
|
||||||
private set
|
|
||||||
|
|
||||||
var viewportWidth = 800
|
var viewportWidth = 800
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@ -47,19 +42,20 @@ var window = 0L
|
|||||||
fun main() {
|
fun main() {
|
||||||
LOGGER.info("Running LWJGL ${Version.getVersion()}")
|
LOGGER.info("Running LWJGL ${Version.getVersion()}")
|
||||||
|
|
||||||
try {
|
val client = StarboundClient()
|
||||||
init()
|
|
||||||
loop()
|
|
||||||
} finally {
|
|
||||||
if (window != NULL) {
|
|
||||||
glfwFreeCallbacks(window)
|
|
||||||
glfwDestroyWindow(window)
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwTerminate()
|
Starbound.addFilePath(File("./unpacked_assets/"))
|
||||||
glfwSetErrorCallback(null)?.free()
|
|
||||||
|
|
||||||
terminateGame = true
|
Starbound.initializeGame { finished, replaceStatus, status ->
|
||||||
|
client.pushLoadingText(status, replaceStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
client.onTermination {
|
||||||
|
Starbound.terminateLoading = true
|
||||||
|
}
|
||||||
|
|
||||||
|
while (client.renderFrame()) {
|
||||||
|
Starbound.pollCallbacks()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,94 +63,14 @@ private var camera: Camera? = null
|
|||||||
private val startupTextList = ArrayList<String>()
|
private val startupTextList = ArrayList<String>()
|
||||||
private var finishStartupRendering = Long.MAX_VALUE
|
private var finishStartupRendering = Long.MAX_VALUE
|
||||||
|
|
||||||
private fun init() {
|
|
||||||
GLFWErrorCallback.create { error, description ->
|
|
||||||
LOGGER.error("LWJGL error {}: {}", error, description)
|
|
||||||
}.set()
|
|
||||||
|
|
||||||
check(glfwInit()) { "Unable to initialize GLFW" }
|
|
||||||
|
|
||||||
glfwDefaultWindowHints()
|
|
||||||
|
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE)
|
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE)
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4)
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6)
|
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
|
|
||||||
|
|
||||||
window = glfwCreateWindow(viewportWidth, viewportHeight, "LWJGL Window!", NULL, NULL)
|
|
||||||
require(window != NULL) { "Unable to create GLFW window" }
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwSetFramebufferSizeCallback(window) { _, w, h ->
|
|
||||||
viewportWidth = w
|
|
||||||
viewportHeight = h
|
|
||||||
viewportMatrixGUI = updateViewportMatrixA()
|
|
||||||
viewportMatrixGame = updateViewportMatrixB()
|
|
||||||
glViewport(0, 0, w, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
val stack = stackPush()
|
|
||||||
|
|
||||||
try {
|
|
||||||
val pWidth = stack.mallocInt(1)
|
|
||||||
val pHeight = stack.mallocInt(1)
|
|
||||||
|
|
||||||
glfwGetWindowSize(window, pWidth, pHeight)
|
|
||||||
|
|
||||||
val vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor())!!
|
|
||||||
|
|
||||||
glfwSetWindowPos(
|
|
||||||
window,
|
|
||||||
(vidmode.width() - pWidth[0]) / 2,
|
|
||||||
(vidmode.height() - pHeight[0]) / 2
|
|
||||||
)
|
|
||||||
} finally {
|
|
||||||
stack.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwMakeContextCurrent(window)
|
|
||||||
|
|
||||||
// vsync
|
|
||||||
glfwSwapInterval(1)
|
|
||||||
|
|
||||||
glfwShowWindow(window)
|
|
||||||
|
|
||||||
startupTextList.add("Initialized GLFW window")
|
|
||||||
|
|
||||||
Starbound.addFilePath(File("./unpacked_assets/"))
|
|
||||||
|
|
||||||
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() + 4000L
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var frameRenderTime = 1.0
|
var frameRenderTime = 1.0
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val framesPerSecond get() = 1.0 / frameRenderTime
|
val framesPerSecond get() = 1.0 / frameRenderTime
|
||||||
|
|
||||||
private fun loop() {
|
private fun loop() {
|
||||||
val state = GLStateTracker()
|
val client = StarboundClient()
|
||||||
|
val state = client.gl
|
||||||
startupTextList.add("Initialized OpenGL context")
|
startupTextList.add("Initialized OpenGL context")
|
||||||
camera = Camera()
|
camera = Camera()
|
||||||
|
|
||||||
@ -166,7 +82,7 @@ private fun loop() {
|
|||||||
|
|
||||||
var chunkRenderer: ChunkRenderer? = null
|
var chunkRenderer: ChunkRenderer? = null
|
||||||
|
|
||||||
Starbound.onInitialize {
|
/*Starbound.onInitialize {
|
||||||
val chunk = Starbound.world.getOrMakeChunk(Vector2i(2, 2))
|
val chunk = Starbound.world.getOrMakeChunk(Vector2i(2, 2))
|
||||||
|
|
||||||
var x = 0
|
var x = 0
|
||||||
@ -208,7 +124,7 @@ private fun loop() {
|
|||||||
chunkRenderer = ChunkRenderer(state, chunk, Starbound.world)
|
chunkRenderer = ChunkRenderer(state, chunk, Starbound.world)
|
||||||
chunkRenderer!!.tesselateStatic()
|
chunkRenderer!!.tesselateStatic()
|
||||||
chunkRenderer!!.uploadStatic()
|
chunkRenderer!!.uploadStatic()
|
||||||
}
|
}*/
|
||||||
|
|
||||||
val runtime = Runtime.getRuntime()
|
val runtime = Runtime.getRuntime()
|
||||||
|
|
||||||
|
@ -14,12 +14,12 @@ class TileDefLoadingException(message: String, cause: Throwable? = null) : Illeg
|
|||||||
object Starbound {
|
object Starbound {
|
||||||
private val tiles = HashMap<String, TileDefinition>()
|
private val tiles = HashMap<String, TileDefinition>()
|
||||||
val tilesAccess = object : Map<String, TileDefinition> by tiles {}
|
val tilesAccess = object : Map<String, TileDefinition> by tiles {}
|
||||||
val world = World()
|
|
||||||
|
|
||||||
var initializing = false
|
var initializing = false
|
||||||
private set
|
private set
|
||||||
var initialized = false
|
var initialized = false
|
||||||
private set
|
private set
|
||||||
|
var terminateLoading = false
|
||||||
|
|
||||||
private val _filepath = ArrayList<File>()
|
private val _filepath = ArrayList<File>()
|
||||||
val filepath = object : List<File> by _filepath {}
|
val filepath = object : List<File> by _filepath {}
|
||||||
@ -70,12 +70,12 @@ object Starbound {
|
|||||||
|
|
||||||
initializing = true
|
initializing = true
|
||||||
|
|
||||||
Thread {
|
Thread({
|
||||||
val time = System.currentTimeMillis()
|
val time = System.currentTimeMillis()
|
||||||
callback(false, false, "Loading materials...")
|
callback(false, false, "Loading materials...")
|
||||||
|
|
||||||
loadTileMaterials {
|
loadTileMaterials {
|
||||||
if (terminateGame) {
|
if (terminateLoading) {
|
||||||
throw InterruptedException("Game is terminating")
|
throw InterruptedException("Game is terminating")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ object Starbound {
|
|||||||
initializing = false
|
initializing = false
|
||||||
initialized = true
|
initialized = true
|
||||||
callback(true, false, "Finished loading in ${System.currentTimeMillis() - time}ms")
|
callback(true, false, "Finished loading in ${System.currentTimeMillis() - time}ms")
|
||||||
}.start()
|
}, "Asset Loader").start()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onInitialize(callback: () -> Unit) {
|
fun onInitialize(callback: () -> Unit) {
|
||||||
|
@ -0,0 +1,228 @@
|
|||||||
|
package ru.dbotthepony.kstarbound.client
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
|
import org.lwjgl.glfw.Callbacks
|
||||||
|
import org.lwjgl.glfw.GLFW
|
||||||
|
import org.lwjgl.glfw.GLFWErrorCallback
|
||||||
|
import org.lwjgl.opengl.GL46.*
|
||||||
|
import org.lwjgl.system.MemoryStack
|
||||||
|
import org.lwjgl.system.MemoryUtil
|
||||||
|
import ru.dbotthepony.kstarbound.client.gl.GLStateTracker
|
||||||
|
import ru.dbotthepony.kstarbound.math.Matrix4f
|
||||||
|
import ru.dbotthepony.kstarbound.client.render.Camera
|
||||||
|
import ru.dbotthepony.kstarbound.client.render.TextAlignX
|
||||||
|
import ru.dbotthepony.kstarbound.client.render.TextAlignY
|
||||||
|
import ru.dbotthepony.kstarbound.util.Color
|
||||||
|
import ru.dbotthepony.kstarbound.util.formatBytesShort
|
||||||
|
import ru.dbotthepony.kstarbound.world.World
|
||||||
|
|
||||||
|
class StarboundClient : AutoCloseable {
|
||||||
|
val window: Long
|
||||||
|
val camera = Camera()
|
||||||
|
|
||||||
|
var gameTerminated = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
var viewportWidth = 800
|
||||||
|
private set
|
||||||
|
|
||||||
|
var viewportHeight = 600
|
||||||
|
private set
|
||||||
|
|
||||||
|
var viewportMatrixGUI = updateViewportMatrixA()
|
||||||
|
private set
|
||||||
|
|
||||||
|
var viewportMatrixGame = updateViewportMatrixB()
|
||||||
|
private set
|
||||||
|
|
||||||
|
private val startupTextList = ArrayList<String>()
|
||||||
|
private var finishStartupRendering = System.currentTimeMillis() + 4000L
|
||||||
|
|
||||||
|
fun pushLoadingText(text: String, replace: Boolean = false) {
|
||||||
|
if (replace) {
|
||||||
|
if (startupTextList.isEmpty()) {
|
||||||
|
startupTextList.add(text)
|
||||||
|
} else {
|
||||||
|
startupTextList[startupTextList.size - 1] = text
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
startupTextList.add(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
finishStartupRendering = System.currentTimeMillis() + 4000L
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateViewportMatrixA(): Matrix4f {
|
||||||
|
return Matrix4f.ortho(0f, viewportWidth.toFloat(), 0f, viewportHeight.toFloat(), 0.1f, 100f)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateViewportMatrixB(): Matrix4f {
|
||||||
|
return Matrix4f.orthoDirect(0f, viewportWidth.toFloat(), 0f, viewportHeight.toFloat(), 1f, 100f)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
GLFWErrorCallback.create { error, description ->
|
||||||
|
LOGGER.error("LWJGL error {}: {}", error, description)
|
||||||
|
}.set()
|
||||||
|
|
||||||
|
check(GLFW.glfwInit()) { "Unable to initialize GLFW" }
|
||||||
|
|
||||||
|
GLFW.glfwDefaultWindowHints()
|
||||||
|
|
||||||
|
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE)
|
||||||
|
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_TRUE)
|
||||||
|
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 4)
|
||||||
|
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 6)
|
||||||
|
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE)
|
||||||
|
|
||||||
|
window = GLFW.glfwCreateWindow(viewportWidth, viewportHeight, "KStarbound", MemoryUtil.NULL, MemoryUtil.NULL)
|
||||||
|
require(window != MemoryUtil.NULL) { "Unable to create GLFW window" }
|
||||||
|
startupTextList.add("Created GLFW window")
|
||||||
|
|
||||||
|
GLFW.glfwSetKeyCallback(window) { window, key, scancode, action, mods ->
|
||||||
|
if (key == GLFW.GLFW_KEY_ESCAPE || key == GLFW.GLFW_RELEASE) {
|
||||||
|
GLFW.glfwSetWindowShouldClose(window, true)
|
||||||
|
} else {
|
||||||
|
camera.userInput(key, scancode, action, mods)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFW.glfwSetFramebufferSizeCallback(window) { _, w, h ->
|
||||||
|
viewportWidth = w
|
||||||
|
viewportHeight = h
|
||||||
|
viewportMatrixGUI = updateViewportMatrixA()
|
||||||
|
viewportMatrixGame = updateViewportMatrixB()
|
||||||
|
glViewport(0, 0, w, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
val stack = MemoryStack.stackPush()
|
||||||
|
|
||||||
|
try {
|
||||||
|
val pWidth = stack.mallocInt(1)
|
||||||
|
val pHeight = stack.mallocInt(1)
|
||||||
|
|
||||||
|
GLFW.glfwGetWindowSize(window, pWidth, pHeight)
|
||||||
|
|
||||||
|
val vidmode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor())!!
|
||||||
|
|
||||||
|
GLFW.glfwSetWindowPos(
|
||||||
|
window,
|
||||||
|
(vidmode.width() - pWidth[0]) / 2,
|
||||||
|
(vidmode.height() - pHeight[0]) / 2
|
||||||
|
)
|
||||||
|
} finally {
|
||||||
|
stack.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFW.glfwMakeContextCurrent(window)
|
||||||
|
|
||||||
|
// vsync
|
||||||
|
GLFW.glfwSwapInterval(1)
|
||||||
|
|
||||||
|
GLFW.glfwShowWindow(window)
|
||||||
|
pushLoadingText("Initialized GLFW window")
|
||||||
|
}
|
||||||
|
|
||||||
|
val gl = GLStateTracker()
|
||||||
|
|
||||||
|
fun ensureSameThread() = gl.ensureSameThread()
|
||||||
|
|
||||||
|
init {
|
||||||
|
pushLoadingText("Initialized OpenGL context")
|
||||||
|
gl.clearColor = Color.SLATE_GREY
|
||||||
|
|
||||||
|
gl.blend = true
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||||
|
}
|
||||||
|
|
||||||
|
var frameRenderTime = 1.0
|
||||||
|
private set
|
||||||
|
|
||||||
|
val framesPerSecond get() = 1.0 / frameRenderTime
|
||||||
|
|
||||||
|
var world: World? = World()
|
||||||
|
|
||||||
|
fun renderFrame(): Boolean {
|
||||||
|
ensureSameThread()
|
||||||
|
|
||||||
|
if (GLFW.glfwWindowShouldClose(window)) {
|
||||||
|
close()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val measure = GLFW.glfwGetTime()
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
|
||||||
|
|
||||||
|
gl.matrixStack.clear(viewportMatrixGame.toMutableMatrix())
|
||||||
|
camera.translate(gl.matrixStack.last)
|
||||||
|
|
||||||
|
gl.matrixStack.clear(viewportMatrixGUI.toMutableMatrix().translate(z = 2f))
|
||||||
|
|
||||||
|
val thisTime = System.currentTimeMillis()
|
||||||
|
|
||||||
|
if (startupTextList.isNotEmpty() && thisTime <= finishStartupRendering) {
|
||||||
|
var alpha = 1f
|
||||||
|
|
||||||
|
if (finishStartupRendering - thisTime < 1000L) {
|
||||||
|
alpha = (finishStartupRendering - thisTime) / 1000f
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.matrixStack.push()
|
||||||
|
gl.matrixStack.translateWithScale(y = viewportHeight.toFloat())
|
||||||
|
var shade = 255
|
||||||
|
|
||||||
|
for (i in startupTextList.size - 1 downTo 0) {
|
||||||
|
val size = gl.font.render(startupTextList[i], alignY = TextAlignY.BOTTOM, scale = 0.4f, color = Color.SHADES_OF_GRAY[shade].copy(alpha = alpha))
|
||||||
|
gl.matrixStack.translateWithScale(y = -size.height * 1.2f)
|
||||||
|
|
||||||
|
if (shade > 120) {
|
||||||
|
shade -= 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.matrixStack.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
val runtime = Runtime.getRuntime()
|
||||||
|
|
||||||
|
gl.font.render("FPS: %.2f".format(framesPerSecond), scale = 0.4f)
|
||||||
|
gl.font.render("Mem: ${formatBytesShort(runtime.totalMemory() - runtime.freeMemory())}", x = viewportWidth.toFloat(), scale = 0.4f, alignX = TextAlignX.RIGHT)
|
||||||
|
|
||||||
|
GLFW.glfwSwapBuffers(window)
|
||||||
|
GLFW.glfwPollEvents()
|
||||||
|
|
||||||
|
frameRenderTime = GLFW.glfwGetTime() - measure
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private val terminateCallbacks = ArrayList<() -> Unit>()
|
||||||
|
|
||||||
|
fun onTermination(lambda: () -> Unit) {
|
||||||
|
terminateCallbacks.add(lambda)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
if (gameTerminated)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (window != MemoryUtil.NULL) {
|
||||||
|
Callbacks.glfwFreeCallbacks(window)
|
||||||
|
GLFW.glfwDestroyWindow(window)
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFW.glfwTerminate()
|
||||||
|
GLFW.glfwSetErrorCallback(null)?.free()
|
||||||
|
|
||||||
|
gameTerminated = true
|
||||||
|
|
||||||
|
for (callback in terminateCallbacks) {
|
||||||
|
callback.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOGGER = LogManager.getLogger(StarboundClient::class.java)
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype
|
package ru.dbotthepony.kstarbound.client.freetype
|
||||||
|
|
||||||
enum class LoadFlag(val value: Long) {
|
enum class LoadFlag(val value: Long) {
|
||||||
DEFAULT (0x0),
|
DEFAULT (0x0),
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype
|
package ru.dbotthepony.kstarbound.client.freetype
|
||||||
|
|
||||||
sealed class FreeTypeException(message: String, cause: Throwable?) : RuntimeException(message, cause) {
|
sealed class FreeTypeException(message: String, cause: Throwable?) : RuntimeException(message, cause) {
|
||||||
abstract val code: Int
|
abstract val code: Int
|
@ -1,8 +1,8 @@
|
|||||||
package ru.dbotthepony.kstarbound.freetype
|
package ru.dbotthepony.kstarbound.client.freetype
|
||||||
|
|
||||||
import com.sun.jna.*
|
import com.sun.jna.*
|
||||||
import com.sun.jna.ptr.LongByReference
|
import com.sun.jna.ptr.LongByReference
|
||||||
import ru.dbotthepony.kstarbound.freetype.struct.FT_FaceRec
|
import ru.dbotthepony.kstarbound.client.freetype.struct.FT_FaceRec
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
private typealias LPointer = Long
|
private typealias LPointer = Long
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.gl
|
package ru.dbotthepony.kstarbound.client.gl
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.gl
|
package ru.dbotthepony.kstarbound.client.gl
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList
|
import com.google.common.collect.ImmutableList
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.gl
|
package ru.dbotthepony.kstarbound.client.gl
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL20
|
import org.lwjgl.opengl.GL20
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.gl
|
package ru.dbotthepony.kstarbound.client.gl
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
|
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
@ -1,14 +1,15 @@
|
|||||||
package ru.dbotthepony.kstarbound.gl
|
package ru.dbotthepony.kstarbound.client.gl
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL
|
import org.lwjgl.opengl.GL
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
import ru.dbotthepony.kstarbound.Starbound
|
import ru.dbotthepony.kstarbound.Starbound
|
||||||
import ru.dbotthepony.kstarbound.freetype.FreeType
|
import ru.dbotthepony.kstarbound.api.IStruct4f
|
||||||
|
import ru.dbotthepony.kstarbound.client.freetype.FreeType
|
||||||
import ru.dbotthepony.kstarbound.math.Matrix4f
|
import ru.dbotthepony.kstarbound.math.Matrix4f
|
||||||
import ru.dbotthepony.kstarbound.math.Matrix4fStack
|
import ru.dbotthepony.kstarbound.math.Matrix4fStack
|
||||||
import ru.dbotthepony.kstarbound.render.Font
|
import ru.dbotthepony.kstarbound.client.render.Font
|
||||||
import ru.dbotthepony.kstarbound.render.TileRenderer
|
import ru.dbotthepony.kstarbound.client.render.TileRenderer
|
||||||
import ru.dbotthepony.kstarbound.render.TileRenderers
|
import ru.dbotthepony.kstarbound.client.render.TileRenderers
|
||||||
import ru.dbotthepony.kstarbound.util.Color
|
import ru.dbotthepony.kstarbound.util.Color
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
@ -35,6 +36,23 @@ private class GLStateSwitchTracker(private val enum: Int, private var value: Boo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class GLStateGenericTracker<T>(private var value: T, private val lambda: (T) -> Unit) {
|
||||||
|
operator fun getValue(glStateTracker: GLStateTracker, property: KProperty<*>): T {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun setValue(glStateTracker: GLStateTracker, property: KProperty<*>, value: T) {
|
||||||
|
glStateTracker.ensureSameThread()
|
||||||
|
|
||||||
|
if (value == this.value)
|
||||||
|
return
|
||||||
|
|
||||||
|
lambda.invoke(value)
|
||||||
|
checkForGLError()
|
||||||
|
this.value = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open class GLTransformableProgram(state: GLStateTracker, vararg shaders: GLShader) : GLShaderProgram(state, *shaders) {
|
open class GLTransformableProgram(state: GLStateTracker, vararg shaders: GLShader) : GLShaderProgram(state, *shaders) {
|
||||||
init {
|
init {
|
||||||
link()
|
link()
|
||||||
@ -142,6 +160,11 @@ class GLStateTracker {
|
|||||||
checkForGLError()
|
checkForGLError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var clearColor by GLStateGenericTracker<IStruct4f>(Color.WHITE) {
|
||||||
|
val (r, g, b, a) = it
|
||||||
|
glClearColor(r, g, b, a)
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
glActiveTexture(GL_TEXTURE0)
|
glActiveTexture(GL_TEXTURE0)
|
||||||
checkForGLError()
|
checkForGLError()
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.gl
|
package ru.dbotthepony.kstarbound.client.gl
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import org.lwjgl.opengl.GL11
|
import org.lwjgl.opengl.GL11
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.gl
|
package ru.dbotthepony.kstarbound.client.gl
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.gl
|
package ru.dbotthepony.kstarbound.client.gl
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.gl
|
package ru.dbotthepony.kstarbound.client.gl
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
@ -17,7 +17,8 @@ object VertexTransformers {
|
|||||||
v0: Float,
|
v0: Float,
|
||||||
u1: Float,
|
u1: Float,
|
||||||
v1: Float,
|
v1: Float,
|
||||||
lambda: VertexTransformer = emptyTransform): VertexTransformer {
|
lambda: VertexTransformer = emptyTransform
|
||||||
|
): VertexTransformer {
|
||||||
return transformer@{ it, index ->
|
return transformer@{ it, index ->
|
||||||
when (index) {
|
when (index) {
|
||||||
0 -> it.pushVec2f(u0, v0)
|
0 -> it.pushVec2f(u0, v0)
|
@ -1,7 +1,11 @@
|
|||||||
package ru.dbotthepony.kstarbound.render
|
package ru.dbotthepony.kstarbound.client.render
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11
|
import org.lwjgl.opengl.GL11
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
|
import ru.dbotthepony.kstarbound.client.gl.GLShaderProgram
|
||||||
|
import ru.dbotthepony.kstarbound.client.gl.GLVertexArrayObject
|
||||||
|
import ru.dbotthepony.kstarbound.client.gl.VertexBuilder
|
||||||
|
import ru.dbotthepony.kstarbound.client.gl.checkForGLError
|
||||||
import ru.dbotthepony.kstarbound.gl.*
|
import ru.dbotthepony.kstarbound.gl.*
|
||||||
import ru.dbotthepony.kstarbound.math.FloatMatrix
|
import ru.dbotthepony.kstarbound.math.FloatMatrix
|
||||||
import ru.dbotthepony.kstarbound.math.Matrix4f
|
import ru.dbotthepony.kstarbound.math.Matrix4f
|
@ -1,4 +1,4 @@
|
|||||||
package ru.dbotthepony.kstarbound.render
|
package ru.dbotthepony.kstarbound.client.render
|
||||||
|
|
||||||
import ru.dbotthepony.kstarbound.math.*
|
import ru.dbotthepony.kstarbound.math.*
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package ru.dbotthepony.kstarbound.render
|
package ru.dbotthepony.kstarbound.client.render
|
||||||
|
|
||||||
|
import ru.dbotthepony.kstarbound.client.gl.GLStateTracker
|
||||||
import ru.dbotthepony.kstarbound.gl.*
|
import ru.dbotthepony.kstarbound.gl.*
|
||||||
import ru.dbotthepony.kstarbound.math.FloatMatrix
|
import ru.dbotthepony.kstarbound.math.FloatMatrix
|
||||||
import ru.dbotthepony.kstarbound.world.Chunk
|
import ru.dbotthepony.kstarbound.world.Chunk
|
@ -1,12 +1,11 @@
|
|||||||
package ru.dbotthepony.kstarbound.render
|
package ru.dbotthepony.kstarbound.client.render
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.chars.Char2ObjectArrayMap
|
import it.unimi.dsi.fastutil.chars.Char2ObjectArrayMap
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
import org.w3c.dom.Text
|
import ru.dbotthepony.kstarbound.client.freetype.LoadFlag
|
||||||
import ru.dbotthepony.kstarbound.freetype.LoadFlag
|
import ru.dbotthepony.kstarbound.client.gl.*
|
||||||
import ru.dbotthepony.kstarbound.freetype.struct.FT_Pixel_Mode
|
import ru.dbotthepony.kstarbound.client.freetype.struct.FT_Pixel_Mode
|
||||||
import ru.dbotthepony.kstarbound.gl.*
|
|
||||||
import ru.dbotthepony.kstarbound.math.Matrix4fStack
|
import ru.dbotthepony.kstarbound.math.Matrix4fStack
|
||||||
import ru.dbotthepony.kstarbound.util.Color
|
import ru.dbotthepony.kstarbound.util.Color
|
||||||
|
|
@ -1,12 +1,12 @@
|
|||||||
package ru.dbotthepony.kstarbound.render
|
package ru.dbotthepony.kstarbound.client.render
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
import ru.dbotthepony.kstarbound.Starbound
|
import ru.dbotthepony.kstarbound.Starbound
|
||||||
|
import ru.dbotthepony.kstarbound.client.gl.*
|
||||||
import ru.dbotthepony.kstarbound.defs.TileDefinition
|
import ru.dbotthepony.kstarbound.defs.TileDefinition
|
||||||
import ru.dbotthepony.kstarbound.defs.TileRenderMatchPiece
|
import ru.dbotthepony.kstarbound.defs.TileRenderMatchPiece
|
||||||
import ru.dbotthepony.kstarbound.defs.TileRenderPiece
|
import ru.dbotthepony.kstarbound.defs.TileRenderPiece
|
||||||
import ru.dbotthepony.kstarbound.gl.*
|
|
||||||
import ru.dbotthepony.kstarbound.math.Vector2i
|
import ru.dbotthepony.kstarbound.math.Vector2i
|
||||||
import ru.dbotthepony.kstarbound.util.Color
|
import ru.dbotthepony.kstarbound.util.Color
|
||||||
import ru.dbotthepony.kstarbound.world.ITileChunk
|
import ru.dbotthepony.kstarbound.world.ITileChunk
|
@ -9,6 +9,7 @@ data class Color(val red: Float, val green: Float, val blue: Float, val alpha: F
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val WHITE = Color(1f, 1f, 1f)
|
val WHITE = Color(1f, 1f, 1f)
|
||||||
|
val SLATE_GREY = Color(0.2f, 0.2f, 0.2f)
|
||||||
|
|
||||||
val SHADES_OF_GRAY = ArrayList<Color>().let {
|
val SHADES_OF_GRAY = ArrayList<Color>().let {
|
||||||
for (i in 0 .. 256) {
|
for (i in 0 .. 256) {
|
||||||
|
Loading…
Reference in New Issue
Block a user