mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 02:15:34 -04:00
render simple letter on screen
This commit is contained in:
parent
b418145f88
commit
c706ee7d36
@ -2,8 +2,12 @@ package de.bixilon.minosoft.gui.rendering
|
||||
|
||||
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||
import de.bixilon.minosoft.data.entities.Location
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.world.ChunkLocation
|
||||
import de.bixilon.minosoft.gui.rendering.font.Font
|
||||
import de.bixilon.minosoft.gui.rendering.font.Font2DMesh
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
||||
import de.bixilon.minosoft.protocol.network.Connection
|
||||
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketPlayerPositionAndRotationSending
|
||||
@ -27,7 +31,9 @@ class RenderWindow(private val connection: Connection) {
|
||||
private var screenHeight = 600
|
||||
private var polygonEnabled = false
|
||||
private lateinit var chunkShader: Shader
|
||||
private lateinit var fontShader: Shader
|
||||
private lateinit var minecraftTextures: TextureArray
|
||||
private lateinit var fontAtlasTexture: TextureArray
|
||||
private var windowId: Long = 0
|
||||
private var deltaTime = 0.0 // time between current frame and last frame
|
||||
|
||||
@ -36,7 +42,8 @@ class RenderWindow(private val connection: Connection) {
|
||||
|
||||
val renderQueue = ConcurrentLinkedQueue<Runnable>()
|
||||
|
||||
val chunkSectionsToDraw = ConcurrentHashMap<ChunkLocation, ConcurrentHashMap<Int, Mesh>>()
|
||||
val chunkSectionsToDraw = ConcurrentHashMap<ChunkLocation, ConcurrentHashMap<Int, WorldMesh>>()
|
||||
val font2DToDraw = ConcurrentLinkedQueue<Font2DMesh>()
|
||||
|
||||
|
||||
fun init(latch: CountUpAndDownLatch? = null) {
|
||||
@ -110,17 +117,35 @@ class RenderWindow(private val connection: Connection) {
|
||||
glEnable(GL_BLEND)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
minecraftTextures = TextureArray(connection.version.assetsManager, connection.version.mapping.blockMap.values)
|
||||
minecraftTextures = TextureArray(connection.version.assetsManager, resolveBlockTextureIds(connection.version.mapping.blockMap.values))
|
||||
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.load()
|
||||
chunkShader.use()
|
||||
chunkShader.setInt("texture0", 0)
|
||||
|
||||
camera.calculateProjectionMatrix(screenWidth, screenHeight, chunkShader)
|
||||
camera.calculateViewMatrix(chunkShader)
|
||||
|
||||
fontShader = Shader("font_vertex.glsl", "font_fragment.glsl")
|
||||
fontShader.load()
|
||||
fontShader.use()
|
||||
fontShader.setFloat("atlasSize", 256f)
|
||||
|
||||
val font = Font()
|
||||
val char = font.chars['§']!!
|
||||
font2DToDraw.add(Font2DMesh(floatArrayOf(
|
||||
-0.5f, -0.5f, char.column * 16f, char.row * 16f + char.width, font.atlasOffset + char.atlasPage.toFloat(),
|
||||
-0.5f, 0f, char.column * 16f, char.row * 16f, font.atlasOffset + char.atlasPage.toFloat(),
|
||||
0f, -0.5f, char.column * 16f + char.width, char.row * 16f + char.width, font.atlasOffset + char.atlasPage.toFloat(),
|
||||
0f, -0.5f, char.column * 16f + char.width, char.row * 16f + char.width, font.atlasOffset + char.atlasPage.toFloat(),
|
||||
-0.5f, 0f, char.column * 16f, char.row * 16f, font.atlasOffset + char.atlasPage.toFloat(),
|
||||
0f, 0f, char.column * 16f + char.width, char.row * 16f, font.atlasOffset + char.atlasPage.toFloat(),
|
||||
)))
|
||||
|
||||
|
||||
glfwSetWindowSizeCallback(windowId, object : GLFWWindowSizeCallback() {
|
||||
override fun invoke(window: Long, width: Int, height: Int) {
|
||||
glViewport(0, 0, width, height)
|
||||
@ -148,6 +173,8 @@ class RenderWindow(private val connection: Connection) {
|
||||
deltaTime = currentFrame - lastFrame
|
||||
lastFrame = currentFrame
|
||||
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
|
||||
minecraftTextures.use(GL_TEXTURE0)
|
||||
|
||||
chunkShader.use()
|
||||
@ -160,6 +187,15 @@ class RenderWindow(private val connection: Connection) {
|
||||
}
|
||||
}
|
||||
|
||||
glDisable(GL_DEPTH_TEST)
|
||||
fontAtlasTexture.use(GL_TEXTURE0)
|
||||
|
||||
fontShader.use()
|
||||
|
||||
for (font in font2DToDraw) {
|
||||
font.draw()
|
||||
}
|
||||
|
||||
glfwSwapBuffers(windowId)
|
||||
|
||||
glfwPollEvents()
|
||||
@ -179,6 +215,7 @@ class RenderWindow(private val connection: Connection) {
|
||||
if (glfwGetTime() - lastPositionChangeTime > 0.05) {
|
||||
// ToDo: Replace this with proper movement and only send it, when out position changed
|
||||
connection.sendPacket(PacketPlayerPositionAndRotationSending(Location(camera.cameraPosition), EntityRotation(camera.yaw, camera.pitch), false))
|
||||
lastPositionChangeTime = glfwGetTime()
|
||||
}
|
||||
|
||||
|
||||
@ -207,4 +244,16 @@ class RenderWindow(private val connection: Connection) {
|
||||
})
|
||||
polygonEnabled = !polygonEnabled
|
||||
}
|
||||
|
||||
private fun resolveBlockTextureIds(blocks: Set<Block>): List<Texture> {
|
||||
val textures: MutableList<Texture> = mutableListOf()
|
||||
textures.add(TextureArray.DEBUG_TEXTURE)
|
||||
val textureMap: MutableMap<String, Texture> = mutableMapOf()
|
||||
textureMap[TextureArray.DEBUG_TEXTURE.name] = TextureArray.DEBUG_TEXTURE
|
||||
|
||||
for (block in blocks) {
|
||||
block.blockModel?.resolveTextures(textures, textureMap)
|
||||
}
|
||||
return textures
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ class Renderer(private val connection: Connection) {
|
||||
renderWindow.renderQueue.add {
|
||||
sectionMap[sectionHeight]?.unload()
|
||||
sectionMap.remove(sectionHeight)
|
||||
sectionMap[sectionHeight] = Mesh(data, Vec3(chunkLocation.x, sectionHeight, chunkLocation.z))
|
||||
sectionMap[sectionHeight] = WorldMesh(data, Vec3(chunkLocation.x, sectionHeight, chunkLocation.z))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,6 @@ package de.bixilon.minosoft.gui.rendering;
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader;
|
||||
import glm_.vec3.Vec3;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
|
||||
import static org.lwjgl.opengl.GL11.glDrawArrays;
|
||||
@ -12,13 +9,13 @@ import static org.lwjgl.opengl.GL15.glDeleteBuffers;
|
||||
import static org.lwjgl.opengl.GL15.glGenBuffers;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
|
||||
public class Mesh {
|
||||
public class WorldMesh {
|
||||
int vAO;
|
||||
int vBO;
|
||||
Vec3 worldPosition;
|
||||
int trianglesCount;
|
||||
|
||||
public Mesh(float[] data, Vec3 worldPosition) {
|
||||
public WorldMesh(float[] data, Vec3 worldPosition) {
|
||||
this.worldPosition = worldPosition;
|
||||
this.trianglesCount = data.length / 6; // <- bytes per vertex
|
||||
this.vAO = glGenVertexArrays();
|
||||
@ -26,17 +23,17 @@ public class Mesh {
|
||||
|
||||
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
|
||||
glBindVertexArray(this.vAO);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.vBO);
|
||||
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STATIC_DRAW);
|
||||
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 6 * Float.BYTES, 0L);
|
||||
GL20.glEnableVertexAttribArray(0);
|
||||
GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false, 6 * Float.BYTES, 3 * Float.BYTES);
|
||||
GL20.glEnableVertexAttribArray(1);
|
||||
GL20.glVertexAttribPointer(2, 1, GL11.GL_FLOAT, false, 6 * Float.BYTES, 5 * Float.BYTES);
|
||||
GL20.glEnableVertexAttribArray(2);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this.vBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, false, 6 * Float.BYTES, 0L);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, false, 6 * Float.BYTES, 3 * Float.BYTES);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(2, 1, GL_FLOAT, false, 6 * Float.BYTES, 5 * Float.BYTES);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
public void draw(Shader chunkShader) {
|
17
src/main/java/de/bixilon/minosoft/gui/rendering/font/Font.kt
Normal file
17
src/main/java/de/bixilon/minosoft/gui/rendering/font/Font.kt
Normal file
@ -0,0 +1,17 @@
|
||||
package de.bixilon.minosoft.gui.rendering.font
|
||||
|
||||
|
||||
class Font {
|
||||
val chars: MutableMap<Char, FontChar> = mutableMapOf()
|
||||
val atlasOffset = 0
|
||||
|
||||
init {
|
||||
for (page in 0 until 256) {
|
||||
for (x in 0 until 16) {
|
||||
for (y in 0 until 16) {
|
||||
chars[(page * 256 + (x * 16 + y)).toChar()] = FontChar(page, x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package de.bixilon.minosoft.gui.rendering.font
|
||||
|
||||
import glm_.BYTES
|
||||
import org.lwjgl.opengl.GL11.GL_FLOAT
|
||||
import org.lwjgl.opengl.GL20.glEnableVertexAttribArray
|
||||
import org.lwjgl.opengl.GL20.glVertexAttribPointer
|
||||
import org.lwjgl.opengl.GL30.*
|
||||
|
||||
class Font2DMesh(data: FloatArray) {
|
||||
var vAO: Int = glGenVertexArrays()
|
||||
var vBO: Int = glGenBuffers()
|
||||
var trianglesCount: Int = data.size / 5 // <- bytes per vertex
|
||||
|
||||
fun draw() {
|
||||
glBindVertexArray(vAO)
|
||||
glDrawArrays(GL_TRIANGLES, 0, trianglesCount)
|
||||
}
|
||||
|
||||
fun unload() {
|
||||
glDeleteVertexArrays(vAO)
|
||||
glDeleteBuffers(vBO)
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
|
||||
glBindVertexArray(vAO)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vBO)
|
||||
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW)
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, false, 5 * Float.BYTES, 0L)
|
||||
glEnableVertexAttribArray(0)
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, false, 5 * Float.BYTES, (2 * Float.BYTES).toLong())
|
||||
glEnableVertexAttribArray(1)
|
||||
glVertexAttribPointer(2, 1, GL_FLOAT, false, 5 * Float.BYTES, (4 * Float.BYTES).toLong())
|
||||
glEnableVertexAttribArray(2)
|
||||
|
||||
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.font
|
||||
|
||||
class FontChar(val atlasPage: Int, val row: Int, val column: Int) {
|
||||
val width = 16
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package de.bixilon.minosoft.gui.rendering.hud
|
||||
|
||||
enum class HUDScale(val scale: Float) {
|
||||
TINY(0.1f),
|
||||
MEDIUM(0.2f),
|
||||
LARGE(0.5f),
|
||||
SENIOR(1.0f),
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.textures
|
||||
|
||||
import de.bixilon.minosoft.data.assets.AssetsManager
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureLoader.loadTextureArray
|
||||
import org.lwjgl.opengl.GL11.*
|
||||
import org.lwjgl.opengl.GL12.glTexImage3D
|
||||
import org.lwjgl.opengl.GL12.glTexSubImage3D
|
||||
@ -11,7 +9,7 @@ import org.lwjgl.opengl.GL30.GL_TEXTURE_2D_ARRAY
|
||||
import org.lwjgl.opengl.GL30.glGenerateMipmap
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
class TextureArray(private val assetsManager: AssetsManager, private val blocks: Set<Block>) {
|
||||
class TextureArray(private val assetsManager: AssetsManager, private val textures: List<Texture>, private val size: Int = 16) {
|
||||
var textureId = 0
|
||||
|
||||
fun load(): Int {
|
||||
@ -24,32 +22,20 @@ class TextureArray(private val assetsManager: AssetsManager, private val blocks:
|
||||
|
||||
|
||||
// load and generate the texture
|
||||
val textures = resolveTextureIds(blocks)
|
||||
val textureMap: Map<Texture, ByteBuffer> = loadTextureArray(assetsManager, textures)
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 16, 16, 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) {
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, key.id, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, value)
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, key.id, size, size, 1, GL_RGBA, GL_UNSIGNED_BYTE, value)
|
||||
}
|
||||
glGenerateMipmap(GL_TEXTURE_2D_ARRAY)
|
||||
return textureId
|
||||
}
|
||||
|
||||
private fun resolveTextureIds(blocks: Set<Block>): List<Texture> {
|
||||
val textures: MutableList<Texture> = mutableListOf()
|
||||
textures.add(DEBUG_TEXTURE)
|
||||
val textureMap: MutableMap<String, Texture> = mutableMapOf()
|
||||
textureMap[DEBUG_TEXTURE.name] = DEBUG_TEXTURE
|
||||
|
||||
for (block in blocks) {
|
||||
block.blockModel?.resolveTextures(textures, textureMap)
|
||||
}
|
||||
return textures
|
||||
}
|
||||
|
||||
fun use(textureMode: Int) {
|
||||
glActiveTexture(textureMode)
|
||||
glBindTexture(GL_TEXTURE_2D, textureId)
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -3,7 +3,6 @@ layout (location = 0) in vec3 inPosition;
|
||||
layout (location = 1) in vec2 textureIndex;
|
||||
layout (location = 2) in float textureLayer;
|
||||
|
||||
out vec3 vertexColor;
|
||||
out vec3 passTextureCoordinates;
|
||||
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
in vec3 passTextureCoordinates;
|
||||
|
||||
uniform sampler2DArray texureArray;
|
||||
|
||||
|
||||
void main() {
|
||||
vec4 texColor = texture(texureArray, passTextureCoordinates);
|
||||
if (texColor.a == 0) {
|
||||
discard;
|
||||
}
|
||||
texColor.r = 0.8f;
|
||||
texColor.g = 0.8f;
|
||||
texColor.b = 0.0f;
|
||||
outColor = texColor;
|
||||
}
|
13
src/main/resources/assets/rendering/shader/font_vertex.glsl
Normal file
13
src/main/resources/assets/rendering/shader/font_vertex.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec2 inPosition;
|
||||
layout (location = 1) in vec2 textureIndex;
|
||||
layout (location = 2) in float textureLayer;
|
||||
|
||||
out vec3 passTextureCoordinates;
|
||||
|
||||
uniform float atlasSize;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(inPosition, 0.0f, 1.0f);
|
||||
passTextureCoordinates = vec3(textureIndex / atlasSize, textureLayer);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user