From 180aad05decc7eefa87e4e45d6747c48f40e5361 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Mon, 17 Apr 2023 12:12:01 -0400 Subject: save --- .../tylermurphy/Minecraft/Render/Data/Display.java | 175 +++++++++++++++++++++ .../tylermurphy/Minecraft/Render/Data/Mesh.java | 82 ++++++++++ .../tylermurphy/Minecraft/Render/Data/Texture.java | 113 +++++++++++++ 3 files changed, 370 insertions(+) create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Data/Display.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Data/Mesh.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Data/Texture.java (limited to 'src/main/java/net/tylermurphy/Minecraft/Render/Data') 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 vaos = new ArrayList<>(); + public static List 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 ids = new ArrayList(); + + 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 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 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 -- cgit v1.2.3-freya