diff --git a/client/res/hexagon.blend b/client/res/hexagon.blend new file mode 100644 index 0000000..52c3616 Binary files /dev/null and b/client/res/hexagon.blend differ diff --git a/client/res/white.png b/client/res/white.png new file mode 100644 index 0000000..3ab7683 Binary files /dev/null and b/client/res/white.png differ diff --git a/client/src/main/java/core/engine/Engine.java b/client/src/main/java/core/engine/Engine.java index 69e18bf..9a9ae45 100644 --- a/client/src/main/java/core/engine/Engine.java +++ b/client/src/main/java/core/engine/Engine.java @@ -3,6 +3,7 @@ package core.engine; import core.engine.entity.Camera; import core.engine.entity.Entity; import core.engine.entity.Light; +import core.engine.model.HexagonModel; import core.engine.model.RawModel; import core.engine.model.TexturedModel; import core.engine.renderer.MasterRenderer; @@ -118,24 +119,25 @@ public class Engine { glClearColor(1.0f, 0.0f, 0.0f, 0.0f); Camera camera = new Camera(); - input(camera); - Light light = new Light(new Vector3f(0,0,-20), new Vector3f(1,1,1)); - RawModel model = OBJLoader.loadOBJModel("dragon", loader); - ModelTexture modelTexture = new ModelTexture(loader.loadTexture("white")); - TexturedModel texturedModel = new TexturedModel(model, modelTexture); - Entity entity = new Entity(texturedModel, new Vector3f(0,0,-50), 0,0,0,1); //Generate Simple, Flat Terrain - Terrain terrain = new Terrain(0,0, loader, new ModelTexture(loader.loadTexture("grass"))); + Terrain terrain = new Terrain( loader, new ModelTexture(loader.loadTexture("white")), 16, 32, 7); + + //Create Hexagon + HexagonModel hexagonModel = new HexagonModel(); + RawModel hexagonRawModel = loader.loadHexagon(hexagonModel); + ModelTexture hexagonTexture = new ModelTexture(loader.loadTexture("white")); + TexturedModel hexagontexturedModel = new TexturedModel(hexagonRawModel, hexagonTexture); + Entity hexagonEntity = new Entity(hexagontexturedModel, new Vector3f(0,1,0), 0,0,0,1); // Run the rendering loop until the user has attempted to close // the window or has pressed the ESCAPE key. MasterRenderer renderer = new MasterRenderer(); + input(camera, renderer); while ( !glfwWindowShouldClose(window) ) { - //entity.increaseRotation(0,1,0); renderer.processTerrain(terrain); - //renderer.processEntity(entity); + //renderer.processEntity(hexagonEntity); renderer.render(light, camera); glfwSwapBuffers(window); // swap the color buffers // Poll for window events. The key callback above will only be @@ -146,7 +148,7 @@ public class Engine { loader.cleanUp(); } - private void input(Camera camera) { + private void input(Camera camera, MasterRenderer masterRenderer) { GLFWScrollCallback glfwScrollCallback = new GLFWScrollCallback() { @Override @@ -226,6 +228,10 @@ public class Engine { if(key == GLFW_KEY_S) { camera.moveBackward(); } + + if(key == GLFW_KEY_Y && action == GLFW_PRESS) { + masterRenderer.switchWireframe(); + } } }); diff --git a/client/src/main/java/core/engine/Loader.java b/client/src/main/java/core/engine/Loader.java index 143ed4c..50e3f21 100644 --- a/client/src/main/java/core/engine/Loader.java +++ b/client/src/main/java/core/engine/Loader.java @@ -1,5 +1,6 @@ package core.engine; +import core.engine.model.HexagonModel; import core.engine.model.RawModel; import core.engine.textures.Texture; import org.lwjgl.BufferUtils; @@ -29,6 +30,10 @@ public class Loader { return new RawModel(vaoID, indices.length); } + public RawModel loadHexagon(HexagonModel hexagonModel) { + return loadToVAO(hexagonModel.getVertices(), hexagonModel.getTextureCoords(), hexagonModel.getNormals(), hexagonModel.getIndices()); + } + public int loadTexture(String fileName) { Texture texture = new Texture("res/" + fileName + ".png"); int textureID = texture.getTextureID(); diff --git a/client/src/main/java/core/engine/entity/Camera.java b/client/src/main/java/core/engine/entity/Camera.java index 11b72f2..2399148 100644 --- a/client/src/main/java/core/engine/entity/Camera.java +++ b/client/src/main/java/core/engine/entity/Camera.java @@ -4,7 +4,7 @@ import utils.vectors.Vector3f; public class Camera { - private Vector3f position = new Vector3f(50,100,50); + private Vector3f position = new Vector3f(0,37,-1); private float pitch = 90; private float yaw = 180; private float roll; diff --git a/client/src/main/java/core/engine/model/HexagonModel.java b/client/src/main/java/core/engine/model/HexagonModel.java new file mode 100644 index 0000000..be17c65 --- /dev/null +++ b/client/src/main/java/core/engine/model/HexagonModel.java @@ -0,0 +1,88 @@ +package core.engine.model; + +import utils.vectors.Vector3f; +public class HexagonModel { + + private float[] vertices; + private float[] normals; + private float[] textureCoords; + private int[] indices; + + public HexagonModel() { + // Vertices (including the center) + vertices = new float[]{ + 0.0f, 0.0f, 0.0f, // Center + 0.0f, 0.0f, 1.0f, // Top Vertex + 0.866f, 0.0f, 0.5f, // Upper Right Vertex + 0.866f, 0.0f, -0.5f, // Lower Right Vertex + 0.0f, 0.0f, -1.0f, // Bottom Vertex + -0.866f, 0.0f, -0.5f, // Lower Left Vertex + -0.866f, 0.0f, 0.5f // Upper Left Vertex + }; + +// Normals + normals = new float[]{ + 0, 1, 0, // Center + 0, 1, 0, // Top Vertex + 0, 1, 0, // Upper Right Vertex + 0, 1, 0, // Lower Right Vertex + 0, 1, 0, // Bottom Vertex + 0, 1, 0, // Lower Left Vertex + 0, 1, 0 // Upper Left Vertex + }; + +// Texture Coordinates + textureCoords = new float[]{ + 0.5f, 0.5f, // Center + 0.5f, 0.0f, // Top Vertex + 1.0f, 0.25f, // Upper Right Vertex + 1.0f, 0.75f, // Lower Right Vertex + 0.5f, 1.0f, // Bottom Vertex + 0.0f, 0.75f, // Lower Left Vertex + 0.0f, 0.25f // Upper Left Vertex + }; + +// Indices + indices = new int[]{ + 0, 1, 2, // Center to Top Vertex to Upper Right Vertex + 0, 2, 3, // Center to Upper Right Vertex to Lower Right Vertex + 0, 3, 4, // Center to Lower Right Vertex to Bottom Vertex + 0, 4, 5, // Center to Bottom Vertex to Lower Left Vertex + 0, 5, 6, // Center to Lower Left Vertex to Upper Left Vertex + 0, 6, 1 // Center to Upper Left Vertex to Top Vertex + }; + + } + + public float[] getVertices() { + return vertices; + } + + public void setVertices(float[] vertices) { + this.vertices = vertices; + } + + public float[] getNormals() { + return normals; + } + + public void setNormals(float[] normals) { + this.normals = normals; + } + + public float[] getTextureCoords() { + return textureCoords; + } + + public void setTextureCoords(float[] textureCoords) { + this.textureCoords = textureCoords; + } + + public int[] getIndices() { + return indices; + } + + public void setIndices(int[] indices) { + this.indices = indices; + } +} diff --git a/client/src/main/java/core/engine/renderer/MasterRenderer.java b/client/src/main/java/core/engine/renderer/MasterRenderer.java index 849271e..c0080db 100644 --- a/client/src/main/java/core/engine/renderer/MasterRenderer.java +++ b/client/src/main/java/core/engine/renderer/MasterRenderer.java @@ -8,6 +8,7 @@ import core.engine.model.TexturedModel; import core.engine.shader.StaticShader; import core.engine.shader.TerrainShader; import core.engine.terrain.Terrain; +import core.engine.terrain.TerrainTile; import org.lwjgl.opengl.GL11; import utils.vectors.Matrix4f; @@ -27,9 +28,11 @@ public class MasterRenderer { private EntityRenderer renderer; private TerrainRenderer terrainRenderer; private Map> entities = new HashMap<>(); - private List terrains = new ArrayList<>(); + private List terrains = new ArrayList<>(); private Matrix4f projectionMatrix; + private boolean wireframe = false; + public MasterRenderer() { GL11.glEnable(GL11.GL_CULL_FACE); GL11.glCullFace(GL11.GL_BACK); @@ -62,7 +65,7 @@ public class MasterRenderer { } public void processTerrain(Terrain terrain) { - terrains.add(terrain); + terrains.addAll(terrain.getTerrainTiles()); } public void processEntity(Entity entity) { @@ -97,4 +100,14 @@ public class MasterRenderer { projectionMatrix.m33 = 0; } + + public void switchWireframe() { + this.wireframe = !this.wireframe; + + if(this.wireframe) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } else { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + } } diff --git a/client/src/main/java/core/engine/renderer/TerrainRenderer.java b/client/src/main/java/core/engine/renderer/TerrainRenderer.java index 688bf0d..4704a2e 100644 --- a/client/src/main/java/core/engine/renderer/TerrainRenderer.java +++ b/client/src/main/java/core/engine/renderer/TerrainRenderer.java @@ -5,6 +5,7 @@ import core.engine.model.RawModel; import core.engine.model.TexturedModel; import core.engine.shader.TerrainShader; import core.engine.terrain.Terrain; +import core.engine.terrain.TerrainTile; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL20; @@ -26,23 +27,24 @@ public class TerrainRenderer { shader.stop(); } - public void render(List terrains) { - for(Terrain terrain : terrains) { + public void render(List terrains) { + for(TerrainTile terrain : terrains) { prepareTerrain(terrain); loadModelMatrix(terrain); - GL11.glDrawElements(GL11.GL_TRIANGLES, terrain.getModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0); + GL11.glDrawElements(GL11.GL_TRIANGLES, terrain.getModel().getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0); unbindTexturedModel(); } } - private void prepareTerrain(Terrain model) { - RawModel rawModel = model.getModel(); + private void prepareTerrain(TerrainTile terrainTile) { + RawModel rawModel = terrainTile.getModel().getRawModel(); GL30.glBindVertexArray(rawModel.getVaoID()); GL20.glEnableVertexAttribArray(0); GL20.glEnableVertexAttribArray(1); GL20.glEnableVertexAttribArray(2); GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexture().getTextureID()); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, terrainTile.getModel().getModelTexture().getTextureID()); + shader.loadTerrainColor(terrainTile.getColor()); } private void unbindTexturedModel() { @@ -52,8 +54,9 @@ public class TerrainRenderer { GL30.glBindVertexArray(0); } - private void loadModelMatrix(Terrain terrain) { - Matrix4f transformationMatrix = MatrixGraphicUtils.createTransformationMatrix(new Vector3f(terrain.getX(), 0, terrain.getZ()), 0,0,0,1); + private void loadModelMatrix(TerrainTile terrain) { + Matrix4f transformationMatrix = MatrixGraphicUtils.createTransformationMatrix(terrain.getPosition(), terrain.getRotX(), + terrain.getRotY(), terrain.getRotZ(), terrain.getScale()); shader.loadTransformationMatrix(transformationMatrix); } } diff --git a/client/src/main/java/core/engine/shader/TerrainShader.java b/client/src/main/java/core/engine/shader/TerrainShader.java index 2c09a51..f62ec55 100644 --- a/client/src/main/java/core/engine/shader/TerrainShader.java +++ b/client/src/main/java/core/engine/shader/TerrainShader.java @@ -4,6 +4,7 @@ import core.engine.entity.Camera; import core.engine.entity.Light; import utils.MatrixGraphicUtils; import utils.vectors.Matrix4f; +import utils.vectors.Vector3f; public class TerrainShader extends ShaderProgram{ private static final String VERTEX_FILE = "src/main/java/core/engine/shader/terrainVertexShader.glsl"; @@ -14,6 +15,7 @@ public class TerrainShader extends ShaderProgram{ private int location_viewMatrix; private int location_lightPosition; private int location_lightColor; + private int location_terrainColor; public TerrainShader() { super(VERTEX_FILE, FRAGMENT_FILE); } @@ -25,6 +27,7 @@ public class TerrainShader extends ShaderProgram{ this.location_viewMatrix = super.getUniformLocation("viewMatrix"); this.location_lightColor = super.getUniformLocation("lightColor"); this.location_lightPosition = super.getUniformLocation("lightPosition"); + this.location_terrainColor = super.getUniformLocation("terrainColor"); } @Override @@ -51,4 +54,8 @@ public class TerrainShader extends ShaderProgram{ super.loadVector(location_lightPosition, light.getPosition()); super.loadVector(location_lightColor, light.getColor()); } + + public void loadTerrainColor(Vector3f color) { + super.loadVector(location_terrainColor, color); + } } diff --git a/client/src/main/java/core/engine/shader/terrainFragmentShader.glsl b/client/src/main/java/core/engine/shader/terrainFragmentShader.glsl index bd7f6d4..0a89847 100644 --- a/client/src/main/java/core/engine/shader/terrainFragmentShader.glsl +++ b/client/src/main/java/core/engine/shader/terrainFragmentShader.glsl @@ -8,6 +8,7 @@ out vec4 out_Color; uniform sampler2D textureSampler; uniform vec3 lightColor; +uniform vec3 terrainColor; void main(void) { vec3 unitNormal = normalize(surfaceNormal); @@ -17,5 +18,5 @@ void main(void) { float brightness = max(nDotl, 0.2); vec3 diffusde = brightness * lightColor; - out_Color = vec4(diffusde, 1.0) * texture(textureSampler, pass_textureCoords); + out_Color = /*vec4(diffusde, 1.0) **/ vec4(terrainColor, 1); } \ No newline at end of file diff --git a/client/src/main/java/core/engine/shader/terrainVertexShader.glsl b/client/src/main/java/core/engine/shader/terrainVertexShader.glsl index 36b0d54..6dfd1b2 100644 --- a/client/src/main/java/core/engine/shader/terrainVertexShader.glsl +++ b/client/src/main/java/core/engine/shader/terrainVertexShader.glsl @@ -17,7 +17,7 @@ out vec3 toLightVector; void main(void) { vec4 worldPosition = transformationMatrix * vec4(position, 1.0); gl_Position = projectionMatrix * viewMatrix * worldPosition; - pass_textureCoords = textureCoords * 40; + pass_textureCoords = textureCoords; surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz; toLightVector = lightPosition - worldPosition.xyz; diff --git a/client/src/main/java/core/engine/terrain/Terrain.java b/client/src/main/java/core/engine/terrain/Terrain.java index 54dbd29..2f369ef 100644 --- a/client/src/main/java/core/engine/terrain/Terrain.java +++ b/client/src/main/java/core/engine/terrain/Terrain.java @@ -1,78 +1,41 @@ package core.engine.terrain; import core.engine.Loader; +import core.engine.model.HexagonModel; import core.engine.model.RawModel; +import core.engine.model.TexturedModel; import core.engine.textures.ModelTexture; +import utils.vectors.Vector3f; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; public class Terrain { - private static final float WIDTH = 100; - private static final float DEPTH = 100; - private static final int VERTEX_COUNT = 128; + private List terrainTiles = new ArrayList<>(); - private float x; - private float z; - private RawModel model; - private ModelTexture texture; + public Terrain(Loader loader, ModelTexture modelTexture, int rows, int columns, int numberPlayers) { + TerrainGenerator terrainGenerator = new TerrainGenerator(); - public Terrain(int gridX, int gridZ, Loader loader, ModelTexture modelTexture) { - this.texture = modelTexture; - this.x = gridX * WIDTH; - this.z = gridZ * DEPTH; - this.model = generateTerrain(loader); - } + HexagonModel hexagonModel = new HexagonModel(); + RawModel rawModel = loader.loadHexagon(hexagonModel); + TexturedModel texturedModel = new TexturedModel(rawModel, modelTexture); + for(int row = 0; row < rows; row++) { + for(int column = 0; column < columns; column++) { + if(row % 2 == 1) { + terrainTiles.add(new TerrainTile(texturedModel, new Vector3f(column * 2* 0.866f, 0, row * 1.5f),0,0,0,1, row, column, terrainGenerator.generateColor(column, row))); + } else { + terrainTiles.add(new TerrainTile(texturedModel, new Vector3f(column *2 * 0.866f - 0.866f, 0, row * 1.5f),0,0,0,1, row, column, terrainGenerator.generateColor(column, row))); + } - private RawModel generateTerrain(Loader loader){ - int count = VERTEX_COUNT * VERTEX_COUNT; - float[] vertices = new float[count * 3]; - float[] normals = new float[count * 3]; - float[] textureCoords = new float[count*2]; - int[] indices = new int[6*(VERTEX_COUNT-1)*(VERTEX_COUNT-1)]; - int vertexPointer = 0; - for(int i=0;i getTerrainTiles() { + return terrainTiles; } } diff --git a/client/src/main/java/core/engine/terrain/TerrainGenerator.java b/client/src/main/java/core/engine/terrain/TerrainGenerator.java new file mode 100644 index 0000000..a1cf2d8 --- /dev/null +++ b/client/src/main/java/core/engine/terrain/TerrainGenerator.java @@ -0,0 +1,37 @@ +package core.engine.terrain; + +import utils.vectors.Vector3f; + +import java.util.Random; + +public class TerrainGenerator { + + private final Random random = new Random(); + private final int seed_red; + private final int seed_blue; + private final int seed_green; + + public TerrainGenerator() { + this.seed_red = random.nextInt(1000000000); + this.seed_blue = random.nextInt(1000000000); + this.seed_green = random.nextInt(1000000000); + } + + public Vector3f generateColor(int x, int z) { + return new Vector3f(getSmoothNoise(x, z, seed_red), getSmoothNoise(x, z, seed_green), getSmoothNoise(x, z, seed_blue)); + } + + private float getSmoothNoise(int x, int z, int seed) { + float corners = (getNoise(x -1, z-1, seed) + getNoise(x+1, z-1, seed) + + getNoise(x-1, z+1, seed) + getNoise(x+1, z+1, seed)) / 16f; + float sides = (getNoise(x-1, z, seed) + getNoise(x+1, z, seed) + + getNoise(x, z-1, seed) + getNoise(x, z+1, seed)) / 8f; + float center = getNoise(x, z, seed) / 4f; + return corners + sides + center; + } + + private float getNoise(int x, int z, int seed) { + random.setSeed(x * 49632L + z * 325176L + seed); + return random.nextFloat(); + } +} diff --git a/client/src/main/java/core/engine/terrain/TerrainTile.java b/client/src/main/java/core/engine/terrain/TerrainTile.java new file mode 100644 index 0000000..95a6fc5 --- /dev/null +++ b/client/src/main/java/core/engine/terrain/TerrainTile.java @@ -0,0 +1,87 @@ +package core.engine.terrain; + +import core.engine.Loader; +import core.engine.model.RawModel; +import core.engine.model.TexturedModel; +import core.engine.textures.ModelTexture; +import utils.vectors.Vector3f; + +public class TerrainTile { + + private TexturedModel model; + private Vector3f position; + private float rotX, rotY, rotZ; + private float scale; + private int row; + private int column; + + private Vector3f color; + + public TerrainTile(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, float scale, int row, int column, Vector3f color) { + this.model = model; + this.position = position; + this.rotX = rotX; + this.rotY = rotY; + this.rotZ = rotZ; + this.scale = scale; + this.row = row; + this.column = column; + this.color = color; + } + + public TexturedModel getModel() { + return model; + } + + public void setModel(TexturedModel model) { + this.model = model; + } + + public Vector3f getPosition() { + return position; + } + + public void setPosition(Vector3f position) { + this.position = position; + } + + public float getRotX() { + return rotX; + } + + public void setRotX(float rotX) { + this.rotX = rotX; + } + + public float getRotY() { + return rotY; + } + + public void setRotY(float rotY) { + this.rotY = rotY; + } + + public float getRotZ() { + return rotZ; + } + + public void setRotZ(float rotZ) { + this.rotZ = rotZ; + } + + public float getScale() { + return scale; + } + + public void setScale(float scale) { + this.scale = scale; + } + + public Vector3f getColor() { + return color; + } + + public void setColor(Vector3f color) { + this.color = color; + } +} \ No newline at end of file