diff --git a/app/src/main/java/com/bartlomiejpluta/samplegame/core/gl/object/texture/Texture.java b/app/src/main/java/com/bartlomiejpluta/samplegame/core/gl/object/texture/Texture.java index b0f1d049..f6a06d27 100755 --- a/app/src/main/java/com/bartlomiejpluta/samplegame/core/gl/object/texture/Texture.java +++ b/app/src/main/java/com/bartlomiejpluta/samplegame/core/gl/object/texture/Texture.java @@ -1,26 +1,27 @@ package com.bartlomiejpluta.samplegame.core.gl.object.texture; import com.bartlomiejpluta.samplegame.core.error.AppException; -import org.lwjgl.BufferUtils; +import lombok.Getter; import org.lwjgl.system.MemoryStack; -import org.lwjgl.system.MemoryUtil; -import java.io.IOException; import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL13.GL_TEXTURE0; import static org.lwjgl.opengl.GL13.glActiveTexture; import static org.lwjgl.opengl.GL30.glGenerateMipmap; -import static org.lwjgl.stb.STBImage.*; +import static org.lwjgl.stb.STBImage.stbi_failure_reason; +import static org.lwjgl.stb.STBImage.stbi_load_from_memory; public class Texture { private static final int DESIRED_CHANNELS = 4; private final int textureId; + + @Getter private final int width; + + @Getter private final int height; Texture(String textureFilename, ByteBuffer buffer) { @@ -42,7 +43,9 @@ public class Texture { glBindTexture(GL_TEXTURE_2D, textureId); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - glGenerateMipmap(GL_TEXTURE_2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } diff --git a/app/src/main/java/com/bartlomiejpluta/samplegame/core/util/res/ResourcesManager.java b/app/src/main/java/com/bartlomiejpluta/samplegame/core/util/res/ResourcesManager.java index 57f32d28..211905fc 100755 --- a/app/src/main/java/com/bartlomiejpluta/samplegame/core/util/res/ResourcesManager.java +++ b/app/src/main/java/com/bartlomiejpluta/samplegame/core/util/res/ResourcesManager.java @@ -23,7 +23,7 @@ public class ResourcesManager { public ByteBuffer loadResourceAsByteBuffer(String fileName) { try { - var bytes = Texture.class.getResourceAsStream(fileName).readAllBytes(); + var bytes = ResourcesManager.class.getResourceAsStream(fileName).readAllBytes(); return ByteBuffer .allocateDirect(bytes.length) .order(ByteOrder.nativeOrder()) diff --git a/app/src/main/java/com/bartlomiejpluta/samplegame/game/logic/DefaultGameLogic.java b/app/src/main/java/com/bartlomiejpluta/samplegame/game/logic/DefaultGameLogic.java index 6d3c4374..66138230 100755 --- a/app/src/main/java/com/bartlomiejpluta/samplegame/game/logic/DefaultGameLogic.java +++ b/app/src/main/java/com/bartlomiejpluta/samplegame/game/logic/DefaultGameLogic.java @@ -1,13 +1,11 @@ package com.bartlomiejpluta.samplegame.game.logic; -import com.bartlomiejpluta.samplegame.core.gl.object.material.Material; -import com.bartlomiejpluta.samplegame.core.gl.object.texture.TextureManager; import com.bartlomiejpluta.samplegame.core.gl.render.Renderer; import com.bartlomiejpluta.samplegame.core.logic.GameLogic; import com.bartlomiejpluta.samplegame.core.ui.Window; import com.bartlomiejpluta.samplegame.core.world.camera.Camera; import com.bartlomiejpluta.samplegame.core.world.scene.Scene; -import com.bartlomiejpluta.samplegame.game.object.Sprite; +import com.bartlomiejpluta.samplegame.game.tile.TileSetManager; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -18,7 +16,7 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class DefaultGameLogic implements GameLogic { private final Renderer renderer; - private final TextureManager textureManager; + private final TileSetManager tileSetManager; private final Camera camera = new Camera(); private final Scene scene = new Scene(camera); @@ -27,13 +25,6 @@ public class DefaultGameLogic implements GameLogic { public void init(Window window) { log.info("Initializing game logic"); renderer.init(); - - var sprite = new Sprite(Material.textured(textureManager.loadTexture("/textures/grass.png"))); - var sprite2 = new Sprite(Material.colored(0.7f, 1.0f, 0.4f, 1.0f)); - sprite.setPosition(320, 240); - sprite2.setPosition(110, 110); - scene.add(sprite2); - scene.add(sprite); } @Override diff --git a/app/src/main/java/com/bartlomiejpluta/samplegame/game/object/Sprite.java b/app/src/main/java/com/bartlomiejpluta/samplegame/game/object/Sprite.java deleted file mode 100755 index 5bb242f0..00000000 --- a/app/src/main/java/com/bartlomiejpluta/samplegame/game/object/Sprite.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.bartlomiejpluta.samplegame.game.object; - -import com.bartlomiejpluta.samplegame.core.gl.object.material.Material; -import com.bartlomiejpluta.samplegame.core.gl.object.mesh.Mesh; -import com.bartlomiejpluta.samplegame.core.world.object.RenderableObject; - -public class Sprite extends RenderableObject { - private static final float[] VERTICES = new float[]{ - -100, 100, - -100, -100, - 100, -100, - 100, 100 - }; - - private static final float[] TEX_COORDS = new float[] { - 0, 0, - 0, 1, - 1, 1, - 1, 0 - }; - - private static final int[] ELEMENTS = new int[]{ - 0, 1, 2, - 2, 3, 0 - }; - - public Sprite(Material material) { - super(new Mesh(VERTICES, TEX_COORDS, ELEMENTS)); - setMaterial(material); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/DefaultTileSetManager.java b/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/DefaultTileSetManager.java new file mode 100755 index 00000000..694cbe61 --- /dev/null +++ b/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/DefaultTileSetManager.java @@ -0,0 +1,17 @@ +package com.bartlomiejpluta.samplegame.game.tile; + +import com.bartlomiejpluta.samplegame.core.gl.object.texture.TextureManager; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +public class DefaultTileSetManager implements TileSetManager { + private final TextureManager textureManager; + + @Override + public TileSet createTileSet(String tileSetFileName) { + return new TileSet(textureManager.loadTexture(tileSetFileName)); + } +} diff --git a/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/Tile.java b/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/Tile.java new file mode 100755 index 00000000..ad2ba1fc --- /dev/null +++ b/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/Tile.java @@ -0,0 +1,52 @@ +package com.bartlomiejpluta.samplegame.game.tile; + +import com.bartlomiejpluta.samplegame.core.gl.object.material.Material; +import com.bartlomiejpluta.samplegame.core.gl.object.mesh.Mesh; +import com.bartlomiejpluta.samplegame.core.gl.object.texture.Texture; +import com.bartlomiejpluta.samplegame.core.world.object.RenderableObject; +import lombok.Getter; + +@Getter +public class Tile extends RenderableObject { + private static final int[] ELEMENTS = new int[]{ + 0, 1, 2, + 2, 3, 0 + }; + + private final int row; + private final int col; + private final int size; + + Tile(Texture texture, int row, int col, int size) { + super(buildTileMesh(texture, row, col, size)); + this.row = row; + this.col = col; + this.size = size; + setMaterial(Material.textured(texture)); + } + + private static Mesh buildTileMesh(Texture texture, int row, int col, int size) { + var vertices = getVertices(size); + var texCoords = getTextureCoordinates(row, col, size, texture.getWidth(), texture.getHeight()); + return new Mesh(vertices, texCoords, ELEMENTS); + } + + private static float[] getVertices(int tileSize) { + var half = tileSize / 2; + return new float[]{ + -half, -half, + -half, half, + half, half, + half, -half + }; + } + + private static float[] getTextureCoordinates(int row, int col, int tileSize, int textureWidth, int textureHeight) { + return new float[]{ + (row * tileSize) / (float) textureWidth, (col * tileSize) / (float) textureHeight, + (row * tileSize) / (float) textureWidth, ((col + 1) * tileSize) / (float) textureHeight, + ((row + 1) * tileSize) / (float) textureWidth, ((col + 1) * tileSize) / (float) textureHeight, + ((row + 1) * tileSize) / (float) textureWidth, (col * tileSize) / (float) textureHeight + }; + } +} diff --git a/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/TileSet.java b/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/TileSet.java new file mode 100755 index 00000000..e0251797 --- /dev/null +++ b/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/TileSet.java @@ -0,0 +1,25 @@ +package com.bartlomiejpluta.samplegame.game.tile; + +import com.bartlomiejpluta.samplegame.core.gl.object.texture.Texture; + +public class TileSet { + private static final int TILE_SIZE = 16; + + private final Texture texture; + private final int rows; + private final int cols; + + public TileSet(Texture texture) { + this.texture = texture; + this.rows = texture.getHeight() / TILE_SIZE; + this.cols = texture.getWidth() / TILE_SIZE; + } + + public Tile getTile(int m, int n) { + return new Tile(texture, m, n, TILE_SIZE); + } + + public Tile getTile(int i) { + return new Tile(texture, i % cols, i / rows, TILE_SIZE); + } +} diff --git a/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/TileSetManager.java b/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/TileSetManager.java new file mode 100755 index 00000000..c8ce49d7 --- /dev/null +++ b/app/src/main/java/com/bartlomiejpluta/samplegame/game/tile/TileSetManager.java @@ -0,0 +1,5 @@ +package com.bartlomiejpluta.samplegame.game.tile; + +public interface TileSetManager { + TileSet createTileSet(String tileSetFileName); +}