Browse Source

Small improvements

- Rotation is now a vector.
- Normal mapped renderer and shader now extend the corresponding entity
classes.
- Improved terrain handling.
- Method to convert array of filenames to InternalFile array.
Tankernn 8 years ago
parent
commit
49da4c7ab5
21 changed files with 142 additions and 149 deletions
  1. 15 24
      src/main/java/eu/tankernn/gameEngine/MainLoop.java
  2. 2 0
      src/main/java/eu/tankernn/gameEngine/TankernnGame.java
  3. 7 8
      src/main/java/eu/tankernn/gameEngine/entities/Car.java
  4. 9 35
      src/main/java/eu/tankernn/gameEngine/entities/Entity.java
  5. 9 7
      src/main/java/eu/tankernn/gameEngine/entities/Player.java
  6. 8 6
      src/main/java/eu/tankernn/gameEngine/entities/PlayerCamera.java
  7. 13 2
      src/main/java/eu/tankernn/gameEngine/loader/Loader.java
  8. 2 3
      src/main/java/eu/tankernn/gameEngine/loader/obj/OBJFileLoader.java
  9. 4 6
      src/main/java/eu/tankernn/gameEngine/loader/obj/normalMapped/NormalMappedObjLoader.java
  10. 4 3
      src/main/java/eu/tankernn/gameEngine/renderEngine/MasterRenderer.java
  11. 13 6
      src/main/java/eu/tankernn/gameEngine/renderEngine/entities/EntityRenderer.java
  12. 6 1
      src/main/java/eu/tankernn/gameEngine/renderEngine/entities/EntityShader.java
  13. 4 21
      src/main/java/eu/tankernn/gameEngine/renderEngine/entities/normalMap/NormalMappingRenderer.java
  14. 7 6
      src/main/java/eu/tankernn/gameEngine/renderEngine/entities/normalMap/NormalMappingShader.java
  15. 0 0
      src/main/java/eu/tankernn/gameEngine/renderEngine/entities/normalMap/normalMapFShader.glsl
  16. 0 0
      src/main/java/eu/tankernn/gameEngine/renderEngine/entities/normalMap/normalMapVShader.glsl
  17. 4 2
      src/main/java/eu/tankernn/gameEngine/renderEngine/shadows/ShadowMapEntityRenderer.java
  18. 1 1
      src/main/java/eu/tankernn/gameEngine/renderEngine/shadows/ShadowMapMasterRenderer.java
  19. 11 11
      src/main/java/eu/tankernn/gameEngine/renderEngine/skybox/Skybox.java
  20. 15 5
      src/main/java/eu/tankernn/gameEngine/terrains/TerrainPack.java
  21. 8 2
      src/main/java/eu/tankernn/gameEngine/util/InternalFile.java

+ 15 - 24
src/main/java/eu/tankernn/gameEngine/MainLoop.java

@@ -22,7 +22,6 @@ import eu.tankernn.gameEngine.font.meshCreator.FontType;
 import eu.tankernn.gameEngine.font.meshCreator.GUIText;
 import eu.tankernn.gameEngine.loader.Loader;
 import eu.tankernn.gameEngine.loader.models.TexturedModel;
-import eu.tankernn.gameEngine.loader.obj.ModelData;
 import eu.tankernn.gameEngine.loader.obj.OBJFileLoader;
 import eu.tankernn.gameEngine.loader.textures.ModelTexture;
 import eu.tankernn.gameEngine.loader.textures.TerrainTexturePack;
