diff options
Diffstat (limited to 'src/main/java/makamys/neodymium')
5 files changed, 544 insertions, 250 deletions
diff --git a/src/main/java/makamys/neodymium/Compat.java b/src/main/java/makamys/neodymium/Compat.java index debb6d6..40feb47 100644 --- a/src/main/java/makamys/neodymium/Compat.java +++ b/src/main/java/makamys/neodymium/Compat.java @@ -1,13 +1,5 @@ package makamys.neodymium; -import static makamys.neodymium.Constants.LOGGER; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.List; - -import org.lwjgl.opengl.GLContext; - import com.falsepattern.triangulator.api.ToggleableTessellator; import cpw.mods.fml.common.Loader; import makamys.neodymium.config.Config; @@ -16,6 +8,13 @@ import makamys.neodymium.util.virtualjar.VirtualJar; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.settings.GameSettings; +import org.lwjgl.opengl.GLContext; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.List; + +import static makamys.neodymium.Constants.LOGGER; public class Compat { @@ -25,9 +24,11 @@ public class Compat { private static int notEnoughVRAMAmountMB = -1; - private static boolean RPLE; + private static boolean IS_RPLE_PRESENT; + + private static boolean IS_FALSE_TWEAKS_PRESENT; - private static boolean FALSE_TWEAKS; + private static boolean isShadersEnabled; public static void init() { isGL33Supported = GLContext.getCapabilities().OpenGL33; @@ -37,35 +38,34 @@ public class Compat { } if (Loader.isModLoaded("rple")) { - RPLE = true; + IS_RPLE_PRESENT = true; } if (Loader.isModLoaded("falsetweaks")) { - FALSE_TWEAKS = true; + IS_FALSE_TWEAKS_PRESENT = true; } } - public static boolean RPLE() { - return RPLE; + public static boolean isRPLEModPresent() { + return IS_RPLE_PRESENT; } - public static boolean FalseTweaks() { - return FALSE_TWEAKS; + public static boolean isFalseTweaksModPresent() { + return IS_FALSE_TWEAKS_PRESENT; } - private static boolean shadersEnabled; - public static boolean isShaders() { - return shadersEnabled; + public static boolean isOptiFineShadersEnabled() { + return isShadersEnabled; } - public static void updateShadersState() { + public static void updateOptiFineShadersState() { try { Class<?> shaders = Class.forName("shadersmod.client.Shaders"); try { String shaderPack = (String)shaders.getMethod("getShaderPackName").invoke(null); if(shaderPack != null) { - shadersEnabled = true; + isShadersEnabled = true; return; } } catch(Exception e) { @@ -75,7 +75,7 @@ public class Compat { } catch (ClassNotFoundException e) { } - shadersEnabled = false; + isShadersEnabled = false; } private static void disableTriangulator() { diff --git a/src/main/java/makamys/neodymium/mixin/MixinWorldRenderer.java b/src/main/java/makamys/neodymium/mixin/MixinWorldRenderer.java index 4daa525..16c4ea6 100644 --- a/src/main/java/makamys/neodymium/mixin/MixinWorldRenderer.java +++ b/src/main/java/makamys/neodymium/mixin/MixinWorldRenderer.java @@ -194,7 +194,7 @@ abstract class MixinWorldRenderer implements IWorldRenderer { public boolean isDrawn() { if (!(skipRenderPass[0] && skipRenderPass[1])) return true; - if (!Compat.isShaders()) + if (!Compat.isOptiFineShadersEnabled()) return isInFrustum; return true; } diff --git a/src/main/java/makamys/neodymium/renderer/ChunkMesh.java b/src/main/java/makamys/neodymium/renderer/ChunkMesh.java index decc90d..9d98bd3 100644 --- a/src/main/java/makamys/neodymium/renderer/ChunkMesh.java +++ b/src/main/java/makamys/neodymium/renderer/ChunkMesh.java @@ -2,7 +2,6 @@ package makamys.neodymium.renderer; import static makamys.neodymium.Constants.LOGGER; -import java.io.IOException; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.ArrayList; @@ -111,9 +110,9 @@ public class ChunkMesh extends Mesh { int verticesPerPrimitive = t.drawMode == GL11.GL_QUADS ? 4 : 3; int tessellatorVertexSize = 8; - if (Compat.isShaders()) + if (Compat.isOptiFineShadersEnabled()) tessellatorVertexSize += 10; - if (Compat.RPLE()) + if (Compat.isRPLEModPresent()) tessellatorVertexSize += 4; for(int quadI = 0; quadI < t.vertexCount / verticesPerPrimitive; quadI++) { @@ -190,26 +189,22 @@ public class ChunkMesh extends Mesh { quads.sort(MESH_QUAD_RENDER_COMPARATOR); } - try { - int i = 0; - for(MeshQuad quad : quads) { - if(i < quadCount) { - if(MeshQuad.isValid(quad)) { - int subMeshStartIdx = sortByNormals ? QUAD_NORMAL_TO_NORMAL_ORDER[quad.normal.ordinal()] : 0; - if(subMeshStart[subMeshStartIdx] == -1) { - subMeshStart[subMeshStartIdx] = i; - } - quad.writeToBuffer(out, stride); - i++; - } else if(sortByNormals){ - break; + int i = 0; + for(MeshQuad quad : quads) { + if(i < quadCount) { + if(MeshQuad.isValid(quad)) { + int subMeshStartIdx = sortByNormals ? QUAD_NORMAL_TO_NORMAL_ORDER[quad.normal.ordinal()] : 0; + if(subMeshStart[subMeshStartIdx] == -1) { + subMeshStart[subMeshStartIdx] = i; } + quad.writeToBuffer(out, stride); + i++; + } else if(sortByNormals){ + break; } } - } catch(IOException e) { - e.printStackTrace(); } - + buffer.flip(); return buffer; diff --git a/src/main/java/makamys/neodymium/renderer/MeshQuad.java b/src/main/java/makamys/neodymium/renderer/MeshQuad.java index 4e72535..2a9fe2d 100644 --- a/src/main/java/makamys/neodymium/renderer/MeshQuad.java +++ b/src/main/java/makamys/neodymium/renderer/MeshQuad.java @@ -1,20 +1,20 @@ package makamys.neodymium.renderer; -import java.io.IOException; -import java.util.Locale; - import makamys.neodymium.Compat; -import org.lwjgl.opengl.GL11; -import org.lwjgl.util.vector.Vector3f; - import makamys.neodymium.config.Config; import makamys.neodymium.util.BufferWriter; import makamys.neodymium.util.Util; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.vector.Vector3f; + +import java.util.Locale; public class MeshQuad { private final static int DEFAULT_BRIGHTNESS = Util.createBrightness(15, 15); private final static int DEFAULT_COLOR = 0xFFFFFFFF; - + + //region common + public float[] xs = new float[4]; public float[] ys = new float[4]; public float[] zs = new float[4]; @@ -24,10 +24,18 @@ public class MeshQuad { // TODO normals? public int[] bs = new int[4]; - //RPLE compat. bs reused as RED + //endregion common + + //region RPLE + + // bs used as RED public int[] bsG = new int[4]; public int[] bsB = new int[4]; + //endregion RPLE + + //region Shaders + public int[] e1 = new int[4]; public int[] e2 = new int[4]; @@ -43,9 +51,15 @@ public class MeshQuad { public float[] um = new float[4]; public float[] vm = new float[4]; + //endregion Shaders + + //region Shaders + RPLE + public float[] ue = new float[4]; public float[] ve = new float[4]; + //endregion Shaders + RPLE + public boolean deleted; public QuadNormal normal; @@ -53,91 +67,245 @@ public class MeshQuad { private static Vector3f vectorA = new Vector3f(); private static Vector3f vectorB = new Vector3f(); private static Vector3f vectorC = new Vector3f(); - + + private void read(int[] rawBuffer, int tessellatorVertexSize, int offset, float offsetX, float offsetY, float offsetZ, int drawMode, ChunkMesh.Flags flags) { + boolean rple = Compat.isRPLEModPresent(); + boolean optiFineShaders = Compat.isOptiFineShadersEnabled(); + + if (rple && optiFineShaders) { + readRPLEAndShaders(rawBuffer, tessellatorVertexSize, offset, offsetX, offsetY, offsetZ, drawMode, flags); + } else if (optiFineShaders) { + readShaders(rawBuffer, tessellatorVertexSize, offset, offsetX, offsetY, offsetZ, drawMode, flags); + } else if (rple) { + readRPLE(rawBuffer, tessellatorVertexSize, offset, offsetX, offsetY, offsetZ, drawMode, flags); + } else { + readVanilla(rawBuffer, tessellatorVertexSize, offset, offsetX, offsetY, offsetZ, drawMode, flags); + } + } + + //region read implementations + + private void readRPLEAndShaders(int[] rawBuffer, int tessellatorVertexSize, int offset, float offsetX, float offsetY, float offsetZ, int drawMode, ChunkMesh.Flags flags) { + //RPLE and Shaders int vertices = drawMode == GL11.GL_TRIANGLES ? 3 : 4; for(int vi = 0; vi < vertices; vi++) { int i = offset + vi * tessellatorVertexSize; - - xs[vi] = Float.intBitsToFloat(rawBuffer[i + 0]) + offsetX; + + xs[vi] = Float.intBitsToFloat(rawBuffer[i]) + offsetX; ys[vi] = Float.intBitsToFloat(rawBuffer[i + 1]) + offsetY; zs[vi] = Float.intBitsToFloat(rawBuffer[i + 2]) + offsetZ; - + us[vi] = Float.intBitsToFloat(rawBuffer[i + 3]); vs[vi] = Float.intBitsToFloat(rawBuffer[i + 4]); cs[vi] = flags.hasColor ? rawBuffer[i + 5] : DEFAULT_COLOR; - // TODO normals? + bs[vi] = flags.hasBrightness ? rawBuffer[i + 6] : DEFAULT_BRIGHTNESS; + + e1[vi] = rawBuffer[i + 7]; + e2[vi] = rawBuffer[i + 8]; + + xn[vi] = Float.intBitsToFloat(rawBuffer[i + 9]); + yn[vi] = Float.intBitsToFloat(rawBuffer[i + 10]); + zn[vi] = Float.intBitsToFloat(rawBuffer[i + 11]); - if (Compat.isShaders()) { - bs[vi] = flags.hasBrightness ? rawBuffer[i + 6] : DEFAULT_BRIGHTNESS; - e1[vi] = rawBuffer[i + 7]; - e2[vi] = rawBuffer[i + 8]; - xn[vi] = Float.intBitsToFloat(rawBuffer[i + 9]); - yn[vi] = Float.intBitsToFloat(rawBuffer[i + 10]); - zn[vi] = Float.intBitsToFloat(rawBuffer[i + 11]); - xt[vi] = Float.intBitsToFloat(rawBuffer[i + 12]); - yt[vi] = Float.intBitsToFloat(rawBuffer[i + 13]); - zt[vi] = Float.intBitsToFloat(rawBuffer[i + 14]); - wt[vi] = Float.intBitsToFloat(rawBuffer[i + 15]); - um[vi] = Float.intBitsToFloat(rawBuffer[i + 16]); - vm[vi] = Float.intBitsToFloat(rawBuffer[i + 17]); - if (Compat.RPLE()) { - bsG[vi] = rawBuffer[i + 18]; - bsB[vi] = rawBuffer[i + 19]; - ue[vi] = Float.intBitsToFloat(rawBuffer[i + 20]); - ve[vi] = Float.intBitsToFloat(rawBuffer[i + 21]); - } + xt[vi] = Float.intBitsToFloat(rawBuffer[i + 12]); + yt[vi] = Float.intBitsToFloat(rawBuffer[i + 13]); + zt[vi] = Float.intBitsToFloat(rawBuffer[i + 14]); + wt[vi] = Float.intBitsToFloat(rawBuffer[i + 15]); + + um[vi] = Float.intBitsToFloat(rawBuffer[i + 16]); + vm[vi] = Float.intBitsToFloat(rawBuffer[i + 17]); + + if (flags.hasBrightness) { + bsG[vi] = rawBuffer[i + 18]; + bsB[vi] = rawBuffer[i + 19]; } else { - bs[vi] = flags.hasBrightness ? rawBuffer[i + 7] : DEFAULT_BRIGHTNESS; - - if (Compat.RPLE()) { - if (flags.hasBrightness) { - bsG[vi] = rawBuffer[i + 8]; - bsB[vi] = rawBuffer[i + 9]; - } else { - bsG[vi] = DEFAULT_BRIGHTNESS; - bsB[vi] = DEFAULT_BRIGHTNESS; - } - } + bsG[vi] = DEFAULT_BRIGHTNESS; + bsB[vi] = DEFAULT_BRIGHTNESS; } + + ue[vi] = Float.intBitsToFloat(rawBuffer[i + 20]); + ve[vi] = Float.intBitsToFloat(rawBuffer[i + 21]); } - + if(vertices == 3) { - // Quadrangulate! + // Quadrangulate! xs[3] = xs[2]; ys[3] = ys[2]; zs[3] = zs[2]; - + us[3] = us[2]; vs[3] = vs[2]; - + + cs[3] = cs[2]; + bs[3] = bs[2]; - if (Compat.RPLE()) { - bsG[3] = bsG[2]; - bsB[3] = bsB[2]; - if (Compat.isShaders()) { - ue[3] = ue[2]; - ve[3] = ve[2]; - } - } + + e1[3] = e1[2]; + e2[3] = e2[2]; + + xn[3] = xn[2]; + yn[3] = yn[2]; + zn[3] = zn[2]; + + xt[3] = xt[2]; + yt[3] = yt[2]; + zt[3] = zt[2]; + wt[3] = wt[2]; + + um[3] = um[2]; + vm[3] = vm[2]; + + bsG[3] = bsG[2]; + bsB[3] = bsB[2]; + + ue[3] = ue[2]; + ve[3] = ve[2]; + } + } + + private void readShaders(int[] rawBuffer, int tessellatorVertexSize, int offset, float offsetX, float offsetY, float offsetZ, int drawMode, ChunkMesh.Flags flags) { + //Only shaders + int vertices = drawMode == GL11.GL_TRIANGLES ? 3 : 4; + for (int vi = 0; vi < vertices; vi++) { + int i = offset + vi * tessellatorVertexSize; + + xs[vi] = Float.intBitsToFloat(rawBuffer[i]) + offsetX; + ys[vi] = Float.intBitsToFloat(rawBuffer[i + 1]) + offsetY; + zs[vi] = Float.intBitsToFloat(rawBuffer[i + 2]) + offsetZ; + + us[vi] = Float.intBitsToFloat(rawBuffer[i + 3]); + vs[vi] = Float.intBitsToFloat(rawBuffer[i + 4]); + + cs[vi] = flags.hasColor ? rawBuffer[i + 5] : DEFAULT_COLOR; + + bs[vi] = flags.hasBrightness ? rawBuffer[i + 6] : DEFAULT_BRIGHTNESS; + e1[vi] = rawBuffer[i + 7]; + e2[vi] = rawBuffer[i + 8]; + xn[vi] = Float.intBitsToFloat(rawBuffer[i + 9]); + yn[vi] = Float.intBitsToFloat(rawBuffer[i + 10]); + zn[vi] = Float.intBitsToFloat(rawBuffer[i + 11]); + xt[vi] = Float.intBitsToFloat(rawBuffer[i + 12]); + yt[vi] = Float.intBitsToFloat(rawBuffer[i + 13]); + zt[vi] = Float.intBitsToFloat(rawBuffer[i + 14]); + wt[vi] = Float.intBitsToFloat(rawBuffer[i + 15]); + um[vi] = Float.intBitsToFloat(rawBuffer[i + 16]); + vm[vi] = Float.intBitsToFloat(rawBuffer[i + 17]); + } + + if (vertices == 3) { + // Quadrangulate! + xs[3] = xs[2]; + ys[3] = ys[2]; + zs[3] = zs[2]; + + us[3] = us[2]; + vs[3] = vs[2]; + cs[3] = cs[2]; - if (Compat.isShaders()) { - e1[3] = e1[2]; - e2[3] = e2[2]; - xn[3] = xn[2]; - yn[3] = yn[2]; - zn[3] = zn[2]; - xt[3] = xt[2]; - yt[3] = yt[2]; - zt[3] = zt[2]; - wt[3] = wt[2]; - um[3] = um[2]; - vm[3] = vm[2]; + + bs[3] = bs[2]; + + e1[3] = e1[2]; + e2[3] = e2[2]; + + xn[3] = xn[2]; + yn[3] = yn[2]; + zn[3] = zn[2]; + + xt[3] = xt[2]; + yt[3] = yt[2]; + zt[3] = zt[2]; + wt[3] = wt[2]; + + um[3] = um[2]; + vm[3] = vm[2]; + } + } + + private void readRPLE(int[] rawBuffer, int tessellatorVertexSize, int offset, float offsetX, float offsetY, float offsetZ, int drawMode, ChunkMesh.Flags flags) { + //Only RPLE + int vertices = drawMode == GL11.GL_TRIANGLES ? 3 : 4; + for(int vi = 0; vi < vertices; vi++) { + int i = offset + vi * tessellatorVertexSize; + + xs[vi] = Float.intBitsToFloat(rawBuffer[i]) + offsetX; + ys[vi] = Float.intBitsToFloat(rawBuffer[i + 1]) + offsetY; + zs[vi] = Float.intBitsToFloat(rawBuffer[i + 2]) + offsetZ; + + us[vi] = Float.intBitsToFloat(rawBuffer[i + 3]); + vs[vi] = Float.intBitsToFloat(rawBuffer[i + 4]); + + cs[vi] = flags.hasColor ? rawBuffer[i + 5] : DEFAULT_COLOR; + + // TODO normals? + + if (flags.hasBrightness) { + bs[vi] = rawBuffer[i + 7]; + bsG[vi] = rawBuffer[i + 8]; + bsB[vi] = rawBuffer[i + 9]; + } else { + bs[vi] = DEFAULT_BRIGHTNESS; + bsG[vi] = DEFAULT_BRIGHTNESS; + bsB[vi] = DEFAULT_BRIGHTNESS; } } + + if(vertices == 3) { + // Quadrangulate! + xs[3] = xs[2]; + ys[3] = ys[2]; + zs[3] = zs[2]; + + us[3] = us[2]; + vs[3] = vs[2]; + + cs[3] = cs[2]; + + bs[3] = bs[2]; + bsG[3] = bsG[2]; + bsB[3] = bsB[2]; + } } + + private void readVanilla(int[] rawBuffer, int tessellatorVertexSize, int offset, float offsetX, float offsetY, float offsetZ, int drawMode, ChunkMesh.Flags flags) { + //No RPLE or Shaders + int vertices = drawMode == GL11.GL_TRIANGLES ? 3 : 4; + for(int vi = 0; vi < vertices; vi++) { + int i = offset + vi * tessellatorVertexSize; + + xs[vi] = Float.intBitsToFloat(rawBuffer[i]) + offsetX; + ys[vi] = Float.intBitsToFloat(rawBuffer[i + 1]) + offsetY; + zs[vi] = Float.intBitsToFloat(rawBuffer[i + 2]) + offsetZ; + + us[vi] = Float.intBitsToFloat(rawBuffer[i + 3]); + vs[vi] = Float.intBitsToFloat(rawBuffer[i + 4]); + + cs[vi] = flags.hasColor ? rawBuffer[i + 5] : DEFAULT_COLOR; + + // TODO normals? + + bs[vi] = flags.hasBrightness ? rawBuffer[i + 7] : DEFAULT_BRIGHTNESS; + } + + if(vertices == 3) { + // Quadrangulate! + xs[3] = xs[2]; + ys[3] = ys[2]; + zs[3] = zs[2]; + + us[3] = us[2]; + vs[3] = vs[2]; + + cs[3] = cs[2]; + + bs[3] = bs[2]; + } + } + + //endregion read implementations public void setState(int[] rawBuffer, int tessellatorVertexSize, int offset, ChunkMesh.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ) { deleted = false; @@ -158,21 +326,104 @@ public class MeshQuad { } /** - * @implSpec This needs to be kept in sync with the attributes in {@link NeoRenderer#init()} + * @implSpec These needs to be kept in sync with the attributes in {@link NeoRenderer#init()} */ - public void writeToBuffer(BufferWriter out, int expectedStride) throws IOException { + public void writeToBuffer(BufferWriter out, int expectedStride) { + boolean rple = Compat.isRPLEModPresent(); + boolean shaders = Compat.isOptiFineShadersEnabled(); + + if (rple && shaders) { + writeToBufferRPLEAndShaders(out, expectedStride); + } else if (shaders) { + writeToBufferShaders(out, expectedStride); + } else if (rple) { + writeToBufferRPLE(out, expectedStride); + } else { + writeToBufferVanilla(out, expectedStride); + } + } + + //region writeToBuffer implementations + + public void writeToBufferRPLEAndShaders(BufferWriter out, int expectedStride) { + for(int vi = 0; vi < 4; vi++) { + out.writeFloat(xs[vi]); + out.writeFloat(ys[vi]); + out.writeFloat(zs[vi]); + + out.writeFloat(us[vi]); + out.writeFloat(vs[vi]); + + out.writeInt(cs[vi]); + + out.writeInt(bs[vi]); + + out.writeInt(e1[vi]); + out.writeInt(e2[vi]); + + out.writeFloat(xn[vi]); + out.writeFloat(yn[vi]); + out.writeFloat(zn[vi]); + + out.writeFloat(xt[vi]); + out.writeFloat(yt[vi]); + out.writeFloat(zt[vi]); + out.writeFloat(wt[vi]); + + out.writeFloat(um[vi]); + out.writeFloat(vm[vi]); + + out.writeInt(bsG[vi]); + out.writeInt(bsB[vi]); + + out.writeFloat(ue[vi]); + out.writeFloat(ve[vi]); + + assert out.position() % expectedStride == 0; + } + } + + public void writeToBufferShaders(BufferWriter out, int expectedStride) { for(int vi = 0; vi < 4; vi++) { - float x = xs[vi]; - float y = ys[vi]; - float z = zs[vi]; - - out.writeFloat(x); - out.writeFloat(y); - out.writeFloat(z); - + out.writeFloat(xs[vi]); + out.writeFloat(ys[vi]); + out.writeFloat(zs[vi]); + + out.writeFloat(us[vi]); + out.writeFloat(vs[vi]); + + out.writeInt( cs[vi]); + + out.writeInt(bs[vi]); + + out.writeInt(e1[vi]); + out.writeInt(e2[vi]); + + out.writeFloat(xn[vi]); + out.writeFloat(yn[vi]); + out.writeFloat(zn[vi]); + + out.writeFloat(xt[vi]); + out.writeFloat(yt[vi]); + out.writeFloat(zt[vi]); + out.writeFloat(wt[vi]); + + out.writeFloat(um[vi]); + out.writeFloat(vm[vi]); + + assert out.position() % expectedStride == 0; + } + } + + public void writeToBufferRPLE(BufferWriter out, int expectedStride) { + for(int vi = 0; vi < 4; vi++) { + out.writeFloat(xs[vi]); + out.writeFloat(ys[vi]); + out.writeFloat(zs[vi]); + float u = us[vi]; float v = vs[vi]; - + if(Config.shortUV) { out.writeShort((short)(Math.round(u * 32768f))); out.writeShort((short)(Math.round(v * 32768f))); @@ -181,41 +432,43 @@ public class MeshQuad { out.writeFloat(v); } - int c = cs[vi]; - - out.writeInt(c); + out.writeInt(cs[vi]); out.writeInt(bs[vi]); + out.writeInt(bsG[vi]); + out.writeInt(bsB[vi]); - if (Compat.isShaders()) { - out.writeInt(e1[vi]); - out.writeInt(e2[vi]); - out.writeFloat(xn[vi]); - out.writeFloat(yn[vi]); - out.writeFloat(zn[vi]); - out.writeFloat(xt[vi]); - out.writeFloat(yt[vi]); - out.writeFloat(zt[vi]); - out.writeFloat(wt[vi]); - out.writeFloat(um[vi]); - out.writeFloat(vm[vi]); - } + assert out.position() % expectedStride == 0; + } + } + + public void writeToBufferVanilla(BufferWriter out, int expectedStride) { + for(int vi = 0; vi < 4; vi++) { + out.writeFloat(xs[vi]); + out.writeFloat(ys[vi]); + out.writeFloat(zs[vi]); + + float u = us[vi]; + float v = vs[vi]; - if (Compat.RPLE()) { - out.writeInt(bsG[vi]); - out.writeInt(bsB[vi]); - if (Compat.isShaders()) { - out.writeFloat(ue[vi]); - out.writeFloat(ve[vi]); - } + if(Config.shortUV) { + out.writeShort((short)(Math.round(u * 32768f))); + out.writeShort((short)(Math.round(v * 32768f))); + } else { + out.writeFloat(u); + out.writeFloat(v); } - + + out.writeInt(cs[vi]); + + out.writeInt(bs[vi]); + assert out.position() % expectedStride == 0; - - //System.out.println("[" + vertexI + "] x: " + x + ", y: " + y + " z: " + z + ", u: " + u + ", v: " + v + ", b: " + b + ", c: " + c); } } + //endregion + @Override public String toString() { return String.format(Locale.ENGLISH, "%s[(%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f)]", deleted ? "XXX " : "", xs[0], ys[0], zs[0], xs[1], ys[1], zs[1], xs[2], ys[2], zs[2], xs[3], ys[3], zs[3]); diff --git a/src/main/java/makamys/neodymium/renderer/NeoRenderer.java b/src/main/java/makamys/neodymium/renderer/NeoRenderer.java index ed8be73..79b6117 100644 --- a/src/main/java/makamys/neodymium/renderer/NeoRenderer.java +++ b/src/main/java/makamys/neodymium/renderer/NeoRenderer.java @@ -291,7 +291,7 @@ public class NeoRenderer { Matrix4f projMatrix = new Matrix4f(); private int render(int pass, double alpha) { - if (!Compat.isShaders()) { + if (!Compat.isOptiFineShadersEnabled()) { int shader = getShaderProgram(pass); if (shader == 0) return 0; @@ -306,7 +306,7 @@ public class NeoRenderer { } int u_renderOffset = -1; - if (!Compat.isShaders()) { + if (!Compat.isOptiFineShadersEnabled()) { u_renderOffset = glGetUniformLocation(getShaderProgram(pass), "renderOffset"); } @@ -320,7 +320,7 @@ public class NeoRenderer { Util.setPositionAndLimit(piFirst[pass], region.batchFirst[pass], region.batchLimit[pass]); Util.setPositionAndLimit(piCount[pass], region.batchFirst[pass], region.batchLimit[pass]); - if (Compat.isShaders()) { + if (Compat.isOptiFineShadersEnabled()) { GL11.glMatrixMode(GL_MODELVIEW); val offsetX = (float) (region.originX - eyePosX); @@ -335,7 +335,7 @@ public class NeoRenderer { glMultiDrawArrays(GL_QUADS, piFirst[pass], piCount[pass]); - if (Compat.isShaders()) + if (Compat.isOptiFineShadersEnabled()) GL11.glPopMatrix(); } Util.setPositionAndLimit(piFirst[pass], 0, oldLimit); @@ -345,7 +345,7 @@ public class NeoRenderer { GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL); } - if (!Compat.isShaders()) { + if (!Compat.isOptiFineShadersEnabled()) { glUseProgram(0); } @@ -389,7 +389,7 @@ public class NeoRenderer { int u_proj = glGetUniformLocation(shaderProgram, "proj"); int u_playerPos = glGetUniformLocation(shaderProgram, "playerPos"); int u_light = 0, u_light_r = 0, u_light_g = 0, u_light_b = 0; - if (Compat.RPLE()) { + if (Compat.isRPLEModPresent()) { u_light_r = glGetUniformLocation(shaderProgram, "lightTexR"); u_light_g = glGetUniformLocation(shaderProgram, "lightTexG"); u_light_b = glGetUniformLocation(shaderProgram, "lightTexB"); @@ -414,7 +414,7 @@ public class NeoRenderer { glUniform3f(u_playerPos, (float) eyePosX, (float) eyePosY, (float) eyePosZ); - if (Compat.RPLE()) { + if (Compat.isRPLEModPresent()) { //TODO connect to RPLE gl api (once that exists) // For now we just use the RPLE default texture indices glUniform1i(u_light_r, 1); @@ -432,6 +432,56 @@ public class NeoRenderer { fogStartEnd.position(0); } + private void initAttributesRPLEAndShaders() { + attributes.addAttribute("POS", 3, 4, GL_FLOAT); + attributes.addAttribute("TEXTURE", 2, 4, GL_FLOAT); + attributes.addAttribute("COLOR", 4, 1, GL_UNSIGNED_BYTE); + attributes.addAttribute("BRIGHTNESS_RED", 2, 2, GL_SHORT); + attributes.addAttribute("ENTITY_DATA_1", 1, 4, GL_UNSIGNED_INT); + attributes.addAttribute("ENTITY_DATA_2", 1, 4, GL_UNSIGNED_INT); + attributes.addAttribute("NORMAL", 3, 4, GL_FLOAT); + attributes.addAttribute("TANGENT", 4, 4, GL_FLOAT); + attributes.addAttribute("MIDTEXTURE", 2, 4, GL_FLOAT); + attributes.addAttribute("BRIGHTNESS_GREEN", 2, 2, GL_SHORT); + attributes.addAttribute("BRIGHTNESS_BLUE", 2, 2, GL_SHORT); + attributes.addAttribute("EDGE_TEX", 2, 4, GL_FLOAT); + } + + private void initAttributesShaders() { + attributes.addAttribute("POS", 3, 4, GL_FLOAT); + attributes.addAttribute("TEXTURE", 2, 4, GL_FLOAT); + attributes.addAttribute("COLOR", 4, 1, GL_UNSIGNED_BYTE); + attributes.addAttribute("BRIGHTNESS", 2, 2, GL_SHORT); + attributes.addAttribute("ENTITY_DATA_1", 1, 4, GL_UNSIGNED_INT); + attributes.addAttribute("ENTITY_DATA_2", 1, 4, GL_UNSIGNED_INT); + attributes.addAttribute("NORMAL", 3, 4, GL_FLOAT); + attributes.addAttribute("TANGENT", 4, 4, GL_FLOAT); + attributes.addAttribute("MIDTEXTURE", 2, 4, GL_FLOAT); + } + + private void initAttributesRPLE() { + attributes.addAttribute("POS", 3, 4, GL_FLOAT); + if (Config.shortUV) { + attributes.addAttribute("TEXTURE", 2, 2, GL_UNSIGNED_SHORT); + } else { + attributes.addAttribute("TEXTURE", 2, 4, GL_FLOAT); + } + attributes.addAttribute("COLOR", 4, 1, GL_UNSIGNED_BYTE); + attributes.addAttribute("BRIGHTNESS_RED", 2, 2, GL_SHORT); + attributes.addAttribute("BRIGHTNESS_GREEN", 2, 2, GL_SHORT); + attributes.addAttribute("BRIGHTNESS_BLUE", 2, 2, GL_SHORT); + } + + private void initAttributesVanilla() { + attributes.addAttribute("POS", 3, 4, GL_FLOAT); + if (Config.shortUV) { + attributes.addAttribute("TEXTURE", 2, 2, GL_UNSIGNED_SHORT); + } else { + attributes.addAttribute("TEXTURE", 2, 4, GL_FLOAT); + } + attributes.addAttribute("COLOR", 4, 1, GL_UNSIGNED_BYTE); + attributes.addAttribute("BRIGHTNESS", 2, 2, GL_SHORT); + } /** * @implSpec The attributes here need to be kept in sync with {@link MeshQuad#writeToBuffer(BufferWriter, int)} */ @@ -440,37 +490,20 @@ public class NeoRenderer { // This means 1 MB of index data per 512 MB of VRAM. MAX_MESHES = Config.VRAMSize * 128; - Compat.updateShadersState(); + Compat.updateOptiFineShadersState(); attributes = new AttributeSet(); - attributes.addAttribute("POS", 3, 4, GL_FLOAT); - if (Config.shortUV) { - attributes.addAttribute("TEXTURE", 2, 2, GL_UNSIGNED_SHORT); - } else { - attributes.addAttribute("TEXTURE", 2, 4, GL_FLOAT); - } - attributes.addAttribute("COLOR", 4, 1, GL_UNSIGNED_BYTE); - if (Compat.RPLE()) { - attributes.addAttribute("BRIGHTNESS_RED", 2, 2, GL_SHORT); - } else { - attributes.addAttribute("BRIGHTNESS", 2, 2, GL_SHORT); - } - if (Compat.isShaders()) { - attributes.addAttribute("ENTITY_DATA_1", 1, 4, GL_UNSIGNED_INT); - attributes.addAttribute("ENTITY_DATA_2", 1, 4, GL_UNSIGNED_INT); - attributes.addAttribute("NORMAL", 3, 4, GL_FLOAT); - attributes.addAttribute("TANGENT", 4, 4, GL_FLOAT); - attributes.addAttribute("MIDTEXTURE", 2, 4, GL_FLOAT); - if (Compat.RPLE()) { - attributes.addAttribute("BRIGHTNESS_GREEN", 2, 2, GL_SHORT); - attributes.addAttribute("BRIGHTNESS_BLUE", 2, 2, GL_SHORT); - attributes.addAttribute("EDGE_TEX", 2, 4, GL_FLOAT); - } + + boolean rple = Compat.isRPLEModPresent(); + boolean optiFineShaders = Compat.isOptiFineShadersEnabled(); + if (rple && optiFineShaders) { + initAttributesRPLEAndShaders(); + } else if (optiFineShaders) { + initAttributesShaders(); + } else if (rple) { + initAttributesRPLE(); } else { - if (Compat.RPLE()) { - attributes.addAttribute("BRIGHTNESS_GREEN", 2, 2, GL_SHORT); - attributes.addAttribute("BRIGHTNESS_BLUE", 2, 2, GL_SHORT); - } + initAttributesVanilla(); } reloadShader(); @@ -481,76 +514,10 @@ public class NeoRenderer { mem = new GPUMemoryManager(); glBindBuffer(GL_ARRAY_BUFFER, mem.VBO); - - // position 3 floats 12 bytes offset 0 - // texture 2 floats 8 bytes offset 12 - // color 4 bytes 4 bytes offset 20 - // brightness 2 shorts 4 bytes offset 24 - // entitydata 3 shorts 6 bytes offset 28 - // <padding> 2 bytes - // normal 3 floats 12 bytes offset 36 - // tangent 4 floats 16 bytes offset 48 - // midtexture 2 floats 8 bytes offset 64 - if (Compat.isShaders()) { - int stride; - if (Compat.FalseTweaks()) { - stride = VertexAPI.recomputeVertexInfo(18, 4); - } else { - stride = 72; - } - val entityAttrib = 10; - val midTexCoordAttrib = 11; - val tangentAttrib = 12; - // position 3 floats 12 bytes offset 0 - GL11.glVertexPointer(3, GL11.GL_FLOAT, stride, 0); - GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY); - // texture 2 floats 8 bytes offset 12 - GL11.glTexCoordPointer(2, GL11.GL_FLOAT, stride, 12); - GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY); - - // color 4 bytes 4 bytes offset 20 - GL11.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, stride, 20); - GL11.glEnableClientState(GL11.GL_COLOR_ARRAY); - - // brightness 2 shorts 4 bytes offset 24 - OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit); - GL11.glTexCoordPointer(2, GL11.GL_SHORT, stride, 24); - GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY); - OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit); - - // entitydata 3 shorts 6 bytes offset 28 - GL20.glVertexAttribPointer(entityAttrib, 3, GL11.GL_SHORT, false, stride, 28); - GL20.glEnableVertexAttribArray(entityAttrib); - - // normal 3 floats 12 bytes offset 36 - GL11.glNormalPointer(GL11.GL_FLOAT, stride, 36); - GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY); - - // tangent 4 floats 16 bytes offset 48 - GL20.glVertexAttribPointer(tangentAttrib, 4, GL11.GL_FLOAT, false, stride, 48); - GL20.glEnableVertexAttribArray(tangentAttrib); - - // midtexture 2 floats 8 bytes offset 64 - GL13.glClientActiveTexture(GL13.GL_TEXTURE3); - GL11.glTexCoordPointer(2, GL11.GL_FLOAT, stride, 64); - GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY); - OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit); - - ARBVertexShader.glVertexAttribPointerARB(midTexCoordAttrib, 2, GL11.GL_FLOAT, false, stride, 64); - ARBVertexShader.glEnableVertexAttribArrayARB(midTexCoordAttrib); - - if (Compat.RPLE()) { - RPLELightMapUtil.enableVertexPointersVBO(); - ARBVertexShader.glVertexAttribPointerARB(RPLEShaderConstants.edgeTexCoordAttrib, - 2, - GL_FLOAT, - false, - stride, - 80); - ARBVertexShader.glEnableVertexAttribArrayARB(RPLEShaderConstants.edgeTexCoordAttrib); - } + if (optiFineShaders) { + initOptiFineShadersVertexPointers(); } else { attributes.enable(); } @@ -568,6 +535,85 @@ public class NeoRenderer { return true; } + // TODO: This format is nice, we should have it in the docs too! + // position 3 floats 12 bytes offset 0 + // texture 2 floats 8 bytes offset 12 + // color 4 bytes 4 bytes offset 20 + // brightness 2 shorts 4 bytes offset 24 (brightness_R with RPLE) + // entitydata 3 shorts 6 bytes offset 28 + // <padding> -------- 2 bytes offset 34 + // normal 3 floats 12 bytes offset 36 + // tangent 4 floats 16 bytes offset 48 + // midtexture 2 floats 8 bytes offset 64 + + // ---RPLE EXTRAS--- + // brightness_G 2 shorts 4 bytes offset 72 + // brightness_B 2 shorts 4 bytes offset 76 + // edgeTex 2 floats 8 bytes offset 80 + private static void initOptiFineShadersVertexPointers() { + int stride; + if (Compat.isFalseTweaksModPresent()) { + stride = VertexAPI.recomputeVertexInfo(18, 4); + } else { + stride = 72; + } + val entityAttrib = 10; + val midTexCoordAttrib = 11; + val tangentAttrib = 12; + + // position 3 floats 12 bytes offset 0 + GL11.glVertexPointer(3, GL11.GL_FLOAT, stride, 0); + GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY); + + // texture 2 floats 8 bytes offset 12 + GL11.glTexCoordPointer(2, GL11.GL_FLOAT, stride, 12); + GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY); + + // color 4 bytes 4 bytes offset 20 + GL11.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, stride, 20); + GL11.glEnableClientState(GL11.GL_COLOR_ARRAY); + + // brightness 2 shorts 4 bytes offset 24 + if (!Compat.isRPLEModPresent()) { // RPLE sets this up in enableVertexPointersVBO + OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit); + GL11.glTexCoordPointer(2, GL11.GL_SHORT, stride, 24); + GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY); + OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit); + } + + // entitydata 3 shorts 6 bytes offset 28 + GL20.glVertexAttribPointer(entityAttrib, 3, GL11.GL_SHORT, false, stride, 28); + GL20.glEnableVertexAttribArray(entityAttrib); + + // normal 3 floats 12 bytes offset 36 + GL11.glNormalPointer(GL11.GL_FLOAT, stride, 36); + GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY); + + // tangent 4 floats 16 bytes offset 48 + GL20.glVertexAttribPointer(tangentAttrib, 4, GL11.GL_FLOAT, false, stride, 48); + GL20.glEnableVertexAttribArray(tangentAttrib); + + // midtexture 2 floats 8 bytes offset 64 + GL13.glClientActiveTexture(GL13.GL_TEXTURE3); + GL11.glTexCoordPointer(2, GL11.GL_FLOAT, stride, 64); + GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY); + OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit); + + ARBVertexShader.glVertexAttribPointerARB(midTexCoordAttrib, 2, GL11.GL_FLOAT, false, stride, 64); + ARBVertexShader.glEnableVertexAttribArrayARB(midTexCoordAttrib); + + if (Compat.isRPLEModPresent()) { + RPLELightMapUtil.enableVertexPointersVBO(); + ARBVertexShader.glVertexAttribPointerARB(RPLEShaderConstants.edgeTexCoordAttrib, + 2, + GL_FLOAT, + false, + stride, + 80); + ARBVertexShader.glEnableVertexAttribArrayARB(RPLEShaderConstants.edgeTexCoordAttrib); + } + } + public int getStride() { return attributes.stride(); } @@ -581,7 +627,7 @@ public class NeoRenderer { if (Config.shortUV) { defines.put("SHORT_UV", ""); } - if (Compat.RPLE()) { + if (Compat.isRPLEModPresent()) { defines.put("RPLE", ""); } if (pass == 0) { |