diff --git a/src/client/java/su/divan2000/veila/client/gl/FullscreenQuad.java b/src/client/java/su/divan2000/veila/client/gl/FullscreenQuad.java index 5ab3a7b..6e6937a 100644 --- a/src/client/java/su/divan2000/veila/client/gl/FullscreenQuad.java +++ b/src/client/java/su/divan2000/veila/client/gl/FullscreenQuad.java @@ -39,6 +39,7 @@ public final class FullscreenQuad { vbo = GL15.glGenBuffers(); int previous = glGetInteger(GL_VERTEX_ARRAY_BINDING); + int previousArrayBuffer = GL11.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING); GL30.glBindVertexArray(vao); @@ -56,6 +57,7 @@ public final class FullscreenQuad { ); GL30.glBindVertexArray(previous); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, previousArrayBuffer); } public static void draw() { diff --git a/src/client/java/su/divan2000/veila/client/render/PostProcessingManager.java b/src/client/java/su/divan2000/veila/client/render/PostProcessingManager.java index 6acf930..42b5e63 100644 --- a/src/client/java/su/divan2000/veila/client/render/PostProcessingManager.java +++ b/src/client/java/su/divan2000/veila/client/render/PostProcessingManager.java @@ -41,6 +41,10 @@ public class PostProcessingManager { private static final FloatBuffer projectionBuffer = BufferUtils.createFloatBuffer(16); private static final FloatBuffer inverseProjectionBuffer = BufferUtils.createFloatBuffer(16); + private static final int[] previousViewport = new int[4]; + private static final int[] previousTexture2D = new int[5]; + private static final int[] previousTexture3D = new int[5]; + /* * Uniform locations - Raymarch Program */ @@ -171,11 +175,15 @@ public class PostProcessingManager { scaledWidth = (int)(width * scale); scaledHeight = (int)(height * scale); + int previousFramebuffer = GL11.glGetInteger(GL30.GL_FRAMEBUFFER_BINDING); + int previousActiveTexture = GL11.glGetInteger(GL13.GL_ACTIVE_TEXTURE); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + int previousTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + scaledFBO = GL30.glGenFramebuffers(); GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, scaledFBO); scaledTexture = GL11.glGenTextures(); - GL13.glActiveTexture(GL13.GL_TEXTURE0); GL11.glBindTexture(GL11.GL_TEXTURE_2D, scaledTexture); GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL30.GL_RGBA16F, scaledWidth, scaledHeight, 0, GL11.GL_RGBA, GL11.GL_FLOAT, 0); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); @@ -196,7 +204,9 @@ public class PostProcessingManager { GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT1, GL11.GL_TEXTURE_2D, scaledDepthTexture, 0); - GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, previousTexture0); + GL13.glActiveTexture(previousActiveTexture); + GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, previousFramebuffer); } public static void render(float tickDelta) { @@ -208,36 +218,64 @@ public class PostProcessingManager { if (client.world == null) return; - Framebuffer framebuffer = client.getFramebuffer(); + int previousProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + int previousActiveTexture = GL11.glGetInteger(GL13.GL_ACTIVE_TEXTURE); + int previousDrawFramebuffer = GL11.glGetInteger(GL30.GL_DRAW_FRAMEBUFFER_BINDING); + int previousReadFramebuffer = GL11.glGetInteger(GL30.GL_READ_FRAMEBUFFER_BINDING); + int previousDrawBuffer = GL11.glGetInteger(GL11.GL_DRAW_BUFFER); + GL11.glGetIntegerv(GL11.GL_VIEWPORT, previousViewport); - int width = framebuffer.textureWidth; - int height = framebuffer.textureHeight; - - // Инициализация scaled фреймбуфера - if (scaledFBO == 0 || scaledWidth != (int)(width * scale) || scaledHeight != (int)(height * scale)) { - if (scaledFBO != 0) { - GL30.glDeleteFramebuffers(scaledFBO); - GL11.glDeleteTextures(scaledTexture); - GL11.glDeleteTextures(scaledDepthTexture); - } - initScaledFramebuffer(width, height); + for (int unit = 0; unit <= 4; unit++) { + GL13.glActiveTexture(GL13.GL_TEXTURE0 + unit); + previousTexture2D[unit] = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + previousTexture3D[unit] = GL11.glGetInteger(GL12.GL_TEXTURE_BINDING_3D); } + GL13.glActiveTexture(previousActiveTexture); - GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, framebuffer.fbo); + try { + Framebuffer framebuffer = client.getFramebuffer(); - DepthCopy.init(width, height); - DepthCopy.copy(width, height); + int width = framebuffer.textureWidth; + int height = framebuffer.textureHeight; - renderDepthDownsample(width, height); + // Инициализация scaled фреймбуфера + if (scaledFBO == 0 || scaledWidth != (int)(width * scale) || scaledHeight != (int)(height * scale)) { + if (scaledFBO != 0) { + GL30.glDeleteFramebuffers(scaledFBO); + GL11.glDeleteTextures(scaledTexture); + GL11.glDeleteTextures(scaledDepthTexture); + } + initScaledFramebuffer(width, height); + } - // === Этап 1: Raymarching в scaled разрешении === - renderRaymarching(tickDelta, client); + GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, framebuffer.fbo); - // === Этап 2: Композитинг с JBU в полном разрешении === - renderComposite(framebuffer, width, height); + DepthCopy.init(width, height); + DepthCopy.copy(width, height); + updateProjectionMatrices(); - GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, 0); - GL13.glActiveTexture(GL13.GL_TEXTURE0); + renderDepthDownsample(width, height); + + // === Этап 1: Raymarching в scaled разрешении === + renderRaymarching(tickDelta, client); + + // === Этап 2: Композитинг с JBU в полном разрешении === + renderComposite(framebuffer, width, height); + + GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, 0); + } finally { + for (int unit = 4; unit >= 0; unit--) { + GL13.glActiveTexture(GL13.GL_TEXTURE0 + unit); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, previousTexture2D[unit]); + GL11.glBindTexture(GL12.GL_TEXTURE_3D, previousTexture3D[unit]); + } + GL13.glActiveTexture(previousActiveTexture); + GL20.glUseProgram(previousProgram); + GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, previousDrawFramebuffer); + GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, previousReadFramebuffer); + GL11.glDrawBuffer(previousDrawBuffer); + GL11.glViewport(previousViewport[0], previousViewport[1], previousViewport[2], previousViewport[3]); + } } private static void renderDepthDownsample(int width, int height) { @@ -259,7 +297,6 @@ public class PostProcessingManager { FullscreenQuad.draw(); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); depthDownsampleProgram.unbind(); } @@ -306,7 +343,6 @@ public class PostProcessingManager { FogSystem.ringChunkOffsetZ() * FogWorldVolume.CHUNK_SIZE); // Матрицы - updateProjectionMatrices(); GL20.glUniformMatrix4fv(rm_projectionLocation, false, projectionBuffer); GL20.glUniformMatrix4fv(rm_inverseProjectionLocation, false, inverseProjectionBuffer); GL20.glUniformMatrix4fv(rm_viewLocation, false, viewBuffer); @@ -372,7 +408,6 @@ public class PostProcessingManager { GL20.glUniform1i(comp_scaledDepthSamplerLocation, 3); // Матрицы для линеаризации depth - updateProjectionMatrices(); GL20.glUniformMatrix4fv(comp_inverseProjectionLocation, false, inverseProjectionBuffer); // Screen size @@ -382,14 +417,7 @@ public class PostProcessingManager { FullscreenQuad.draw(); // Очистка - GL13.glActiveTexture(GL13.GL_TEXTURE3); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); - GL13.glActiveTexture(GL13.GL_TEXTURE2); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); + // restore state once in render() finalizer compositeProgram.unbind(); }