mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 02:15:34 -04:00
rendering: improve texture loading, load font from minecraft assets, render single char
This commit is contained in:
parent
9a1c4aace2
commit
d7a10ae082
@ -56,10 +56,11 @@ object ChunkPreparer {
|
|||||||
section.getBlock(position.getLocationByDirection(Directions.EAST))
|
section.getBlock(position.getLocationByDirection(Directions.EAST))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun drawBlock() {
|
// if(block.fullIdentifier != "minecraft:dropper"){
|
||||||
block.blockModel.render(position, data, arrayOf(blockBelow, blockAbove, blockNorth, blockSouth, blockWest, blockEast))
|
// continue
|
||||||
}
|
// }
|
||||||
drawBlock()
|
|
||||||
|
block.blockModel.render(position, data, arrayOf(blockBelow, blockAbove, blockNorth, blockSouth, blockWest, blockEast))
|
||||||
}
|
}
|
||||||
return data.toFloatArray()
|
return data.toFloatArray()
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
|||||||
import de.bixilon.minosoft.protocol.network.Connection
|
import de.bixilon.minosoft.protocol.network.Connection
|
||||||
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketPlayerPositionAndRotationSending
|
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketPlayerPositionAndRotationSending
|
||||||
import de.bixilon.minosoft.util.CountUpAndDownLatch
|
import de.bixilon.minosoft.util.CountUpAndDownLatch
|
||||||
|
import glm_.vec2.Vec2
|
||||||
import org.lwjgl.*
|
import org.lwjgl.*
|
||||||
import org.lwjgl.glfw.Callbacks
|
import org.lwjgl.glfw.Callbacks
|
||||||
import org.lwjgl.glfw.GLFW.*
|
import org.lwjgl.glfw.GLFW.*
|
||||||
@ -110,17 +111,14 @@ class RenderWindow(private val connection: Connection) {
|
|||||||
|
|
||||||
|
|
||||||
// Make the window visible
|
// Make the window visible
|
||||||
glfwShowWindow(windowId)
|
|
||||||
GL.createCapabilities()
|
GL.createCapabilities()
|
||||||
glClearColor(137 / 256f, 207 / 256f, 240 / 256f, 1.0f)
|
glClearColor(137 / 256f, 207 / 256f, 240 / 256f, 1.0f)
|
||||||
glEnable(GL_DEPTH_TEST)
|
glEnable(GL_DEPTH_TEST)
|
||||||
glEnable(GL_BLEND)
|
glEnable(GL_BLEND)
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||||
|
|
||||||
minecraftTextures = TextureArray(connection.version.assetsManager, resolveBlockTextureIds(connection.version.mapping.blockMap.values))
|
minecraftTextures = TextureArray.createTextureArray(connection.version.assetsManager, resolveBlockTextureIds(connection.version.mapping.blockMap.values), 16, 16) // ToDo :Remove fixed size
|
||||||
minecraftTextures.load()
|
minecraftTextures.load()
|
||||||
fontAtlasTexture = TextureArray(connection.version.assetsManager, listOf(Texture("font/unicode_page_00", 0)), 256)
|
|
||||||
fontAtlasTexture.load()
|
|
||||||
|
|
||||||
chunkShader = Shader("chunk_vertex.glsl", "chunk_fragment.glsl")
|
chunkShader = Shader("chunk_vertex.glsl", "chunk_fragment.glsl")
|
||||||
chunkShader.load()
|
chunkShader.load()
|
||||||
@ -132,18 +130,37 @@ class RenderWindow(private val connection: Connection) {
|
|||||||
fontShader = Shader("font_vertex.glsl", "font_fragment.glsl")
|
fontShader = Shader("font_vertex.glsl", "font_fragment.glsl")
|
||||||
fontShader.load()
|
fontShader.load()
|
||||||
fontShader.use()
|
fontShader.use()
|
||||||
fontShader.setFloat("atlasSize", 256f)
|
|
||||||
|
|
||||||
val font = Font()
|
val font = Font()
|
||||||
val char = font.chars['§']!!
|
font.load(connection.version.assetsManager)
|
||||||
font2DToDraw.add(Font2DMesh(floatArrayOf(
|
|
||||||
-0.5f, -0.5f, char.column * 16f, char.row * 16f + char.width, font.atlasOffset + char.atlasPage.toFloat(),
|
fun drawLetterVertex(position: Vec2, uv: Vec2, atlasPage: Int, meshData: MutableList<Float>) {
|
||||||
-0.5f, 0f, char.column * 16f, char.row * 16f, font.atlasOffset + char.atlasPage.toFloat(),
|
meshData.add(position.x)
|
||||||
0f, -0.5f, char.column * 16f + char.width, char.row * 16f + char.width, font.atlasOffset + char.atlasPage.toFloat(),
|
meshData.add(position.y)
|
||||||
0f, -0.5f, char.column * 16f + char.width, char.row * 16f + char.width, font.atlasOffset + char.atlasPage.toFloat(),
|
meshData.add(uv.x)
|
||||||
-0.5f, 0f, char.column * 16f, char.row * 16f, font.atlasOffset + char.atlasPage.toFloat(),
|
meshData.add(uv.y)
|
||||||
0f, 0f, char.column * 16f + char.width, char.row * 16f, font.atlasOffset + char.atlasPage.toFloat(),
|
meshData.add(atlasPage.toFloat())
|
||||||
)))
|
}
|
||||||
|
|
||||||
|
fontAtlasTexture = font.createAtlasTexture()
|
||||||
|
fontAtlasTexture.load()
|
||||||
|
|
||||||
|
|
||||||
|
fun drawLetter(position: Vec2, char: Char) {
|
||||||
|
val fontChar = font.getChar(char)
|
||||||
|
val meshData: MutableList<Float> = mutableListOf()
|
||||||
|
|
||||||
|
drawLetterVertex(Vec2(-0.5f, -0.5f), fontChar.uvLeftDown, fontChar.atlasTextureIndex, meshData)
|
||||||
|
drawLetterVertex(Vec2(-0.5f, 0f), fontChar.uvLeftUp, fontChar.atlasTextureIndex, meshData)
|
||||||
|
drawLetterVertex(Vec2(0f, -0.5f), fontChar.uvRightDown, fontChar.atlasTextureIndex, meshData)
|
||||||
|
drawLetterVertex(Vec2(0f, -0.5f), fontChar.uvRightDown, fontChar.atlasTextureIndex, meshData)
|
||||||
|
drawLetterVertex(Vec2(-0.5f, 0f), fontChar.uvLeftUp, fontChar.atlasTextureIndex, meshData)
|
||||||
|
drawLetterVertex(Vec2(0f, 0f), fontChar.uvRightUp, fontChar.atlasTextureIndex, meshData)
|
||||||
|
|
||||||
|
font2DToDraw.add(Font2DMesh(meshData.toFloatArray()))
|
||||||
|
}
|
||||||
|
|
||||||
|
drawLetter(Vec2(0, 0), 'ä')
|
||||||
|
|
||||||
|
|
||||||
glfwSetWindowSizeCallback(windowId, object : GLFWWindowSizeCallback() {
|
glfwSetWindowSizeCallback(windowId, object : GLFWWindowSizeCallback() {
|
||||||
@ -155,6 +172,8 @@ class RenderWindow(private val connection: Connection) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
glfwShowWindow(windowId)
|
||||||
|
|
||||||
latch?.countDown()
|
latch?.countDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,44 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.font
|
package de.bixilon.minosoft.gui.rendering.font
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.assets.AssetsManager
|
||||||
|
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||||
|
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
||||||
|
|
||||||
class Font {
|
class Font {
|
||||||
val chars: MutableMap<Char, FontChar> = mutableMapOf()
|
lateinit var providers: List<FontProvider>
|
||||||
val atlasOffset = 0
|
|
||||||
|
|
||||||
init {
|
fun load(assetsManager: AssetsManager) {
|
||||||
for (page in 0 until 256) {
|
providers = FontLoader.loadFontProviders(assetsManager)
|
||||||
for (x in 0 until 16) {
|
}
|
||||||
for (y in 0 until 16) {
|
|
||||||
chars[(page * 256 + (x * 16 + y)).toChar()] = FontChar(page, x, y)
|
fun getChar(char: Char): FontChar {
|
||||||
}
|
for (provider in providers) {
|
||||||
|
provider.chars[char]?.let {
|
||||||
|
return it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
throw IllegalStateException("$char can not be rendered!")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createAtlasTexture(): TextureArray {
|
||||||
|
val textures: MutableList<Texture> = mutableListOf()
|
||||||
|
for (provider in providers) {
|
||||||
|
for (atlasPage in provider.atlasTextures) {
|
||||||
|
textures.add(atlasPage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val textureArray = TextureArray.createTextureArray(textures = textures)
|
||||||
|
|
||||||
|
|
||||||
|
val atlasWidthSinglePixel = 1f / textureArray.maxWidth
|
||||||
|
val atlasHeightSinglePixel = 1f / textureArray.maxHeight
|
||||||
|
|
||||||
|
for (provider in providers) {
|
||||||
|
for (char in provider.chars.values) {
|
||||||
|
char.calculateUV(provider.width, atlasWidthSinglePixel, atlasHeightSinglePixel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return textureArray
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,25 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.font
|
package de.bixilon.minosoft.gui.rendering.font
|
||||||
|
|
||||||
class FontChar(val atlasPage: Int, val row: Int, val column: Int) {
|
import glm_.vec2.Vec2
|
||||||
val width = 16
|
|
||||||
|
|
||||||
|
data class FontChar(
|
||||||
|
val atlasPage: Int,
|
||||||
|
val atlasTextureIndex: Int,
|
||||||
|
val row: Int,
|
||||||
|
val column: Int,
|
||||||
|
val startPixel: Int,
|
||||||
|
val endPixel: Int,
|
||||||
|
val height: Int,
|
||||||
|
) {
|
||||||
|
lateinit var uvLeftUp: Vec2
|
||||||
|
lateinit var uvRightUp: Vec2
|
||||||
|
lateinit var uvRightDown: Vec2
|
||||||
|
lateinit var uvLeftDown: Vec2
|
||||||
|
|
||||||
|
fun calculateUV(letterWidth: Int, atlasWidthSinglePixel: Float, atlasHeightSinglePixel: Float) {
|
||||||
|
uvLeftUp = Vec2(atlasWidthSinglePixel * (letterWidth * column + startPixel), atlasHeightSinglePixel * (height * row))
|
||||||
|
uvRightUp = Vec2(atlasWidthSinglePixel * (letterWidth * column + endPixel), atlasHeightSinglePixel * (height * row))
|
||||||
|
uvRightDown = Vec2(atlasWidthSinglePixel * (letterWidth * column + endPixel), atlasHeightSinglePixel * (height * (row + 1)))
|
||||||
|
uvLeftDown = Vec2(atlasWidthSinglePixel * (letterWidth * column + startPixel), atlasHeightSinglePixel * (height * (row + 1)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering.font
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import de.bixilon.minosoft.data.assets.AssetsManager
|
||||||
|
import de.bixilon.minosoft.data.mappings.ModIdentifier
|
||||||
|
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||||
|
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
object FontLoader {
|
||||||
|
private const val FONT_ATLAS_SIZE = 16
|
||||||
|
private val MISSING_UNICODE_PAGES = listOf(0x08, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xEE, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8)
|
||||||
|
|
||||||
|
private fun getCharArray(data: JsonArray): List<Char> {
|
||||||
|
val ret: MutableList<Char> = mutableListOf()
|
||||||
|
for (string in data) {
|
||||||
|
ret.addAll(string.asString.toCharArray().toList())
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadBitmapFontProvider(atlasPath: ModIdentifier, height: Int? = 8, ascent: Int, chars: List<Char>, assetsManager: AssetsManager, atlasOffset: Int): FontProvider {
|
||||||
|
val width = if (ascent == 7) {
|
||||||
|
8
|
||||||
|
} else {
|
||||||
|
9
|
||||||
|
}
|
||||||
|
val provider = FontProvider(width)
|
||||||
|
val atlasTexture = Texture((atlasPath.mod + "/textures/" + atlasPath.identifier), atlasOffset)
|
||||||
|
atlasTexture.load(assetsManager)
|
||||||
|
provider.atlasTextures.add(atlasTexture)
|
||||||
|
val height = height ?: atlasTexture.width / 16
|
||||||
|
for ((i, char) in chars.withIndex()) {
|
||||||
|
val fontChar = FontChar(0, atlasOffset, i / FONT_ATLAS_SIZE, i % FONT_ATLAS_SIZE, 0, width, height)
|
||||||
|
provider.chars[char] = fontChar
|
||||||
|
}
|
||||||
|
return provider
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun loadUnicodeFontProvider(template: ModIdentifier, sizes: InputStream, assetsManager: AssetsManager, atlasOffset: Int): FontProvider {
|
||||||
|
val provider = FontProvider(16)
|
||||||
|
var i = 0
|
||||||
|
lateinit var currentAtlasTexture: Texture
|
||||||
|
while (sizes.available() > 0) {
|
||||||
|
if (i % 256 == 0) {
|
||||||
|
currentAtlasTexture = if (MISSING_UNICODE_PAGES.contains(i / 256)) {
|
||||||
|
// ToDo: Why is this texture missing in minecraft?
|
||||||
|
Texture(TextureArray.DEBUG_TEXTURE.name, i / 256)
|
||||||
|
} else {
|
||||||
|
// new page (texture)
|
||||||
|
Texture((template.mod + "/textures/" + template.identifier).format("%02x".format(i / 256)), atlasOffset + (i / 256))
|
||||||
|
}
|
||||||
|
currentAtlasTexture.load(assetsManager)
|
||||||
|
provider.atlasTextures.add(currentAtlasTexture)
|
||||||
|
}
|
||||||
|
val sizeByte = sizes.read()
|
||||||
|
val fontChar = FontChar((i / 256), atlasOffset + (i / 256), (i % 256) / FONT_ATLAS_SIZE, (i % 256) % FONT_ATLAS_SIZE, (sizeByte shr 4) and 0x0F, sizeByte and 0x0F, 16)
|
||||||
|
provider.chars[i.toChar()] = fontChar
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return provider
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadFontProvider(data: JsonObject, assetsManager: AssetsManager, atlasTextureOffset: Int): FontProvider {
|
||||||
|
return when (data["type"].asString) {
|
||||||
|
"bitmap" -> {
|
||||||
|
loadBitmapFontProvider(ModIdentifier(data["file"].asString), data["height"]?.asInt, data["ascent"].asInt, getCharArray(data["chars"].asJsonArray), assetsManager, atlasTextureOffset)
|
||||||
|
}
|
||||||
|
"legacy_unicode" -> {
|
||||||
|
loadUnicodeFontProvider(ModIdentifier(data["template"].asString), assetsManager.readAssetAsStream(ModIdentifier(data["sizes"].asString)), assetsManager, atlasTextureOffset)
|
||||||
|
}
|
||||||
|
else -> throw IllegalArgumentException("${data["type"]} is not a valid font provider type!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun loadFontProviders(assetsManager: AssetsManager): List<FontProvider> {
|
||||||
|
val ret: MutableList<FontProvider> = mutableListOf()
|
||||||
|
var atlasTextureOffset = 0
|
||||||
|
for (providerElement in assetsManager.readJsonAsset("minecraft/font/default.json").asJsonObject["providers"].asJsonArray) {
|
||||||
|
val provider = loadFontProvider(providerElement.asJsonObject, assetsManager, atlasTextureOffset)
|
||||||
|
atlasTextureOffset += provider.atlasTextures.size
|
||||||
|
ret.add(provider)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering.font
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||||
|
|
||||||
|
class FontProvider(val width: Int) {
|
||||||
|
val chars: MutableMap<Char, FontChar> = mutableMapOf()
|
||||||
|
val atlasTextures: MutableList<Texture> = mutableListOf()
|
||||||
|
}
|
@ -1,9 +1,40 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.textures
|
package de.bixilon.minosoft.gui.rendering.textures
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.assets.AssetsManager
|
||||||
|
import de.matthiasmann.twl.utils.PNGDecoder
|
||||||
|
import org.lwjgl.BufferUtils
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
|
|
||||||
class Texture(
|
class Texture(
|
||||||
val name: String,
|
val name: String,
|
||||||
val id: Int,
|
val id: Int,
|
||||||
) {
|
) {
|
||||||
|
var width: Int = 0
|
||||||
|
var height: Int = 0
|
||||||
var isTransparent: Boolean = false
|
var isTransparent: Boolean = false
|
||||||
|
lateinit var buffer: ByteBuffer
|
||||||
|
var loaded = false
|
||||||
|
|
||||||
|
fun load(assetsManager: AssetsManager) {
|
||||||
|
if (loaded) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val texturePath = if (name.endsWith(".png")) {
|
||||||
|
name
|
||||||
|
} else {
|
||||||
|
"minecraft/textures/${name}.png"
|
||||||
|
}
|
||||||
|
val decoder = PNGDecoder(assetsManager.readAssetAsStream(texturePath))
|
||||||
|
buffer = BufferUtils.createByteBuffer(decoder.width * decoder.height * PNGDecoder.Format.RGBA.numComponents)
|
||||||
|
decoder.decode(buffer, decoder.width * PNGDecoder.Format.RGBA.numComponents, PNGDecoder.Format.RGBA)
|
||||||
|
width = decoder.width
|
||||||
|
height = decoder.height
|
||||||
|
buffer.flip()
|
||||||
|
if (TextureArray.TRANSPARENT_TEXTURES.contains(name)) { // ToDo: this should not be hardcoded!
|
||||||
|
isTransparent = true
|
||||||
|
}
|
||||||
|
buffer.flip()
|
||||||
|
loaded = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import org.lwjgl.opengl.GL30.GL_TEXTURE_2D_ARRAY
|
|||||||
import org.lwjgl.opengl.GL30.glGenerateMipmap
|
import org.lwjgl.opengl.GL30.glGenerateMipmap
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
class TextureArray(private val assetsManager: AssetsManager, private val textures: List<Texture>, private val size: Int = 16) {
|
class TextureArray(private val textures: List<Texture>, val maxWidth: Int, val maxHeight: Int) {
|
||||||
var textureId = 0
|
var textureId = 0
|
||||||
|
|
||||||
fun load(): Int {
|
fun load(): Int {
|
||||||
@ -21,12 +21,10 @@ class TextureArray(private val assetsManager: AssetsManager, private val texture
|
|||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||||
|
|
||||||
|
|
||||||
// load and generate the texture
|
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, maxWidth, maxHeight, textures.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, null as ByteBuffer?)
|
||||||
val textureMap: Map<Texture, ByteBuffer> = TextureLoader.loadTextureArray(assetsManager, textures)
|
|
||||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, size, size, textures.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, null as ByteBuffer?)
|
|
||||||
|
|
||||||
for ((key, value) in textureMap) {
|
for (texture in textures) {
|
||||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, key.id, size, size, 1, GL_RGBA, GL_UNSIGNED_BYTE, value)
|
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, texture.id, texture.width, texture.height, 1, GL_RGBA, GL_UNSIGNED_BYTE, texture.buffer)
|
||||||
}
|
}
|
||||||
glGenerateMipmap(GL_TEXTURE_2D_ARRAY)
|
glGenerateMipmap(GL_TEXTURE_2D_ARRAY)
|
||||||
return textureId
|
return textureId
|
||||||
@ -40,5 +38,29 @@ class TextureArray(private val assetsManager: AssetsManager, private val texture
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val DEBUG_TEXTURE = Texture("block/debug", 0)
|
val DEBUG_TEXTURE = Texture("block/debug", 0)
|
||||||
|
val TRANSPARENT_TEXTURES = listOf("block/glass")
|
||||||
|
|
||||||
|
fun createTextureArray(assetsManager: AssetsManager? = null, textures: List<Texture>, maxWidth: Int = -1, maxHeight: Int = -1): TextureArray {
|
||||||
|
var calculatedMaxWidth = 0
|
||||||
|
var calculatedMaxHeight = 0
|
||||||
|
for (texture in textures) {
|
||||||
|
if (!texture.loaded) {
|
||||||
|
texture.load(assetsManager!!)
|
||||||
|
}
|
||||||
|
if (texture.width > calculatedMaxWidth) {
|
||||||
|
calculatedMaxWidth = texture.width
|
||||||
|
}
|
||||||
|
if (texture.height > calculatedMaxHeight) {
|
||||||
|
calculatedMaxHeight = texture.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxWidth != -1) {
|
||||||
|
calculatedMaxWidth = maxWidth
|
||||||
|
}
|
||||||
|
if (maxHeight != -1) {
|
||||||
|
calculatedMaxHeight = maxWidth
|
||||||
|
}
|
||||||
|
return TextureArray(textures, calculatedMaxWidth, calculatedMaxHeight)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.textures
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.assets.AssetsManager
|
|
||||||
import de.matthiasmann.twl.utils.PNGDecoder
|
|
||||||
import org.lwjgl.BufferUtils
|
|
||||||
import java.nio.ByteBuffer
|
|
||||||
|
|
||||||
|
|
||||||
object TextureLoader {
|
|
||||||
private val TRANSPARENT_TEXTURES = listOf("block/glass")
|
|
||||||
fun loadTextureArray(assetsManager: AssetsManager, textures: List<Texture>): Map<Texture, ByteBuffer> {
|
|
||||||
val result: MutableMap<Texture, ByteBuffer> = mutableMapOf()
|
|
||||||
for (texture in textures) {
|
|
||||||
result[texture] = loadTexture(assetsManager, texture)
|
|
||||||
}
|
|
||||||
return result.toMap()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadTexture(assetsManager: AssetsManager, texture: Texture): ByteBuffer {
|
|
||||||
val decoder = PNGDecoder(assetsManager.readAssetAsStream("minecraft/textures/${texture.name}.png"))
|
|
||||||
val buffer = BufferUtils.createByteBuffer(decoder.width * decoder.height * PNGDecoder.Format.RGBA.numComponents)
|
|
||||||
decoder.decode(buffer, decoder.width * PNGDecoder.Format.RGBA.numComponents, PNGDecoder.Format.RGBA)
|
|
||||||
buffer.flip()
|
|
||||||
if (TRANSPARENT_TEXTURES.contains(texture.name)) { // ToDo: this should not be hardcoded!
|
|
||||||
texture.isTransparent = true
|
|
||||||
}
|
|
||||||
buffer.flip()
|
|
||||||
return buffer
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,12 +8,13 @@ uniform sampler2DArray texureArray;
|
|||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 texColor = texture(texureArray, passTextureCoordinates);
|
vec4 textureColor = texture(texureArray, passTextureCoordinates);
|
||||||
if (texColor.a == 0) {
|
if (textureColor.a == 0) {
|
||||||
discard;
|
textureColor.a = 0.4f;
|
||||||
|
//discard;
|
||||||
}
|
}
|
||||||
texColor.r = 0.8f;
|
textureColor.r = 0.8f;
|
||||||
texColor.g = 0.8f;
|
textureColor.g = 0.8f;
|
||||||
texColor.b = 0.0f;
|
textureColor.b = 0.0f;
|
||||||
outColor = texColor;
|
outColor = textureColor;
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,8 @@ layout (location = 2) in float textureLayer;
|
|||||||
|
|
||||||
out vec3 passTextureCoordinates;
|
out vec3 passTextureCoordinates;
|
||||||
|
|
||||||
uniform float atlasSize;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(inPosition, 0.0f, 1.0f);
|
gl_Position = vec4(inPosition, 0.0f, 1.0f);
|
||||||
passTextureCoordinates = vec3(textureIndex / atlasSize, textureLayer);
|
passTextureCoordinates = vec3(textureIndex, textureLayer);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user