summaryrefslogtreecommitdiff
path: root/src/main/java/net/tylermurphy/Minecraft/Render/ChunkRenderer.java
blob: 29e079bce3317befd160a5e16c9f3708498b9fd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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();
	}

}