aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/makamys/neodymium/Compat.java44
-rw-r--r--src/main/java/makamys/neodymium/mixin/MixinWorldRenderer.java2
-rw-r--r--src/main/java/makamys/neodymium/renderer/ChunkMesh.java33
-rw-r--r--src/main/java/makamys/neodymium/renderer/MeshQuad.java461
-rw-r--r--src/main/java/makamys/neodymium/renderer/NeoRenderer.java254
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) {