diff --git a/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeGenericRenderCleanupEvent.java b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeGenericRenderCleanupEvent.java
new file mode 100644
index 000000000..e9c6bfbd4
--- /dev/null
+++ b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeGenericRenderCleanupEvent.java
@@ -0,0 +1,47 @@
+/*
+ * 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 .
+ */
+
+package com.seibel.distanthorizons.api.methods.events.abstractEvents;
+
+import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
+import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
+import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
+
+/**
+ * Called before Distant Horizons starts the cleanup process done after rendering generic objects.
+ * This is called after all generic objects have finished rendering.
+ *
+ * @author James Seibel
+ * @version 2024-7-13
+ * @since API 3.0.0
+ */
+public abstract class DhApiBeforeGenericRenderCleanupEvent implements IDhApiEvent
+{
+ /** Fired before Distant Horizons starts the cleanup process once rendering has finished. */
+ public abstract void beforeCleanup(DhApiEventParam event);
+
+
+ //=========================//
+ // internal DH API methods //
+ //=========================//
+
+ @Override
+ public final void fireEvent(DhApiEventParam event) { this.beforeCleanup(event); }
+
+}
\ No newline at end of file
diff --git a/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeGenericRenderSetupEvent.java b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeGenericRenderSetupEvent.java
new file mode 100644
index 000000000..2dea2942c
--- /dev/null
+++ b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeGenericRenderSetupEvent.java
@@ -0,0 +1,50 @@
+/*
+ * 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 .
+ */
+
+package com.seibel.distanthorizons.api.methods.events.abstractEvents;
+
+import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
+import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
+import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
+
+/**
+ * Called before Distant Horizons has started setting up OpenGL objects for rendering generic objects.
+ * If you want to modify already bound DH OpenGL objects try using {@link DhApiBeforeGenericObjectRenderEvent}.
+ *
+ * @author James Seibel
+ * @version 2024-7-12
+ * @since API 3.0.0
+ *
+ * @see DhApiBeforeGenericObjectRenderEvent
+ */
+public abstract class DhApiBeforeGenericRenderSetupEvent implements IDhApiEvent
+{
+ /** Fired before Distant Horizons has started setting up OpenGL objects for rendering generic objects. */
+ public abstract void beforeSetup(DhApiEventParam input);
+
+
+ //=========================//
+ // internal DH API methods //
+ //=========================//
+
+ @Override
+ public final void fireEvent(DhApiEventParam input) { this.beforeSetup(input); }
+
+
+}
\ No newline at end of file
diff --git a/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeRenderCleanupEvent.java b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeRenderCleanupEvent.java
index b8eb08568..85533fa35 100644
--- a/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeRenderCleanupEvent.java
+++ b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeRenderCleanupEvent.java
@@ -33,7 +33,7 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
*/
public abstract class DhApiBeforeRenderCleanupEvent implements IDhApiEvent
{
- /** Fired before Distant Horizons renders LODs. */
+ /** Fired before Distant Horizons starts the cleanup process once rendering has finished. */
public abstract void beforeCleanup(DhApiEventParam event);
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java
index 94ab35d92..201eab388 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java
@@ -25,8 +25,7 @@ import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
-import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericObjectRenderEvent;
-import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent;
+import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
@@ -368,6 +367,8 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
GLState glState = new GLState();
this.init();
+ ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
+
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
GL32.glEnable(GL32.GL_DEPTH_TEST);
@@ -433,6 +434,8 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
// clean up //
profiler.popPush("cleanup");
+ ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam);
+
shaderProgram.unbind();
glState.restore();