From 6e215afbb6d3f8f67088bea9b0f95e9a92c573a5 Mon Sep 17 00:00:00 2001 From: Martin Jakobsson Date: Wed, 31 Jul 2024 23:02:57 +0200 Subject: [PATCH] Improved grass texture and some other minor stuff --- .../src/main/resources/shaders/sky/frag.glsl | 7 ++-- .../resources/textures/blocks/grassSide.png | Bin 6876 -> 7063 bytes .../scala/hexacraft/client/GameClient.scala | 1 - .../scala/hexacraft/client/InventoryBox.scala | 36 ++++++++++-------- .../scala/hexacraft/text/TextMaster.scala | 2 +- .../client/render/BufferHandlerTest.scala | 10 ----- .../scala/hexacraft/game/NetworkPacket.scala | 9 ----- .../main/scala/hexacraft/world/HexBox.scala | 2 +- .../main/scala/hexacraft/world/Player.scala | 2 +- .../scala/hexacraft/world/collision.scala | 1 - .../test/scala/hexacraft/RootArchTest.scala | 22 ++--------- .../scala/hexacraft/main/GameSceneTest.scala | 12 +++++- .../scala/hexacraft/server/GameServer.scala | 5 --- .../hexacraft/world/ServerWorldTest.scala | 26 ++++++------- 14 files changed, 52 insertions(+), 83 deletions(-) diff --git a/client/src/main/resources/shaders/sky/frag.glsl b/client/src/main/resources/shaders/sky/frag.glsl index ee13662b..4270c76a 100644 --- a/client/src/main/resources/shaders/sky/frag.glsl +++ b/client/src/main/resources/shaders/sky/frag.glsl @@ -10,14 +10,13 @@ void main() { vec4 coordsBeforeMatr = vec4(fragPosition.x, fragPosition.y, -1, 1); vec4 coordsAfterProj = invProjMatr * coordsBeforeMatr; vec3 ray = normalize((invViewMatr * vec4(coordsAfterProj.xy, -1, 0)).xyz); - vec3 theSun = normalize(sun); - float sunBrightness = min(exp((dot(ray, theSun)-1)*400), 1) * 0.5; - float sunGlow = exp((dot(ray, theSun)-1)*4) * 0.4; + vec3 sunDir = normalize(sun); + float sunBrightness = min(exp((dot(ray, sunDir)-1)*400), 1) * 0.5; + float sunGlow = exp((dot(ray, sunDir)-1)*4) * 0.4; vec3 up = vec3(0, 1, 0); float rayUp = dot(ray, up); float gradientFalloff = 0.5; if (rayUp < 0) gradientFalloff = 2.0; - // TODO: The world is cylindrical! vec3 col = sunBrightness * vec3(0.8, 0.65, 0.8) + sunGlow * vec3(0.8, 0.65, 0.8) + vec3(0.4, 0.7, 0.5) * (1 - abs(rayUp) * gradientFalloff) + vec3(0.0, 0.0, 0.7); color = vec4(col, 1); } \ No newline at end of file diff --git a/client/src/main/resources/textures/blocks/grassSide.png b/client/src/main/resources/textures/blocks/grassSide.png index d4c21034322f3d62db35d6cb9031823855946d3d..e57356662cea8e08823afc5450cb040fe9ce5949 100644 GIT binary patch delta 3221 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 Hu0mjfI)(1K delta 3202 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 diff --git a/client/src/main/scala/hexacraft/client/GameClient.scala b/client/src/main/scala/hexacraft/client/GameClient.scala index c70fb458..3637e851 100644 --- a/client/src/main/scala/hexacraft/client/GameClient.scala +++ b/client/src/main/scala/hexacraft/client/GameClient.scala @@ -72,7 +72,6 @@ object GameClient { val crosshairVAO: VAO = CrosshairShader.createVao() val crosshairRenderer: Renderer = CrosshairShader.createRenderer() - // TODO: get chunks from the server instead of generating the entire world val world = ClientWorld(worldInfo) given CylinderSize = world.size diff --git a/client/src/main/scala/hexacraft/client/InventoryBox.scala b/client/src/main/scala/hexacraft/client/InventoryBox.scala index d855e255..be636cda 100644 --- a/client/src/main/scala/hexacraft/client/InventoryBox.scala +++ b/client/src/main/scala/hexacraft/client/InventoryBox.scala @@ -3,7 +3,7 @@ package hexacraft.client import hexacraft.gui.{Event, LocationInfo, RenderContext} import hexacraft.gui.comp.{Component, GUITransformation} import hexacraft.infra.window.{KeyAction, KeyboardKey, MouseAction} -import hexacraft.util.{Channel, Tracker} +import hexacraft.util.Channel import hexacraft.world.Inventory import hexacraft.world.block.Block @@ -45,10 +45,10 @@ class InventoryBox private ( eventHandler: Channel.Sender[InventoryBox.Event] ) extends Component { - private val location: LocationInfo = LocationInfo(-4.5f * 0.2f, -2.5f * 0.2f, 9 * 0.2f, 4 * 0.2f) + private val bounds: LocationInfo = LocationInfo(-4.5f * 0.2f, -2.5f * 0.2f, 9 * 0.2f, 4 * 0.2f) private val backgroundColor = new Vector4f(0.4f, 0.4f, 0.4f, 0.75f) private val selectedColor = new Vector4f(0.2f, 0.2f, 0.2f, 0.25f) - private val selectedBox = LocationInfo(location.x + 0.01f, location.y + 0.01f, 0.18f, 0.18f) + private val selectedBox = LocationInfo(bounds.x + 0.01f, bounds.y + 0.01f, 0.18f, 0.18f) /** The index of the slot under the cursor */ private var hoverIndex: Option[Int] = None @@ -64,9 +64,9 @@ class InventoryBox private ( } private def calculateHoverIndex(mx: Float, my: Float) = { - if location.containsPoint(mx, my) then { - val xi = ((mx - location.x) / 0.2f).toInt - val yi = ((my - location.y) / 0.2f).toInt + if bounds.containsPoint(mx, my) then { + val xi = ((mx - bounds.x) / 0.2f).toInt + val yi = ((my - bounds.y) / 0.2f).toInt Some(xi + yi * 9) } else { None @@ -79,27 +79,31 @@ class InventoryBox private ( case KeyEvent(key, _, KeyAction.Press, _) => key match { case KeyboardKey.Escape | KeyboardKey.Letter('E') => - handleFloatingBlock() + releaseFloatingBlock() eventHandler.send(InventoryBox.Event.BoxClosed) case _ => } - case MouseClickEvent(_, MouseAction.Release, _, mousePos) if location.containsPoint(mousePos) => + case MouseClickEvent(_, MouseAction.Release, _, mousePos) if bounds.containsPoint(mousePos) => hoverIndex match { case Some(hover) => - val newFloatingBlock = Some(inventory(hover)).filter(_ != Block.Air) - inventory = inventory.updated(hover, floatingBlock.getOrElse(Block.Air)) - eventHandler.send(InventoryBox.Event.InventoryUpdated(inventory)) - updateRendererContent() - floatingBlock = newFloatingBlock + swapFloatingBlock(hover) case None => - handleFloatingBlock() + releaseFloatingBlock() } case _ => } true } - private def handleFloatingBlock(): Unit = { + private def swapFloatingBlock(index: Int): Unit = { + val newFloatingBlock = Some(inventory(index)).filter(_ != Block.Air) + inventory = inventory.updated(index, floatingBlock.getOrElse(Block.Air)) + eventHandler.send(InventoryBox.Event.InventoryUpdated(inventory)) + updateRendererContent() + floatingBlock = newFloatingBlock + } + + private def releaseFloatingBlock(): Unit = { floatingBlock match { case Some(block) => inventory.firstEmptySlot match { @@ -124,7 +128,7 @@ class InventoryBox private ( floatingBlockRenderer.updateContent(mousePos.x, mousePos.y, Seq(floatingBlock.get)) } - Component.drawRect(location, transformation.x, transformation.y, backgroundColor, context.windowAspectRatio) + Component.drawRect(bounds, transformation.x, transformation.y, backgroundColor, context.windowAspectRatio) if hoverIndex.isDefined then { val xOffset = transformation.x + (hoverIndex.get % 9) * 0.2f diff --git a/client/src/main/scala/hexacraft/text/TextMaster.scala b/client/src/main/scala/hexacraft/text/TextMaster.scala index 90895356..7df45f9d 100644 --- a/client/src/main/scala/hexacraft/text/TextMaster.scala +++ b/client/src/main/scala/hexacraft/text/TextMaster.scala @@ -29,7 +29,6 @@ class TextMaster { textBatch -= text if textBatch.isEmpty then { texts -= text.font - // TODO: remove VAO } } @@ -39,6 +38,7 @@ class TextMaster { text <- texts(font) } do { text.unload() + // TODO: this class is currently not the owner of the Text, but it probably should be } texts.clear() } diff --git a/client/src/test/scala/hexacraft/client/render/BufferHandlerTest.scala b/client/src/test/scala/hexacraft/client/render/BufferHandlerTest.scala index 07af1e58..8fd424a9 100644 --- a/client/src/test/scala/hexacraft/client/render/BufferHandlerTest.scala +++ b/client/src/test/scala/hexacraft/client/render/BufferHandlerTest.scala @@ -39,16 +39,6 @@ class BufferHandlerTest extends FunSuite { assertEquals(dest.localBuffer.array().toSeq.take(6), Seq(0, 1, 2, 3, 0, 0).map(_.toByte)) } - // TODO: fill in these tests or remove them - - test("set should transfer the data into the correct buffers even if a border is crossed".ignore) {} - test("set should transfer the data into the correct buffers even if several borders are crossed".ignore) {} - - test("render should do nothing if length is 0".ignore) {} - test("render should render the correct amount if no border is crossed".ignore) {} - test("render should render the correct amount if a border is crossed".ignore) {} - test("render should render the correct amount if several borders are crossed".ignore) {} - test("unload should unload all buffers") { val dest = new LocalRenderBuffer(BufferSize) val allocator = new LocalRenderBuffer.Allocator(_ => dest) diff --git a/game/src/main/scala/hexacraft/game/NetworkPacket.scala b/game/src/main/scala/hexacraft/game/NetworkPacket.scala index 73b11708..62720a24 100644 --- a/game/src/main/scala/hexacraft/game/NetworkPacket.scala +++ b/game/src/main/scala/hexacraft/game/NetworkPacket.scala @@ -20,7 +20,6 @@ enum NetworkPacket { case Logout case GetWorldInfo - case LoadChunkData(coords: ChunkRelWorld) case LoadColumnData(coords: ColumnRelWorld) case LoadWorldData @@ -63,9 +62,6 @@ object NetworkPacket { NetworkPacket.Logout case "get_world_info" => NetworkPacket.GetWorldInfo - case "load_chunk_data" => - val coords = ChunkRelWorld(root.getLong("coords", -1)) - NetworkPacket.LoadChunkData(coords) case "load_column_data" => val coords = ColumnRelWorld(root.getLong("coords", -1)) NetworkPacket.LoadColumnData(coords) @@ -114,7 +110,6 @@ object NetworkPacket { case NetworkPacket.Login(_, _) => "login" case NetworkPacket.Logout => "logout" case NetworkPacket.GetWorldInfo => "get_world_info" - case NetworkPacket.LoadChunkData(_) => "load_chunk_data" case NetworkPacket.LoadColumnData(_) => "load_column_data" case NetworkPacket.LoadWorldData => "load_world_data" case NetworkPacket.GetPlayerState => "get_player_state" @@ -146,10 +141,6 @@ object NetworkPacket { "id" -> Nbt.ByteArrayTag(idBytes), "name" -> Nbt.StringTag(name) ) - case NetworkPacket.LoadChunkData(coords) => - Nbt.makeMap( - "coords" -> Nbt.LongTag(coords.value) - ) case NetworkPacket.LoadColumnData(coords) => Nbt.makeMap( "coords" -> Nbt.LongTag(coords.value) diff --git a/game/src/main/scala/hexacraft/world/HexBox.scala b/game/src/main/scala/hexacraft/world/HexBox.scala index 4d4b6b2e..68b18ca7 100644 --- a/game/src/main/scala/hexacraft/world/HexBox.scala +++ b/game/src/main/scala/hexacraft/world/HexBox.scala @@ -44,7 +44,7 @@ class HexBox(val radius: Float, val bottom: Float, val top: Float) { val yLo = math.floor((pos.y + this.bottom) * 2).toInt val yHi = math.floor((pos.y + this.top) * 2).toInt - // TODO: improve this implementation to be more correct + // TODO: improve this implementation to be more correct (the HexBox radius might be too big) for { y <- yLo to yHi dx <- -1 to 1 diff --git a/game/src/main/scala/hexacraft/world/Player.scala b/game/src/main/scala/hexacraft/world/Player.scala index 48bbe1d4..b3e0d5cc 100644 --- a/game/src/main/scala/hexacraft/world/Player.scala +++ b/game/src/main/scala/hexacraft/world/Player.scala @@ -16,7 +16,7 @@ class Player(val id: UUID, var inventory: Inventory) { var flying = false var selectedItemSlot: Int = 0 - def blockInHand: Block = inventory(selectedItemSlot) // TODO: temporary, make inventory system + def blockInHand: Block = inventory(selectedItemSlot) def toNBT: Nbt.MapTag = { Nbt.makeMap( diff --git a/game/src/main/scala/hexacraft/world/collision.scala b/game/src/main/scala/hexacraft/world/collision.scala index 00dd732a..103eabdf 100644 --- a/game/src/main/scala/hexacraft/world/collision.scala +++ b/game/src/main/scala/hexacraft/world/collision.scala @@ -212,7 +212,6 @@ class CollisionDetector(world: BlocksInWorld)(using cylSize: CylinderSize) { } val velDists = reflectionDirs.map(t => t.dx * vx + t.dy * vy + t.dz * vz) // the length of v along the normals - // TODO: possible bug: the dot product above uses normals that are not normalized. Could this lead to incorrect velDists? if !distances.indices.exists(i => distances(i) <= velDists(i)) then { // no intersection after moving return (0, -1) diff --git a/main/src/test/scala/hexacraft/RootArchTest.scala b/main/src/test/scala/hexacraft/RootArchTest.scala index 7c9d92f1..6a5f44c1 100644 --- a/main/src/test/scala/hexacraft/RootArchTest.scala +++ b/main/src/test/scala/hexacraft/RootArchTest.scala @@ -96,25 +96,9 @@ class RootArchTest extends FunSuite { )* ) .where(Game, _.mayOnlyAccessLayers(Infra, Physics, World, JOML, Nbt)) - .where( - Client, - _.mayOnlyAccessLayers( - Game, - Text, - GUI, - Infra, - Math, - Renderer, - Shaders, - Physics, - Util, - World, - JOML, - LWJGL, - Nbt, - ZeroMQ - ) - ) + // format: off + .where(Client, _.mayOnlyAccessLayers(Game, Text, GUI, Infra, Math, Renderer, Shaders, Physics, Util, World, JOML, LWJGL, Nbt, ZeroMQ)) + // format: on .where(Server, _.mayOnlyAccessLayers(Game, Infra, Math, Physics, Util, World, JOML, Nbt, ZeroMQ)) .where(GUI, _.mayOnlyAccessLayers(root, Infra, Math, Text, Renderer, Shaders, Util, JOML)) .where(Infra, _.mayOnlyAccessLayers(Math, Util, JOML, WrappedLibs, LWJGL, Nbt)) diff --git a/main/src/test/scala/hexacraft/main/GameSceneTest.scala b/main/src/test/scala/hexacraft/main/GameSceneTest.scala index 5c80f3fb..d7fa88fb 100644 --- a/main/src/test/scala/hexacraft/main/GameSceneTest.scala +++ b/main/src/test/scala/hexacraft/main/GameSceneTest.scala @@ -76,6 +76,8 @@ class GameSceneTest extends FunSuite { // All newly loaded shader programs should be released after the game is unloaded assertEquals(shadersRemoved.sorted, shadersAdded.sorted) + + gameScene.unload() } test("GameScene emits QuitGame event when quit-button is pressed in pause menu") { @@ -108,6 +110,8 @@ class GameSceneTest extends FunSuite { GameScene.Event.GameQuit // when the "Back to Menu" button is pressed ) ) + + gameScene.unload() } test("GameScene plays a sound when the player breaks a block") { @@ -150,8 +154,7 @@ class GameSceneTest extends FunSuite { gameScene.tick(tickContext) Thread.sleep(20) gameScene.tick(tickContext) - - println(gameScene.client.player.position) + Thread.sleep(2) // start listening for audio events val audioTracker = Tracker.withStorage[AudioSystem.Event] @@ -163,6 +166,8 @@ class GameSceneTest extends FunSuite { // the sound should have started playing assertEquals(audioTracker.events, Seq(AudioSystem.Event.StartedPlaying)) + + gameScene.unload() } test("GameScene plays a sound when the player places a block") { @@ -205,6 +210,7 @@ class GameSceneTest extends FunSuite { gameScene.tick(tickContext) Thread.sleep(20) gameScene.tick(tickContext) + Thread.sleep(2) // start listening for audio events val audioTracker = Tracker.withStorage[AudioSystem.Event] @@ -216,5 +222,7 @@ class GameSceneTest extends FunSuite { // the sound should have started playing assertEquals(audioTracker.events, Seq(AudioSystem.Event.StartedPlaying)) + + gameScene.unload() } } diff --git a/server/src/main/scala/hexacraft/server/GameServer.scala b/server/src/main/scala/hexacraft/server/GameServer.scala index 1501302a..6062b1a6 100644 --- a/server/src/main/scala/hexacraft/server/GameServer.scala +++ b/server/src/main/scala/hexacraft/server/GameServer.scala @@ -413,11 +413,6 @@ class GameServer(isOnline: Boolean, port: Int, worldProvider: WorldProvider, wor case GetWorldInfo => val info = worldProvider.getWorldInfo Some(info.toNBT) - case LoadChunkData(coords) => - world.getChunk(coords) match { - case Some(chunk) => Some(chunk.toNbt) - case None => Some(Nbt.emptyMap) // TODO: return None - } case LoadColumnData(coords) => world.getColumn(coords) match { case Some(column) => Some(ChunkColumnData(Some(column.terrainHeight)).toNBT) diff --git a/server/src/test/scala/hexacraft/world/ServerWorldTest.scala b/server/src/test/scala/hexacraft/world/ServerWorldTest.scala index aa991792..f8aff7f8 100644 --- a/server/src/test/scala/hexacraft/world/ServerWorldTest.scala +++ b/server/src/test/scala/hexacraft/world/ServerWorldTest.scala @@ -18,7 +18,7 @@ class ServerWorldTest extends FunSuite { val world = ServerWorld(provider, provider.getWorldInfo) val camera = new Camera(new CameraProjection(70, 1.6f, 0.01f, 1000f)) - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(), Seq()) val cCoords = ChunkRelWorld(3, 7, -4) @@ -72,9 +72,9 @@ class ServerWorldTest extends FunSuite { assert(world.getChunk(cCoords).isEmpty) // Run the game a bit - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(cCoords), Seq()) Thread.sleep(20) - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(), Seq()) // The chunk should be loaded assert(world.getChunk(cCoords).isDefined) @@ -92,9 +92,9 @@ class ServerWorldTest extends FunSuite { camera.setPosition(BlockCoords(BlockRelWorld(8, 8, 8, cCoords)).toCylCoords.toVector3d) // Run the game a bit - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(cCoords), Seq()) Thread.sleep(20) - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(), Seq()) // The chunk should be loaded assert(world.getChunk(cCoords).isDefined) @@ -103,9 +103,9 @@ class ServerWorldTest extends FunSuite { camera.setPosition(BlockCoords(BlockRelWorld(8, 8, 8, cCoords.offset(100, 0, 0))).toCylCoords.toVector3d) // Run the game a bit - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(), Seq(cCoords)) Thread.sleep(20) - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(), Seq()) // The chunk should be unloaded assert(world.getChunk(cCoords).isEmpty) @@ -123,9 +123,9 @@ class ServerWorldTest extends FunSuite { // Make sure the chunk is loaded camera.setPosition(entityPosition.toVector3d) - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(ChunkRelWorld(0, 0, 0)), Seq()) Thread.sleep(20) - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(), Seq()) val entity = Entity( UUID.randomUUID(), @@ -136,25 +136,25 @@ class ServerWorldTest extends FunSuite { world.addEntity(entity) val pos1 = entity.transform.position - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(), Seq()) val pos2 = entity.transform.position assertNotEquals(pos1, pos2) world.removeEntity(entity) - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(), Seq()) val pos3 = entity.transform.position assertEquals(pos2, pos3) world.addEntity(entity) - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(), Seq()) val pos4 = entity.transform.position assertNotEquals(pos3, pos4) world.removeAllEntities() - world.tick(Seq(camera)) + world.tick(Seq(camera), Seq(), Seq()) val pos5 = entity.transform.position assertEquals(pos4, pos5) }