diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java index 0807f9c87..819a88f0e 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java @@ -10,6 +10,7 @@ import com.seibel.lod.core.a7.datatype.transform.FullToColumnTransformer; import com.seibel.lod.core.a7.level.IClientLevel; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.a7.render.RenderBuffer; +import com.seibel.lod.core.a7.render.a7LodRenderer; import com.seibel.lod.core.a7.save.io.render.RenderMetaFile; import com.seibel.lod.core.enums.ELodDirection; import com.seibel.lod.core.logging.DhLoggerBuilder; @@ -332,20 +333,25 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype { RenderBuffer[] newBuffers = inBuildRenderBuffer.join(); RenderBuffer oldBuffersOpaque = referenceSlotsOpaque.getAndSet(newBuffers[0]); - RenderBuffer oldBuffersTransparent = referenceSlotsTransparent.getAndSet(newBuffers[1]); ColumnRenderBuffer swapped; + if (oldBuffersOpaque instanceof ColumnRenderBuffer) { swapped = usedBufferOpaque.swap((ColumnRenderBuffer) oldBuffersOpaque); LodUtil.assertTrue(swapped == null); } - if (oldBuffersTransparent instanceof ColumnRenderBuffer) { - swapped = usedBufferTransparent.swap((ColumnRenderBuffer) oldBuffersTransparent); - LodUtil.assertTrue(swapped == null); - } + if(a7LodRenderer.transparencyEnabled) { + RenderBuffer oldBuffersTransparent = referenceSlotsTransparent.getAndSet(newBuffers[1]); + if (a7LodRenderer.transparencyEnabled) { + if (oldBuffersTransparent instanceof ColumnRenderBuffer) { + swapped = usedBufferTransparent.swap((ColumnRenderBuffer) oldBuffersTransparent); + LodUtil.assertTrue(swapped == null); + } + } + } inBuildRenderBuffer = null; return true; } diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnBox.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnBox.java index 0556138c8..1b39a92c0 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnBox.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnBox.java @@ -20,17 +20,18 @@ package com.seibel.lod.core.a7.datatype.column.render; import com.seibel.lod.core.a7.datatype.column.accessor.ColumnArrayView; +import com.seibel.lod.core.a7.render.a7LodRenderer; import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder; +import com.seibel.lod.core.config.Config; import com.seibel.lod.core.enums.ELodDirection; import com.seibel.lod.core.handlers.dependencyInjection.SingletonInjector; import com.seibel.lod.core.util.ColorUtil; import com.seibel.lod.core.util.DataPointUtil; +import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; public class ColumnBox { - private static boolean transparencyEnabled = true; - private static boolean fakeOceanFloor = false; private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); public static void addBoxQuadsToBuilder(LodQuadBuilder builder, short xSize, short ySize, short zSize, short x, @@ -42,41 +43,37 @@ public class ColumnBox byte skyLightTop = skyLight; byte skyLightBot = DataPointUtil.doesItExist(botData) ? DataPointUtil.getLightSky(botData) : 0; - boolean isTransparent = ColorUtil.getAlpha(color)<255 && transparencyEnabled; - boolean isTopTransparent = DataPointUtil.getAlpha(topData)<255 && transparencyEnabled; - boolean isBotTransparent = DataPointUtil.getAlpha(botData)<255 && transparencyEnabled; + boolean isTransparent = ColorUtil.getAlpha(color)<255 && a7LodRenderer.transparencyEnabled; + boolean isTopTransparent = DataPointUtil.getAlpha(topData)<255 && a7LodRenderer.transparencyEnabled; + boolean isBotTransparent = DataPointUtil.getAlpha(botData)<255 && a7LodRenderer.transparencyEnabled; // Up direction case - boolean skipTop = DataPointUtil.doesItExist(topData) && ( - (isTransparent && (DataPointUtil.getDepth(topData) == maxY)) || - (!isTransparent && (DataPointUtil.getDepth(topData) == maxY) && !isTopTransparent)); - boolean skipBot = DataPointUtil.doesItExist(botData) && ( - (isTransparent && (DataPointUtil.getDepth(botData) == maxY)) || - (!isTransparent && (DataPointUtil.getDepth(botData) == maxY) && !isBotTransparent)); + //We skip if + // current block is not transparent: we check if the adj block is attached and opaque - if(fakeOceanFloor && transparencyEnabled) - { - if(!isTransparent && isTopTransparent) - { + boolean skipTop = DataPointUtil.doesItExist(topData) && (DataPointUtil.getDepth(topData) == maxY) && !isTopTransparent; + boolean skipBot = DataPointUtil.doesItExist(botData) && (DataPointUtil.getHeight(botData) == y) && !isBotTransparent; + if(a7LodRenderer.transparencyEnabled && a7LodRenderer.fakeOceanFloor) { + if (!isTransparent && isTopTransparent && DataPointUtil.doesItExist(topData)) { + skyLightTop = (byte) LodUtil.clamp(0, 15 - (DataPointUtil.getHeight(topData) - y), 15); ySize = (short) (DataPointUtil.getHeight(topData) - y - 1); - } - else if(isTransparent && !isBotTransparent) - { + //y = (short) (DataPointUtil.getHeight(topData) - 2); + //ySize = 1; + } else if (isTransparent && !isBotTransparent && DataPointUtil.doesItExist(botData)) { y = (short) (y + ySize - 1); ySize = 1; } - }else if(!transparencyEnabled) - { - color = ColorUtil.rgbToInt(ColorUtil.getRed(color),ColorUtil.getGreen(color),ColorUtil.getBlue(color)); + maxY = (short) (y + ySize); } - maxY = (short) (y + ySize); if (!skipTop) builder.addQuadUp(x, maxY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(ELodDirection.UP)), skyLightTop, blockLight); if (!skipBot) builder.addQuadDown(x, y, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(ELodDirection.DOWN)), skyLightBot, blockLight); - + + if(isTransparent) + return; //If the adj pos is at the same level we cull the faces normally, otherwise we divide the face in two and cull the two part separately //NORTH face vertex creation @@ -185,23 +182,23 @@ public class ColumnBox boolean allAbove = true; short previousDepth = -1; byte nextSkyLight = upSkyLight; - boolean isTransparent = ColorUtil.getAlpha(color) < 255 && transparencyEnabled;; + boolean isTransparent = ColorUtil.getAlpha(color) < 255 && a7LodRenderer.transparencyEnabled; boolean lastWasTransparent = false; for (i = 0; i < dataPoint.size() && DataPointUtil.doesItExist(adjData.get(i)) && !DataPointUtil.isVoid(adjData.get(i)); i++) { long adjPoint = adjData.get(i); - boolean isAdjTransparent = DataPointUtil.getAlpha(adjPoint) < 255 && transparencyEnabled; + boolean isAdjTransparent = DataPointUtil.getAlpha(adjPoint) < 255 && a7LodRenderer.transparencyEnabled; - if (!isTransparent && isAdjTransparent && transparencyEnabled) + if (!isTransparent && isAdjTransparent && a7LodRenderer.transparencyEnabled) continue; short height = DataPointUtil.getHeight(adjPoint); short depth = DataPointUtil.getDepth(adjPoint); - if(fakeOceanFloor && transparencyEnabled) + if(a7LodRenderer.transparencyEnabled && a7LodRenderer.fakeOceanFloor) { if(lastWasTransparent && !isAdjTransparent) diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnRenderBuffer.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnRenderBuffer.java index 6e7a1c38e..ac95ddb93 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnRenderBuffer.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnRenderBuffer.java @@ -372,7 +372,7 @@ public class ColumnRenderBuffer extends RenderBuffer { // We send the call to create the vertices - if(DataPointUtil.getAlpha(data) == 255) + if(DataPointUtil.getAlpha(data) == 255 || !a7LodRenderer.transparencyEnabled) { CubicLodTemplate.addLodToBuffer(data, adjDataTop, adjDataBot, adjData, detailLevel, x, z, quadBuilderOpaque, debugMode); @@ -386,6 +386,7 @@ public class ColumnRenderBuffer extends RenderBuffer { } } quadBuilderOpaque.mergeQuads(); - quadBuilderTransparent.mergeQuads(); + if(a7LodRenderer.transparencyEnabled) + quadBuilderTransparent.mergeQuads(); } } diff --git a/src/main/java/com/seibel/lod/core/a7/render/RenderBufferHandler.java b/src/main/java/com/seibel/lod/core/a7/render/RenderBufferHandler.java index d120ad78a..c0b6dcc9a 100644 --- a/src/main/java/com/seibel/lod/core/a7/render/RenderBufferHandler.java +++ b/src/main/java/com/seibel/lod/core/a7/render/RenderBufferHandler.java @@ -26,6 +26,10 @@ public class RenderBufferHandler { this.pos = pos; } + /** + * This will render all opaque lods + * @param renderContext + */ public void renderOpaque(a7LodRenderer renderContext) { RenderBuffer buff; @@ -41,6 +45,11 @@ public class RenderBufferHandler { } } } + + /** + * This will render all transparent lods + * @param renderContext + */ public void renderTransparent(a7LodRenderer renderContext) { RenderBuffer buff; buff = renderBufferSlotTransparent.get(); @@ -141,7 +150,8 @@ public class RenderBufferHandler { //TODO: Directional culling //TODO: Ordered by distance renderBufferNodes.forEachOrdered(n -> n.renderOpaque(renderContext)); - renderBufferNodes.forEachOrdered(n -> n.renderTransparent(renderContext)); + if(a7LodRenderer.transparencyEnabled) + renderBufferNodes.forEachOrdered(n -> n.renderTransparent(renderContext)); } public void update() { diff --git a/src/main/java/com/seibel/lod/core/a7/render/a7LodRenderer.java b/src/main/java/com/seibel/lod/core/a7/render/a7LodRenderer.java index 6067d903e..8407a5692 100644 --- a/src/main/java/com/seibel/lod/core/a7/render/a7LodRenderer.java +++ b/src/main/java/com/seibel/lod/core/a7/render/a7LodRenderer.java @@ -39,6 +39,7 @@ import com.seibel.lod.core.render.objects.GLState; import com.seibel.lod.core.render.objects.GLVertexBuffer; import com.seibel.lod.core.render.objects.QuadElementBuffer; import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper; @@ -70,6 +71,9 @@ public class a7LodRenderer public static final boolean ENABLE_IBO = true; + public static boolean transparencyEnabled = true; + public static boolean fakeOceanFloor = true; + public void setupOffset(DHBlockPos pos) { Vec3d cam = MC_RENDER.getCameraExactPosition(); shaderProgram.setModelPos(new Vec3f((float) (pos.x - cam.x), (float) (pos.y - cam.y), (float) (pos.z - cam.z))); @@ -147,7 +151,7 @@ public class a7LodRenderer //===================// // draw params setup // //===================// - + profiler.push("LOD draw setup"); /*---------Set GL State--------*/ // Make sure to unbind current VBO so we don't mess up vanilla settings @@ -170,10 +174,18 @@ public class a7LodRenderer GL32.glEnable(GL32.GL_DEPTH_TEST); // GL32.glDisable(GL32.GL_DEPTH_TEST); GL32.glDepthFunc(GL32.GL_LESS); - // TODO: enable for transparent rendering - GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA); - GL32.glEnable(GL32.GL_BLEND); - //GL32.glDisable(GL32.GL_BLEND); + + + + transparencyEnabled = Config.Client.Graphics.Quality.transparency.get().tranparencyEnabled; + fakeOceanFloor = Config.Client.Graphics.Quality.transparency.get().fakeTransparencyEnabled; + if(transparencyEnabled) { + GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA); + GL32.glEnable(GL32.GL_BLEND); + }else{ + GL32.glDisable(GL32.GL_BLEND); + } + GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT); /*---------Bind required objects--------*/ diff --git a/src/main/java/com/seibel/lod/core/config/Config.java b/src/main/java/com/seibel/lod/core/config/Config.java index d02850c79..caad5a111 100644 --- a/src/main/java/com/seibel/lod/core/config/Config.java +++ b/src/main/java/com/seibel/lod/core/config/Config.java @@ -156,6 +156,10 @@ public class Config + " or "+ EDropoffQuality.PERFORMANCE_FOCUSED +" otherwise.") .build(); + public static ConfigEntry transparency = new ConfigEntry.Builder() + .set(ETransparency.COMPLETE) + .comment("") + .build(); public static ConfigEntry lodBiomeBlending = new ConfigEntry.Builder() .setMinDefaultMax(0,1,7) .comment("" diff --git a/src/main/java/com/seibel/lod/core/enums/rendering/ETransparency.java b/src/main/java/com/seibel/lod/core/enums/rendering/ETransparency.java new file mode 100644 index 000000000..f12d331a5 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/enums/rendering/ETransparency.java @@ -0,0 +1,60 @@ +/* + * This file is part of the Distant Horizons mod (formerly the LOD Mod), + * licensed under the GNU LGPL v3 License. + * + * Copyright (C) 2020-2022 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.lod.core.enums.rendering; + +/** + * OFF,
+ * SHOW_WIREFRAME,
+ * SHOW_DETAIL,
+ * SHOW_DETAIL_WIREFRAME,
+ * SHOW_GENMODE,
+ * SHOW_GENMODE_WIREFRAME,
+ * SHOW_OVERLAPPING_QUADS,
+ * SHOW_OVERLAPPING_QUADS_WIREFRAME,
+ * + * @author Leetom + * @author James Seibel + * @version 2022-7-2 + */ +public enum ETransparency +{ + // Reminder: + // when adding items up the API minor version + // when removing items up the API major version + + + /** */ + DISABLED(false, false), + + /** */ + FAKE(true, true), + + /** */ + COMPLETE(true, false); + + public final boolean tranparencyEnabled; + public final boolean fakeTransparencyEnabled; + + ETransparency(boolean tranparencyEnabled, boolean fakeTransparencyEnabled) + { + this.tranparencyEnabled = tranparencyEnabled; + this.fakeTransparencyEnabled = fakeTransparencyEnabled; + } +} diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java index 39f6ea8d6..6275c1b94 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java @@ -89,6 +89,10 @@ public interface ILodConfigWrapperSingleton extends IBindable return dropoffQuality; } + public void setTransparency(ETransparency newTransparency); + + public ETransparency getTransparency(); + int getLodBiomeBlending(); void setLodBiomeBlending(int newLodBiomeBlending); } diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/LodConfigWrapperSingleton.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/LodConfigWrapperSingleton.java index da39cd971..ea4554ab9 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/LodConfigWrapperSingleton.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/LodConfigWrapperSingleton.java @@ -188,6 +188,17 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton Config.Client.Graphics.Quality.dropoffQuality.set(newDropoffQuality); } + @Override + public void setTransparency(ETransparency newTransparency) { + Config.Client.Graphics.Quality.transparency.set(newTransparency); + } + + @Override + public ETransparency getTransparency(){ + return Config.Client.Graphics.Quality.transparency.get(); + } + + @Override public int getLodBiomeBlending() { return Config.Client.Graphics.Quality.lodBiomeBlending.get();