Replace many GL32 calls with GLMC (IMinecraftGLWrapper)

Also fix wireframe rendering
This commit is contained in:
James Seibel
2024-12-07 09:56:36 -06:00
parent 872421f39f
commit 821fa086e6
23 changed files with 534 additions and 501 deletions
@@ -887,7 +887,6 @@ public class Config
+ " Mod compatibility is not guaranteed.")
.build();
@Deprecated // TODO fixme
public static ConfigEntry<Boolean> renderWireframe = new ConfigEntry.Builder<Boolean>()
.set(false)
.comment(""
@@ -20,12 +20,12 @@
package com.seibel.distanthorizons.core.config.gui;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
import com.seibel.distanthorizons.core.render.glObject.GLState;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute;
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import org.lwjgl.opengl.GL32;
import java.nio.ByteBuffer;
@@ -36,26 +36,30 @@ import java.nio.ByteOrder;
*/
public class OpenGLConfigScreen extends AbstractScreen
{
ShaderProgram basicShader;
GLVertexBuffer sameContextBuffer;
GLVertexBuffer sharedContextBuffer;
AbstractVertexAttribute va;
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
private ShaderProgram basicShader;
private GLVertexBuffer sameContextBuffer;
private GLVertexBuffer sharedContextBuffer;
private AbstractVertexAttribute va;
@Override
public void init()
{
System.out.println("init");
va = AbstractVertexAttribute.create();
va.bind();
this.va = AbstractVertexAttribute.create();
this.va.bind();
// Pos
va.setVertexAttribute(0, 0, VertexPointer.addVec2Pointer(false));
this.va.setVertexAttribute(0, 0, VertexPointer.addVec2Pointer(false));
// Color
va.setVertexAttribute(0, 1, VertexPointer.addVec4Pointer(false));
va.completeAndCheck(Float.BYTES * 6);
basicShader = new ShaderProgram("shaders/test/vert.vert", "shaders/test/frag.frag",
"fragColor", new String[]{"vPosition", "color"});
createBuffer();
this.va.setVertexAttribute(0, 1, VertexPointer.addVec4Pointer(false));
this.va.completeAndCheck(Float.BYTES * 6);
this.basicShader = new ShaderProgram("shaders/test/vert.vert", "shaders/test/frag.frag",
"fragColor", new String[]{"vPosition", "color"});
this.createBuffer();
}
// Render a square with uv color
@@ -82,8 +86,8 @@ public class OpenGLConfigScreen extends AbstractScreen
private void createBuffer()
{
sharedContextBuffer = createTextingBuffer();
sameContextBuffer = createTextingBuffer();
this.sharedContextBuffer = createTextingBuffer();
this.sameContextBuffer = createTextingBuffer();
}
@Override
@@ -91,40 +95,32 @@ public class OpenGLConfigScreen extends AbstractScreen
{
System.out.println("Updated config screen with the delta of " + delta);
GLState state = new GLState();
GL32.glViewport(0, 0, width, height);
GL32.glViewport(0, 0, this.width, this.height);
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
GL32.glDisable(GL32.GL_CULL_FACE);
GL32.glDisable(GL32.GL_DEPTH_TEST);
GL32.glDisable(GL32.GL_STENCIL_TEST);
GL32.glDisable(GL32.GL_BLEND);
//GL32.glDisable(GL32.GL_SCISSOR_TEST);
GLMC.disableFaceCulling();
GLMC.disableDepthTest();
GLMC.disableBlend();
basicShader.bind();
va.bind();
this.basicShader.bind();
this.va.bind();
// Switch between the two buffers per second
if (System.currentTimeMillis() % 2000 < 1000)
{
sameContextBuffer.bind();
va.bindBufferToAllBindingPoints(sameContextBuffer.getId());
this.sameContextBuffer.bind();
this.va.bindBufferToAllBindingPoints(this.sameContextBuffer.getId());
}
else
{
sameContextBuffer.bind();
va.bindBufferToAllBindingPoints(sharedContextBuffer.getId());
this.sameContextBuffer.bind();
this.va.bindBufferToAllBindingPoints(this.sharedContextBuffer.getId());
}
// Render the square
GL32.glDrawArrays(GL32.GL_TRIANGLE_FAN, 0, 4);
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
state.restore();
}
@Override
public void tick()
{
System.out.println("Ticked");
}
public void tick() { System.out.println("Ticked"); }
}
@@ -33,11 +33,14 @@ import com.seibel.distanthorizons.core.logging.f3.F3Screen;
import com.seibel.distanthorizons.core.pos.DhLodPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.pos.Pos2D;
import com.seibel.distanthorizons.core.render.glObject.buffer.QuadElementBuffer;
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
import com.seibel.distanthorizons.core.util.objects.quadTree.QuadNode;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IOverrideInjector;
@@ -47,6 +50,7 @@ import com.seibel.distanthorizons.core.util.math.Vec3f;
import org.apache.logging.log4j.Logger;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.lwjgl.opengl.GL32;
import java.util.Comparator;
import java.util.Iterator;
@@ -62,6 +66,7 @@ public class RenderBufferHandler implements AutoCloseable
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class);
@@ -343,26 +348,69 @@ public class RenderBufferHandler implements AutoCloseable
// render methods //
//================//
public void renderOpaque(LodRenderer renderContext, DhApiRenderParam renderEventParam)
{
// TODO why can these sometimes be null when teleporting between multiverses
if (this.loadedNearToFarBuffers != null)
{
this.loadedNearToFarBuffers.forEach(loadedBuffer -> loadedBuffer.buffer.renderOpaque(renderContext, renderEventParam));
}
}
public void renderOpaque(LodRenderer renderContext,DhApiRenderParam renderEventParam)
{ this.renderPass(renderContext, renderEventParam, true); }
public void renderTransparent(LodRenderer renderContext, DhApiRenderParam renderEventParam)
{ this.renderPass(renderContext, renderEventParam, false); }
private void renderPass(LodRenderer renderContext, DhApiRenderParam renderEventParam, boolean opaquePass)
{
// TODO why can these sometimes be null when teleporting between multiverses
if (this.loadedNearToFarBuffers != null)
//=======================//
// debug wireframe setup //
//=======================//
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
if (renderWireframe)
{
ListIterator<LoadedRenderBuffer> iter = this.loadedNearToFarBuffers.listIterator(this.loadedNearToFarBuffers.size());
while (iter.hasPrevious())
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
GLMC.disableFaceCulling();
}
else
{
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
GLMC.enableFaceCulling();
}
//===========//
// rendering //
//===========//
if (opaquePass)
{
// TODO why can these sometimes be null when teleporting between multiverses
if (this.loadedNearToFarBuffers != null)
{
LoadedRenderBuffer loadedBuffer = iter.previous();
loadedBuffer.buffer.renderTransparent(renderContext, renderEventParam);
this.loadedNearToFarBuffers.forEach(loadedBuffer -> loadedBuffer.buffer.renderOpaque(renderContext, renderEventParam));
}
}
else
{
// TODO why can these sometimes be null when teleporting between multiverses
if (this.loadedNearToFarBuffers != null)
{
ListIterator<LoadedRenderBuffer> iter = this.loadedNearToFarBuffers.listIterator(this.loadedNearToFarBuffers.size());
while (iter.hasPrevious())
{
LoadedRenderBuffer loadedBuffer = iter.previous();
loadedBuffer.buffer.renderTransparent(renderContext, renderEventParam);
}
}
}
//=========================//
// debug wireframe cleanup //
//=========================//
if (renderWireframe)
{
// default back to GL_FILL since all other rendering uses it
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
GLMC.enableFaceCulling();
}
}
@@ -19,11 +19,16 @@
package com.seibel.distanthorizons.core.render.glObject;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import org.lwjgl.opengl.GL32;
// TODO make this Closable or AutoClosable so it can be used with try-resource blocks
public class GLState
{
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
private static final int FBO_MAX = 4;
public int program;
@@ -52,17 +57,19 @@ public class GLState
public boolean depth;
public boolean writeToDepthBuffer;
public int depthFunc;
public boolean stencil;
public int stencilFunc;
public int stencilRef;
public int stencilMask;
//public boolean stencil;
//public int stencilFunc;
//public int stencilRef;
//public int stencilMask;
public int[] view;
public boolean cull;
public int cullMode;
public int polyMode;
public GLState() {
public GLState()
{
this.fbo = new int[FBO_MAX];
this.saveState();
@@ -80,19 +87,19 @@ public class GLState
this.texture2D = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
this.activeTextureNumber = GL32.glGetInteger(GL32.GL_ACTIVE_TEXTURE);
GL32.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
this.texture0 = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
GL32.glActiveTexture(GL32.GL_TEXTURE1);
GLMC.glActiveTexture(GL32.GL_TEXTURE1);
this.texture1 = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
GL32.glActiveTexture(GL32.GL_TEXTURE2);
GLMC.glActiveTexture(GL32.GL_TEXTURE2); // problem with Iris
this.texture2 = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
GL32.glActiveTexture(GL32.GL_TEXTURE3);
GLMC.glActiveTexture(GL32.GL_TEXTURE3);
this.texture3= GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
GL32.glActiveTexture(this.activeTextureNumber);
GLMC.glActiveTexture(this.activeTextureNumber);
this.frameBufferTexture0 = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
this.frameBufferTexture1 = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT1, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
@@ -109,10 +116,10 @@ public class GLState
this.depth = GL32.glIsEnabled(GL32.GL_DEPTH_TEST);
this.writeToDepthBuffer = GL32.glGetInteger(GL32.GL_DEPTH_WRITEMASK) == GL32.GL_TRUE;
this.depthFunc = GL32.glGetInteger(GL32.GL_DEPTH_FUNC);
this.stencil = GL32.glIsEnabled(GL32.GL_STENCIL_TEST);
this.stencilFunc = GL32.glGetInteger(GL32.GL_STENCIL_FUNC);
this.stencilRef = GL32.glGetInteger(GL32.GL_STENCIL_REF);
this.stencilMask = GL32.glGetInteger(GL32.GL_STENCIL_VALUE_MASK);
//this.stencil = GL32.glIsEnabled(GL32.GL_STENCIL_TEST);
//this.stencilFunc = GL32.glGetInteger(GL32.GL_STENCIL_FUNC);
//this.stencilRef = GL32.glGetInteger(GL32.GL_STENCIL_REF);
//this.stencilMask = GL32.glGetInteger(GL32.GL_STENCIL_VALUE_MASK);
this.view = new int[4];
GL32.glGetIntegerv(GL32.GL_VIEWPORT, this.view);
this.cull = GL32.glIsEnabled(GL32.GL_CULL_FACE);
@@ -131,8 +138,8 @@ public class GLState
", FB depth=" + this.frameBufferDepthTexture +
", blend=" + this.blend + ", scissor=" + this.scissor + ", blendMode=" + GLEnums.getString(this.blendSrcColor) + "," + GLEnums.getString(this.blendDstColor) +
", depth=" + this.depth +
", depthFunc=" + GLEnums.getString(this.depthFunc) + ", stencil=" + this.stencil + ", stencilFunc=" +
GLEnums.getString(this.stencilFunc) + ", stencilRef=" + this.stencilRef + ", stencilMask=" + this.stencilMask +
//", depthFunc=" + GLEnums.getString(this.depthFunc) + ", stencil=" + this.stencil + ", stencilFunc=" +
//GLEnums.getString(this.stencilFunc) + ", stencilRef=" + this.stencilRef + ", stencilMask=" + this.stencilMask +
", view={x:" + this.view[0] + ", y:" + this.view[1] +
", w:" + this.view[2] + ", h:" + this.view[3] + "}" + ", cull=" + this.cull + ", cullMode="
+ GLEnums.getString(this.cullMode) + ", polyMode=" + GLEnums.getString(this.polyMode) +
@@ -142,14 +149,14 @@ public class GLState
public void RestoreFrameBuffer()
{
// explicitly unbinding the frame buffer is necessary to prevent GL_CLEAR calls from hitting the wrong buffer
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, 0);
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, 0);
for (int i = 0; i < FBO_MAX; i++)
{
int buffer = this.fbo[i];
if (i > 0 && buffer == 0) break;
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, GL32.glIsFramebuffer(buffer) ? buffer : 0);
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, GL32.glIsFramebuffer(buffer) ? buffer : 0);
}
}
@@ -159,36 +166,36 @@ public class GLState
if (this.blend)
{
GL32.glEnable(GL32.GL_BLEND);
GLMC.enableBlend();
}
else
{
GL32.glDisable(GL32.GL_BLEND);
GLMC.disableBlend();
}
if (this.scissor)
{
GL32.glEnable(GL32.GL_SCISSOR_TEST);
GLMC.enableScissorTest();
}
else
{
GL32.glDisable(GL32.GL_SCISSOR_TEST);
GLMC.disableScissorTest();
}
GL32.glActiveTexture(GL32.GL_TEXTURE0);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, GL32.glIsTexture(this.texture0) ? this.texture0 : 0);
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(GL32.glIsTexture(this.texture0) ? this.texture0 : 0);
GL32.glActiveTexture(GL32.GL_TEXTURE1);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, GL32.glIsTexture(this.texture1) ? this.texture1 : 0);
GLMC.glActiveTexture(GL32.GL_TEXTURE1);
GLMC.glBindTexture(GL32.glIsTexture(this.texture1) ? this.texture1 : 0);
GL32.glActiveTexture(GL32.GL_TEXTURE2);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, GL32.glIsTexture(this.texture2) ? this.texture2 : 0);
GLMC.glActiveTexture(GL32.GL_TEXTURE2);
GLMC.glBindTexture(GL32.glIsTexture(this.texture2) ? this.texture2 : 0);
GL32.glActiveTexture(GL32.GL_TEXTURE3);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, GL32.glIsTexture(this.texture3) ? this.texture3 : 0);
GLMC.glActiveTexture(GL32.GL_TEXTURE3);
GLMC.glBindTexture(GL32.glIsTexture(this.texture3) ? this.texture3 : 0);
GL32.glActiveTexture(this.activeTextureNumber);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, GL32.glIsTexture(this.texture2D) ? this.texture2D : 0);
GLMC.glActiveTexture(this.activeTextureNumber);
GLMC.glBindTexture(GL32.glIsTexture(this.texture2D) ? this.texture2D : 0);
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.frameBufferTexture0, 0);
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT1, GL32.GL_TEXTURE_2D, this.frameBufferTexture1, 0);
@@ -199,39 +206,47 @@ public class GLState
GL32.glBindBuffer(GL32.GL_ELEMENT_ARRAY_BUFFER, GL32.glIsBuffer(this.ebo) ? this.ebo: 0);
GL32.glUseProgram(GL32.glIsProgram(this.program) ? this.program : 0);
GL32.glDepthMask(this.writeToDepthBuffer);
if (this.writeToDepthBuffer)
{
GLMC.enableDepthMask();
}
else
{
GLMC.disableDepthMask();
}
//GL32.glBlendFunc(this.blendSrcColor, this.blendDstColor);
GL32.glBlendEquationSeparate(this.blendEqRGB, this.blendEqAlpha);
GL32.glBlendFuncSeparate(this.blendSrcColor, this.blendDstColor, this.blendSrcAlpha, this.blendDstAlpha);
GLMC.glBlendFuncSeparate(this.blendSrcColor, this.blendDstColor, this.blendSrcAlpha, this.blendDstAlpha);
if (this.depth)
{
GL32.glEnable(GL32.GL_DEPTH_TEST);
GLMC.enableDepthTest();
}
else
{
GL32.glDisable(GL32.GL_DEPTH_TEST);
GLMC.disableDepthTest();
}
GL32.glDepthFunc(this.depthFunc);
GLMC.glDepthFunc(this.depthFunc);
if (this.stencil)
{
GL32.glEnable(GL32.GL_STENCIL_TEST);
}
else
{
GL32.glDisable(GL32.GL_STENCIL_TEST);
}
GL32.glStencilFunc(this.stencilFunc, this.stencilRef, this.stencilMask);
//if (this.stencil)
//{
// GL32.glEnable(GL32.GL_STENCIL_TEST);
//}
//else
//{
// GL32.glDisable(GL32.GL_STENCIL_TEST);
//}
//GL32.glStencilFunc(this.stencilFunc, this.stencilRef, this.stencilMask);
GL32.glViewport(this.view[0], this.view[1], this.view[2], this.view[3]);
if (this.cull)
{
GL32.glEnable(GL32.GL_CULL_FACE);
GLMC.enableFaceCulling();
}
else
{
GL32.glDisable(GL32.GL_CULL_FACE);
GLMC.disableFaceCulling();
}
GL32.glCullFace(this.cullMode);
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, this.polyMode);
@@ -1,84 +0,0 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2023 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.core.render.glObject;
import org.lwjgl.opengl.GL32;
public class LightmapTexture
{
public int id;
public LightmapTexture()
{
id = GL32.glGenTextures();
bind();
}
public void bind()
{
GL32.glBindTexture(GL32.GL_TEXTURE_2D, id);
}
public void unbind()
{
GL32.glBindTexture(GL32.GL_TEXTURE_2D, 0);
}
public void free()
{
GL32.glDeleteTextures(id);
}
// private int[] testArray;
public void fillData(int lightMapWidth, int lightMapHeight, int[] pixels)
{
GL32.glDeleteTextures(id);
id = GL32.glGenTextures();
GL32.glBindTexture(GL32.GL_TEXTURE_2D, id);
if (pixels.length != lightMapWidth * lightMapHeight)
throw new RuntimeException("Lightmap Width*Height not equal to pixels provided!");
// comment me out to see when the lightmap is changing
/*
boolean same = true;
int badIndex = 0;
if (testArray != null && pixels != null)
for (int i = 0; i < pixels.length; i++)
{
if(pixels[i] != testArray[i])
{
same = false;
badIndex = i;
break;
}
}
testArray = pixels;
MC.sendChatMessage(same + " " + badIndex);
*/
// comment this line out to prevent uploading the new lightmap
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RGBA8, lightMapWidth * lightMapHeight,
1, 0, GL32.GL_RGBA, GL32.GL_UNSIGNED_BYTE, pixels);
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_S, GL32.GL_CLAMP_TO_BORDER);
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_T, GL32.GL_CLAMP_TO_BORDER);
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_NEAREST);
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_NEAREST);
}
}
@@ -21,11 +21,13 @@ package com.seibel.distanthorizons.core.render.glObject.buffer;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.ThreadUtil;
import com.seibel.distanthorizons.core.util.math.UnitBytes;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import org.apache.logging.log4j.Logger;
import org.lwjgl.opengl.GL32;
import org.lwjgl.opengl.GL44;
@@ -43,6 +45,9 @@ public class GLBuffer implements AutoCloseable
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
public static final double BUFFER_EXPANSION_MULTIPLIER = 1.3;
public static final double BUFFER_SHRINK_TRIGGER = BUFFER_EXPANSION_MULTIPLIER * BUFFER_EXPANSION_MULTIPLIER;
/** the number of active buffers, can be used for debugging */
@@ -99,7 +104,7 @@ public class GLBuffer implements AutoCloseable
LodUtil.assertNotReach("Thread ["+Thread.currentThread()+"] tried to create a GLBuffer outside the MC render thread.");
}
this.id = GL32.glGenBuffers();
this.id = GLMC.glGenBuffers();
this.bufferStorage = asBufferStorage;
bufferCount.getAndIncrement();
@@ -138,7 +143,7 @@ public class GLBuffer implements AutoCloseable
// the buffer may not exist if the destroy method is called twice
if (GL32.glIsBuffer(id))
{
GL32.glDeleteBuffers(id);
GLMC.glDeleteBuffers(id);
bufferCount.decrementAndGet();
if (Config.Client.Advanced.Debugging.logBufferGarbageCollection.get())
@@ -256,8 +261,8 @@ public class GLBuffer implements AutoCloseable
this.size = newSize;
if (this.bufferStorage)
{
GL32.glDeleteBuffers(this.id);
this.id = GL32.glGenBuffers();
GLMC.glDeleteBuffers(this.id);
this.id = GLMC.glGenBuffers();
GL32.glBindBuffer(this.getBufferBindingTarget(), this.id);
GL32.glBindBuffer(this.getBufferBindingTarget(), this.id);
GL44.glBufferStorage(this.getBufferBindingTarget(), newSize, bufferHint);
@@ -1,12 +1,16 @@
package com.seibel.distanthorizons.core.render.glObject.texture;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import org.lwjgl.opengl.GL32;
public class DhFramebuffer implements IDhApiFramebuffer
{
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
private final Int2IntMap attachments;
private final int maxDrawBuffers;
private final int maxColorAttachments;
@@ -113,12 +117,12 @@ public class DhFramebuffer implements IDhApiFramebuffer
{
throw new IllegalStateException("Framebuffer does not exist!");
}
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.id);
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.id);
}
public void bindAsReadBuffer() { GL32.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, this.id); }
public void bindAsReadBuffer() { GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, this.id); }
public void bindAsDrawBuffer() { GL32.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, this.id); }
public void bindAsDrawBuffer() { GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, this.id); }
@Override
public void destroy()
@@ -29,12 +29,12 @@ import com.seibel.distanthorizons.core.logging.ConfigBasedSpamLogger;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
import com.seibel.distanthorizons.core.pos.DhLodPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.glObject.GLState;
import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer;
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute;
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d;
@@ -52,14 +52,19 @@ import java.nio.ByteOrder;
import java.util.*;
import java.util.concurrent.PriorityBlockingQueue;
/**
* Handles rendering the wireframe particles that are used for seeing what the system's doing.
*/
public class DebugRenderer
{
public static DebugRenderer INSTANCE = new DebugRenderer();
public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(TestRenderer.class), () -> EDhApiLoggerMode.LOG_ALL_TO_CHAT);
public static final ConfigBasedSpamLogger SPAM_LOGGER = new ConfigBasedSpamLogger(LogManager.getLogger(TestRenderer.class), () -> EDhApiLoggerMode.LOG_ALL_TO_CHAT, 1);
public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(DebugRenderer.class), () -> EDhApiLoggerMode.LOG_ALL_TO_CHAT);
public static final ConfigBasedSpamLogger SPAM_LOGGER = new ConfigBasedSpamLogger(LogManager.getLogger(DebugRenderer.class), () -> EDhApiLoggerMode.LOG_ALL_TO_CHAT, 1);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
// rendering setup
@@ -191,21 +196,21 @@ public class DebugRenderer
Vec3d camPos = MC_RENDER.getCameraExactPosition();
this.camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z);
GLState glState = new GLState();
this.init();
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
GL32.glEnable(GL32.GL_DEPTH_TEST);
GLMC.enableDepthTest();
this.basicShader.bind();
this.va.bind();
this.va.bindBufferToAllBindingPoints(this.vertexBuffer.getId());
this.outlineIndexBuffer.bind();
this.outlineIndexBuffer.bind();
this.rendererLists.render(this);
// particle rendering
BoxParticle head = null;
while ((head = this.particles.poll()) != null && head.isDead(System.nanoTime()))
{ /* remove dead particles */ }
@@ -215,14 +220,13 @@ public class DebugRenderer
this.particles.add(head);
}
// box rendering
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
for (BoxParticle particle : this.particles)
{
this.renderBox(particle.getBox());
}
glState.restore();
}
public void renderBox(Box box)
@@ -26,6 +26,7 @@ import com.seibel.distanthorizons.core.render.renderer.shaders.FadeApplyShader;
import com.seibel.distanthorizons.core.render.renderer.shaders.FadeShader;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
@@ -49,6 +50,7 @@ public class FadeRenderer
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
private boolean init = false;
@@ -86,15 +88,15 @@ public class FadeRenderer
if (this.fadeTexture != -1)
{
GL32.glDeleteTextures(this.fadeTexture);
GLMC.glDeleteTextures(this.fadeTexture);
this.fadeTexture = -1;
}
this.fadeFramebuffer = GL32.glGenFramebuffers();
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.fadeFramebuffer);
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.fadeFramebuffer);
this.fadeTexture = GL32.glGenTextures();
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.fadeTexture);
GLMC.glBindTexture(this.fadeTexture);
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RGBA16, width, height, 0, GL32.GL_RGBA, GL32.GL_UNSIGNED_SHORT_4_4_4_4, (ByteBuffer) null);
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR);
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR);
@@ -115,7 +117,9 @@ public class FadeRenderer
profiler.push("DH-RenderLevel");
GLState mcState = new GLState();
// TODO try removing this now that we use GLMC
// if there are reports of things breaking, we might have to re-add it
//GLState mcState = new GLState();
try
{
@@ -140,7 +144,7 @@ public class FadeRenderer
FadeShader.INSTANCE.render(partialTicks);
// restored so we can write the fade texture to the main frame buffer
mcState.restore();
//mcState.restore();
profiler.popPush("Fade Apply");
@@ -156,7 +160,7 @@ public class FadeRenderer
finally
{
// make sure we always revert to MC's state to prevent GL state corruption
mcState.restore();
//mcState.restore();
}
}
@@ -20,10 +20,10 @@
package com.seibel.distanthorizons.core.render.renderer;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.glObject.GLState;
import com.seibel.distanthorizons.core.render.renderer.shaders.FogApplyShader;
import com.seibel.distanthorizons.core.render.renderer.shaders.FogShader;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import org.lwjgl.opengl.GL32;
@@ -40,6 +40,7 @@ public class FogRenderer
public static FogRenderer INSTANCE = new FogRenderer();
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
private boolean init = false;
@@ -77,15 +78,15 @@ public class FogRenderer
if (this.fogTexture != -1)
{
GL32.glDeleteTextures(this.fogTexture);
GLMC.glDeleteTextures(this.fogTexture);
this.fogTexture = -1;
}
this.fogFramebuffer = GL32.glGenFramebuffers();
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.fogFramebuffer);
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.fogFramebuffer);
this.fogTexture = GL32.glGenTextures();
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.fogTexture);
this.fogTexture = GLMC.glGenTextures();
GLMC.glBindTexture(this.fogTexture);
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RGBA16, width, height, 0, GL32.GL_RGBA, GL32.GL_UNSIGNED_SHORT_4_4_4_4, (ByteBuffer) null);
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR);
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR);
@@ -98,9 +99,8 @@ public class FogRenderer
// render //
//========//
public void render(GLState primaryState, Mat4f modelViewProjectionMatrix, float partialTicks)
public void render(Mat4f modelViewProjectionMatrix, float partialTicks)
{
GLState state = new GLState();
this.init();
// resize the framebuffer if necessary
@@ -117,13 +117,8 @@ public class FogRenderer
FogShader.INSTANCE.setProjectionMatrix(modelViewProjectionMatrix);
FogShader.INSTANCE.render(partialTicks);
// restored so we can write the SSAO texture to the main frame buffer
primaryState.restore();
FogApplyShader.INSTANCE.fogTexture = this.fogTexture;
FogApplyShader.INSTANCE.render(partialTicks);
state.restore();
}
public void free()
@@ -39,7 +39,9 @@ import com.seibel.distanthorizons.core.render.glObject.buffer.QuadElementBuffer;
import com.seibel.distanthorizons.core.render.glObject.texture.*;
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
import com.seibel.distanthorizons.core.render.renderer.shaders.*;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
@@ -49,7 +51,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccess
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import org.apache.logging.log4j.LogManager;
@@ -73,11 +74,14 @@ public class LodRenderer
private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class);
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
public static final boolean ENABLE_DRAW_LAG_SPIKE_LOGGING = false;
public static final boolean ENABLE_DUMP_GL_STATE = true;
public static final long DRAW_LAG_SPIKE_THRESHOLD_NS = TimeUnit.NANOSECONDS.convert(20, TimeUnit.MILLISECONDS);
public static final boolean ENABLE_IBO = true;
// TODO make these private, the LOD Builder can get these variables from the config itself
public static boolean transparencyEnabled = true;
@@ -93,9 +97,6 @@ public class LodRenderer
private int cachedWidth;
private int cachedHeight;
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private final ReentrantLock setupLock = new ReentrantLock();
public final RenderBufferHandler bufferHandler;
@@ -241,7 +242,6 @@ public class LodRenderer
try
{
// Note: Since lightmapTexture is changing every frame, it's faster to recreate it than to reuse the old one.
ILightMapWrapper lightmap = MC_RENDER.getLightmapWrapper(clientLevelWrapper);
if (lightmap == null)
{
@@ -249,23 +249,12 @@ public class LodRenderer
return;
}
// Save Minecraft's GL state so it can be restored at the end of LOD rendering
LagSpikeCatcher drawSaveGLState = new LagSpikeCatcher();
GLState minecraftGlState = new GLState();
if (ENABLE_DUMP_GL_STATE)
{
tickLogger.debug("Saving GL state: " + minecraftGlState);
}
drawSaveGLState.end("drawSaveGLState");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderSetupEvent.class, renderEventParam);
this.setupGLStateAndRenderObjects(minecraftGlState, profiler, renderEventParam, renderingFirstPass);
this.setupGLStateAndRenderObjects(profiler, renderEventParam, renderingFirstPass);
lightmap.bind();
if (ENABLE_IBO)
{
this.quadIBO.bind();
}
this.quadIBO.bind();
if (renderingFirstPass)
{
@@ -282,24 +271,26 @@ public class LodRenderer
// rendering //
//===========//
LagSpikeCatcher drawLagSpikeCatcher = new LagSpikeCatcher();
if (!runningDeferredPass)
{
//===================================//
// standard (non-deferred) rendering //
//===================================//
//=================================//
// opaque (non-deferred) rendering //
//=================================//
// Disable blending for opaque rendering
GL32.glDisable(GL32.GL_BLEND);
GLMC.disableBlend();
// terrain
profiler.popPush("LOD Opaque");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam);
this.bufferHandler.renderOpaque(this, renderEventParam);
// custom objects with SSAO
if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get())
{
@@ -312,7 +303,7 @@ public class LodRenderer
if (Config.Client.Advanced.Graphics.Ssao.enableSsao.get())
{
profiler.popPush("LOD SSAO");
SSAORenderer.INSTANCE.render(minecraftGlState, new Mat4f(renderEventParam.dhProjectionMatrix), renderEventParam.partialTicks);
SSAORenderer.INSTANCE.render(new Mat4f(renderEventParam.dhProjectionMatrix), renderEventParam.partialTicks);
}
@@ -324,11 +315,9 @@ public class LodRenderer
}
//DarkShader.INSTANCE.render(partialTicks); // A test shader to make the world darker
if (!deferTransparentRendering && Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled)
{
this.renderTransparentBuffers(profiler, renderEventParam, renderEventParam.partialTicks);
this.renderTransparentBuffersAndFireApiEvent(profiler, renderEventParam);
}
@@ -339,12 +328,10 @@ public class LodRenderer
Mat4f combinedMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
combinedMatrix.multiply(renderEventParam.dhModelViewMatrix);
FogRenderer.INSTANCE.render(minecraftGlState, combinedMatrix, renderEventParam.partialTicks);
FogRenderer.INSTANCE.render(combinedMatrix, renderEventParam.partialTicks);
}
drawLagSpikeCatcher.end("LodDraw");
//=================//
@@ -384,12 +371,8 @@ public class LodRenderer
{
profiler.popPush("LOD Apply");
GLState dhApplyGlState = new GLState();
// Copy the LOD framebuffer to Minecraft's framebuffer
DhApplyShader.INSTANCE.render(renderEventParam.partialTicks);
dhApplyGlState.restore();
}
}
else
@@ -400,7 +383,9 @@ public class LodRenderer
if (Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled)
{
this.renderTransparentBuffers(profiler, renderEventParam, renderEventParam.partialTicks);
profiler.popPush("LOD Transparent");
this.renderTransparentBuffersAndFireApiEvent(profiler, renderEventParam);
if (Config.Client.Advanced.Graphics.Fog.enableDhFog.get())
@@ -410,11 +395,9 @@ public class LodRenderer
Mat4f combinedMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
combinedMatrix.multiply(renderEventParam.dhModelViewMatrix);
FogRenderer.INSTANCE.render(minecraftGlState, combinedMatrix, renderEventParam.partialTicks);
FogRenderer.INSTANCE.render(combinedMatrix, renderEventParam.partialTicks);
}
}
drawLagSpikeCatcher.end("LodTranslucentDraw");
}
@@ -424,14 +407,10 @@ public class LodRenderer
//================//
profiler.popPush("LOD cleanup");
LagSpikeCatcher drawCleanup = new LagSpikeCatcher();
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderCleanupEvent.class, renderEventParam);
lightmap.unbind();
if (ENABLE_IBO)
{
this.quadIBO.unbind();
}
this.quadIBO.unbind();
IDhApiShaderProgram shaderProgram = this.lodRenderProgram;
IDhApiShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class);
@@ -441,8 +420,6 @@ public class LodRenderer
}
shaderProgram.unbind();
minecraftGlState.restore();
drawCleanup.end("LodDrawCleanup");
// end of internal LOD profiling
profiler.pop();
@@ -455,17 +432,18 @@ public class LodRenderer
}
}
private void renderTransparentBuffers(IProfilerWrapper profiler, DhApiRenderParam renderEventParam, float partialTicks)
private void renderTransparentBuffersAndFireApiEvent(IProfilerWrapper profiler, DhApiRenderParam renderEventParam)
{
profiler.popPush("LOD Transparent");
GL32.glEnable(GL32.GL_BLEND);
GLMC.enableBlend();
GLMC.enableDepthTest();
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
GL32.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam);
this.bufferHandler.renderTransparent(this, renderEventParam);
GL32.glDepthMask(true); // Apparently the depth mask state is stored in the FBO, so glState fails to restore it...
GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam);
this.bufferHandler.renderTransparent(this, renderEventParam);
}
/** called by each {@link ColumnRenderBuffer} before rendering */
@@ -523,7 +501,7 @@ public class LodRenderer
//=================//
private void setupGLStateAndRenderObjects(
GLState minecraftGlState, IProfilerWrapper profiler,
IProfilerWrapper profiler,
DhApiRenderParam renderEventParam,
boolean firstPass)
{
@@ -580,12 +558,6 @@ public class LodRenderer
{
if (this.usingMcFrameBuffer && framebufferOverride == null)
{
if (ENABLE_DUMP_GL_STATE)
{
tickLogger.debug("Re-saving GL state due to Optifine presence: " + minecraftGlState);
}
// Due to using MC/Optifine's framebuffer we need to re-bind the depth texture,
// otherwise we'll be writing to MC/Optifine's depth texture which causes rendering issues
activeFrameBuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F.isCombinedStencil());
@@ -600,28 +572,14 @@ public class LodRenderer
}
}
GL32.glEnable(GL32.GL_DEPTH_TEST);
GL32.glDepthFunc(GL32.GL_LESS);
// Set OpenGL polygon mode
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
if (renderWireframe)
{
// TODO fix
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
//GL32.glDisable(GL32.GL_CULL_FACE);
}
else
{
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
GL32.glEnable(GL32.GL_CULL_FACE);
}
// by default draw everything as triangles
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
GLMC.enableFaceCulling();
// Enable depth test and depth mask
GL32.glEnable(GL32.GL_DEPTH_TEST);
GL32.glDepthFunc(GL32.GL_LESS);
GL32.glDepthMask(true);
GLMC.enableDepthTest();
GLMC.glDepthFunc(GL32.GL_LESS);
GLMC.enableDepthMask();
/*---------Bind required objects--------*/
// Setup LodRenderProgram and the LightmapTexture if it has not yet been done
@@ -668,11 +626,9 @@ public class LodRenderer
EVENT_LOGGER.info("Setting up renderer");
this.isSetupComplete = true;
this.lodRenderProgram = new DhTerrainShaderProgram();
if (ENABLE_IBO)
{
this.quadIBO = new QuadElementBuffer();
this.quadIBO.reserve(ColumnRenderBuffer.MAX_QUADS_PER_BUFFER);
}
this.quadIBO = new QuadElementBuffer();
this.quadIBO.reserve(ColumnRenderBuffer.MAX_QUADS_PER_BUFFER);
// create or get the frame buffer
@@ -851,6 +807,7 @@ public class LodRenderer
// helper classes //
//================//
// TODO move
public static class LagSpikeCatcher
{
long timer = System.nanoTime();
@@ -23,6 +23,7 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.glObject.GLState;
import com.seibel.distanthorizons.core.render.renderer.shaders.SSAOApplyShader;
import com.seibel.distanthorizons.core.render.renderer.shaders.SSAOShader;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import org.lwjgl.opengl.GL32;
@@ -40,6 +41,7 @@ public class SSAORenderer
public static SSAORenderer INSTANCE = new SSAORenderer();
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
private boolean init = false;
@@ -77,15 +79,15 @@ public class SSAORenderer
if (this.ssaoTexture != -1)
{
GL32.glDeleteTextures(this.ssaoTexture);
GLMC.glDeleteTextures(this.ssaoTexture);
this.ssaoTexture = -1;
}
this.ssaoFramebuffer = GL32.glGenFramebuffers();
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer);
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer);
this.ssaoTexture = GL32.glGenTextures();
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture);
this.ssaoTexture = GLMC.glGenTextures();
GLMC.glBindTexture(this.ssaoTexture);
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_R16F, width, height, 0, GL32.GL_RED, GL32.GL_HALF_FLOAT, (ByteBuffer) null);
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR);
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR);
@@ -98,9 +100,12 @@ public class SSAORenderer
// render //
//========//
public void render(GLState primaryState, Mat4f projectionMatrix, float partialTicks)
public void render(Mat4f projectionMatrix, float partialTicks)
{
// TODO remove need for GLState, there are a few GL items that aren't being cleaned up correctly
// note that this doesn't affect Iris since Iris disables SSAO
GLState state = new GLState();
this.init();
// resize the framebuffer if necessary
@@ -117,9 +122,6 @@ public class SSAORenderer
SSAOShader.INSTANCE.setProjectionMatrix(projectionMatrix);
SSAOShader.INSTANCE.render(partialTicks);
// restored so we can write the SSAO texture to the main frame buffer
primaryState.restore();
SSAOApplyShader.INSTANCE.ssaoTexture = this.ssaoTexture;
SSAOApplyShader.INSTANCE.render(partialTicks);
@@ -24,12 +24,11 @@ import com.seibel.distanthorizons.api.enums.config.EDhApiLoggerMode;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
import com.seibel.distanthorizons.core.logging.ConfigBasedSpamLogger;
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
import com.seibel.distanthorizons.core.render.glObject.GLState;
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute;
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import org.apache.logging.log4j.LogManager;
@@ -41,21 +40,26 @@ import java.nio.ByteOrder;
public class TestRenderer
{
public TestRenderer() { }
public static final ConfigBasedLogger logger = new ConfigBasedLogger(
LogManager.getLogger(TestRenderer.class), () -> EDhApiLoggerMode.LOG_ALL_TO_CHAT);
public static final ConfigBasedSpamLogger spamLogger = new ConfigBasedSpamLogger(
LogManager.getLogger(TestRenderer.class), () -> EDhApiLoggerMode.LOG_ALL_TO_CHAT, 1);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
ShaderProgram basicShader;
GLVertexBuffer sameContextBuffer;
GLVertexBuffer sharedContextBuffer;
GLVertexBuffer vbo;
AbstractVertexAttribute va;
boolean init = false;
public TestRenderer() { }
public void init()
{
if (this.init)
@@ -74,6 +78,7 @@ public class TestRenderer
this.va.completeAndCheck(Float.BYTES * 6);
this.basicShader = new ShaderProgram("shaders/test/vert.vert", "shaders/test/frag.frag",
"fragColor", new String[]{"vPosition", "color"});
this.createBuffer();
}
@@ -86,61 +91,42 @@ public class TestRenderer
-0.2f, 0.2f, 0.0f, 1.0f, 1.0f, 1.0f
};
private static GLVertexBuffer createTextingBuffer()
{
ByteBuffer buffer = ByteBuffer.allocateDirect(vertices.length * Float.BYTES);
// Fill buffer with the vertices.
buffer = buffer.order(ByteOrder.nativeOrder());
buffer.asFloatBuffer().put(vertices);
buffer.rewind();
GLVertexBuffer vbo = new GLVertexBuffer(false);
vbo.bind();
vbo.uploadBuffer(buffer, 4, EDhApiGpuUploadMethod.DATA, vertices.length * Float.BYTES);
return vbo;
}
private void createBuffer()
{
this.sharedContextBuffer = createTextingBuffer();
this.sameContextBuffer = createTextingBuffer();
ByteBuffer buffer = ByteBuffer.allocateDirect(vertices.length * Float.BYTES);
// Fill buffer with vertices.
buffer.order(ByteOrder.nativeOrder());
buffer.asFloatBuffer().put(vertices);
buffer.rewind();
this.vbo = new GLVertexBuffer(false);
this.vbo.bind();
this.vbo.uploadBuffer(buffer, 4, EDhApiGpuUploadMethod.DATA, vertices.length * Float.BYTES);
}
public void render()
{
spamLogger.debug("rendering");
GLState state = new GLState();
this.init();
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, MC_RENDER.getTargetFrameBuffer());
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, MC_RENDER.getTargetFrameBuffer());
GL32.glViewport(0, 0, MC_RENDER.getTargetFrameBufferViewportWidth(), MC_RENDER.getTargetFrameBufferViewportHeight());
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
GL32.glDisable(GL32.GL_CULL_FACE);
GL32.glDisable(GL32.GL_DEPTH_TEST);
GL32.glDisable(GL32.GL_STENCIL_TEST);
GL32.glDisable(GL32.GL_BLEND);
//GL32.glDisable(GL32.GL_SCISSOR_TEST);
GLMC.disableFaceCulling();
GLMC.disableDepthTest();
GLMC.disableBlend();
GLMC.disableScissorTest();
this.basicShader.bind();
this.va.bind();
// Switch between the two buffers per second
if (System.currentTimeMillis() % 2000 < 1000)
{
this.sameContextBuffer.bind();
this.va.bindBufferToAllBindingPoints(this.sameContextBuffer.getId());
spamLogger.debug("same context buffer");
}
else
{
this.sameContextBuffer.bind();
this.va.bindBufferToAllBindingPoints(this.sharedContextBuffer.getId());
spamLogger.debug("shared context buffer");
}
this.vbo.bind();
this.va.bindBufferToAllBindingPoints(this.vbo.getId());
// Render the square
GL32.glDrawArrays(GL32.GL_TRIANGLE_FAN, 0, 4);
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
state.restore();
spamLogger.incLogTries();
}
@@ -38,10 +38,10 @@ import com.seibel.distanthorizons.core.logging.ConfigBasedSpamLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
import com.seibel.distanthorizons.core.render.glObject.GLState;
import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer;
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.util.math.Vec3d;
@@ -74,6 +74,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final ISodiumAccessor SODIUM = ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
/**
* Can be used to troubleshoot the renderer.
@@ -388,7 +389,6 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
// render setup //
profiler.push("setup");
GLState glState = new GLState();
this.init();
boolean useInstancedRendering = this.instancedRenderingAvailable
@@ -396,12 +396,22 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
GL32.glEnable(GL32.GL_DEPTH_TEST);
GL32.glEnable(GL32.GL_BLEND);
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
if (renderWireframe)
{
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
GLMC.disableFaceCulling();
}
else
{
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
GLMC.enableFaceCulling();
}
GLMC.enableBlend();
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
GL32.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
IDhApiGenericObjectShaderProgram shaderProgram = useInstancedRendering ? this.instancedShaderProgram : this.directShaderProgram;
IDhApiGenericObjectShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiGenericObjectShaderProgram.class);
@@ -457,14 +467,22 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
}
//==========//
// clean up //
//==========//
profiler.popPush("cleanup");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam);
if (renderWireframe)
{
// default back to GL_FILL since all other rendering uses it
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
GLMC.enableFaceCulling();
}
shaderProgram.unbind();
glState.restore();
profiler.pop();
}
@@ -1,63 +0,0 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2023 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.core.render.renderer.shaders;
import com.seibel.distanthorizons.core.render.glObject.GLState;
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
import org.lwjgl.opengl.GL32;
public class DarkShader extends AbstractShaderRenderer
{
public static DarkShader INSTANCE = new DarkShader();
@Override
public void onInit()
{
this.shader = new ShaderProgram(
"shaders/normal.vert",
"shaders/test/dark.frag",
"fragColor",
new String[]{"vPosition", "color"});
}
@Override
protected void onApplyUniforms(float partialTicks)
{
GL32.glActiveTexture(GL32.GL_TEXTURE0);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
}
@Override
protected void onRender()
{
GLState state = new GLState();
GL32.glDisable(GL32.GL_DEPTH_TEST);
GL32.glDisable(GL32.GL_SCISSOR_TEST);
GL32.glEnable(GL32.GL_BLEND);
GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA);
ScreenQuad.INSTANCE.render();
state.restore();
}
}
@@ -19,9 +19,11 @@
package com.seibel.distanthorizons.core.render.renderer.shaders;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.opengl.GL32;
@@ -36,6 +38,8 @@ public class DhApplyShader extends AbstractShaderRenderer
public static DhApplyShader INSTANCE = new DhApplyShader();
private static final Logger LOGGER = LogManager.getLogger();
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
// uniforms
public int gDhColorTextureUniform;
@@ -78,22 +82,22 @@ public class DhApplyShader extends AbstractShaderRenderer
}
GL32.glDisable(GL32.GL_DEPTH_TEST);
GLMC.disableDepthTest();
GL32.glEnable(GL32.GL_BLEND);
GLMC.enableBlend();
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
GL32.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
GLMC.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
GL32.glActiveTexture(GL32.GL_TEXTURE0);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveColorTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(LodRenderer.getActiveColorTextureId());
GL32.glUniform1i(this.gDhColorTextureUniform, 0);
GL32.glActiveTexture(GL32.GL_TEXTURE1);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveDepthTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE1);
GLMC.glBindTexture(LodRenderer.getActiveDepthTextureId());
GL32.glUniform1i(this.gDepthMapUniform, 1);
// Copy to MC's framebuffer
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, targetFrameBuffer);
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, targetFrameBuffer);
ScreenQuad.INSTANCE.render();
}
@@ -24,6 +24,7 @@ import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.renderer.FadeRenderer;
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import org.lwjgl.opengl.GL32;
@@ -39,6 +40,8 @@ public class FadeApplyShader extends AbstractShaderRenderer
public static FadeApplyShader INSTANCE = new FadeApplyShader();
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
public int fadeTexture;
@@ -78,16 +81,16 @@ public class FadeApplyShader extends AbstractShaderRenderer
@Override
protected void onApplyUniforms(float partialTicks)
{
GL32.glActiveTexture(GL32.GL_TEXTURE0);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.fadeTexture);
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(this.fadeTexture);
GL32.glUniform1i(this.uFadeColorTextureUniform, 0);
GL32.glActiveTexture(GL32.GL_TEXTURE1);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveDepthTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE1);
GLMC.glBindTexture(LodRenderer.getActiveDepthTextureId());
GL32.glUniform1i(this.uDhDepthTextureUniform, 1);
GL32.glActiveTexture(GL32.GL_TEXTURE2);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE2);
GLMC.glBindTexture(MC_RENDER.getDepthTextureId());
GL32.glUniform1i(this.uMcDepthTextureUniform, 2);
}
@@ -101,19 +104,21 @@ public class FadeApplyShader extends AbstractShaderRenderer
@Override
protected void onRender()
{
GL32.glDisable(GL32.GL_BLEND);
GLMC.disableBlend();
// Depth testing must be disabled otherwise this application shader won't apply anything.
// setting this isn't necessary in vanilla, but some mods may change this, requiring it to be set manually,
// it should be automatically restored after rendering is complete.
GL32.glDisable(GL32.GL_DEPTH_TEST);
GLMC.disableDepthTest();
// apply the rendered Fade to Minecraft's framebuffer
GL32.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, FadeShader.INSTANCE.frameBuffer);
GL32.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, MC_RENDER.getTargetFrameBuffer());
GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, FadeShader.INSTANCE.frameBuffer);
GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, MC_RENDER.getTargetFrameBuffer());
ScreenQuad.INSTANCE.render();
GLMC.enableDepthTest();
}
}
@@ -28,6 +28,7 @@ import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import org.lwjgl.opengl.GL32;
@@ -37,6 +38,7 @@ public class FadeShader extends AbstractShaderRenderer
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
public int frameBuffer = -1;
@@ -153,33 +155,29 @@ public class FadeShader extends AbstractShaderRenderer
@Override
protected void onRender()
{
GLState state = new GLState();
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.frameBuffer);
GLMC.disableScissorTest();
GLMC.disableDepthTest();
GLMC.disableBlend();
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.frameBuffer);
GL32.glDisable(GL32.GL_SCISSOR_TEST);
GL32.glDisable(GL32.GL_DEPTH_TEST);
GL32.glDisable(GL32.GL_BLEND);
GL32.glActiveTexture(GL32.GL_TEXTURE0);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(MC_RENDER.getDepthTextureId());
GL32.glUniform1i(this.uMcDepthTexture, 0);
GL32.glActiveTexture(GL32.GL_TEXTURE1);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveDepthTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE1);
GLMC.glBindTexture(LodRenderer.getActiveDepthTextureId());
GL32.glUniform1i(this.uDhDepthTexture, 1);
GL32.glActiveTexture(GL32.GL_TEXTURE2);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getColorTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE2);
GLMC.glBindTexture(MC_RENDER.getColorTextureId());
GL32.glUniform1i(this.uCombinedMcDhColorTexture, 2);
GL32.glActiveTexture(GL32.GL_TEXTURE3);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveColorTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE3);
GLMC.glBindTexture(LodRenderer.getActiveColorTextureId());
GL32.glUniform1i(this.uDhColorTexture, 3);
ScreenQuad.INSTANCE.render();
state.restore();
}
}
@@ -19,10 +19,12 @@
package com.seibel.distanthorizons.core.render.renderer.shaders;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.renderer.FogRenderer;
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import org.lwjgl.opengl.GL32;
/**
@@ -36,6 +38,9 @@ public class FogApplyShader extends AbstractShaderRenderer
{
public static FogApplyShader INSTANCE = new FogApplyShader();
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
public int fogTexture;
// uniforms
@@ -72,12 +77,12 @@ public class FogApplyShader extends AbstractShaderRenderer
@Override
protected void onApplyUniforms(float partialTicks)
{
GL32.glActiveTexture(GL32.GL_TEXTURE0);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.fogTexture);
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(this.fogTexture);
GL32.glUniform1i(this.colorTextureUniform, 0);
GL32.glActiveTexture(GL32.GL_TEXTURE1);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveDepthTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE1);
GLMC.glBindTexture(LodRenderer.getActiveDepthTextureId());
GL32.glUniform1i(this.depthTextureUniform, 1);
}
@@ -90,21 +95,23 @@ public class FogApplyShader extends AbstractShaderRenderer
@Override
protected void onRender()
{
GL32.glEnable(GL32.GL_BLEND);
GLMC.enableBlend();
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
GL32.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
// Depth testing must be disabled otherwise this application shader won't apply anything.
// setting this isn't necessary in vanilla, but some mods may change this, requiring it to be set manually,
// it should be automatically restored after rendering is complete.
GL32.glDisable(GL32.GL_DEPTH_TEST);
GLMC.disableDepthTest();
// apply the rendered Fog to DH's framebuffer
GL32.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, FogShader.INSTANCE.frameBuffer);
GL32.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, LodRenderer.getActiveFramebufferId());
GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, FogShader.INSTANCE.frameBuffer);
GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, LodRenderer.getActiveFramebufferId());
ScreenQuad.INSTANCE.render();
GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, 0);
}
}
@@ -24,14 +24,13 @@ import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogDirection;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.glObject.GLState;
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import org.lwjgl.opengl.GL32;
import java.awt.*;
@@ -41,7 +40,7 @@ public class FogShader extends AbstractShaderRenderer
public static final FogShader INSTANCE = new FogShader();
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final IVersionConstants VERSION_CONSTANTS = SingletonInjector.INSTANCE.get(IVersionConstants.class);
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
public int frameBuffer;
@@ -243,15 +242,13 @@ public class FogShader extends AbstractShaderRenderer
@Override
protected void onRender()
{
GLState state = new GLState();
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.frameBuffer);
GLMC.disableScissorTest();
GLMC.disableDepthTest();
GLMC.disableBlend();
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.frameBuffer);
GL32.glDisable(GL32.GL_SCISSOR_TEST);
GL32.glDisable(GL32.GL_DEPTH_TEST);
GL32.glDisable(GL32.GL_BLEND);
GL32.glActiveTexture(GL32.GL_TEXTURE0);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveDepthTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(LodRenderer.getActiveDepthTextureId());
GL32.glUniform1i(this.uDepthMap, 0);
// this is necessary for MC 1.16 (IE Legacy OpenGL)
@@ -260,8 +257,6 @@ public class FogShader extends AbstractShaderRenderer
ScreenQuad.INSTANCE.render();
state.restore();
}
}
@@ -20,12 +20,13 @@
package com.seibel.distanthorizons.core.render.renderer.shaders;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
import com.seibel.distanthorizons.core.render.renderer.SSAORenderer;
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import org.lwjgl.opengl.GL32;
/**
@@ -39,6 +40,9 @@ public class SSAOApplyShader extends AbstractShaderRenderer
{
public static SSAOApplyShader INSTANCE = new SSAOApplyShader();
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
public int ssaoTexture;
// uniforms
@@ -82,12 +86,12 @@ public class SSAOApplyShader extends AbstractShaderRenderer
@Override
protected void onApplyUniforms(float partialTicks)
{
GL32.glActiveTexture(GL32.GL_TEXTURE0);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveDepthTextureId());
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(LodRenderer.getActiveDepthTextureId());
GL32.glUniform1i(this.gDepthMapUniform, 0);
GL32.glActiveTexture(GL32.GL_TEXTURE1);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture);
GLMC.glActiveTexture(GL32.GL_TEXTURE1);
GLMC.glBindTexture(this.ssaoTexture);
GL32.glUniform1i(this.gSSAOMapUniform, 1);
GL32.glUniform1i(this.gBlurRadiusUniform, Config.Client.Advanced.Graphics.Ssao.blurRadius.get());
@@ -121,20 +125,24 @@ public class SSAOApplyShader extends AbstractShaderRenderer
@Override
protected void onRender()
{
GL32.glEnable(GL32.GL_BLEND);
GLMC.enableBlend();
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
GL32.glBlendFuncSeparate(GL32.GL_ZERO, GL32.GL_SRC_ALPHA, GL32.GL_ZERO, GL32.GL_ONE);
GLMC.glBlendFuncSeparate(GL32.GL_ZERO, GL32.GL_SRC_ALPHA, GL32.GL_ZERO, GL32.GL_ONE);
// Depth testing must be disabled otherwise this application shader won't apply anything.
// setting this isn't necessary in vanilla, but some mods may change this, requiring it to be set manually,
// it should be automatically restored after rendering is complete.
GL32.glDisable(GL32.GL_DEPTH_TEST);
GLMC.disableDepthTest();
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(0);
// apply the rendered SSAO to the LODs
GL32.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, SSAOShader.INSTANCE.frameBuffer);
GL32.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, LodRenderer.getActiveFramebufferId());
GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, SSAOShader.INSTANCE.frameBuffer);
GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, LodRenderer.getActiveFramebufferId());
ScreenQuad.INSTANCE.render();
}
}
@@ -20,11 +20,13 @@
package com.seibel.distanthorizons.core.render.renderer.shaders;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
import com.seibel.distanthorizons.core.render.renderer.SSAORenderer;
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import org.lwjgl.opengl.GL32;
/**
@@ -38,6 +40,8 @@ public class SSAOShader extends AbstractShaderRenderer
{
public static SSAOShader INSTANCE = new SSAOShader();
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
public int frameBuffer;
@@ -117,9 +121,6 @@ public class SSAOShader extends AbstractShaderRenderer
Number bias = Config.Client.Advanced.Graphics.Ssao.bias.get();
this.shader.setUniform(this.gBiasUniform, bias.floatValue());
GL32.glActiveTexture(GL32.GL_TEXTURE0);
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveDepthTextureId());
GL32.glUniform1i(this.gDepthMapUniform, 0);
}
@@ -132,10 +133,13 @@ public class SSAOShader extends AbstractShaderRenderer
@Override
protected void onRender()
{
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.frameBuffer);
GL32.glDisable(GL32.GL_SCISSOR_TEST);
GL32.glDisable(GL32.GL_DEPTH_TEST);
GL32.glDisable(GL32.GL_BLEND);
GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.frameBuffer);
GLMC.disableScissorTest();
GLMC.disableDepthTest();
GLMC.disableBlend();
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(LodRenderer.getActiveDepthTextureId());
ScreenQuad.INSTANCE.render();
}
@@ -0,0 +1,126 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2023 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General License for more details.
*
* You should have received a copy of the GNU Lesser General License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.core.wrapperInterfaces.minecraft;
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable;
import org.lwjgl.opengl.GL32;
import java.util.ArrayList;
import java.util.UUID;
/**
* Used to sync GL state changes between DH and MC.
* This is specifically important for other mods that change MC's rendering like Iris.
*/
public interface IMinecraftGLWrapper extends IBindable
{
// scissor //
/** @see GL32#GL_SCISSOR_TEST */
void enableScissorTest();
/** @see GL32#GL_SCISSOR_TEST */
void disableScissorTest();
// stencil //
///** @see GL32#GL_SCISSOR_TEST */
//void enableScissorTest() { GlStateManager._enableScissorTest(); }
///** @see GL32#GL_SCISSOR_TEST */
//void disableScissorTest() { GlStateManager._disableScissorTest(); }
// depth //
/** @see GL32#GL_DEPTH_TEST */
void enableDepthTest();
/** @see GL32#GL_DEPTH_TEST */
void disableDepthTest();
/** @see GL32#glDepthFunc(int) */
void glDepthFunc(int func);
/** @see GL32#glDepthMask(boolean) */
void enableDepthMask();
/** @see GL32#glDepthMask(boolean) */
void disableDepthMask();
// blending //
/** @see GL32#GL_BLEND */
void enableBlend();
/** @see GL32#GL_BLEND */
void disableBlend();
/** @see GL32#glBlendFunc */
void glBlendFunc(int sfactor, int dfactor);
/** @see GL32#glBlendFuncSeparate */
void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha);
// frame buffers //
/** @see GL32#glBindFramebuffer */
void glBindFramebuffer(int target, int framebuffer);
// buffers //
/** @see GL32#glGenBuffers() */
int glGenBuffers();
/** @see GL32#glDeleteBuffers(int) */
void glDeleteBuffers(int buffer);
// culling //
/** @see GL32#GL_CULL_FACE */
void enableFaceCulling();
/** @see GL32#GL_CULL_FACE */
void disableFaceCulling();
// textures //
/** @see GL32#glGenTextures() */
int glGenTextures();
/** @see GL32#glDeleteTextures(int) */
void glDeleteTextures(int texture);
/** @see GL32#glActiveTexture(int) */
void glActiveTexture(int textureId);
/**
* Only works for textures bound via this system. <br>
* Returns the bound {@link GL32#GL_TEXTURE_BINDING_2D}
*/
int getActiveTexture();
/**
* Always binds to {@link GL32#GL_TEXTURE_2D}
* @see GL32#glBindTexture(int, int)
*/
void glBindTexture(int texture);
}