Skip to content

Commit

Permalink
Improved grass texture and some other minor stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
Martomate committed Jul 31, 2024
1 parent 1eea34f commit 6e215af
Show file tree
Hide file tree
Showing 14 changed files with 52 additions and 83 deletions.
7 changes: 3 additions & 4 deletions client/src/main/resources/shaders/sky/frag.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Binary file modified client/src/main/resources/textures/blocks/grassSide.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion client/src/main/scala/hexacraft/client/GameClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
36 changes: 20 additions & 16 deletions client/src/main/scala/hexacraft/client/InventoryBox.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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 {
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion client/src/main/scala/hexacraft/text/TextMaster.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ class TextMaster {
textBatch -= text
if textBatch.isEmpty then {
texts -= text.font
// TODO: remove VAO
}
}

Expand All @@ -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()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 0 additions & 9 deletions game/src/main/scala/hexacraft/game/NetworkPacket.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ enum NetworkPacket {
case Logout

case GetWorldInfo
case LoadChunkData(coords: ChunkRelWorld)
case LoadColumnData(coords: ColumnRelWorld)
case LoadWorldData

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion game/src/main/scala/hexacraft/world/HexBox.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion game/src/main/scala/hexacraft/world/Player.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
1 change: 0 additions & 1 deletion game/src/main/scala/hexacraft/world/collision.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
22 changes: 3 additions & 19 deletions main/src/test/scala/hexacraft/RootArchTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
12 changes: 10 additions & 2 deletions main/src/test/scala/hexacraft/main/GameSceneTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down Expand Up @@ -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") {
Expand Down Expand Up @@ -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]
Expand All @@ -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") {
Expand Down Expand Up @@ -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]
Expand All @@ -216,5 +222,7 @@ class GameSceneTest extends FunSuite {

// the sound should have started playing
assertEquals(audioTracker.events, Seq(AudioSystem.Event.StartedPlaying))

gameScene.unload()
}
}
5 changes: 0 additions & 5 deletions server/src/main/scala/hexacraft/server/GameServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
26 changes: 13 additions & 13 deletions server/src/test/scala/hexacraft/world/ServerWorldTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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(),
Expand All @@ -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)
}
Expand Down

0 comments on commit 6e215af

Please sign in to comment.