diff options
author | Tyler Murphy <tylerm@tylerm.dev> | 2023-04-17 12:12:01 -0400 |
---|---|---|
committer | Tyler Murphy <tylerm@tylerm.dev> | 2023-04-17 12:12:01 -0400 |
commit | 180aad05decc7eefa87e4e45d6747c48f40e5361 (patch) | |
tree | 51545197f7c94b4022acab880772c9f4fc65db0e /src/main/java/net/tylermurphy/Minecraft/Render | |
download | minecraftjava-main.tar.gz minecraftjava-main.tar.bz2 minecraftjava-main.zip |
Diffstat (limited to '')
13 files changed, 1189 insertions, 0 deletions
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/ChunkRenderer.java b/src/main/java/net/tylermurphy/Minecraft/Render/ChunkRenderer.java new file mode 100755 index 0000000..29e079b --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/ChunkRenderer.java @@ -0,0 +1,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();
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/Data/Display.java b/src/main/java/net/tylermurphy/Minecraft/Render/Data/Display.java new file mode 100755 index 0000000..f866e97 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/Data/Display.java @@ -0,0 +1,175 @@ +package net.tylermurphy.Minecraft.Render.Data;
+
+import java.nio.DoubleBuffer;
+import java.nio.IntBuffer;
+
+import org.joml.Vector2f;
+import org.lwjgl.BufferUtils;
+import org.lwjgl.glfw.GLFW;
+import org.lwjgl.glfw.GLFWFramebufferSizeCallback;
+import org.lwjgl.glfw.GLFWImage;
+import org.lwjgl.glfw.GLFWVidMode;
+import org.lwjgl.opengl.GL;
+import org.lwjgl.opengl.GL11;
+
+import net.tylermurphy.Minecraft.Input.Input;
+
+public class Display {
+
+ private static long monitor;
+ private static long window;
+
+ private static int width,height;
+
+ private static double previousTime = GLFW.glfwGetTime();
+ private static double passedTime = 0;
+
+ private static boolean contextReady = false;
+
+ public static boolean wasResized = false;
+
+ public static boolean fullscreen = false;
+ private static int backup_xpos,backup_ypos,backup_xsize,backup_ysize;
+
+ public static void create(int width, int height, String title, Texture icon) {
+
+ Display.width = width;
+ Display.height = height;
+
+ if(!GLFW.glfwInit()) {
+ System.err.println("Error: Coudnt init GLFW");
+ System.exit(-1);
+ }
+
+ Input.init();
+
+ GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
+
+ monitor = GLFW.glfwGetPrimaryMonitor();
+ window = GLFW.glfwCreateWindow(width, height, title, 0, 0);
+
+ GLFW.glfwSetKeyCallback(window, Input.getKeyboardCallback());
+ GLFW.glfwSetCursorPosCallback(window, Input.getMouseMoveCallback());
+ GLFW.glfwSetMouseButtonCallback(window, Input.getMouseButtonCallback());
+ GLFW.glfwSetCharCallback(window, Input.getCharCallback());
+
+ GLFWFramebufferSizeCallback framebufferCallback = new GLFWFramebufferSizeCallback() {
+ public void invoke(long window, int width, int height) {
+ if(contextReady) {
+ Display.width = width;
+ Display.height = height;
+ Display.wasResized = true;
+ GL11.glViewport(0, 0, width, height);
+ }
+ }
+ };
+
+ GLFW.glfwSetFramebufferSizeCallback(window, framebufferCallback);
+
+ if(window==0) {
+ System.err.println("Error: Coudnt create window");
+ System.exit(-1);
+ }
+
+ if(icon != null) {
+ GLFWImage image = GLFWImage.malloc(); GLFWImage.Buffer imagebf = GLFWImage.malloc(1);
+ image.set(icon.getWidth(), icon.getHeight(), icon.getImage());
+ imagebf.put(0, image);
+ GLFW.glfwSetWindowIcon(window, imagebf);
+ }
+
+ GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
+ assert videoMode != null;
+ GLFW.glfwSetWindowPos(window, (videoMode.width() - width) / 2, (videoMode.height() - height) / 2);
+ GLFW.glfwMakeContextCurrent(window);
+ GLFW.glfwSwapInterval(0);
+ GLFW.glfwShowWindow(window);
+
+ GL.createCapabilities();
+ grabCursor();
+
+ contextReady = true;
+
+ }
+
+ public static boolean closed() {
+ return !GLFW.glfwWindowShouldClose(window);
+ }
+
+ public static void update() {
+ double currentTime = GLFW.glfwGetTime();
+ passedTime = currentTime - previousTime;
+ previousTime = currentTime;
+ GLFW.glfwPollEvents();
+ }
+
+ public static void swapBuffers() {
+ GLFW.glfwSwapBuffers(window);
+ }
+
+ public static void close() {
+ Input.destroy();
+ GLFW.glfwDestroyWindow(window);
+ GLFW.glfwTerminate();
+ GL.destroy();
+ }
+
+ public static int getWidth() {
+ return width;
+ }
+
+ public static int getHeight() {
+ return height;
+ }
+
+ public static float getFrameTimeSeconds() {
+ return (float) passedTime;
+ }
+
+ public static void grabCursor() {
+ GLFW.glfwSetInputMode(window, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_DISABLED);
+ }
+
+ public static void releaseCursor() {
+ GLFW.glfwSetInputMode(window, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL);
+ }
+
+ public static Vector2f getCursorPos() {
+ DoubleBuffer xpos = BufferUtils.createDoubleBuffer(1);
+ DoubleBuffer ypos = BufferUtils.createDoubleBuffer(1);
+ GLFW.glfwGetCursorPos(window, xpos, ypos);
+ return new Vector2f((float)xpos.get(),(float)ypos.get());
+ }
+
+ public static void setFullScreen(boolean fullscreen) {
+
+ if(Display.fullscreen == fullscreen)
+ return;
+
+ Display.fullscreen = fullscreen;
+
+ if(fullscreen) {
+
+ IntBuffer xpos = BufferUtils.createIntBuffer(1);
+ IntBuffer ypos = BufferUtils.createIntBuffer(1);
+ GLFW.glfwGetWindowPos(window, xpos, ypos);
+
+ IntBuffer xsize = BufferUtils.createIntBuffer(1);
+ IntBuffer ysize = BufferUtils.createIntBuffer(1);
+ GLFW.glfwGetWindowSize(window, xsize, ysize);
+
+ backup_xpos = xpos.get();
+ backup_ypos = ypos.get();
+ backup_xsize = xsize.get();
+ backup_ysize = ysize.get();
+
+ GLFWVidMode mode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
+
+ assert mode != null;
+ GLFW.glfwSetWindowMonitor(window, monitor, backup_xpos, backup_ypos, mode.width(), mode.height(), 0);
+ } else {
+ GLFW.glfwSetWindowMonitor(window, 0, backup_xpos, backup_ypos, backup_xsize, backup_ysize, 0);
+ }
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/Data/Mesh.java b/src/main/java/net/tylermurphy/Minecraft/Render/Data/Mesh.java new file mode 100755 index 0000000..093a58e --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/Data/Mesh.java @@ -0,0 +1,82 @@ +package net.tylermurphy.Minecraft.Render.Data;
+
+import org.lwjgl.BufferUtils;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL15;
+import org.lwjgl.opengl.GL20;
+import org.lwjgl.opengl.GL30;
+
+import java.io.Serializable;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Mesh implements Serializable {
+
+ private static final long serialVersionUID = -8137846451745511907L;
+
+ public static List<Integer> vaos = new ArrayList<>();
+ public static List<Integer> vbos = new ArrayList<>();
+
+ private final int id;
+ private final int vertexCount;
+ private int counter = 0;
+
+ public Mesh(int vertexCount){
+ this.id = GL30.glGenVertexArrays();
+ vaos.add(id);
+ this.vertexCount = vertexCount;
+ GL30.glBindVertexArray(id);
+ }
+
+ public Mesh store(float[] data, int coordinateSize){
+ int id = GL15.glGenBuffers();
+ vbos.add(id);
+ GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, id);
+ FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
+ buffer.put(data);
+ buffer.flip();
+ GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
+ GL20.glVertexAttribPointer(counter,coordinateSize, GL11.GL_FLOAT,false,0,0);
+ GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
+ counter++;
+ return this;
+ }
+
+ public Mesh finish(){
+ GL30.glBindVertexArray(0);
+ return this;
+ }
+
+ public void delete(){
+ IntBuffer amount = BufferUtils.createIntBuffer(1);
+ GL20.glGetIntegerv(GL20.GL_MAX_VERTEX_ATTRIBS, amount);
+ GL30.glBindVertexArray(id);
+ for (int i=0; i < amount.get(0); i++) {
+ IntBuffer vbo = BufferUtils.createIntBuffer(1);
+ GL20.glGetVertexAttribiv(i, GL20.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, vbo);
+ if(vbo.get(0) > 0) {
+ GL15.glDeleteBuffers(vbo.get(0));
+ }
+ }
+ GL30.glDeleteVertexArrays(id);
+ }
+
+ public int getID() {
+ return id;
+ }
+ public int getVertexCount() {
+ return vertexCount;
+ }
+
+ public static void cleanUp() {
+ for(int vao:vaos){
+ GL30.glDeleteVertexArrays(vao);
+ }
+ for(int vbo:vbos){
+ GL30.glDeleteBuffers(vbo);
+ }
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/Data/Texture.java b/src/main/java/net/tylermurphy/Minecraft/Render/Data/Texture.java new file mode 100755 index 0000000..edfce82 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/Data/Texture.java @@ -0,0 +1,113 @@ +package net.tylermurphy.Minecraft.Render.Data;
+
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.lwjgl.opengl.GL30.*;
+
+import org.lwjgl.opengl.EXTTextureFilterAnisotropic;
+import org.lwjgl.opengl.GL;
+import org.lwjgl.stb.STBImage;
+import org.lwjgl.system.MemoryStack;
+
+import net.tylermurphy.Minecraft.Util.Constants;
+
+public class Texture {
+
+ public ByteBuffer getImage() {
+ return image;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ private ByteBuffer image;
+ private int width, height;
+
+ private static List<Integer> ids = new ArrayList<Integer>();
+
+ Texture(int width, int heigh, ByteBuffer image) {
+ this.image = image;
+ this.height = heigh;
+ this.width = width;
+ }
+
+ public static Texture loadRawTextureData(String fileName) {
+ ByteBuffer image;
+ int width, height;
+ try (MemoryStack stack = MemoryStack.stackPush()) {
+ IntBuffer comp = stack.mallocInt(1);
+ IntBuffer w = stack.mallocInt(1);
+ IntBuffer h = stack.mallocInt(1);
+ image = STBImage.stbi_load(Constants.PNG_LOCATION + fileName + ".png", w, h, comp, 4);
+ if (image == null) {
+ System.err.println("Couldn't load " + Constants.PNG_LOCATION + fileName + ".png");
+ }
+ width = w.get();
+ height = h.get();
+ return new Texture(width, height, image);
+ }
+ }
+
+ private static int loadImage(String fileName) {
+ int id = glGenTextures();
+ Texture image = loadRawTextureData(fileName);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, id);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getImage());
+ glGenerateMipmap(GL_TEXTURE_2D);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ ids.add(id);
+ return id;
+ }
+
+ public static int loadTexture(String fileName) {
+ return loadImage(fileName);
+ }
+
+ public static int loadFontAtlas(String fileName) {
+ return loadImage(fileName);
+ }
+
+ public static int loadTexture2DArray(HashMap<Integer, Texture> textures){
+ int id = glGenTextures();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, id);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ if (GL.getCapabilities().GL_EXT_texture_filter_anisotropic) {
+ float maxAnisotropy = glGetFloat(EXTTextureFilterAnisotropic.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy);
+ }
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, textures.get(0).width, textures.get(0).height, textures.values().size(), 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer) null);
+ for(Map.Entry<Integer, Texture> entry : textures.entrySet()){
+ glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, entry.getKey(), entry.getValue().width, entry.getValue().height, 1, GL_RGBA, GL_UNSIGNED_BYTE, entry.getValue().getImage());
+ }
+ glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
+ ids.add(id);
+ return id;
+ }
+
+ public static void cleanUp(){
+ for(int id:ids){
+ glDeleteTextures(id);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, id);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/FontRenderer.java b/src/main/java/net/tylermurphy/Minecraft/Render/FontRenderer.java new file mode 100755 index 0000000..ed17824 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/FontRenderer.java @@ -0,0 +1,101 @@ +package net.tylermurphy.Minecraft.Render;
+
+import java.util.List;
+
+import java.util.Map;
+
+import net.tylermurphy.Minecraft.Render.Data.Mesh;
+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.Vector2f;
+import org.joml.Vector4f;
+
+import net.tylermurphy.Minecraft.Render.Shaders.FontShader;
+import net.tylermurphy.Minecraft.Render.Shaders.QuadShader;
+import net.tylermurphy.Minecraft.UI.UIFont;
+import net.tylermurphy.Minecraft.UI.UIText;
+import net.tylermurphy.Minecraft.Util.Maths;
+
+public class FontRenderer {
+
+ private final Mesh quad;
+ private final FontShader fontShader;
+ private final QuadShader quadShader;
+
+ public FontRenderer() {
+ float[] positions = {-1, 1, -1, -1, 1, 1, 1, -1};
+ quad = new Mesh(positions.length/2).store(positions, 2).finish();
+ fontShader = new FontShader();
+ quadShader = new QuadShader();
+ }
+
+ public void render(Map<UIFont, List<UIText>> texts){
+ for(UIFont font : texts.keySet()){
+ for(UIText text : texts.get(font)){
+ renderQuad(text);
+ }
+ }
+ prepare();
+ for(UIFont font : texts.keySet()){
+ GL13.glActiveTexture(GL13.GL_TEXTURE0);
+ GL11.glBindTexture(GL11.GL_TEXTURE_2D, font.getTextureAtlas());
+ for(UIText text : texts.get(font)){
+ renderText(text);
+ }
+ }
+ endRendering();
+ }
+
+ public void cleanUp(){
+ fontShader.cleanUp();
+ quadShader.cleanUp();
+ }
+
+ private void prepare(){
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glDisable(GL11.GL_DEPTH_TEST);
+ fontShader.start();
+ }
+
+ private void renderText(UIText text){
+ GL30.glBindVertexArray(text.getMesh());
+ GL20.glEnableVertexAttribArray(0);
+ GL20.glEnableVertexAttribArray(1);
+ fontShader.loadColor(text.getColour());
+ fontShader.loadTranslation(text.getConvertedPosition());
+ GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, text.getVertexCount());
+ GL20.glDisableVertexAttribArray(0);
+ GL20.glDisableVertexAttribArray(1);
+ GL30.glBindVertexArray(0);
+ }
+
+ private void renderQuad(UIText text) {
+ quadShader.start();
+ GL30.glBindVertexArray(quad.getID());
+ GL20.glEnableVertexAttribArray(0);
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glDisable(GL11.GL_DEPTH_TEST);
+ Matrix4f matrix = Maths.createTransformationMatrix(new Vector2f(text.getStretchBackdrop() ? -1 : text.getConvertedPosition().x*2-1,(1-text.getConvertedPosition().y-.0125f*text.getFontSize()-.0025f)*2-1), new Vector2f(text.getStretchBackdrop() ? 2 : (float) text.getMaxX()*2,.025f*text.getFontSize()));
+ quadShader.loadTransformation(matrix);
+ quadShader.loadColor(new Vector4f(150/255f,150/255f,150/255f,.5f));
+ GL11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, quad.getVertexCount());
+ GL11.glEnable(GL11.GL_DEPTH_TEST);
+ GL20.glDisableVertexAttribArray(0);
+ GL30.glBindVertexArray(0);
+ quadShader.stop();
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glEnable(GL11.GL_DEPTH_TEST);
+ }
+
+ private void endRendering(){
+ fontShader.stop();
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glEnable(GL11.GL_DEPTH_TEST);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/GuiRenderer.java b/src/main/java/net/tylermurphy/Minecraft/Render/GuiRenderer.java new file mode 100755 index 0000000..b7ae6f2 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/GuiRenderer.java @@ -0,0 +1,57 @@ +package net.tylermurphy.Minecraft.Render;
+
+import java.util.List;
+
+
+import net.tylermurphy.Minecraft.Render.Data.Mesh;
+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.Vector2f;
+
+import net.tylermurphy.Minecraft.Render.Shaders.GuiShader;
+import net.tylermurphy.Minecraft.UI.UIComponent;
+import net.tylermurphy.Minecraft.UI.UIImage;
+import net.tylermurphy.Minecraft.Util.Maths;
+
+
+public class GuiRenderer {
+
+ private final Mesh quad;
+ private GuiShader shader;
+
+ public GuiRenderer(){
+ float[] positions = {-1, 1, -1, -1, 1, 1, 1, -1};
+ quad = new Mesh(positions.length/2).store(positions, 2).finish();
+ shader = new GuiShader();
+ }
+
+ public void render(List<UIComponent> components){
+ shader.start();
+ GL30.glBindVertexArray(quad.getID());
+ GL20.glEnableVertexAttribArray(0);
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glDisable(GL11.GL_DEPTH_TEST);
+ for(UIComponent cp : components) {
+ if(!(cp instanceof UIImage)) continue;
+ UIImage gui = (UIImage)cp;
+ GL13.glActiveTexture(GL13.GL_TEXTURE0);
+ GL11.glBindTexture(GL11.GL_TEXTURE_2D, gui.getTexture());
+ Matrix4f matrix = Maths.createTransformationMatrix(new Vector2f(gui.getConvertedPosition().x*2-1,(1-gui.getConvertedPosition().y)*2-1), gui.getConvertedSize());
+ shader.loadTransformation(matrix);
+ GL11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, quad.getVertexCount());
+ }
+ GL11.glEnable(GL11.GL_DEPTH_TEST);
+ GL11.glDisable(GL11.GL_BLEND);
+ GL20.glDisableVertexAttribArray(0);
+ GL30.glBindVertexArray(0);
+ shader.stop();
+ }
+
+ public void cleanUp(){
+ shader.cleanUp();
+ }
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/MainRenderer.java b/src/main/java/net/tylermurphy/Minecraft/Render/MainRenderer.java new file mode 100755 index 0000000..28ec88f --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/MainRenderer.java @@ -0,0 +1,73 @@ +package net.tylermurphy.Minecraft.Render;
+
+import net.tylermurphy.Minecraft.Render.Data.Mesh;
+import org.joml.Matrix4f;
+
+import net.tylermurphy.Minecraft.Audio.SoundManager;
+import net.tylermurphy.Minecraft.Render.Data.Texture;
+import net.tylermurphy.Minecraft.Scene.World;
+import net.tylermurphy.Minecraft.UI.UIMaster;
+import net.tylermurphy.Minecraft.Util.Constants;
+import net.tylermurphy.Minecraft.Render.Data.Display;
+import net.tylermurphy.Minecraft.Util.MousePicker;
+import org.joml.Vector3f;
+
+public class MainRenderer {
+
+ private final GuiRenderer guiRenderer;
+ private final FontRenderer fontRenderer;
+ private final ChunkRenderer chunkRenderer;
+
+ private Matrix4f projectionMatrix;
+
+ public MainRenderer() {
+ guiRenderer = new GuiRenderer();
+ fontRenderer = new FontRenderer();
+ createProjectionMatrix();
+ MousePicker.init(projectionMatrix);
+ chunkRenderer = new ChunkRenderer(projectionMatrix);
+ }
+
+ public void update() {
+ if(Display.wasResized) {
+ Display.wasResized = false;
+ createProjectionMatrix();
+ }
+ chunkRenderer.render(projectionMatrix);
+ if(!World.player.isDead) {
+ World.player.move();
+ World.player.getTransform().setRotation(new Vector3f(
+ World.camera.getPitch(),
+ -World.camera.getYaw(),
+ World.camera.getRoll()
+ ));
+ World.camera.move();
+ }
+ UIMaster.renderUI(guiRenderer, fontRenderer);
+ MousePicker.update();
+ SoundManager.setListenerData(World.player.getTransform().getPosition().x, World.player.getTransform().getPosition().y , World.player.getTransform().getPosition().z);
+ }
+
+ public void close() {
+ guiRenderer.cleanUp();
+ chunkRenderer.cleanUp();
+ Mesh.cleanUp();
+ Texture.cleanUp();
+ }
+
+ private void createProjectionMatrix(){
+ float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
+ float y_scale = (float) ((1f / Math.tan(Math.toRadians(Constants.FOV / 2f))));
+ float x_scale = y_scale / aspectRatio;
+ float frustum_length = Constants.FAR_DISTANCE - Constants.NEAR_DISTANCE;
+
+ projectionMatrix = new Matrix4f()
+ .m00(x_scale)
+ .m11(y_scale)
+ .m22( -((Constants.FAR_DISTANCE + Constants.NEAR_DISTANCE) / frustum_length) )
+ .m23(-1)
+ .m32( -((2 * Constants.NEAR_DISTANCE * Constants.FAR_DISTANCE) / frustum_length) )
+ .m33(0);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/ChunkShader.java b/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/ChunkShader.java new file mode 100755 index 0000000..f998e7a --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/ChunkShader.java @@ -0,0 +1,81 @@ +package net.tylermurphy.Minecraft.Render.Shaders;
+
+import org.joml.Matrix4f;
+import org.joml.Vector3f;
+
+import net.tylermurphy.Minecraft.Render.Util.ShaderProgram;
+import net.tylermurphy.Minecraft.Scene.Camera;
+import net.tylermurphy.Minecraft.Util.Maths;
+
+public class ChunkShader extends ShaderProgram{
+
+ private static final String VERTEX_FILE = "Chunk_VS.glsl";
+ private static final String FRAGMENT_FILE = "Chunk_FS.glsl";
+
+ private int location_transformationMatrix;
+ private int location_projectionMatrix;
+ private int location_viewMatrix;
+ private int location_modelTexture;
+ private int location_tint;
+ private int location_playerPosition;
+ private int location_renderDistance;
+ private int location_skyColor;
+
+ public ChunkShader() {
+ super(VERTEX_FILE, FRAGMENT_FILE);
+ }
+
+ @Override
+ public void bindAttributes() {
+ super.bindAttribute(0, "position");
+ super.bindAttribute(1, "textureCoordinates");
+ super.bindAttribute(2, "baseLightingValue");
+ super.bindAttribute(3, "layer");
+ }
+
+ @Override
+ public void getAllUniformLocations() {
+ location_transformationMatrix = super.getUniformLocation("transformationMatrix");
+ location_projectionMatrix = super.getUniformLocation("projectionMatrix");
+ location_viewMatrix = super.getUniformLocation("viewMatrix");
+ location_modelTexture = super.getUniformLocation("modelTexture");
+ location_tint = super.getUniformLocation("tint");
+ location_playerPosition = super.getUniformLocation("playerPosition");
+ location_renderDistance = super.getUniformLocation("renderDistance");
+ location_skyColor = super.getUniformLocation("skyColor");
+ }
+
+ public void connectTextureUnits() {
+ super.loadInt(location_modelTexture, 0);
+ }
+
+ public void loadTint(Vector3f tint) {
+ super.loadVector(location_tint, tint);
+ }
+
+ public void loadTransformationMatrix(Matrix4f matrix){
+ super.loadMatrix(location_transformationMatrix, matrix);
+ }
+
+ public void loadViewMatrix(Camera camera){
+ Matrix4f viewMatrix = Maths.createViewMatrix(camera);
+ super.loadMatrix(location_viewMatrix, viewMatrix);
+ }
+
+ public void loadProjectionMatrix(Matrix4f projection){
+ super.loadMatrix(location_projectionMatrix, projection);
+ }
+
+ public void loadPlayerPosition(Vector3f position) {
+ super.loadVector(location_playerPosition, position);
+ }
+
+ public void loadRenderDistance(int distance) {
+ super.loadInt(location_renderDistance, distance);
+ }
+
+ public void loadSkyColor(Vector3f color) {
+ super.loadVector(location_skyColor, color);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/FontShader.java b/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/FontShader.java new file mode 100755 index 0000000..0615b13 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/FontShader.java @@ -0,0 +1,40 @@ +package net.tylermurphy.Minecraft.Render.Shaders;
+
+import org.joml.Vector2f;
+import org.joml.Vector3f;
+
+import net.tylermurphy.Minecraft.Render.Util.ShaderProgram;
+
+public class FontShader extends ShaderProgram{
+
+ private static final String VERTEX_FILE ="Font_VS.glsl";
+ private static final String FRAGMENT_FILE = "Font_FS.glsl";
+
+ private int location_color;
+ private int location_translation;
+
+ public FontShader() {
+ super(VERTEX_FILE, FRAGMENT_FILE);
+ }
+
+ @Override
+ protected void getAllUniformLocations() {
+ location_color = super.getUniformLocation("color");
+ location_translation = super.getUniformLocation("translation");
+ }
+
+ @Override
+ protected void bindAttributes() {
+ super.bindAttribute(0, "position");
+ super.bindAttribute(1, "textureCoords");
+ }
+
+ public void loadColor(Vector3f colour){
+ super.loadVector(location_color, colour);
+ }
+
+ public void loadTranslation(Vector2f vector2f){
+ super.load2DVector(location_translation, vector2f);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/GuiShader.java b/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/GuiShader.java new file mode 100755 index 0000000..cf10ff3 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/GuiShader.java @@ -0,0 +1,33 @@ +package net.tylermurphy.Minecraft.Render.Shaders;
+
+import org.joml.Matrix4f;
+
+import net.tylermurphy.Minecraft.Render.Util.ShaderProgram;
+
+public class GuiShader extends ShaderProgram{
+
+ private static final String VERTEX_FILE = "Gui_VS.glsl";
+ private static final String FRAGMENT_FILE = "Gui_FS.glsl";
+
+ private int location_transformationMatrix;
+
+ public GuiShader() {
+ super(VERTEX_FILE, FRAGMENT_FILE);
+ }
+
+ public void loadTransformation(Matrix4f matrix){
+ super.loadMatrix(location_transformationMatrix, matrix);
+ }
+
+ protected void getAllUniformLocations() {
+ location_transformationMatrix = super.getUniformLocation("transformationMatrix");
+ }
+
+ protected void bindAttributes() {
+ super.bindAttribute(0, "position");
+ }
+
+
+
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/QuadShader.java b/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/QuadShader.java new file mode 100755 index 0000000..0424cc3 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/Shaders/QuadShader.java @@ -0,0 +1,37 @@ +package net.tylermurphy.Minecraft.Render.Shaders;
+
+import org.joml.Matrix4f;
+import org.joml.Vector4f;
+
+import net.tylermurphy.Minecraft.Render.Util.ShaderProgram;
+
+public class QuadShader extends ShaderProgram{
+
+ private static final String VERTEX_FILE = "Quad_VS.glsl";
+ private static final String FRAGMENT_FILE = "Quad_FS.glsl";
+
+ private int location_transformationMatrix;
+ private int location_color;
+
+ public QuadShader() {
+ super(VERTEX_FILE, FRAGMENT_FILE);
+ }
+
+ public void loadTransformation(Matrix4f matrix){
+ super.loadMatrix(location_transformationMatrix, matrix);
+ }
+
+ protected void getAllUniformLocations() {
+ location_transformationMatrix = super.getUniformLocation("transformationMatrix");
+ location_color = super.getUniformLocation("color");
+ }
+
+ protected void bindAttributes() {
+ super.bindAttribute(0, "position");
+ }
+
+ public void loadColor(Vector4f color) {
+ super.loadVector(location_color, color);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/Util/FrustumCuller.java b/src/main/java/net/tylermurphy/Minecraft/Render/Util/FrustumCuller.java new file mode 100755 index 0000000..41472c4 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/Util/FrustumCuller.java @@ -0,0 +1,172 @@ +package net.tylermurphy.Minecraft.Render.Util;
+
+import java.nio.FloatBuffer;
+
+import org.lwjgl.BufferUtils;
+import org.joml.Matrix4f;
+
+import net.tylermurphy.Minecraft.Render.Util.FrustumCuller;
+
+public class FrustumCuller {
+ public float[][] m_Frustum = new float[6][4];
+ public static final int RIGHT = 0;
+ public static final int LEFT = 1;
+ public static final int BOTTOM = 2;
+ public static final int TOP = 3;
+ public static final int BACK = 4;
+ public static final int FRONT = 5;
+ public static final int A = 0;
+ public static final int B = 1;
+ public static final int C = 2;
+ public static final int D = 3;
+ private static FrustumCuller frustum = new FrustumCuller();
+
+ private static FloatBuffer modlBuffer = BufferUtils.createFloatBuffer(16);
+ private static FloatBuffer projBuffer = BufferUtils.createFloatBuffer(16);
+
+ float[] proj = new float[16];
+ float[] modl = new float[16];
+ float[] clip = new float[16];
+
+ public static FrustumCuller getFrustum(Matrix4f viewMatrix, Matrix4f projectionMatrix) {
+ frustum.calculateFrustum(viewMatrix, projectionMatrix);
+ return frustum;
+ }
+
+ private void normalizePlane(float[][] frustum, int side) {
+ float magnitude = (float) Math.sqrt(frustum[side][0] * frustum[side][0] + frustum[side][1] * frustum[side][1] + frustum[side][2] * frustum[side][2]);
+
+ frustum[side][0] /= magnitude;
+ frustum[side][1] /= magnitude;
+ frustum[side][2] /= magnitude;
+ frustum[side][3] /= magnitude;
+ }
+
+ private void calculateFrustum(Matrix4f viewMatrix, Matrix4f projectionMatrix) {
+
+ modlBuffer.rewind();
+ viewMatrix.get(modlBuffer);
+ projBuffer.rewind();
+ projectionMatrix.get(projBuffer);
+
+ for(int i = 0; i < 16; i ++) {
+ modl[i] = modlBuffer.get(i);
+ proj[i] = projBuffer.get(i);
+ }
+
+ this.clip[0] = (this.modl[0] * this.proj[0] + this.modl[1] * this.proj[4] + this.modl[2] * this.proj[8] + this.modl[3] * this.proj[12]);
+ this.clip[1] = (this.modl[0] * this.proj[1] + this.modl[1] * this.proj[5] + this.modl[2] * this.proj[9] + this.modl[3] * this.proj[13]);
+ this.clip[2] = (this.modl[0] * this.proj[2] + this.modl[1] * this.proj[6] + this.modl[2] * this.proj[10] + this.modl[3] * this.proj[14]);
+ this.clip[3] = (this.modl[0] * this.proj[3] + this.modl[1] * this.proj[7] + this.modl[2] * this.proj[11] + this.modl[3] * this.proj[15]);
+
+ this.clip[4] = (this.modl[4] * this.proj[0] + this.modl[5] * this.proj[4] + this.modl[6] * this.proj[8] + this.modl[7] * this.proj[12]);
+ this.clip[5] = (this.modl[4] * this.proj[1] + this.modl[5] * this.proj[5] + this.modl[6] * this.proj[9] + this.modl[7] * this.proj[13]);
+ this.clip[6] = (this.modl[4] * this.proj[2] + this.modl[5] * this.proj[6] + this.modl[6] * this.proj[10] + this.modl[7] * this.proj[14]);
+ this.clip[7] = (this.modl[4] * this.proj[3] + this.modl[5] * this.proj[7] + this.modl[6] * this.proj[11] + this.modl[7] * this.proj[15]);
+
+ this.clip[8] = (this.modl[8] * this.proj[0] + this.modl[9] * this.proj[4] + this.modl[10] * this.proj[8] + this.modl[11] * this.proj[12]);
+ this.clip[9] = (this.modl[8] * this.proj[1] + this.modl[9] * this.proj[5] + this.modl[10] * this.proj[9] + this.modl[11] * this.proj[13]);
+ this.clip[10] = (this.modl[8] * this.proj[2] + this.modl[9] * this.proj[6] + this.modl[10] * this.proj[10] + this.modl[11] * this.proj[14]);
+ this.clip[11] = (this.modl[8] * this.proj[3] + this.modl[9] * this.proj[7] + this.modl[10] * this.proj[11] + this.modl[11] * this.proj[15]);
+
+ this.clip[12] = (this.modl[12] * this.proj[0] + this.modl[13] * this.proj[4] + this.modl[14] * this.proj[8] + this.modl[15] * this.proj[12]);
+ this.clip[13] = (this.modl[12] * this.proj[1] + this.modl[13] * this.proj[5] + this.modl[14] * this.proj[9] + this.modl[15] * this.proj[13]);
+ this.clip[14] = (this.modl[12] * this.proj[2] + this.modl[13] * this.proj[6] + this.modl[14] * this.proj[10] + this.modl[15] * this.proj[14]);
+ this.clip[15] = (this.modl[12] * this.proj[3] + this.modl[13] * this.proj[7] + this.modl[14] * this.proj[11] + this.modl[15] * this.proj[15]);
+
+ this.m_Frustum[0][0] = (this.clip[3] - this.clip[0]);
+ this.m_Frustum[0][1] = (this.clip[7] - this.clip[4]);
+ this.m_Frustum[0][2] = (this.clip[11] - this.clip[8]);
+ this.m_Frustum[0][3] = (this.clip[15] - this.clip[12]);
+
+ normalizePlane(this.m_Frustum, 0);
+
+ this.m_Frustum[1][0] = (this.clip[3] + this.clip[0]);
+ this.m_Frustum[1][1] = (this.clip[7] + this.clip[4]);
+ this.m_Frustum[1][2] = (this.clip[11] + this.clip[8]);
+ this.m_Frustum[1][3] = (this.clip[15] + this.clip[12]);
+
+ normalizePlane(this.m_Frustum, 1);
+
+ this.m_Frustum[2][0] = (this.clip[3] + this.clip[1]);
+ this.m_Frustum[2][1] = (this.clip[7] + this.clip[5]);
+ this.m_Frustum[2][2] = (this.clip[11] + this.clip[9]);
+ this.m_Frustum[2][3] = (this.clip[15] + this.clip[13]);
+
+ normalizePlane(this.m_Frustum, 2);
+
+ this.m_Frustum[3][0] = (this.clip[3] - this.clip[1]);
+ this.m_Frustum[3][1] = (this.clip[7] - this.clip[5]);
+ this.m_Frustum[3][2] = (this.clip[11] - this.clip[9]);
+ this.m_Frustum[3][3] = (this.clip[15] - this.clip[13]);
+
+ normalizePlane(this.m_Frustum, 3);
+
+ this.m_Frustum[4][0] = (this.clip[3] - this.clip[2]);
+ this.m_Frustum[4][1] = (this.clip[7] - this.clip[6]);
+ this.m_Frustum[4][2] = (this.clip[11] - this.clip[10]);
+ this.m_Frustum[4][3] = (this.clip[15] - this.clip[14]);
+
+ normalizePlane(this.m_Frustum, 4);
+
+ this.m_Frustum[5][0] = (this.clip[3] + this.clip[2]);
+ this.m_Frustum[5][1] = (this.clip[7] + this.clip[6]);
+ this.m_Frustum[5][2] = (this.clip[11] + this.clip[10]);
+ this.m_Frustum[5][3] = (this.clip[15] + this.clip[14]);
+
+ normalizePlane(this.m_Frustum, 5);
+ }
+
+ public boolean pointInFrustum(float x, float y, float z) {
+ for (int i = 0; i < 6; i++) {
+ if (this.m_Frustum[i][0] * x + this.m_Frustum[i][1] * y + this.m_Frustum[i][2] * z + this.m_Frustum[i][3] <= 0.0F) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean sphereInFrustum(float x, float y, float z, float radius) {
+ for (int i = 0; i < 6; i++) {
+ if (this.m_Frustum[i][0] * x + this.m_Frustum[i][1] * y + this.m_Frustum[i][2] * z + this.m_Frustum[i][3] <= -radius) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean cubeFullyInFrustum(float x1, float y1, float z1, float x2, float y2, float z2) {
+ for (int i = 0; i < 6; i++) {
+ if (this.m_Frustum[i][0] * x1 + this.m_Frustum[i][1] * y1 + this.m_Frustum[i][2] * z1 + this.m_Frustum[i][3] <= 0.0F)
+ return false;
+ if (this.m_Frustum[i][0] * x2 + this.m_Frustum[i][1] * y1 + this.m_Frustum[i][2] * z1 + this.m_Frustum[i][3] <= 0.0F)
+ return false;
+ if (this.m_Frustum[i][0] * x1 + this.m_Frustum[i][1] * y2 + this.m_Frustum[i][2] * z1 + this.m_Frustum[i][3] <= 0.0F)
+ return false;
+ if (this.m_Frustum[i][0] * x2 + this.m_Frustum[i][1] * y2 + this.m_Frustum[i][2] * z1 + this.m_Frustum[i][3] <= 0.0F)
+ return false;
+ if (this.m_Frustum[i][0] * x1 + this.m_Frustum[i][1] * y1 + this.m_Frustum[i][2] * z2 + this.m_Frustum[i][3] <= 0.0F)
+ return false;
+ if (this.m_Frustum[i][0] * x2 + this.m_Frustum[i][1] * y1 + this.m_Frustum[i][2] * z2 + this.m_Frustum[i][3] <= 0.0F)
+ return false;
+ if (this.m_Frustum[i][0] * x1 + this.m_Frustum[i][1] * y2 + this.m_Frustum[i][2] * z2 + this.m_Frustum[i][3] <= 0.0F)
+ return false;
+ if (this.m_Frustum[i][0] * x2 + this.m_Frustum[i][1] * y2 + this.m_Frustum[i][2] * z2 + this.m_Frustum[i][3] <= 0.0F)
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean cubeInFrustum(float x1, float y1, float z1, float x2, float y2, float z2) {
+ return true;
+// for (int i = 0; i < 6; i++) {
+// if ((this.m_Frustum[i][0] * x1 + this.m_Frustum[i][1] * y1 + this.m_Frustum[i][2] * z1 + this.m_Frustum[i][3] <= 0.0F) && (this.m_Frustum[i][0] * x2 + this.m_Frustum[i][1] * y1 + this.m_Frustum[i][2] * z1 + this.m_Frustum[i][3] <= 0.0F) && (this.m_Frustum[i][0] * x1 + this.m_Frustum[i][1] * y2 + this.m_Frustum[i][2] * z1 + this.m_Frustum[i][3] <= 0.0F) && (this.m_Frustum[i][0] * x2 + this.m_Frustum[i][1] * y2 + this.m_Frustum[i][2] * z1 + this.m_Frustum[i][3] <= 0.0F) && (this.m_Frustum[i][0] * x1 + this.m_Frustum[i][1] * y1 + this.m_Frustum[i][2] * z2 + this.m_Frustum[i][3] <= 0.0F) && (this.m_Frustum[i][0] * x2 + this.m_Frustum[i][1] * y1 + this.m_Frustum[i][2] * z2 + this.m_Frustum[i][3] <= 0.0F) && (this.m_Frustum[i][0] * x1 + this.m_Frustum[i][1] * y2 + this.m_Frustum[i][2] * z2 + this.m_Frustum[i][3] <= 0.0F) && (this.m_Frustum[i][0] * x2 + this.m_Frustum[i][1] * y2 + this.m_Frustum[i][2] * z2 + this.m_Frustum[i][3] <= 0.0F)) {
+// return false;
+// }
+// }
+// return true;
+ }
+}
\ No newline at end of file diff --git a/src/main/java/net/tylermurphy/Minecraft/Render/Util/ShaderProgram.java b/src/main/java/net/tylermurphy/Minecraft/Render/Util/ShaderProgram.java new file mode 100755 index 0000000..ce5bae6 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Render/Util/ShaderProgram.java @@ -0,0 +1,126 @@ +package net.tylermurphy.Minecraft.Render.Util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.FloatBuffer;
+
+import org.lwjgl.BufferUtils;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL20;
+import org.joml.Matrix4f;
+import org.joml.Vector2f;
+import org.joml.Vector3f;
+import org.joml.Vector4f;
+
+import net.tylermurphy.Minecraft.Util.Constants;
+
+public abstract class ShaderProgram {
+
+ private int programID;
+ private int vertexShaderID;
+ private int fragmentShaderID;
+
+ private static FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16);
+
+ public ShaderProgram(String vertexFile,String fragmentFile){
+ vertexShaderID = loadShader(vertexFile,GL20.GL_VERTEX_SHADER);
+ fragmentShaderID = loadShader(fragmentFile,GL20.GL_FRAGMENT_SHADER);
+ programID = GL20.glCreateProgram();
+ GL20.glAttachShader(programID, vertexShaderID);
+ GL20.glAttachShader(programID, fragmentShaderID);
+ bindAttributes();
+ GL20.glLinkProgram(programID);
+ GL20.glValidateProgram(programID);
+ getAllUniformLocations();
+ }
+
+ protected abstract void getAllUniformLocations();
+
+ protected int getUniformLocation(String uniformName){
+ return GL20.glGetUniformLocation(programID,uniformName);
+ }
+
+ public void start(){
+ GL20.glUseProgram(programID);
+ }
+
+ public void stop(){
+ GL20.glUseProgram(0);
+ }
+
+ public void cleanUp(){
+ stop();
+ GL20.glDetachShader(programID, vertexShaderID);
+ GL20.glDetachShader(programID, fragmentShaderID);
+ GL20.glDeleteShader(vertexShaderID);
+ GL20.glDeleteShader(fragmentShaderID);
+ GL20.glDeleteProgram(programID);
+ }
+
+ protected abstract void bindAttributes();
+
+ protected void bindAttribute(int attribute, String variableName){
+ GL20.glBindAttribLocation(programID, attribute, variableName);
+ }
+
+ protected void loadFloat(int location, float value){
+ GL20.glUniform1f(location, value);
+ }
+
+ protected void loadInt(int location, int value){
+ GL20.glUniform1i(location, value);
+ }
+
+ protected void loadVector(int location, Vector3f vector){
+ GL20.glUniform3f(location,vector.x,vector.y,vector.z);
+ }
+
+ protected void loadVector(int location, Vector4f vector){
+ GL20.glUniform4f(location,vector.x,vector.y,vector.z, vector.w);
+ }
+
+ protected void load2DVector(int location, Vector2f vector){
+ GL20.glUniform2f(location,vector.x,vector.y);
+ }
+
+ protected void loadBoolean(int location, boolean value){
+ float toLoad = 0;
+ if(value){
+ toLoad = 1;
+ }
+ GL20.glUniform1f(location, toLoad);
+ }
+
+ protected void loadMatrix(int location, Matrix4f matrix){
+ matrix.get(matrixBuffer);
+ GL20.glUniformMatrix4fv(location, false, matrixBuffer);
+ }
+
+ private static int loadShader(String file, int type){
+ StringBuilder shaderSource = new StringBuilder();
+ try{
+ FileReader fr = new FileReader(new File(Constants.SHADER_LOCATION + file));
+ BufferedReader reader = new BufferedReader(fr);
+ String line;
+ while((line = reader.readLine())!=null){
+ shaderSource.append(line).append("//\n");
+ }
+ reader.close();
+ }catch(IOException e){
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ int shaderID = GL20.glCreateShader(type);
+ GL20.glShaderSource(shaderID, shaderSource);
+ GL20.glCompileShader(shaderID);
+ if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS )== GL11.GL_FALSE){
+ System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
+ System.err.println("Could not compile shader!");
+ System.exit(-1);
+ }
+ return shaderID;
+ }
+
+}
|