package tk.captainsplexx.Render; import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; import static org.lwjgl.opengl.GL11.GL_LINE_STRIP; import static org.lwjgl.opengl.GL11.GL_MODELVIEW; import static org.lwjgl.opengl.GL11.glBegin; import static org.lwjgl.opengl.GL11.glClear; import static org.lwjgl.opengl.GL11.glClearColor; import static org.lwjgl.opengl.GL11.glColor3f; import static org.lwjgl.opengl.GL11.glEnable; import static org.lwjgl.opengl.GL11.glEnd; import static org.lwjgl.opengl.GL11.glLoadIdentity; import static org.lwjgl.opengl.GL11.glMatrixMode; import static org.lwjgl.opengl.GL11.glVertex3f; import java.util.ArrayList; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import org.lwjgl.util.vector.Matrix4f; import org.lwjgl.util.vector.Vector3f; import tk.captainsplexx.Camera.FPCameraController; import tk.captainsplexx.Entity.Entity; import tk.captainsplexx.Entity.EntityTextureData; import tk.captainsplexx.Entity.Entity.Type; import tk.captainsplexx.Entity.ObjectEntity; import tk.captainsplexx.Entity.Layer.EntityLayer; import tk.captainsplexx.Game.Core; import tk.captainsplexx.Game.Game; import tk.captainsplexx.Game.Point; import tk.captainsplexx.Maths.Matrices; import tk.captainsplexx.Model.RawModel; import tk.captainsplexx.Model.TexturedModel; import tk.captainsplexx.Player.PlayerEntity; import tk.captainsplexx.Render.Gui.GuiRenderer; import tk.captainsplexx.Shader.StaticShader; import tk.captainsplexx.Terrain.Terrain; import tk.captainsplexx.Terrain.TerrainShader; public class Render { public Game game; FPCameraController camera; PlayerEntity pe; public Matrix4f viewMatrix; public Matrix4f projectionMatrix; public Matrix4f transformationMatrix; GuiRenderer guiRenderer; int renderCalls = 0; public static Matrix4f identityMatrix = new Matrix4f(); public Render(Game game) { this.game = game; guiRenderer = new GuiRenderer(game.getModelHandler().getLoader()); pe = game.getPlayerHandler().getPlayerEntity(); camera = new FPCameraController(pe); updateProjectionMatrix(Core.FOV, Core.DISPLAY_WIDTH, Core.DISPLAY_HEIGHT, Core.zNear, Core.zFar); glMatrixMode(GL_MODELVIEW); glEnable(GL_DEPTH_TEST); } public void drawAxisAlignedBoundingBox(Vector3f minCoords, Vector3f maxCoords) { glColor3f(0.7f, 0.0f, 0.0f); // Bottom glBegin(GL11.GL_LINE_STRIP); glVertex3f(minCoords.x, minCoords.y, minCoords.z); glVertex3f(maxCoords.x, minCoords.y, minCoords.z); glEnd(); glBegin(GL11.GL_LINE_STRIP); glVertex3f(maxCoords.x, minCoords.y, minCoords.z); glVertex3f(maxCoords.x, minCoords.y, maxCoords.z); glEnd(); glBegin(GL11.GL_LINE_STRIP); glVertex3f(maxCoords.x, minCoords.y, maxCoords.z); glVertex3f(minCoords.x, minCoords.y, maxCoords.z); glEnd(); glBegin(GL11.GL_LINE_STRIP); glVertex3f(minCoords.x, minCoords.y, maxCoords.z); glVertex3f(minCoords.x, minCoords.y, minCoords.z); glEnd(); // Top glBegin(GL11.GL_LINE_STRIP); glVertex3f(minCoords.x, maxCoords.y, minCoords.z); glVertex3f(maxCoords.x, maxCoords.y, minCoords.z); glEnd(); glBegin(GL11.GL_LINE_STRIP); glVertex3f(maxCoords.x, maxCoords.y, minCoords.z); glVertex3f(maxCoords.x, maxCoords.y, maxCoords.z); glEnd(); glBegin(GL11.GL_LINE_STRIP); glVertex3f(maxCoords.x, maxCoords.y, maxCoords.z); glVertex3f(minCoords.x, maxCoords.y, maxCoords.z); glEnd(); glBegin(GL11.GL_LINE_STRIP); glVertex3f(minCoords.x, maxCoords.y, maxCoords.z); glVertex3f(minCoords.x, maxCoords.y, minCoords.z); glEnd(); // Connection Lines glBegin(GL11.GL_LINE_STRIP); glVertex3f(minCoords.x, minCoords.y, minCoords.z); glVertex3f(minCoords.x, maxCoords.y, minCoords.z); glEnd(); glBegin(GL11.GL_LINE_STRIP); glVertex3f(maxCoords.x, minCoords.y, minCoords.z); glVertex3f(maxCoords.x, maxCoords.y, minCoords.z); glEnd(); glBegin(GL11.GL_LINE_STRIP); glVertex3f(maxCoords.x, minCoords.y, maxCoords.z); glVertex3f(maxCoords.x, maxCoords.y, maxCoords.z); glEnd(); glBegin(GL11.GL_LINE_STRIP); glVertex3f(minCoords.x, minCoords.y, maxCoords.z); glVertex3f(minCoords.x, maxCoords.y, maxCoords.z); glEnd(); } public FPCameraController getCamera() { return camera; } public Matrix4f getProjectionMatrix() { return projectionMatrix; } public void update() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.4f, 0.4f, 0.4f, 1.0f); glLoadIdentity(); camera.lookThrough(); if (Display.isActive() && Mouse.isGrabbed()) { camera.dx = Mouse.getDX(); camera.dy = Mouse.getDY(); } camera.yaw(camera.dx * camera.mouseSensitivity); camera.pitch(-camera.dy * camera.mouseSensitivity); viewMatrix = Matrices.createViewMatrix(camera.getPosition(), new Vector3f(camera.getPitch(), camera.getYaw(), 0.0f)); StaticShader shader = game.getShaderHandler().getStaticShader(); shader.start(); shader.loadProjectionMatrix(projectionMatrix); shader.loadViewMatrix(viewMatrix); renderCalls = 0; RenderEntityLayers(game.getEntityHandler().getLayers(), identityMatrix, shader); //System.out.println("RenderCalls: "+renderCalls); shader.stop(); RenderTerrains(game.getShaderHandler().getTerrainShader()); guiRenderer.update(game.getGuis()); Display.update(); if (Display.wasResized()) { updateProjectionMatrix(Core.FOV, Display.getWidth(), Display.getHeight(), Core.zNear, Core.zFar); } Display.sync(Core.DISPLAY_RATE); //Display.setVSyncEnabled(true); } public void RenderEntityLayers(ArrayList<EntityLayer> layers, Matrix4f identityMatrix, StaticShader shader){ for (EntityLayer layer : layers){ RenderEntities(layer.getEntities(), identityMatrix, shader, false); } } public void RenderEntity(Entity e, Matrix4f parentMtx, StaticShader shader, boolean recalcChilds){ if (e.isVisible) { Matrix4f stackMtx = null; if (e.isRecalculateAbs() || recalcChilds || e.getAbsMatrix()==null){ e.recalculateAbsMatrix(parentMtx); e.setRecalculateAbs(false); recalcChilds = true; } stackMtx = e.getAbsMatrix(); if (e.isShowBoundingBox()) { shader.loadTransformationMatrix(Matrices .createTransformationMatrix( e.getPosition(), new Vector3f(0f, 0f, 0f), e.getScaling()) ); drawAxisAlignedBoundingBox(e.getMinCoords(), e.getMaxCoords()); } if (e.getHighlighted()) { shader.loadHighlighted(true); } shader.loadHeighlightedColor(e.getHeighlightedColor()); RawModel[] rawModels = e.getRawModels(); shader.loadTransformationMatrix(stackMtx); if (rawModels!=null){ int[] diffuseTextures = null; if (e.getType()==Type.Object){ ObjectEntity objEntity = (ObjectEntity) e; EntityTextureData etd = objEntity.getTextureData(); if (etd!=null){ if (etd.getMeshGUID().getInstanceGUID().equalsIgnoreCase("003c1de501eed2fab93fc29b19850e89")){ //System.out.println("Y"); } if (etd.getDiffuseIDs()!=null){ diffuseTextures = etd.getDiffuseIDs(); } } } for (int i = 0; i < rawModels.length; i++) { RawModel raw = rawModels[i]; glColor3f(0.25f, 0.25f, 0.25f); GL30.glBindVertexArray(raw.vaoID); GL20.glEnableVertexAttribArray(0); GL20.glEnableVertexAttribArray(1); GL13.glActiveTexture(GL13.GL_TEXTURE0); if (diffuseTextures!=null&&(i<diffuseTextures.length)){ GL11.glBindTexture(GL11.GL_TEXTURE_2D, diffuseTextures[i]); }else{ GL11.glBindTexture(GL11.GL_TEXTURE_2D, game.getModelHandler().getLoader().getNotFoundID()); } GL11.glDrawElements(raw.drawMethod, raw.vertexCount, GL11.GL_UNSIGNED_INT, 0); GL20.glDisableVertexAttribArray(0); GL20.glDisableVertexAttribArray(1); GL30.glBindVertexArray(0); } } renderCalls++; RenderEntities(e.getChildrens(), stackMtx, shader, recalcChilds); shader.loadHighlighted(false); } } public void RenderEntities(ArrayList<Entity> entities, Matrix4f parentMtx, StaticShader shader, boolean recalcChilds){ for (Entity e : entities) { RenderEntity(e, parentMtx, shader, recalcChilds); } } public void RenderTerrains(TerrainShader terrainShader){ terrainShader.start(); terrainShader.loadProjectionMatrix(projectionMatrix); terrainShader.loadViewMatrix(viewMatrix); Matrix4f TerrainransformationMatrix = Matrices .createTransformationMatrix( new Vector3f(0.0f, 0.0f, 0.0f), new Vector3f(0.0f, 0.0f, 0.0f), new Vector3f(1.0f, 1.0f, 1.0f) ); for (Terrain curTerr : game.getTerrainHandler().getTerrainList()) { Point[][] points = curTerr.getPoints(); terrainShader.loadTransformationMatrix(TerrainransformationMatrix); for (int i1 = 0; i1 < points.length - 1; i1++) { glBegin(GL_LINE_STRIP); for (int i2 = 0; i2 < points[i1].length - 1; i2++) { glVertex3f(points[i1 + 1][i2].x, points[i1 + 1][i2].y, points[i1 + 1][i2].z); glVertex3f(points[i1][i2 + 1].x, points[i1][i2 + 1].y, points[i1][i2 + 1].z); } glEnd(); } } terrainShader.stop(); } public void updateProjectionMatrix(float FOV, int DISPLAY_WIDTH, int DISPLAY_HEIGHT, float zNear, float zFar) { System.out.println("Projection Matrix gets an update!"); Core.FOV = FOV; Core.DISPLAY_WIDTH = DISPLAY_WIDTH; Core.DISPLAY_HEIGHT = DISPLAY_HEIGHT; Core.zNear = zNear; Core.zFar = zFar; this.projectionMatrix = Matrices.createProjectionMatrix(Core.FOV, Core.DISPLAY_WIDTH, Core.DISPLAY_HEIGHT, Core.zNear, Core.zFar); } public GuiRenderer getGuiRenderer() { return guiRenderer; } }