package net.tylermurphy.Minecraft.Render; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import org.joml.Matrix4f; import org.joml.Vector3f; import net.tylermurphy.Minecraft.Chunk.Chunk; import net.tylermurphy.Minecraft.Render.Shaders.ChunkShader; import net.tylermurphy.Minecraft.Render.Util.FrustumCuller; import net.tylermurphy.Minecraft.Scene.World; import net.tylermurphy.Minecraft.Scene.Objects.Renderable; import net.tylermurphy.Minecraft.Util.Constants; import net.tylermurphy.Minecraft.Util.Maths; public class ChunkRenderer { private final ChunkShader shader; public ChunkRenderer(Matrix4f projectionMatrix) { this.shader = new ChunkShader(); shader.start(); shader.loadProjectionMatrix(projectionMatrix); shader.connectTextureUnits(); shader.stop(); } public void render(Matrix4f projectionMatrix) { FrustumCuller frustum = FrustumCuller.getFrustum(Maths.createViewMatrix(World.camera),projectionMatrix); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glEnable(GL11.GL_CULL_FACE); GL11.glCullFace(GL11.GL_BACK); GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); GL11.glClearColor(Constants.RED, Constants.GREEN, Constants.BLUE, 1); shader.start(); if(World.player.isDead) shader.loadTint(new Vector3f(100,0,0)); else shader.loadTint(new Vector3f(0,0,0)); shader.loadViewMatrix(World.camera); shader.loadPlayerPosition(World.player.getTransform().getPosition()); shader.loadRenderDistance(World.renderDistance); shader.loadSkyColor(new Vector3f(Constants.RED,Constants.GREEN,Constants.BLUE)); attemptFrameChunkMeshLoad(); boolean loadedMesh = false; for (Chunk chunk : World.getChunks()) { if(chunk==null) continue; if(!frustum.cubeInFrustum( chunk.gridX*16 - World.world_origin.x(), 0, chunk.gridZ*16 - World.world_origin.z(), chunk.gridX*16 + 16 - World.world_origin.x() , 256, chunk.gridZ*16 + 16 - World.world_origin.z() )) { continue; } if(!loadedMesh) loadedMesh = chunk.loadMesh(); if(chunk.renderable() != null) renderChunkMesh(chunk.renderable()); if(chunk.transparentRenderable() != null) renderChunkMesh(chunk.transparentRenderable()); GL20.glDisableVertexAttribArray(0); GL20.glDisableVertexAttribArray(1); GL20.glDisableVertexAttribArray(2); GL20.glDisableVertexAttribArray(3); GL30.glBindVertexArray(0); } GL11.glDisable(GL11.GL_CULL_FACE); shader.stop(); } private void attemptFrameChunkMeshLoad(){ } private void renderChunkMesh(Renderable renderable) { GL30.glBindVertexArray(renderable.getMesh().getID()); GL20.glEnableVertexAttribArray(0); GL20.glEnableVertexAttribArray(1); GL20.glEnableVertexAttribArray(2); GL20.glEnableVertexAttribArray(3); GL13.glActiveTexture(GL13.GL_TEXTURE0); GL11.glBindTexture(GL30.GL_TEXTURE_2D_ARRAY, renderable.getTexture()); prepareInstance(renderable); GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, renderable.getMesh().getVertexCount()); } private void prepareInstance(Renderable renderable) { Matrix4f transformationMatrix = Maths.createTransformationMatrix( new Vector3f( renderable.getTransform().getPosition().x - World.world_origin.x(), renderable.getTransform().getPosition().y, renderable.getTransform().getPosition().z - World.world_origin.z() ), renderable.getTransform().getRotation().x,renderable.getTransform().getRotation().y, renderable.getTransform().getRotation().z, renderable.getTransform().getScale()); shader.loadTransformationMatrix(transformationMatrix); } public void cleanUp() { shader.cleanUp(); } }