@@ -87,8 +86,7 @@ public class MainLoop {
 		TerrainPack terrainPack = new TerrainPack(loader, texturePack, blendMap, SEED);
 
 		// Player
-		ModelData playrModelData = OBJFileLoader.loadOBJ(new InternalFile("dragon.obj"));
-		RawModel playerModel = loader.loadToVAO(playrModelData);
+		RawModel playerModel = loader.loadOBJ(new InternalFile("dragon.obj"));
 		TexturedModel texturedMonkeyModel = new TexturedModel(playerModel,
 				new ModelTexture(loader.loadTexture("white.png")));
 
@@ -96,20 +94,15 @@ public class MainLoop {
 		texture.setReflectivity(3);
 		texture.setShineDamper(10);
 
-		Entity entity = new Entity(texturedMonkeyModel, new Vector3f(0, 0, 20), 0, 0, 0, 1);
+		Entity entity = new Entity(texturedMonkeyModel, new Vector3f(0, 0, 20), new Vector3f(0, 0, 0), 1);
 		entities.add(entity);
 		TexturedModel monkey = new TexturedModel(playerModel, new ModelTexture(loader.loadTexture("white.png")));
-		Player player = new Player(monkey, new Vector3f(10, 0, 50), 0, 0, 0, 1, terrainPack);
+		Player player = new Player(monkey, new Vector3f(10, 0, 50), new Vector3f(0, 0, 0), 1, terrainPack);
 		entities.add(player);
 		Camera camera = new PlayerCamera(player, terrainPack);
 
-		InternalFile[] dayTextures = new InternalFile[TEXTURE_FILES.length],
-				nightTextures = new InternalFile[NIGHT_TEXTURE_FILES.length];
-
-		for (int i = 0; i < TEXTURE_FILES.length; i++)
-			dayTextures[i] = new InternalFile("skybox/" + TEXTURE_FILES[i] + ".png");
-		for (int i = 0; i < NIGHT_TEXTURE_FILES.length; i++)
-			nightTextures[i] = new InternalFile("skybox/" + NIGHT_TEXTURE_FILES[i] + ".png");
+		InternalFile[] dayTextures = InternalFile.fromFilenames("skybox", TEXTURE_FILES, "png"),
+				nightTextures = InternalFile.fromFilenames("skybox", NIGHT_TEXTURE_FILES, "png");
 
 		Skybox skybox = new Skybox(Texture.newCubeMap(dayTextures, 500), Texture.newCubeMap(nightTextures, 500), 500);
 
@@ -119,15 +112,16 @@ public class MainLoop {
 
 		FontType font = new FontType(loader.loadTexture("arial.png"), "arial.fnt");
 		GUIText text = new GUIText("Sample text", 3, font, new Vector2f(0.5f, 0.5f), 0.5f, true).setColor(1, 1, 1);
+		TextMaster.loadText(text);
 
 		// Barrel
-		TexturedModel barrelModel = new TexturedModel(loader.loadOBJ(new InternalFile("barrel.obj")),
+		TexturedModel barrelModel = new TexturedModel(loader.loadNormalMappedOBJ(new InternalFile("barrel.obj")),
 				new ModelTexture(loader.loadTexture("barrel.png")));
 
 		barrelModel.getModelTexture().setNormalMap(loader.loadTexture("barrelNormal.png"))
 				.setSpecularMap(loader.loadTexture("barrelS.png")).setShineDamper(10).setReflectivity(0.5f);
 
-		Entity barrel = new Entity(barrelModel, new Vector3f(75, 10, 75), 0, 0, 0, 1f);
+		Entity barrel = new Entity(barrelModel, new Vector3f(75, 10, 75), new Vector3f(0, 0, 0), 1f);
 		normalMapEntities.add(barrel);
 
 		Light sun = new Light(new Vector3f(100000, 150000, -70000), new Vector3f(1f, 1f, 1f));
@@ -135,10 +129,6 @@ public class MainLoop {
 
 		lights.add(sun);
 		lights.add(flashLight);
-		lights.add(new Light(new Vector3f(10, 100, 0), new Vector3f(0, 1, 0)));
-		lights.add(new Light(new Vector3f(20, 100, 0), new Vector3f(0, 0, 1)));
-		lights.add(new Light(new Vector3f(30, 100, 0), new Vector3f(1, 0, 0)));
-		lights.add(new Light(new Vector3f(40, 100, 0), new Vector3f(1, 1, 0)));
 
 		terrainPack.update(player);
 
@@ -153,15 +143,17 @@ public class MainLoop {
 		grassModel.getModelTexture().setReflectivity(0.5f);
 		grassModel.getModelTexture().setSpecularMap(loader.loadTexture("lanternS.png"));
 
-		Random rand = new Random();
+		Random rand = new Random(SEED);
 
-		for (int i = 0; i < 1000; i++) {
+		for (int i = 0; i < 100; i++) {
 			float x = rand.nextFloat() * 1000;
 			float z = rand.nextFloat() * 1000;
 
 			entities.add(new Entity(grassModel, rand.nextInt(4),
-					new Vector3f(x, terrainPack.getTerrainHeightByWorldPos(x, z), z), 0, 0, 0, 1));
+					new Vector3f(x, terrainPack.getTerrainHeightByWorldPos(x, z), z), new Vector3f(), 1));
 		}
+		
+		terrainPack.addWaitingForTerrainHeight(entities.toArray(new Entity[entities.size()]));
 
 		// #### Water rendering ####
 		WaterMaster waterMaster = new WaterMaster(loader, DUDV_MAP, NORMAL_MAP, camera);
@@ -170,7 +162,6 @@ public class MainLoop {
 
 		// #### Gui rendering ####
 		List<GuiTexture> guis = new ArrayList<GuiTexture>();
-
 		GuiRenderer guiRenderer = new GuiRenderer(loader);
 
 		ParticleTexture particleTexture = new ParticleTexture(loader.loadTexture("particles/cosmic.png"), 4, true);
@@ -186,8 +177,8 @@ public class MainLoop {
 		MousePicker picker = new MousePicker(camera, camera.getProjectionMatrix(), terrainPack, entities, guis);
 
 		while (!Display.isCloseRequested()) {
-			barrel.increaseRotation(0, 1, 0);
-			player.move(terrainPack);
+			barrel.increaseRotation(new Vector3f(0, 1, 0));
+			player.move();
 			terrainPack.update(player);
 			camera.update();
 			picker.update();

+ 2 - 0
src/main/java/eu/tankernn/gameEngine/TankernnGame.java

@@ -12,8 +12,10 @@ public class TankernnGame {
 	protected MasterRenderer renderer;
 	protected WaterMaster waterMaster;
 	protected Camera camera;
+	protected Skybox sky;
 	
 	public TankernnGame(Skybox skybox, String dudvMap, String normalMap) {
+		this.sky = skybox;
 		loader = new Loader();
 		camera = new Camera();
 		renderer = new MasterRenderer(loader, camera, skybox);

+ 7 - 8
src/main/java/eu/tankernn/gameEngine/entities/Car.java

@@ -14,18 +14,17 @@ public class Car extends Player {
 	private static final float MAX_SPEED = 100.0f, ACCELERATION = 20.0f, DECELERATION = 10.0f, BRAKE = 40.0f,
 			TURN_FORCE = 160.0f;
 
-	public Car(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, float scale,
-			TerrainPack terrainPack) {
-		super(model, position, rotX, rotY, rotZ, scale, terrainPack);
+	public Car(TexturedModel model, Vector3f position, Vector3f rotation, float scale, TerrainPack terrainPack) {
+		super(model, position, rotation, scale, terrainPack);
 	}
 
 	@Override
-	public void move(TerrainPack terrainPack) {
+	public void move() {
 		checkInputs();
-		super.increaseRotation(0, currentTurnSpeed * DisplayManager.getFrameTimeSeconds(), 0);
+		super.increaseRotation(new Vector3f(0, currentTurnSpeed * DisplayManager.getFrameTimeSeconds(), 0));
 		float distance = currentSpeed * DisplayManager.getFrameTimeSeconds();
-		float dx = (float) (distance * Math.sin(Math.toRadians(super.getRotY())));
-		float dz = (float) (distance * Math.cos(Math.toRadians(super.getRotY())));
+		float dx = (float) (distance * Math.sin(Math.toRadians(super.getRotation().y)));
+		float dz = (float) (distance * Math.cos(Math.toRadians(super.getRotation().y)));
 		super.increasePosition(dx, 0, dz);
 
 		upwardsSpeed += Physics.GRAVITY * DisplayManager.getFrameTimeSeconds();
@@ -71,7 +70,7 @@ public class Car extends Player {
 					this.currentTurnSpeed = 0;
 			}
 		}
-		
+
 		this.currentTurnSpeed = Math.min(currentTurnSpeed, TURN_MAX);
 		this.currentTurnSpeed = Math.max(currentTurnSpeed, -TURN_MAX);
 

+ 9 - 35
src/main/java/eu/tankernn/gameEngine/entities/Entity.java

@@ -11,29 +11,25 @@ public class Entity implements IPositionable {
 	
 	private TexturedModel model;
 	private Vector3f position;
-	private float rotX, rotY, rotZ;
+	private Vector3f rotation;
 	private float scale;
 	private AABB boundingBox;
 	
 	private int textureIndex = 0;
 	
-	public Entity(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, float scale) {
+	public Entity(TexturedModel model, Vector3f position, Vector3f rotation, float scale) {
 		this.model = model;
 		this.position = position;
-		this.rotX = rotX;
-		this.rotY = rotY;
-		this.rotZ = rotZ;
+		this.rotation = rotation;
 		this.scale = scale;
 		this.boundingBox = new AABB(position, SIZE);
 	}
 	
-	public Entity(TexturedModel model, int index, Vector3f position, float rotX, float rotY, float rotZ, float scale) {
+	public Entity(TexturedModel model, int index, Vector3f position, Vector3f rotation, float scale) {
 		this.model = model;
 		this.textureIndex = index;
 		this.position = position;
-		this.rotX = rotX;
-		this.rotY = rotY;
-		this.rotZ = rotZ;
+		this.rotation = rotation;
 		this.scale = scale;
 		this.boundingBox = new AABB(position, SIZE);
 	}
@@ -55,10 +51,8 @@ public class Entity implements IPositionable {
 		updateBoundingBox();
 	}
 	
-	public void increaseRotation(float dx, float dy, float dz) {
-		this.rotX += dx;
-		this.rotY += dy;
-		this.rotZ += dz;
+	public void increaseRotation(Vector3f deltaRotation) {
+		Vector3f.add(this.rotation, deltaRotation, this.rotation);
 	}
 	
 	private void updateBoundingBox() {
@@ -81,28 +75,8 @@ public class Entity implements IPositionable {
 		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 Vector3f getRotation() {
+		return rotation;
 	}
 	
 	public float getScale() {

+ 9 - 7
src/main/java/eu/tankernn/gameEngine/entities/Player.java

@@ -16,7 +16,7 @@ public class Player extends Entity {
 	protected static final float TURN_MAX = 160;
 	private static final float JUMP_POWER = 30;
 	
-	private TerrainPack terrainPack;
+	protected TerrainPack terrainPack;
 	
 	protected float currentSpeed = 0;
 	protected float currentTurnSpeed = 0;
@@ -25,17 +25,17 @@ public class Player extends Entity {
 	
 	private float height = 2.0f;
 	
-	public Player(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, float scale, TerrainPack terrainPack) {
-		super(model, position, rotX, rotY, rotZ, scale);
+	public Player(TexturedModel model, Vector3f position, Vector3f rotation, float scale, TerrainPack terrainPack) {
+		super(model, position, rotation, scale);
 		this.terrainPack = terrainPack;
 	}
 	
-	public void move(TerrainPack terrainPack) {
+	public void move() {
 		checkInputs();
-		super.increaseRotation(0, currentTurnSpeed * DisplayManager.getFrameTimeSeconds(), 0);
+		super.increaseRotation(new Vector3f(0, currentTurnSpeed * DisplayManager.getFrameTimeSeconds(), 0));
 		float distance = currentSpeed * DisplayManager.getFrameTimeSeconds();
-		float dx = (float) (distance * Math.sin(Math.toRadians(super.getRotY())));
-		float dz = (float) (distance * Math.cos(Math.toRadians(super.getRotY())));
+		float dx = (float) (distance * Math.sin(Math.toRadians(super.getRotation().y)));
+		float dz = (float) (distance * Math.cos(Math.toRadians(super.getRotation().y)));
 		super.increasePosition(dx, 0, dz);
 		upwardsSpeed += Physics.GRAVITY * DisplayManager.getFrameTimeSeconds();
 		super.increasePosition(0, upwardsSpeed * DisplayManager.getFrameTimeSeconds(), 0);
@@ -51,6 +51,8 @@ public class Player extends Entity {
 			upwardsSpeed = 0;
 			this.isInAir = false;
 			super.getPosition().y = terrainHeight;
+		} else {
+			this.isInAir = true;
 		}
 	}
 	

+ 8 - 6
src/main/java/eu/tankernn/gameEngine/entities/PlayerCamera.java

@@ -6,6 +6,7 @@ import org.lwjgl.LWJGLException;
 import org.lwjgl.input.Cursor;
 import org.lwjgl.input.Keyboard;
 import org.lwjgl.input.Mouse;
+import org.lwjgl.util.vector.Vector3f;
 
 import eu.tankernn.gameEngine.terrains.TerrainPack;
 
@@ -30,11 +31,12 @@ public class PlayerCamera extends Camera {
 	 */
 	@Override
 	public void update() {
+		Vector3f rot = player.getRotation();
 		calculateZoom();
 		if (Mouse.isButtonDown(0) || Mouse.isButtonDown(1)) {
 			if (!this.isLocked) { // Happens first frame mouse held down
 				this.isLocked = true;
-				this.lockedPosition = player.getRotY();
+				this.lockedPosition = rot.y;
 			}
 			hideCursor();
 			
@@ -43,13 +45,13 @@ public class PlayerCamera extends Camera {
 			
 			if (Mouse.isButtonDown(1)) { // Right click
 				float targetRot = this.angleAroundPlayer + this.lockedPosition;
-				float delta = targetRot - player.getRotY();
-				player.increaseRotation(0, delta, 0);
+				float delta = targetRot - rot.y;
+				player.increaseRotation(new Vector3f(0, delta, 0));
 			}
 		} else {
 			if (this.isLocked) {
 				this.isLocked = false;
-				this.angleAroundPlayer -= (player.getRotY() - lockedPosition);
+				this.angleAroundPlayer -= (rot.y - lockedPosition);
 			}
 			showCursor();
 		}
@@ -65,7 +67,7 @@ public class PlayerCamera extends Camera {
 		if (this.isLocked) {
 			this.yaw = 180 - (lockedPosition + angleAroundPlayer);
 		} else
-			this.yaw = 180 - (player.getRotY() + angleAroundPlayer);
+			this.yaw = 180 - (rot.y + angleAroundPlayer);
 		
 		super.update();
 	}
@@ -102,7 +104,7 @@ public class PlayerCamera extends Camera {
 		if (this.isLocked)
 			theta = lockedPosition + angleAroundPlayer;
 		else
-			theta = player.getRotY() + angleAroundPlayer;
+			theta = player.getRotation().y + angleAroundPlayer;
 		float offsetX = (float) (horizDistance * Math.sin(Math.toRadians(theta)));
 		float offsetZ = (float) (horizDistance * Math.cos(Math.toRadians(theta)));
 		position.x = player.getPosition().x - offsetX;

+ 13 - 2
src/main/java/eu/tankernn/gameEngine/loader/Loader.java

@@ -12,6 +12,8 @@ import org.lwjgl.opengl.GL30;
 import org.lwjgl.opengl.GL33;
 
 import eu.tankernn.gameEngine.loader.obj.ModelData;
+import eu.tankernn.gameEngine.loader.obj.OBJFileLoader;
+import eu.tankernn.gameEngine.loader.obj.normalMapped.ModelDataNM;
 import eu.tankernn.gameEngine.loader.obj.normalMapped.NormalMappedObjLoader;
 import eu.tankernn.gameEngine.loader.textures.Texture;
 import eu.tankernn.gameEngine.renderEngine.RawModel;
@@ -94,6 +96,11 @@ public class Loader {
 	public RawModel loadToVAO(ModelData data) {
 		return (RawModel) loadToVAO(data.getVertices(), data.getTextureCoords(), data.getNormals(), data.getIndices());
 	}
+	
+	public RawModel loadToVAO(ModelDataNM data) {
+		return (RawModel) loadToVAO(data.getVertices(), data.getTextureCoords(), data.getNormals(), data.getTangents(), data.getIndices());
+	}
+	
 	/**
 	 * Loads a texture to the GPU.
 	 * @param filename The path, relative to the root of the jar file, of the file to load.
@@ -162,8 +169,12 @@ public class Loader {
 		buffer.flip();
 		return buffer;
 	}
-
+	
 	public RawModel loadOBJ(InternalFile objFile) {
-		return NormalMappedObjLoader.loadOBJ(objFile, this);
+		return this.loadToVAO(OBJFileLoader.loadOBJ(objFile));
+	}
+	
+	public RawModel loadNormalMappedOBJ(InternalFile objFile) {
+		return this.loadToVAO(NormalMappedObjLoader.loadOBJ(objFile));
 	}
 }

+ 2 - 3
src/main/java/eu/tankernn/gameEngine/loader/obj/OBJFileLoader.java

@@ -1,7 +1,6 @@
 package eu.tankernn.gameEngine.loader.obj;
 
 import java.io.BufferedReader;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -13,11 +12,11 @@ import eu.tankernn.gameEngine.util.InternalFile;
 
 public class OBJFileLoader {
 	
-	public static ModelData loadOBJ(InternalFile objFile) throws FileNotFoundException {
+	public static ModelData loadOBJ(InternalFile objFile) {
 		BufferedReader reader;
 		try {
 			reader = objFile.getReader();
-		} catch (Exception e1) {
+		} catch (IOException e1) {
 			e1.printStackTrace();
 			return null;
 		}

+ 4 - 6
src/main/java/eu/tankernn/gameEngine/loader/obj/normalMapped/NormalMappedObjLoader.java

@@ -8,13 +8,11 @@ import java.util.List;
 import org.lwjgl.util.vector.Vector2f;
 import org.lwjgl.util.vector.Vector3f;
 
-import eu.tankernn.gameEngine.loader.Loader;
-import eu.tankernn.gameEngine.renderEngine.RawModel;
 import eu.tankernn.gameEngine.util.InternalFile;
 
 public class NormalMappedObjLoader {
 
-	public static RawModel loadOBJ(InternalFile objFile, Loader loader) {
+	public static ModelDataNM loadOBJ(InternalFile objFile) {
 		BufferedReader reader;
 		try {
 			reader = objFile.getReader();
@@ -73,11 +71,11 @@ public class NormalMappedObjLoader {
 		float[] texturesArray = new float[vertices.size() * 2];
 		float[] normalsArray = new float[vertices.size() * 3];
 		float[] tangentsArray = new float[vertices.size() * 3];
-		/*float furthest = */convertDataToArrays(vertices, textures, normals, verticesArray,
+		float furthest = convertDataToArrays(vertices, textures, normals, verticesArray,
 				texturesArray, normalsArray, tangentsArray);
 		int[] indicesArray = convertIndicesListToArray(indices);
-
-		return loader.loadToVAO(verticesArray, texturesArray, normalsArray, tangentsArray, indicesArray);
+		
+		return new ModelDataNM(verticesArray, texturesArray, normalsArray, tangentsArray, indicesArray, furthest);
 	}
 
 	//NEW 

+ 4 - 3
src/main/java/eu/tankernn/gameEngine/renderEngine/MasterRenderer.java

@@ -21,7 +21,8 @@ import eu.tankernn.gameEngine.loader.Loader;
 import eu.tankernn.gameEngine.loader.models.TexturedModel;
 import eu.tankernn.gameEngine.loader.textures.Texture;
 import eu.tankernn.gameEngine.renderEngine.entities.EntityRenderer;
-import eu.tankernn.gameEngine.renderEngine.normalMap.NormalMappingRenderer;
+import eu.tankernn.gameEngine.renderEngine.entities.EntityShader;
+import eu.tankernn.gameEngine.renderEngine.entities.normalMap.NormalMappingRenderer;
 import eu.tankernn.gameEngine.renderEngine.shadows.ShadowMapMasterRenderer;
 import eu.tankernn.gameEngine.renderEngine.skybox.Skybox;
 import eu.tankernn.gameEngine.renderEngine.skybox.SkyboxRenderer;
@@ -37,7 +38,7 @@ import eu.tankernn.gameEngine.util.ICamera;
 public class MasterRenderer {
 	private static final Vector4f NO_CLIP = new Vector4f(0, 0, 0, 1);
 	
-	private EntityRenderer entityRenderer;
+	private EntityRenderer<EntityShader> entityRenderer;
 	private TerrainRenderer terrainRenderer;
 	private SkyboxRenderer skyboxRenderer;
 	private NormalMappingRenderer normalMapRenderer;
@@ -61,7 +62,7 @@ public class MasterRenderer {
 		normalMapRenderer = new NormalMappingRenderer(camera.getProjectionMatrix());
 		shadowMapRenderer = new ShadowMapMasterRenderer(camera);
 		skyboxRenderer = new SkyboxRenderer(loader, camera.getProjectionMatrix(), skybox);
-		entityRenderer = new EntityRenderer(camera.getProjectionMatrix());
+		entityRenderer = new EntityRenderer<EntityShader>(camera.getProjectionMatrix());
 	}
 
 	/**

+ 13 - 6
src/main/java/eu/tankernn/gameEngine/renderEngine/entities/EntityRenderer.java

@@ -9,6 +9,7 @@ import java.util.Map;
 
 import org.lwjgl.opengl.GL11;
 import org.lwjgl.util.vector.Matrix4f;
+import org.lwjgl.util.vector.Vector3f;
 import org.lwjgl.util.vector.Vector4f;
 
 import eu.tankernn.gameEngine.entities.Entity;
@@ -26,8 +27,8 @@ import eu.tankernn.gameEngine.util.Maths;
  * @author Frans
  *
  */
-public class EntityRenderer {
-	private EntityShader shader;
+public class EntityRenderer<S extends EntityShader> {
+	protected S shader;
 
 	/**
 	 * Starts shader and loads initial values.
@@ -37,8 +38,13 @@ public class EntityRenderer {
 	 * @param projectionMatrix
 	 *            The projection matrix to use when rendering entities
 	 */
+	@SuppressWarnings("unchecked")
 	public EntityRenderer(Matrix4f projectionMatrix) {
-		this.shader = new EntityShader();
+		this((S) new EntityShader(), projectionMatrix);
+	}
+	
+	protected EntityRenderer(S shader, Matrix4f projectionMatrix) {
+		this.shader = shader;
 		shader.start();
 		shader.projectionMatrix.loadMatrix(projectionMatrix);
 		shader.connectTextureUnits();
@@ -106,9 +112,10 @@ public class EntityRenderer {
 		model.getRawModel().unbind(0, 1, 2);
 	}
 
-	private void prepareInstance(Entity entity) {
-		Matrix4f transformationMatrix = Maths.createTransformationMatrix(entity.getPosition(), entity.getRotX(),
-				entity.getRotY(), entity.getRotZ(), entity.getScale());
+	protected void prepareInstance(Entity entity) {
+		Vector3f rot = entity.getRotation();
+		Matrix4f transformationMatrix = Maths.createTransformationMatrix(entity.getPosition(), rot.x, rot.y, rot.z,
+				entity.getScale());
 		shader.transformationMatrix.loadMatrix(transformationMatrix);
 		shader.offset.loadVec2(entity.getTextureXOffset(), entity.getTextureYOffset());
 	}

+ 6 - 1
src/main/java/eu/tankernn/gameEngine/renderEngine/entities/EntityShader.java

@@ -18,6 +18,7 @@ public class EntityShader extends ShaderProgram {
 	protected UniformMatrix transformationMatrix = new UniformMatrix("transformationMatrix");
 	protected UniformMatrix projectionMatrix = new UniformMatrix("projectionMatrix");
 	protected UniformViewMatrix viewMatrix = new UniformViewMatrix("viewMatrix");
+	
 	protected UniformFloat shineDamper = new UniformFloat("shineDamper");
 	protected UniformFloat reflectivity = new UniformFloat("reflectivity");
 	protected UniformBoolean useFakeLighting = new UniformBoolean("useFakeLighting");
@@ -41,7 +42,11 @@ public class EntityShader extends ShaderProgram {
 				usesSpecularMap, modelTexture, cameraPosition, enviroMap);
 	}
 
-	public void connectTextureUnits() {
+	public EntityShader(String vertexFile, String fragmentFile, String... string) {
+		super(vertexFile, fragmentFile, string);
+	}
+
+	protected void connectTextureUnits() {
 		shadowMap.loadTexUnit(5);
 		modelTexture.loadTexUnit(0);
 		specularMap.loadTexUnit(1);

+ 4 - 21
src/main/java/eu/tankernn/gameEngine/renderEngine/normalMap/NormalMappingRenderer.java → src/main/java/eu/tankernn/gameEngine/renderEngine/entities/normalMap/NormalMappingRenderer.java

@@ -1,4 +1,4 @@
-package eu.tankernn.gameEngine.renderEngine.normalMap;
+package eu.tankernn.gameEngine.renderEngine.entities.normalMap;
 
 import java.util.List;
 import java.util.Map;
@@ -13,20 +13,14 @@ import eu.tankernn.gameEngine.loader.models.TexturedModel;
 import eu.tankernn.gameEngine.loader.textures.ModelTexture;
 import eu.tankernn.gameEngine.renderEngine.MasterRenderer;
 import eu.tankernn.gameEngine.renderEngine.RawModel;
+import eu.tankernn.gameEngine.renderEngine.entities.EntityRenderer;
 import eu.tankernn.gameEngine.settings.Settings;
 import eu.tankernn.gameEngine.util.ICamera;
-import eu.tankernn.gameEngine.util.Maths;
 
-public class NormalMappingRenderer {
-
-	private NormalMappingShader shader;
+public class NormalMappingRenderer extends EntityRenderer<NormalMappingShader> {
 
 	public NormalMappingRenderer(Matrix4f projectionMatrix) {
-		this.shader = new NormalMappingShader();
-		shader.start();
-		shader.projectionMatrix.loadMatrix(projectionMatrix);
-		shader.connectTextureUnits();
-		shader.stop();
+		super(new NormalMappingShader(), projectionMatrix);
 	}
 
 	public void render(Map<TexturedModel, List<Entity>> entities, Vector4f clipPlane, List<Light> lights,
@@ -45,10 +39,6 @@ public class NormalMappingRenderer {
 		shader.stop();
 	}
 
-	public void cleanUp() {
-		shader.cleanUp();
-	}
-
 	private void prepareTexturedModel(TexturedModel model) {
 		RawModel rawModel = model.getRawModel();
 		rawModel.bind(0, 1, 2, 3);
@@ -72,13 +62,6 @@ public class NormalMappingRenderer {
 		model.getRawModel().unbind(0, 1, 2, 3);
 	}
 
-	private void prepareInstance(Entity entity) {
-		Matrix4f transformationMatrix = Maths.createTransformationMatrix(entity.getPosition(), entity.getRotX(),
-				entity.getRotY(), entity.getRotZ(), entity.getScale());
-		shader.transformationMatrix.loadMatrix(transformationMatrix);
-		shader.offset.loadVec2(entity.getTextureXOffset(), entity.getTextureYOffset());
-	}
-
 	private void prepare(Vector4f clipPlane, List<Light> lights, ICamera camera) {
 		shader.plane.loadVec4(clipPlane);
 		// need to be public variables in MasterRenderer

+ 7 - 6
src/main/java/eu/tankernn/gameEngine/renderEngine/normalMap/NormalMappingShader.java → src/main/java/eu/tankernn/gameEngine/renderEngine/entities/normalMap/NormalMappingShader.java

@@ -1,4 +1,4 @@
-package eu.tankernn.gameEngine.renderEngine.normalMap;
+package eu.tankernn.gameEngine.renderEngine.entities.normalMap;
 
 import java.util.List;
 
@@ -7,7 +7,7 @@ import org.lwjgl.util.vector.Vector3f;
 import org.lwjgl.util.vector.Vector4f;
 
 import eu.tankernn.gameEngine.entities.Light;
-import eu.tankernn.gameEngine.renderEngine.shaders.ShaderProgram;
+import eu.tankernn.gameEngine.renderEngine.entities.EntityShader;
 import eu.tankernn.gameEngine.renderEngine.shaders.UniformBoolean;
 import eu.tankernn.gameEngine.renderEngine.shaders.UniformFloat;
 import eu.tankernn.gameEngine.renderEngine.shaders.UniformMatrix;
@@ -15,15 +15,16 @@ import eu.tankernn.gameEngine.renderEngine.shaders.UniformSampler;
 import eu.tankernn.gameEngine.renderEngine.shaders.UniformVec2;
 import eu.tankernn.gameEngine.renderEngine.shaders.UniformVec3;
 import eu.tankernn.gameEngine.renderEngine.shaders.UniformVec4;
+import eu.tankernn.gameEngine.renderEngine.shaders.UniformViewMatrix;
 
-public class NormalMappingShader extends ShaderProgram {
+public class NormalMappingShader extends EntityShader {
 
-	private static final String VERTEX_FILE = "/eu/tankernn/gameEngine/renderEngine/normalMap/normalMapVShader.glsl";
-	private static final String FRAGMENT_FILE = "/eu/tankernn/gameEngine/renderEngine/normalMap/normalMapFShader.glsl";
+	private static final String VERTEX_FILE = "/eu/tankernn/gameEngine/renderEngine/entities/normalMap/normalMapVShader.glsl";
+	private static final String FRAGMENT_FILE = "/eu/tankernn/gameEngine/renderEngine/entities/normalMap/normalMapFShader.glsl";
 
 	protected UniformMatrix transformationMatrix = new UniformMatrix("transformationMatrix");
 	protected UniformMatrix projectionMatrix = new UniformMatrix("projectionMatrix");
-	protected UniformMatrix viewMatrix = new UniformMatrix("viewMatrix");
+	protected UniformViewMatrix viewMatrix = new UniformViewMatrix("viewMatrix");
 	private UniformVec3[] lightPositionEyeSpace;
 	protected UniformFloat shineDamper = new UniformFloat("shineDamper");
 	protected UniformFloat reflectivity = new UniformFloat("reflectivity");

+ 0 - 0
src/main/java/eu/tankernn/gameEngine/renderEngine/normalMap/normalMapFShader.glsl → src/main/java/eu/tankernn/gameEngine/renderEngine/entities/normalMap/normalMapFShader.glsl


+ 0 - 0
src/main/java/eu/tankernn/gameEngine/renderEngine/normalMap/normalMapVShader.glsl → src/main/java/eu/tankernn/gameEngine/renderEngine/entities/normalMap/normalMapVShader.glsl


+ 4 - 2
src/main/java/eu/tankernn/gameEngine/renderEngine/shadows/ShadowMapEntityRenderer.java

@@ -7,6 +7,7 @@ import org.lwjgl.opengl.GL11;
 import org.lwjgl.opengl.GL20;
 import org.lwjgl.opengl.GL30;
 import org.lwjgl.util.vector.Matrix4f;
+import org.lwjgl.util.vector.Vector3f;
 
 import eu.tankernn.gameEngine.entities.Entity;
 import eu.tankernn.gameEngine.loader.models.TexturedModel;
@@ -82,8 +83,9 @@ public class ShadowMapEntityRenderer {
 	 *            - the entity to be prepared for rendering.
 	 */
 	private void prepareInstance(Entity entity) {
-		Matrix4f modelMatrix = Maths.createTransformationMatrix(entity.getPosition(), entity.getRotX(),
-				entity.getRotY(), entity.getRotZ(), entity.getScale());
+		Vector3f rot = entity.getRotation();
+		Matrix4f modelMatrix = Maths.createTransformationMatrix(entity.getPosition(), rot.x, rot.y, rot.z,
+				entity.getScale());
 		Matrix4f mvpMatrix = Matrix4f.mul(projectionViewMatrix, modelMatrix, null);
 		shader.mvpMatrix.loadMatrix(mvpMatrix);
 	}

+ 1 - 1
src/main/java/eu/tankernn/gameEngine/renderEngine/shadows/ShadowMapMasterRenderer.java

@@ -25,7 +25,7 @@ import eu.tankernn.gameEngine.loader.textures.Texture;
  */
 public class ShadowMapMasterRenderer {
 
-	public static final int SHADOW_MAP_SIZE = 4096;
+	public static final int SHADOW_MAP_SIZE = 1024 * 16;
 
 	private ShadowFrameBuffer shadowFbo;
 	private ShadowShader shader;

+ 11 - 11
src/main/java/eu/tankernn/gameEngine/renderEngine/skybox/Skybox.java

@@ -4,29 +4,29 @@ import eu.tankernn.gameEngine.loader.textures.Texture;
 import eu.tankernn.gameEngine.renderEngine.RawModel;
 
 public class Skybox {
-	
+
 	private RawModel cube;
 	private Texture dayTexture, nightTexture;
-	
-	public Skybox(Texture dayTexture, Texture nightTexture, float size){
+
+	public Skybox(Texture dayTexture, Texture nightTexture, float size) {
 		cube = CubeGenerator.generateCube(size);
 		this.dayTexture = dayTexture;
 		this.nightTexture = nightTexture;
 	}
-	
-	public RawModel getCubeVao(){
+
+	public RawModel getCubeVao() {
 		return cube;
 	}
-	
-	public Texture getDayTexture(){
+
+	public Texture getDayTexture() {
 		return dayTexture;
 	}
-	
-	public Texture getNightTexture(){
+
+	public Texture getNightTexture() {
 		return nightTexture;
 	}
-	
-	public void delete(){
+
+	public void delete() {
 		cube.delete();
 		dayTexture.delete();
 	}

+ 15 - 5
src/main/java/eu/tankernn/gameEngine/terrains/TerrainPack.java

@@ -3,6 +3,7 @@ package eu.tankernn.gameEngine.terrains;
 import static eu.tankernn.gameEngine.settings.Settings.TERRAIN_SIZE;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -23,6 +24,7 @@ import eu.tankernn.gameEngine.util.IPositionable;
 public class TerrainPack {
 	private Map<Pair<Integer, Integer>, Terrain> terrains = new HashMap<Pair<Integer, Integer>, Terrain>();
 	private List<Future<TerrainModelData>> waitingData = new ArrayList<Future<TerrainModelData>>();
+	private List<IPositionable> waitingForHeight = new ArrayList<IPositionable>();
 	private ExecutorService executor = Executors.newCachedThreadPool();
 	private int seed;
 	private Loader loader;
@@ -86,10 +88,6 @@ public class TerrainPack {
 		int newX = currentTerrain.getLeft();
 		int newZ = currentTerrain.getRight();
 
-		if (terrains.isEmpty()) {
-			terrains.put(Pair.of(newX, newZ), new Terrain(newX, newZ, loader, texturePack, blendMap, seed));
-		}
-
 		for (Future<TerrainModelData> futureData : waitingData) {
 			if (futureData.isDone()) {
 				System.out.println("Adding terrain.");
@@ -102,11 +100,19 @@ public class TerrainPack {
 				}
 			}
 		}
+		
+		waitingForHeight.removeIf(p -> {
+			if (!terrains.containsKey(getGridPosByWorldPos(p.getPosition().x, p.getPosition().z)))
+				return false;
+			p.getPosition().setY(getTerrainHeightByWorldPos(p.getPosition().x, p.getPosition().z));
+			return true;
+		});
+		
 		// FIXME If a task finishes between the loop above and this statement,
 		// the terrain will never be added.
 		waitingData.removeIf(f -> f.isDone());
 
-		if (lastX != newX || lastZ != newZ) {
+		if (lastX != newX || lastZ != newZ || terrains.isEmpty()) {
 			List<Pair<Integer, Integer>> toGenerate = new ArrayList<Pair<Integer, Integer>>();
 
 			for (int x = newX - 1; x <= newX + 1; x++)
@@ -146,4 +152,8 @@ public class TerrainPack {
 		executor.shutdown();
 	}
 
+	public void addWaitingForTerrainHeight(IPositionable... positionables) {
+		waitingForHeight.addAll(Arrays.asList(positionables));
+	}
+
 }

+ 8 - 2
src/main/java/eu/tankernn/gameEngine/util/InternalFile.java

@@ -4,8 +4,10 @@ import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.Arrays;
 
 public class InternalFile {
 
@@ -60,12 +62,12 @@ public class InternalFile {
 		return in;
 	}
 
-	public BufferedReader getReader() throws Exception {
+	public BufferedReader getReader() throws IOException {
 		try {
 			InputStreamReader isr = new InputStreamReader(getInputStream());
 			BufferedReader reader = new BufferedReader(isr);
 			return reader;
-		} catch (Exception e) {
+		} catch (IOException e) {
 			System.err.println("Couldn't get reader for " + path);
 			throw e;
 		}
@@ -74,5 +76,9 @@ public class InternalFile {
 	public String getName() {
 		return name;
 	}
+	
+	public static InternalFile[] fromFilenames(String dir, String[] filenames, String extension) {
+		return Arrays.asList(filenames).stream().map(f -> new InternalFile(dir + FILE_SEPARATOR + f + "." + extension)).toArray(size -> new InternalFile[size]);
+	}
 
 }