MasterRenderer.java 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. package eu.tankernn.gameEngine.renderEngine;
  2. import static eu.tankernn.gameEngine.settings.Settings.BLUE;
  3. import static eu.tankernn.gameEngine.settings.Settings.FAR_PLANE;
  4. import static eu.tankernn.gameEngine.settings.Settings.FOV;
  5. import static eu.tankernn.gameEngine.settings.Settings.GREEN;
  6. import static eu.tankernn.gameEngine.settings.Settings.NEAR_PLANE;
  7. import static eu.tankernn.gameEngine.settings.Settings.RED;
  8. import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
  9. import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
  10. import java.util.ArrayList;
  11. import java.util.HashMap;
  12. import java.util.List;
  13. import java.util.Map;
  14. import org.lwjgl.opengl.Display;
  15. import org.lwjgl.opengl.GL11;
  16. import org.lwjgl.opengl.GL13;
  17. import org.lwjgl.util.vector.Matrix4f;
  18. import org.lwjgl.util.vector.Vector4f;
  19. import eu.tankernn.gameEngine.entities.Camera;
  20. import eu.tankernn.gameEngine.entities.Entity;
  21. import eu.tankernn.gameEngine.entities.Light;
  22. import eu.tankernn.gameEngine.models.TexturedModel;
  23. import eu.tankernn.gameEngine.normalMapping.renderer.NormalMappingRenderer;
  24. import eu.tankernn.gameEngine.shaders.StaticShader;
  25. import eu.tankernn.gameEngine.shaders.TerrainShader;
  26. import eu.tankernn.gameEngine.shadows.ShadowMapMasterRenderer;
  27. import eu.tankernn.gameEngine.skybox.SkyboxRenderer;
  28. import eu.tankernn.gameEngine.terrains.Terrain;
  29. /**
  30. * Handles most of the rendering in the game.
  31. *
  32. * @author Frans
  33. */
  34. public class MasterRenderer {
  35. private StaticShader staticShader = new StaticShader();
  36. private TerrainShader terrainShader = new TerrainShader();
  37. private EntityRenderer entityRenderer;
  38. private TerrainRenderer terrainRenderer;
  39. private SkyboxRenderer skyboxRenderer;
  40. private NormalMappingRenderer normalMapRenderer;
  41. private ShadowMapMasterRenderer shadowMapRenderer;
  42. private Matrix4f projectionMatrix;
  43. private Map<TexturedModel, List<Entity>> entities = new HashMap<TexturedModel, List<Entity>>();
  44. private Map<TexturedModel, List<Entity>> normalMapEntities = new HashMap<TexturedModel, List<Entity>>();
  45. private List<Terrain> terrains = new ArrayList<Terrain>();
  46. /**
  47. * Sets up most other renderers for rendering.
  48. *
  49. * @param loader The main <code>Loader</code>, used by some other renderers
  50. * @param camera The main <code>Camera</code>
  51. */
  52. public MasterRenderer(Loader loader, Camera camera) {
  53. enableCulling();
  54. createProjectionMatrix();
  55. entityRenderer = new EntityRenderer(staticShader, projectionMatrix);
  56. terrainRenderer = new TerrainRenderer(terrainShader, projectionMatrix);
  57. skyboxRenderer = new SkyboxRenderer(loader, projectionMatrix);
  58. normalMapRenderer = new NormalMappingRenderer(projectionMatrix);
  59. shadowMapRenderer = new ShadowMapMasterRenderer(camera);
  60. }
  61. /**
  62. * Enables culling of faces facing away from the camera.
  63. */
  64. public static void enableCulling() {
  65. GL11.glEnable(GL11.GL_CULL_FACE);
  66. GL11.glCullFace(GL11.GL_BACK);
  67. }
  68. /**
  69. * Disables culling of faces facing away from the camera. Used when
  70. * rendering flat objects.
  71. */
  72. public static void disableCulling() {
  73. GL11.glDisable(GL11.GL_CULL_FACE);
  74. }
  75. /**
  76. * Renders a scene.
  77. *
  78. * @param scene The <code>Scene</code> to render.
  79. * @param clipPlane The clip plane.
  80. */
  81. public void renderScene(Scene scene, Vector4f clipPlane) {
  82. scene.getTerrainPack().prepareRenderTerrains(this);
  83. for (Entity e: scene.getEntities()) {
  84. processEntity(e);
  85. }
  86. for (Entity e: scene.getNormalEntities()) {
  87. processNormalMappedEntity(e);
  88. }
  89. render(scene.getLights(), scene.getCamera(), clipPlane);
  90. }
  91. /**
  92. * Renders the current scene to the current buffer.
  93. *
  94. * @param lights List of lights in the scene.
  95. * @param camera The main camera.
  96. * @param clipPlane The clip plane.
  97. */
  98. public void render(List<Light> lights, Camera camera, Vector4f clipPlane) {
  99. prepare();
  100. staticShader.start();
  101. staticShader.loadClipPlane(clipPlane);
  102. staticShader.loadSkyColor(RED, GREEN, BLUE);
  103. staticShader.loadLights(lights);
  104. staticShader.loadViewMatrix(camera);
  105. entityRenderer.render(entities, shadowMapRenderer.getToShadowMapSpaceMatrix());
  106. staticShader.stop();
  107. normalMapRenderer.render(normalMapEntities, clipPlane, lights, camera);
  108. terrainShader.start();
  109. terrainShader.loadClipPlane(clipPlane);
  110. terrainShader.loadSkyColor(RED, GREEN, BLUE);
  111. terrainShader.loadShadowMapSize(ShadowMapMasterRenderer.SHADOW_MAP_SIZE);
  112. terrainShader.loadLights(lights);
  113. terrainShader.loadViewMatrix(camera);
  114. terrainRenderer.render(terrains, shadowMapRenderer.getToShadowMapSpaceMatrix());
  115. terrainShader.stop();
  116. skyboxRenderer.render(camera, RED, GREEN, BLUE);
  117. entities.clear();
  118. terrains.clear();
  119. normalMapEntities.clear();
  120. }
  121. /**
  122. * Adds an entity to the list of entities.
  123. *
  124. * @param entity Entity to add to the list
  125. */
  126. public void processEntity(Entity entity) {
  127. TexturedModel entityModel = entity.getModel();
  128. List<Entity> batch = entities.get(entityModel);
  129. if (batch != null) {
  130. batch.add(entity);
  131. } else {
  132. List<Entity> newBatch = new ArrayList<Entity>();
  133. newBatch.add(entity);
  134. entities.put(entityModel, newBatch);
  135. }
  136. }
  137. /**
  138. * Same as {@link #processEntity(Entity)}, but for normal-mapped entities.
  139. *
  140. * @param entity Entity to add to the list
  141. */
  142. public void processNormalMappedEntity(Entity entity) {
  143. TexturedModel entityModel = entity.getModel();
  144. List<Entity> batch = normalMapEntities.get(entityModel);
  145. if (batch != null) {
  146. batch.add(entity);
  147. } else {
  148. List<Entity> newBatch = new ArrayList<Entity>();
  149. newBatch.add(entity);
  150. normalMapEntities.put(entityModel, newBatch);
  151. }
  152. }
  153. /**
  154. * Adds specified terrain to the terrain list.
  155. *
  156. * @param terrain Terrain object to add to list
  157. */
  158. public void processTerrain(Terrain terrain) {
  159. terrains.add(terrain);
  160. }
  161. public void renderShadowMap(List<Entity> entityList, Light sun) {
  162. for (Entity e: entityList) {
  163. processEntity(e);
  164. }
  165. shadowMapRenderer.render(entities, sun);
  166. entities.clear();
  167. }
  168. /**
  169. * Gets the shadow map texture from the <code>shadowMapRenderer</code>.
  170. *
  171. * @return
  172. */
  173. public int getShadowMapTexture() {
  174. return shadowMapRenderer.getShadowMap();
  175. }
  176. /**
  177. * Runs the cleanup method for the other renderers.
  178. */
  179. public void cleanUp() {
  180. staticShader.cleanUp();
  181. terrainShader.cleanUp();
  182. normalMapRenderer.cleanUp();
  183. shadowMapRenderer.cleanUp();
  184. }
  185. /**
  186. * Prepares the current buffer for rendering.
  187. */
  188. public void prepare() {
  189. GL11.glEnable(GL11.GL_DEPTH_TEST | GL11.GL_DEPTH_BUFFER_BIT);
  190. GL11.glClearColor(RED, GREEN, BLUE, 1);
  191. GL11.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
  192. GL13.glActiveTexture(GL13.GL_TEXTURE5);
  193. GL11.glBindTexture(GL11.GL_TEXTURE_2D, getShadowMapTexture());
  194. }
  195. private void createProjectionMatrix() {
  196. float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
  197. float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))));
  198. float x_scale = y_scale / aspectRatio;
  199. float frustum_length = FAR_PLANE - NEAR_PLANE;
  200. projectionMatrix = new Matrix4f();
  201. projectionMatrix.m00 = x_scale;
  202. projectionMatrix.m11 = y_scale;
  203. projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length);
  204. projectionMatrix.m23 = -1;
  205. projectionMatrix.m32 = -((2 * FAR_PLANE * NEAR_PLANE) / frustum_length);
  206. projectionMatrix.m33 = 0;
  207. }
  208. /**
  209. * Gets the current projection matrix.
  210. * @return The current projection matrix
  211. */
  212. public Matrix4f getProjectionMatrix() {
  213. return projectionMatrix;
  214. }
  215. }