diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java index e08ad746c..fdbf3902b 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java @@ -60,7 +60,7 @@ import net.minecraft.util.math.ChunkPos; * This object is used to create NearFarBuffer objects. * * @author James Seibel - * @version 9-25-2021 + * @version 10-2-2021 */ public class LodBufferBuilder { @@ -550,14 +550,8 @@ public class LodBufferBuilder try { // make sure we are uploading to the builder context, - // to prevent interference (IE stuttering) with the Minecraft context. - // But only set the context once, we don't need to set it multiple times. - if (glProxy.getGlContext() != GlProxyContext.LOD_BUILDER) - { - glProxy.setGlContext(GlProxyContext.LOD_BUILDER); - ClientProxy.LOGGER.debug(Thread.currentThread().getName() + ": setting OpenGL context to: [" + GlProxyContext.LOD_BUILDER + "]"); - } - + // this helps prevent interference (IE stuttering) with the Minecraft context. + glProxy.setGlContext(GlProxyContext.LOD_BUILDER); // actually upload the buffers for (int x = 0; x < buildableVbos.length; x++) @@ -581,6 +575,13 @@ public class LodBufferBuilder ClientProxy.LOGGER.error(LodBufferBuilder.class.getSimpleName() + " - UploadBuffers failed: " + e.getMessage()); e.printStackTrace(); } + finally + { + // close the context so it can be re-used later. + // I'm guessing we can't just leave it because the executer service + // does something that invalidates the OpenGL context + glProxy.setGlContext(GlProxyContext.NONE); + } } /** diff --git a/src/main/java/com/seibel/lod/proxy/ClientProxy.java b/src/main/java/com/seibel/lod/proxy/ClientProxy.java index 8e525ed38..dd61024ef 100644 --- a/src/main/java/com/seibel/lod/proxy/ClientProxy.java +++ b/src/main/java/com/seibel/lod/proxy/ClientProxy.java @@ -258,7 +258,6 @@ public class ClientProxy ThreadMapUtil.clearMaps(); LodWorldGenerator.INSTANCE.numberOfChunksWaitingToGenerate.set(0); - // the player has disconnected from a server lodWorld.deselectWorld(); @@ -359,7 +358,7 @@ public class ClientProxy */ public void firstFrameSetup() { - // make sure the GlProxy is created before the LodBufferBuilder + // make sure the GlProxy is created before the LodBufferBuilder needs it GlProxy.getInstance(); // TODO shouldn't these already be empty? diff --git a/src/main/java/com/seibel/lod/proxy/GlProxy.java b/src/main/java/com/seibel/lod/proxy/GlProxy.java index afc82266d..0d2e36595 100644 --- a/src/main/java/com/seibel/lod/proxy/GlProxy.java +++ b/src/main/java/com/seibel/lod/proxy/GlProxy.java @@ -1,15 +1,8 @@ package com.seibel.lod.proxy; -import org.apache.commons.lang3.SystemUtils; -import org.lwjgl.PointerBuffer; -import org.lwjgl.opengl.CGL; +import org.lwjgl.glfw.GLFW; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GLCapabilities; -import org.lwjgl.opengl.GLX; -import org.lwjgl.opengl.GLX14; -import org.lwjgl.opengl.WGL; -import org.lwjgl.system.linux.X11; -import org.lwjgl.system.linux.XVisualInfo; import com.mojang.blaze3d.systems.RenderSystem; import com.seibel.lod.enums.GlProxyContext; @@ -27,37 +20,23 @@ import com.seibel.lod.enums.GlProxyContext; * * * @author James Seibel - * @version 10-1-2021 + * @version 10-2-2021 */ public class GlProxy { private static GlProxy instance = null; - - // windows context variables - private long windowsDeviceContext; - - // mac context variables - private long macPixelFormat; - - // linux context variables - long linuxDisplayID; - - long linuxMcDrawable; - long linuxMcReadDrawable; - - long linuxLodBuilderDrawable; - long linuxLodBuilderReadDrawable; - - - + /** Minecraft's GLFW window */ public final long minecraftGlContext; + /** Minecraft's GL context */ public final GLCapabilities minecraftGlCapabilities; + /** the LodBuilder's GLFW window */ public final long lodBuilderGlContext; + /** the LodBuilder's GL context */ public final GLCapabilities lodBuilderGlCapabilities; - /** This is just used for debugging, hopefuly it can be removed once + /** This is just used for debugging, hopefully it can be removed once * the context switching is more stable. */ public Thread lodBuilderOwnerThread = null; @@ -80,81 +59,25 @@ public class GlProxy // create the builder context // //============================// - + // get Minecraft's context + minecraftGlContext = GLFW.glfwGetCurrentContext(); minecraftGlCapabilities = GL.getCapabilities(); - // run OS specific context creation code - if (SystemUtils.IS_OS_WINDOWS) - { - ClientProxy.LOGGER.info(GlProxy.class.getSimpleName() + " Running Windows setup."); - - // get Minecraft variables - minecraftGlContext = WGL.wglGetCurrentContext(); - windowsDeviceContext = WGL.wglGetCurrentDC(); - - // setup the lodBuilder variables - lodBuilderGlContext = WGL.wglCreateContext(windowsDeviceContext); - if (!WGL.wglShareLists(minecraftGlContext, lodBuilderGlContext)) - throw new IllegalStateException("Unable to share lists between Minecraft and builder contexts."); - if (!WGL.wglMakeCurrent(windowsDeviceContext, lodBuilderGlContext)) - throw new IllegalStateException("Unable to change OpenGL contexts! tried to change to [" + GlProxyContext.LOD_BUILDER.toString() + "] from [" + GlProxyContext.MINECRAFT.toString() + "]"); - lodBuilderGlCapabilities = GL.createCapabilities(); - } - else if (SystemUtils.IS_OS_MAC) - { - ClientProxy.LOGGER.info(GlProxy.class.getSimpleName() + " Running Mac setup."); - - // get Minecraft variables - minecraftGlContext = CGL.CGLGetCurrentContext(); - macPixelFormat = CGL.CGLGetPixelFormat(minecraftGlContext); - - // setup the lodBuilder variables - lodBuilderGlContext = CGL.CGLCreateContext(macPixelFormat, minecraftGlContext, null); - lodBuilderGlCapabilities = GL.createCapabilities(); - } - else - { - // if we can't determine the OS, default to linux - if (SystemUtils.IS_OS_LINUX) - ClientProxy.LOGGER.info(GlProxy.class.getSimpleName() + " Running Linux setup."); - else - ClientProxy.LOGGER.info(GlProxy.class.getSimpleName() + " Unkown OS: [" + SystemUtils.OS_NAME + "] Running Linux setup."); - - - // get Minecraft variables // - - minecraftGlContext = GLX14.glXGetCurrentContext(); - linuxDisplayID = GLX14.glXGetCurrentDisplay(); - - - // setup the lodBuilder variables // - - linuxMcDrawable = GLX14.glXGetCurrentDrawable(); - linuxMcReadDrawable = GLX14.glXGetCurrentReadDrawable(); - - // single buffered example config -// int attributeList[] = { GLX.GLX_RGBA, -// GLX.GLX_RED_SIZE, 1, -// GLX.GLX_GREEN_SIZE, 1, -// GLX.GLX_BLUE_SIZE, 1, -// GLX.GLX_DEPTH_SIZE, 12, -// X11.None }; - - // use the defaults for all config options - int attributeList[] = { X11.None }; - - PointerBuffer config = GLX14.glXChooseFBConfig(linuxDisplayID, 0, attributeList); - XVisualInfo visualInfo = GLX14.glXGetVisualFromFBConfig(linuxDisplayID, config.address()); - lodBuilderGlContext = GLX14.glXCreateContext(linuxDisplayID, visualInfo, minecraftGlContext, false); - lodBuilderGlCapabilities = GL.createCapabilities(); - - linuxLodBuilderDrawable = GLX14.glXGetCurrentDrawable(); - linuxLodBuilderReadDrawable = GLX14.glXGetCurrentReadDrawable(); - } + // create the LodBuilder's context + // Hopefully this shouldn't cause any issues with other mods that need custom contexts + // (although the number that do should be relatively few) + GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE); + + // create an invisible window to hold the context + lodBuilderGlContext = GLFW.glfwCreateWindow(640, 480, "LOD window", 0L, minecraftGlContext); + GLFW.glfwMakeContextCurrent(lodBuilderGlContext); + lodBuilderGlCapabilities = GL.createCapabilities(); // Since this is called on the render thread, make sure the Minecraft context is used in the end - setGlContext(GlProxyContext.MINECRAFT); + GLFW.glfwMakeContextCurrent(minecraftGlContext); + GL.setCapabilities(minecraftGlCapabilities); + @@ -192,25 +115,17 @@ public class GlProxy long contextPointer = 0L; - long linuxDrawable = 0L; - long linuxReadDrawable = 0L; GLCapabilities newGlCapabilities = null; // get the pointer(s) for this context switch(newContext) { case LOD_BUILDER: - linuxDrawable = linuxLodBuilderDrawable; - linuxReadDrawable = linuxLodBuilderReadDrawable; - contextPointer = lodBuilderGlContext; newGlCapabilities = lodBuilderGlCapabilities; break; case MINECRAFT: - linuxDrawable = linuxMcDrawable; - linuxReadDrawable = linuxMcReadDrawable; - contextPointer = minecraftGlContext; newGlCapabilities = minecraftGlCapabilities; break; @@ -218,8 +133,6 @@ public class GlProxy default: // default should never happen, it is just here to make the compiler happy case NONE: // 0L is equivalent to null - linuxDrawable = 0L; - linuxReadDrawable = 0L; contextPointer = 0L; newGlCapabilities = null; @@ -227,26 +140,7 @@ public class GlProxy } - String contextSwitchError = "Unable to change OpenGL contexts! tried to change to [" + newContext.toString() + "] from [" + currentContext.toString() + "] on thread: [" + Thread.currentThread().getName() + "] lod builder owner thread: " + (lodBuilderOwnerThread != null ? lodBuilderOwnerThread.getName() : "null"); - - // run the OS specific context switching code - if (SystemUtils.IS_OS_WINDOWS) - { - if (!WGL.wglMakeCurrent(windowsDeviceContext, contextPointer)) - throw new IllegalStateException(contextSwitchError); - } - else if (SystemUtils.IS_OS_MAC) - { - if (CGL.CGLSetCurrentContext(contextPointer) != CGL.kCGLNoError) - throw new IllegalStateException(contextSwitchError); - } - else //if (SystemUtils.IS_OS_LINUX) - { - // default to linux - if (!GLX14.glXMakeContextCurrent(linuxDisplayID, linuxDrawable, linuxReadDrawable, contextPointer)) - throw new IllegalStateException(contextSwitchError); - } - + GLFW.glfwMakeContextCurrent(contextPointer); GL.setCapabilities(newGlCapabilities); @@ -265,14 +159,7 @@ public class GlProxy /** Returns this thread's OpenGL context. */ public GlProxyContext getGlContext() { - long currentContext; - - if (SystemUtils.IS_OS_WINDOWS) - currentContext = WGL.wglGetCurrentContext(); - else if (SystemUtils.IS_OS_MAC) - currentContext = CGL.CGLGetCurrentContext(); - else //if (SystemUtils.IS_OS_LINUX) // default to Linux - currentContext = GLX.glXGetCurrentContext(); + long currentContext = GLFW.glfwGetCurrentContext(); if(currentContext == lodBuilderGlContext) @@ -294,7 +181,8 @@ public class GlProxy { if (instance == null) instance = new GlProxy(); - }catch (Exception e) + } + catch (Exception e) { e.printStackTrace(); } @@ -309,5 +197,4 @@ public class GlProxy - }