Add support for tilesets

This commit is contained in:
2021-01-30 19:49:00 +01:00
parent fab70ddc86
commit 18aeb06c4e
8 changed files with 112 additions and 50 deletions

View File

@@ -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);
}
}

View File

@@ -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())

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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
};
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,5 @@
package com.bartlomiejpluta.samplegame.game.tile;
public interface TileSetManager {
TileSet createTileSet(String tileSetFileName);
}