From 9c4fef260d43d1b4f5b74c4df58131422af04e30 Mon Sep 17 00:00:00 2001 From: austin Date: Mon, 2 Sep 2024 13:03:16 -0400 Subject: [PATCH] more framebuffer fixes --- .../renderer/RenderingEngine.java | 24 ++++++++++++------- .../renderer/framebuffer/Framebuffer.java | 21 ++++++++++++---- .../framebuffer/FramebufferUtils.java | 6 +++++ .../renderer/texture/Texture.java | 23 ++++++++++++++++++ 4 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index f60d1e35..f15253e0 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -73,6 +73,8 @@ import org.joml.Vector3d; import org.joml.Vector3f; import org.lwjgl.BufferUtils; import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.GLFWErrorCallback; +import org.lwjgl.glfw.GLFWWindowSizeCallback; import org.lwjgl.glfw.GLFWWindowSizeCallbackI; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL11; @@ -225,8 +227,16 @@ public class RenderingEngine { public void createOpenglContext(){ LoggerInterface.loggerRenderer.INFO("Create OpenGL Context"); + + // + //set error callback + GLFW.glfwSetErrorCallback(GLFWErrorCallback.createThrow()); + //Initializes opengl - glfwInit(); + boolean glfwInited = glfwInit(); + if(!glfwInited){ + throw new IllegalStateException("Failed to initialize glfw!"); + } //Gives hints to glfw to control how opengl will be used glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); @@ -254,14 +264,10 @@ public class RenderingEngine { glfwTerminate(); } //set resize callback - GLFWWindowSizeCallbackI windowSizeCallback = new GLFWWindowSizeCallbackI(){ - @Override - public void invoke(long window, int width, int height){ - Globals.WINDOW_HEIGHT = height; - Globals.WINDOW_WIDTH = width; - } - }; - GLFW.glfwSetWindowSizeCallback(Globals.window, windowSizeCallback); + GLFW.glfwSetWindowSizeCallback(Globals.window, (long window, int width, int height) -> { + Globals.WINDOW_HEIGHT = height; + Globals.WINDOW_WIDTH = width; + }); //Makes the window that was just created the current OS-level window context glfwMakeContextCurrent(Globals.window); //Maximize it diff --git a/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java b/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java index 43df5936..a71a5dc9 100644 --- a/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java +++ b/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java @@ -104,11 +104,12 @@ public class Framebuffer { } public void checkStatus(){ - if(isError()){ - LoggerInterface.loggerRenderer.WARNING("Framebuffer [error] - " + RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError())); - } else if(!isComplete()){ + if(this.isError()){ LoggerInterface.loggerRenderer.WARNING("Framebuffer [glError] - " + RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError())); - LoggerInterface.loggerRenderer.WARNING("Framebuffer [status] - " + getStatus()); + LoggerInterface.loggerRenderer.WARNING("Framebuffer [status] - " + this.getStatus()); + } else if(!this.isComplete()){ + LoggerInterface.loggerRenderer.WARNING("Framebuffer [glError] - " + RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError())); + LoggerInterface.loggerRenderer.WARNING("Framebuffer [status] - " + this.getStatus()); LoggerInterface.loggerRenderer.ERROR("Failed to build framebuffer", new IllegalStateException("Framebuffer failed to build.")); } } @@ -210,6 +211,9 @@ public class Framebuffer { if(texture.getTexturePointer() == Texture.UNINITIALIZED_TEXTURE){ throw new IllegalStateException("Trying to attach uninitialized image to frame buffer!"); } + if(!GL40.glIsTexture(texture.getTexturePointer())){ + throw new IllegalStateException("Tried to attach incomplete texture to framebuffer!"); + } openGLState.glBindFramebuffer(GL40.GL_FRAMEBUFFER, this.framebufferPointer); GL40.glFramebufferTexture2D(GL40.GL_FRAMEBUFFER, GL40.GL_COLOR_ATTACHMENT0 + attachmentNum, GL40.GL_TEXTURE_2D, texture.getTexturePointer(), 0); Globals.renderingEngine.checkError(); @@ -224,6 +228,15 @@ public class Framebuffer { public void setDepthAttachment(OpenGLState openGLState, Texture depthTexture){ openGLState.glBindFramebuffer(GL40.GL_FRAMEBUFFER, this.framebufferPointer); this.depthTexture = depthTexture; + if(this.framebufferPointer == Framebuffer.DEFAULT_FRAMEBUFFER_POINTER){ + throw new IllegalStateException("Trying to attach image to default frame buffer!"); + } + if(depthTexture.getTexturePointer() == Texture.UNINITIALIZED_TEXTURE){ + throw new IllegalStateException("Trying to attach uninitialized image to frame buffer!"); + } + if(!GL40.glIsTexture(depthTexture.getTexturePointer())){ + throw new IllegalStateException("Tried to attach incomplete texture to framebuffer!"); + } GL40.glFramebufferTexture2D(GL40.GL_FRAMEBUFFER, GL40.GL_DEPTH_ATTACHMENT, GL40.GL_TEXTURE_2D, depthTexture.getTexturePointer(), 0); Globals.renderingEngine.checkError(); Globals.renderingEngine.defaultFramebuffer.bind(openGLState); diff --git a/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java b/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java index e3e496eb..6aa7b33c 100644 --- a/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java +++ b/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java @@ -81,6 +81,12 @@ public class FramebufferUtils { Texture texture = new Texture(); texture.glTexImage2D(openGLState, width, height, GL_DEPTH_COMPONENT, GL_FLOAT); + texture.setMinFilter(openGLState, GL_LINEAR); + texture.setMagFilter(openGLState, GL_LINEAR); + //these make sure the texture actually clamps to the borders of the quad + texture.setWrap(openGLState, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + texture.setWrap(openGLState, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + //guarantees that the texture object has actually been created (calling gen buffers does not guarantee object creation) texture.bind(openGLState); openGLState.glBindTexture(GL40.GL_TEXTURE_2D, Texture.DEFAULT_TEXTURE); diff --git a/src/main/java/electrosphere/renderer/texture/Texture.java b/src/main/java/electrosphere/renderer/texture/Texture.java index aa656ee5..df0c659f 100644 --- a/src/main/java/electrosphere/renderer/texture/Texture.java +++ b/src/main/java/electrosphere/renderer/texture/Texture.java @@ -14,6 +14,7 @@ import java.nio.IntBuffer; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.GL45; import org.lwjgl.stb.STBImage; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; @@ -398,6 +399,21 @@ public class Texture { Globals.renderingEngine.checkError(); } + /** + * Specifies a 2d image + * @param width The width of the image + * @param height The height of the image + * @param datatype The data type of a single component of a pixel (ie GL_BYTE, GL_UNSIGNED_INT, etc) + */ + public void glTextureStorage2D(OpenGLState openGLState, int width, int height, int format, int datatype){ + //store provided values + this.width = width; + this.height = height; + this.datatype = datatype; + GL45.glTextureStorage2D(this.texturePointer, 1, datatype, width, height); + Globals.renderingEngine.checkError(); + } + /** * Specifies a 2d image * @param width The width of the image @@ -482,6 +498,7 @@ public class Texture { * @param state The opengl state */ public void checkStatus(OpenGLState state){ + //try bind approach this.bind(state); int errorCode = Globals.renderingEngine.getError(); if(errorCode != GL40.GL_NO_ERROR){ @@ -503,6 +520,12 @@ public class Texture { } break; } } + //try dedicated approach + boolean isTexture = GL40.glIsTexture(this.texturePointer); + if(!isTexture){ + String message = "Texture is not complete!"; + LoggerInterface.loggerRenderer.ERROR(new IllegalStateException(message)); + } } @Override