Browse Source

Entity reflection and refraction

Tankernn 8 years ago
parent
commit
55abd0366d

+ 14 - 2
src/main/java/eu/tankernn/gameEngine/renderEngine/EntityRenderer.java

@@ -9,9 +9,11 @@ import org.lwjgl.opengl.GL20;
 import org.lwjgl.opengl.GL30;
 import org.lwjgl.util.vector.Matrix4f;
 
+import eu.tankernn.gameEngine.entities.Camera;
 import eu.tankernn.gameEngine.entities.Entity;
 import eu.tankernn.gameEngine.models.TexturedModel;
 import eu.tankernn.gameEngine.shaders.StaticShader;
+import eu.tankernn.gameEngine.skybox.CubeMap;
 import eu.tankernn.gameEngine.textures.ModelTexture;
 import eu.tankernn.gameEngine.util.Maths;
 /**
@@ -21,13 +23,16 @@ import eu.tankernn.gameEngine.util.Maths;
  */
 public class EntityRenderer {
 	private StaticShader shader;
+	private CubeMap environmentMap;
+	
 	/**
 	 * Starts shader and loads initial values.
 	 * @param shader The shader to use when rendering entities
 	 * @param projectionMatrix The projection matrix to use when rendering entities
 	 */
-	public EntityRenderer(StaticShader shader, Matrix4f projectionMatrix) {
+	public EntityRenderer(StaticShader shader, Matrix4f projectionMatrix, CubeMap environmentMap) {
 		this.shader = shader;
+		this.environmentMap = environmentMap;
 		shader.start();
 		shader.loadProjectionMatrix(projectionMatrix);
 		shader.connectTextureUnits();
@@ -41,8 +46,9 @@ public class EntityRenderer {
 	 * @param toShadowSpace Transformation matrix to shadow space. Used for
 	 *        applying shadows.
 	 */
-	public void render(Map<TexturedModel, List<Entity>> entities, Matrix4f toShadowSpace) {
+	public void render(Map<TexturedModel, List<Entity>> entities, Matrix4f toShadowSpace, Camera cam) {
 		shader.loadToShadowSpaceMatrix(toShadowSpace);
+		shader.loadCameraPosition(cam.getPosition());
 		for (TexturedModel model: entities.keySet()) {
 			prepareTexturedModel(model);
 			List<Entity> batch = entities.get(model);
@@ -72,6 +78,12 @@ public class EntityRenderer {
 			GL13.glActiveTexture(GL13.GL_TEXTURE1);
 			GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture.getSpecularMap());
 		}
+		bindEnvironmentMap();
+	}
+	
+	private void bindEnvironmentMap() {
+		GL13.glActiveTexture(GL13.GL_TEXTURE10);
+		GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, environmentMap.getTexture());
 	}
 	
 	private void unbindTexturedModel() {

+ 7 - 0
src/main/java/eu/tankernn/gameEngine/renderEngine/Loader.java

@@ -99,6 +99,13 @@ public class Loader {
 		return new RawModel(vaoID, positions.length / 2);
 	}
 	
+	public RawModel loadToVAO(float[] positions) {
+		int vaoID = createVAO();
+		this.storeDataInAttributeList(0, 3, positions);
+		unbindVAO();
+		return new RawModel(vaoID, positions.length / 3);
+	}
+	
 	public RawModel loadToVAO(ModelData data) {
 		return loadToVAO(data.getVertices(), data.getTextureCoords(), data.getNormals(), data.getIndices());
 	}

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

@@ -28,6 +28,7 @@ import eu.tankernn.gameEngine.normalMapping.renderer.NormalMappingRenderer;
 import eu.tankernn.gameEngine.shaders.StaticShader;
 import eu.tankernn.gameEngine.shaders.TerrainShader;
 import eu.tankernn.gameEngine.shadows.ShadowMapMasterRenderer;
+import eu.tankernn.gameEngine.skybox.CubeMap;
 import eu.tankernn.gameEngine.skybox.SkyboxRenderer;
 import eu.tankernn.gameEngine.terrains.Terrain;
 
@@ -61,11 +62,11 @@ public class MasterRenderer {
 	public MasterRenderer(Loader loader, Camera camera) {
 		enableCulling();
 		createProjectionMatrix();
-		entityRenderer = new EntityRenderer(staticShader, projectionMatrix);
 		terrainRenderer = new TerrainRenderer(terrainShader, projectionMatrix);
 		skyboxRenderer = new SkyboxRenderer(loader, projectionMatrix);
 		normalMapRenderer = new NormalMappingRenderer(projectionMatrix);
 		shadowMapRenderer = new ShadowMapMasterRenderer(camera);
+		entityRenderer = new EntityRenderer(staticShader, projectionMatrix, skyboxRenderer.getCubeMap());
 	}
 	
 	/**
@@ -115,7 +116,7 @@ public class MasterRenderer {
 		staticShader.loadSkyColor(RED, GREEN, BLUE);
 		staticShader.loadLights(lights);
 		staticShader.loadViewMatrix(camera);
-		entityRenderer.render(entities, shadowMapRenderer.getToShadowMapSpaceMatrix());
+		entityRenderer.render(entities, shadowMapRenderer.getToShadowMapSpaceMatrix(), camera);
 		staticShader.stop();
 		
 		normalMapRenderer.render(normalMapEntities, clipPlane, lights, camera);

+ 9 - 0
src/main/java/eu/tankernn/gameEngine/shaders/StaticShader.java

@@ -37,6 +37,8 @@ public class StaticShader extends ShaderProgram {
 	private int location_specularMap;
 	private int location_usesSpecularMap;
 	private int location_modelTexture;
+	private int location_cameraPosition;
+	private int location_enviroMap;
 	
 	public StaticShader() {
 		super(VERTEX_FILE, FRAGMENT_FILE);
@@ -67,6 +69,8 @@ public class StaticShader extends ShaderProgram {
 		location_specularMap = super.getUniformLocation("specularMap");
 		location_usesSpecularMap = super.getUniformLocation("usesSpecularMap");
 		location_modelTexture = super.getUniformLocation("modelTexture");
+		location_cameraPosition = super.getUniformLocation("cameraPosition");
+		location_enviroMap = super.getUniformLocation("enviroMap");
 		
 		location_lightPosition = new int[MAX_LIGHTS];
 		location_lightColor = new int[MAX_LIGHTS];
@@ -82,6 +86,7 @@ public class StaticShader extends ShaderProgram {
 		super.loadInt(location_shadowMap, 5);
 		super.loadInt(location_modelTexture, 0);
 		super.loadInt(location_specularMap, 1);
+		super.loadInt(location_enviroMap, 10);
 	}
 	
 	public void loadUseSpecularMap(boolean useSpecularMap) {
@@ -125,6 +130,10 @@ public class StaticShader extends ShaderProgram {
 		super.loadMatrix(location_transformationMatrix, matrix);
 	}
 	
+	public void loadCameraPosition(Vector3f vector) {
+		super.loadVector(location_cameraPosition, vector);
+	}
+	
 	public void loadLights(List<Light> lights) {
 		for (int i = 0; i < MAX_LIGHTS; i++) {
 			if (i < lights.size()) {

+ 7 - 0
src/main/java/eu/tankernn/gameEngine/shaders/fragmentShader.glsl

@@ -6,6 +6,8 @@ in vec3 toLightVector[4]; //4 max light sources
 in vec3 toCameraVector;
 in float visibility;
 in vec4 shadowCoords;
+in vec3 reflectedVector;
+in vec3 refractedVector;
 
 layout (location = 0) out vec4 out_Color;
 layout (location = 1) out vec4 out_BrightColor;
@@ -13,6 +15,7 @@ layout (location = 1) out vec4 out_BrightColor;
 uniform sampler2D shadowMap;
 uniform sampler2D textureSampler;
 uniform sampler2D specularMap;
+uniform samplerCube enviroMap;
 uniform float usesSpecularMap;
 uniform vec3 lightColor[4]; //4 max light sources
 uniform vec3 attenuation[4];
@@ -75,5 +78,9 @@ void main(void){
 	out_Color = vec4(totalDiffuse, 1.0) * textureColor + vec4(totalSpecular, 1.0);
 	out_Color = mix(vec4(skyColor, 1.0), out_Color, visibility);
 	
+	vec4 reflectedColor = texture(enviroMap, reflectedVector);
+	vec4 refractedColor = texture(enviroMap, refractedVector);
+	vec4 enviroColor = mix(reflectedColor, refractedColor, 0.5);
 	
+	out_Color = mix(out_Color, enviroColor, 0.3);
 }

+ 9 - 0
src/main/java/eu/tankernn/gameEngine/shaders/vertexShader.glsl

@@ -10,6 +10,8 @@ out vec3 toLightVector[4]; //4 max light sources
 out vec3 toCameraVector;
 out float visibility;
 out vec4 shadowCoords;
+out vec3 reflectedVector;
+out vec3 refractedVector;
 
 uniform mat4 transformationMatrix;
 uniform mat4 projectionMatrix;
@@ -24,6 +26,8 @@ uniform vec2 offset;
 uniform mat4 toShadowMapSpace;
 uniform float shadowDistance;
 
+uniform vec3 cameraPosition;
+
 const float density = 0.004;
 const float gradient = 2.0;
 
@@ -48,6 +52,11 @@ void main(void) {
 		toLightVector[i] = lightPosition[i] - worldPosition.xyz;
 	}
 	
+	vec3 unitNormal = normalize(normal);
+	vec3 viewVector = normalize(worldPosition.xyz - cameraPosition);
+	reflectedVector = reflect(viewVector, unitNormal);
+	refractedVector = refract(viewVector, unitNormal, 1.0/1.33);
+	
 	toCameraVector = (inverse(viewMatrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz;
 	
 	float distance = length(positionRelativeToCam.xyz);

+ 70 - 0
src/main/java/eu/tankernn/gameEngine/skybox/CubeMap.java

@@ -0,0 +1,70 @@
+package eu.tankernn.gameEngine.skybox;
+
+import eu.tankernn.gameEngine.models.RawModel;
+import eu.tankernn.gameEngine.renderEngine.Loader;
+
+public class CubeMap {
+	
+	private static final float SIZE = 500f;
+	
+	private static final float[] VERTICES = {        
+	    -SIZE,  SIZE, -SIZE,
+	    -SIZE, -SIZE, -SIZE,
+	    SIZE, -SIZE, -SIZE,
+	     SIZE, -SIZE, -SIZE,
+	     SIZE,  SIZE, -SIZE,
+	    -SIZE,  SIZE, -SIZE,
+
+	    -SIZE, -SIZE,  SIZE,
+	    -SIZE, -SIZE, -SIZE,
+	    -SIZE,  SIZE, -SIZE,
+	    -SIZE,  SIZE, -SIZE,
+	    -SIZE,  SIZE,  SIZE,
+	    -SIZE, -SIZE,  SIZE,
+
+	     SIZE, -SIZE, -SIZE,
+	     SIZE, -SIZE,  SIZE,
+	     SIZE,  SIZE,  SIZE,
+	     SIZE,  SIZE,  SIZE,
+	     SIZE,  SIZE, -SIZE,
+	     SIZE, -SIZE, -SIZE,
+
+	    -SIZE, -SIZE,  SIZE,
+	    -SIZE,  SIZE,  SIZE,
+	     SIZE,  SIZE,  SIZE,
+	     SIZE,  SIZE,  SIZE,
+	     SIZE, -SIZE,  SIZE,
+	    -SIZE, -SIZE,  SIZE,
+
+	    -SIZE,  SIZE, -SIZE,
+	     SIZE,  SIZE, -SIZE,
+	     SIZE,  SIZE,  SIZE,
+	     SIZE,  SIZE,  SIZE,
+	    -SIZE,  SIZE,  SIZE,
+	    -SIZE,  SIZE, -SIZE,
+
+	    -SIZE, -SIZE, -SIZE,
+	    -SIZE, -SIZE,  SIZE,
+	     SIZE, -SIZE, -SIZE,
+	     SIZE, -SIZE, -SIZE,
+	    -SIZE, -SIZE,  SIZE,
+	     SIZE, -SIZE,  SIZE
+	};
+	
+	private RawModel cube;
+	private int texture;
+	
+	public CubeMap(String[] textureFiles, String folder, Loader loader){
+		cube = loader.loadToVAO(VERTICES);
+		texture = loader.loadCubeMap(textureFiles, folder);
+	}
+	
+	public RawModel getCube(){
+		return cube;
+	}
+	
+	public int getTexture(){
+		return texture;
+	}
+
+}

+ 19 - 64
src/main/java/eu/tankernn/gameEngine/skybox/SkyboxRenderer.java

@@ -7,71 +7,22 @@ import org.lwjgl.opengl.GL30;
 import org.lwjgl.util.vector.Matrix4f;
 
 import eu.tankernn.gameEngine.entities.Camera;
-import eu.tankernn.gameEngine.models.RawModel;
 import eu.tankernn.gameEngine.renderEngine.DisplayManager;
 import eu.tankernn.gameEngine.renderEngine.Loader;
 
 public class SkyboxRenderer {
-	private static final float SIZE = 500f;
 	private static final int DAY_LENGTH = 24000;
 	
-	private static final float[] VERTICES = {
-			-SIZE, SIZE, -SIZE,
-			-SIZE, -SIZE, -SIZE,
-			SIZE, -SIZE, -SIZE,
-			SIZE, -SIZE, -SIZE,
-			SIZE, SIZE, -SIZE,
-			-SIZE, SIZE, -SIZE,
-			
-			-SIZE, -SIZE, SIZE,
-			-SIZE, -SIZE, -SIZE,
-			-SIZE, SIZE, -SIZE,
-			-SIZE, SIZE, -SIZE,
-			-SIZE, SIZE, SIZE,
-			-SIZE, -SIZE, SIZE,
-			
-			SIZE, -SIZE, -SIZE,
-			SIZE, -SIZE, SIZE,
-			SIZE, SIZE, SIZE,
-			SIZE, SIZE, SIZE,
-			SIZE, SIZE, -SIZE,
-			SIZE, -SIZE, -SIZE,
-			
-			-SIZE, -SIZE, SIZE,
-			-SIZE, SIZE, SIZE,
-			SIZE, SIZE, SIZE,
-			SIZE, SIZE, SIZE,
-			SIZE, -SIZE, SIZE,
-			-SIZE, -SIZE, SIZE,
-			
-			-SIZE, SIZE, -SIZE,
-			SIZE, SIZE, -SIZE,
-			SIZE, SIZE, SIZE,
-			SIZE, SIZE, SIZE,
-			-SIZE, SIZE, SIZE,
-			-SIZE, SIZE, -SIZE,
-			
-			-SIZE, -SIZE, -SIZE,
-			-SIZE, -SIZE, SIZE,
-			SIZE, -SIZE, -SIZE,
-			SIZE, -SIZE, -SIZE,
-			-SIZE, -SIZE, SIZE,
-			SIZE, -SIZE, SIZE
-	};
+	private static final String[] TEXTURE_FILES = {"alps_rt", "alps_lf", "alps_up", "alps_dn", "alps_bk", "alps_ft"};
+	private static final String[] NIGHT_TEXTURE_FILES = {"midnight_rt", "midnight_lf", "midnight_up", "midnight_dn", "midnight_bk", "midnight_ft"};
 	
-	private static String[] TEXTURE_FILES = {"alps_rt", "alps_lf", "alps_up", "alps_dn", "alps_bk", "alps_ft"};
-	private static String[] NIGHT_TEXTURE_FILES = {"midnight_rt", "midnight_lf", "midnight_up", "midnight_dn", "midnight_bk", "midnight_ft"};
-	
-	private RawModel cube;
-	private int texture;
-	private int nightTexture;
+	private CubeMap dayCube, nightCube;
 	private SkyboxShader shader;
 	private float time = 0;
 	
 	public SkyboxRenderer(Loader loader, Matrix4f projectionmatrix) {
-		cube = loader.loadToVAO(VERTICES, 3);
-		texture = loader.loadCubeMap(TEXTURE_FILES, "skybox/");
-		nightTexture = loader.loadCubeMap(NIGHT_TEXTURE_FILES, "skybox/");
+		dayCube = new CubeMap(TEXTURE_FILES, "skybox/", loader);
+		nightCube = new CubeMap(NIGHT_TEXTURE_FILES, "skybox/", loader);
 		shader = new SkyboxShader();
 		shader.start();
 		shader.connectTextureUnits();
@@ -83,10 +34,10 @@ public class SkyboxRenderer {
 		shader.start();
 		shader.loadViewMatrix(camera);
 		shader.loadFogColor(r, g, b);
-		GL30.glBindVertexArray(cube.getVaoID());
+		GL30.glBindVertexArray(dayCube.getCube().getVaoID());
 		GL20.glEnableVertexAttribArray(0);
 		bindTextures();
-		GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, cube.getVertexCount());
+		GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, dayCube.getCube().getVertexCount());
 		GL20.glDisableVertexAttribArray(0);
 		GL30.glBindVertexArray(0);
 		shader.stop();
@@ -104,20 +55,20 @@ public class SkyboxRenderer {
 		int texture2;
 		float blendFactor;
 		if (time >= 0 && time < morning) {
-			texture1 = nightTexture;
-			texture2 = nightTexture;
+			texture1 = nightCube.getTexture();
+			texture2 = nightCube.getTexture();
 			blendFactor = (time - 0) / (morning - 0);
 		} else if (time >= morning && time < noon) {
-			texture1 = nightTexture;
-			texture2 = texture;
+			texture1 = nightCube.getTexture();
+			texture2 = dayCube.getTexture();
 			blendFactor = (time - morning) / (noon - morning);
 		} else if (time >= noon && time < evening) {
-			texture1 = texture;
-			texture2 = texture;
+			texture1 = dayCube.getTexture();
+			texture2 = dayCube.getTexture();
 			blendFactor = (time - noon) / (evening - noon);
 		} else {
-			texture1 = texture;
-			texture2 = nightTexture;
+			texture1 = dayCube.getTexture();
+			texture2 = nightCube.getTexture();
 			blendFactor = (time - evening) / (DAY_LENGTH - evening);
 		}
 		
@@ -127,4 +78,8 @@ public class SkyboxRenderer {
 		GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, texture2);
 		shader.loadBlendFactor(blendFactor);
 	}
+	
+	public CubeMap getCubeMap() {
+		return dayCube;
+	}
 }