aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVen <tudurap.com@gmail.com>2023-12-05 19:11:22 +0000
committermakamys <makamys@outlook.com>2024-01-08 22:49:40 +0100
commit74ffb8a2210d134dc05593100ea405c4666c84f9 (patch)
treea643c33d6f140f3276800ffc0654545fa1e4591d
parent180dee59e103dc94d17a4c4121f7963bc33c3ad6 (diff)
downloadNeodymium-74ffb8a2210d134dc05593100ea405c4666c84f9.tar.gz
Neodymium-74ffb8a2210d134dc05593100ea405c4666c84f9.tar.bz2
Neodymium-74ffb8a2210d134dc05593100ea405c4666c84f9.zip
Dirty OF Shader Compat
-rw-r--r--src/main/java/makamys/neodymium/renderer/ChunkMesh.java2
-rw-r--r--src/main/java/makamys/neodymium/renderer/NeoRenderer.java550
2 files changed, 314 insertions, 238 deletions
diff --git a/src/main/java/makamys/neodymium/renderer/ChunkMesh.java b/src/main/java/makamys/neodymium/renderer/ChunkMesh.java
index 24acc30..72c20ff 100644
--- a/src/main/java/makamys/neodymium/renderer/ChunkMesh.java
+++ b/src/main/java/makamys/neodymium/renderer/ChunkMesh.java
@@ -110,7 +110,7 @@ public class ChunkMesh extends Mesh {
int verticesPerPrimitive = t.drawMode == GL11.GL_QUADS ? 4 : 3;
- int tessellatorVertexSize = Compat.RPLE() ? 12 : 8;
+ int tessellatorVertexSize = Compat.isShaders() ? 18 : Compat.RPLE() ? 12 : 8;
for(int quadI = 0; quadI < t.vertexCount / verticesPerPrimitive; quadI++) {
MeshQuad quad = quadBuf.next();
diff --git a/src/main/java/makamys/neodymium/renderer/NeoRenderer.java b/src/main/java/makamys/neodymium/renderer/NeoRenderer.java
index ff13dd7..0cc7692 100644
--- a/src/main/java/makamys/neodymium/renderer/NeoRenderer.java
+++ b/src/main/java/makamys/neodymium/renderer/NeoRenderer.java
@@ -1,69 +1,66 @@
package makamys.neodymium.renderer;
-import static makamys.neodymium.Constants.VERSION;
-
-import static org.lwjgl.opengl.GL11.*;
-import static org.lwjgl.opengl.GL14.*;
-import static org.lwjgl.opengl.GL15.*;
-import static org.lwjgl.opengl.GL20.*;
-import static org.lwjgl.opengl.GL30.*;
-
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
+import lombok.val;
import makamys.neodymium.Compat;
-import makamys.neodymium.renderer.attribs.AttributeSet;
-import makamys.neodymium.util.BufferWriter;
-import org.lwjgl.BufferUtils;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.opengl.GL11;
-import org.lwjgl.util.vector.Matrix4f;
-import org.lwjgl.util.vector.Vector4f;
-
import makamys.neodymium.Neodymium;
import makamys.neodymium.config.Config;
import makamys.neodymium.ducks.IWorldRenderer;
import makamys.neodymium.renderer.Mesh.GPUStatus;
-import makamys.neodymium.util.CheatHelper;
-import makamys.neodymium.util.GuiHelper;
-import makamys.neodymium.util.OFUtil;
-import makamys.neodymium.util.Preprocessor;
-import makamys.neodymium.util.Util;
+import makamys.neodymium.renderer.attribs.AttributeSet;
+import makamys.neodymium.util.*;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
+import org.lwjgl.BufferUtils;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.opengl.ARBVertexShader;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL13;
+import org.lwjgl.opengl.GL20;
+import org.lwjgl.util.vector.Matrix4f;
+import org.lwjgl.util.vector.Vector4f;
+
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.util.*;
+import java.util.Map.Entry;
+
+import static makamys.neodymium.Constants.VERSION;
+import static org.lwjgl.opengl.GL11.glGetInteger;
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL14.glMultiDrawArrays;
+import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
+import static org.lwjgl.opengl.GL15.glBindBuffer;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
-/** The main renderer class. */
+/**
+ * The main renderer class.
+ */
public class NeoRenderer {
-
+
public boolean hasInited = false;
public boolean destroyPending;
public boolean reloadPending;
public int rendererSpeedup;
-
+
private static boolean[] wasDown = new boolean[256];
-
+
public boolean renderWorld;
public boolean rendererActive;
private boolean showMemoryDebugger;
-
+
public boolean forceRenderFog;
public boolean hasIncompatibilities;
-
+
private boolean fogEnabled;
-
+
private static int MAX_MESHES;
-
+
private int VAO;
private int[] shaderProgramsFog = {0, 0};
private int[] shaderProgramsNoFog = {0, 0};
@@ -71,136 +68,136 @@ public class NeoRenderer {
private IntBuffer[] piCount = new IntBuffer[2];
GPUMemoryManager mem;
private AttributeSet attributes;
-
+
private Map<ChunkCoordIntPair, NeoRegion> loadedRegionsMap = new HashMap<>();
private List<NeoRegion> loadedRegionsList = new ArrayList<>();
-
+
public World world;
-
+
// Eye position in world space
private double eyePosX;
private double eyePosY;
private double eyePosZ;
-
+
// Eye position in world space, transformed by model-view matrix (takes third person camera offset into account)
private double eyePosXT;
private double eyePosYT;
private double eyePosZT;
-
+
// eyePos?T divided by 16
int eyePosXTDiv;
int eyePosYTDiv;
int eyePosZTDiv;
-
+
private int renderedMeshes, renderedQuads;
private int frameCount;
-
- public NeoRenderer(World world){
+
+ public NeoRenderer(World world) {
this.world = world;
- if(shouldRenderInWorld(world)) {
+ if (shouldRenderInWorld(world)) {
hasInited = init();
}
-
+
renderWorld = true;
rendererActive = true;
}
-
+
Vector4f transformedOrigin = new Vector4f();
-
+
public void preRenderSortedRenderers(int renderPass, double alpha, WorldRenderer[] sortedWorldRenderers) {
- if(hasInited) {
- if(renderPass == 0) {
+ if (hasInited) {
+ if (renderPass == 0) {
renderedMeshes = 0;
renderedQuads = 0;
-
+
mainLoop();
- if(Minecraft.getMinecraft().currentScreen == null) {
+ if (Minecraft.getMinecraft().currentScreen == null) {
handleKeyboard();
}
- if(mem.getCoherenceRate() < 0.95f || frameCount % 4 == 0) {
+ if (mem.getCoherenceRate() < 0.95f || frameCount % 4 == 0) {
mem.runGC(false);
}
-
- if(rendererActive && renderWorld) {
+
+ if (rendererActive && renderWorld) {
updateGLValues();
-
+
transformedOrigin.set(0, 0, 0, 1);
Matrix4f.transform(modelViewMatrixInv, transformedOrigin, transformedOrigin);
-
+
Entity rve = Minecraft.getMinecraft().renderViewEntity;
-
+
eyePosX = rve.lastTickPosX + (rve.posX - rve.lastTickPosX) * alpha;
eyePosY = rve.lastTickPosY + (rve.posY - rve.lastTickPosY) * alpha + rve.getEyeHeight();
eyePosZ = rve.lastTickPosZ + (rve.posZ - rve.lastTickPosZ) * alpha;
-
+
eyePosXT = eyePosX + transformedOrigin.x;
eyePosYT = eyePosY + transformedOrigin.y;
eyePosZT = eyePosZ + transformedOrigin.z;
-
- eyePosXTDiv = Math.floorDiv((int)Math.floor(eyePosXT), 16);
- eyePosYTDiv = Math.floorDiv((int)Math.floor(eyePosYT), 16);
- eyePosZTDiv = Math.floorDiv((int)Math.floor(eyePosZT), 16);
-
+
+ eyePosXTDiv = Math.floorDiv((int) Math.floor(eyePosXT), 16);
+ eyePosYTDiv = Math.floorDiv((int) Math.floor(eyePosYT), 16);
+ eyePosZTDiv = Math.floorDiv((int) Math.floor(eyePosZT), 16);
+
sort(frameCount % 100 == 0, frameCount % Config.sortFrequency == 0);
-
+
initIndexBuffers();
}
-
+
frameCount++;
}
-
- if(rendererActive && renderWorld) {
- Minecraft.getMinecraft().entityRenderer.enableLightmap((double)alpha);
-
+
+ if (rendererActive && renderWorld) {
+ Minecraft.getMinecraft().entityRenderer.enableLightmap((double) alpha);
+
render(renderPass, alpha);
-
- Minecraft.getMinecraft().entityRenderer.disableLightmap((double)alpha);
+
+ Minecraft.getMinecraft().entityRenderer.disableLightmap((double) alpha);
}
}
}
-
+
public void onRenderTickEnd() {
- if(Neodymium.isActive()) {
- if(reloadPending) {
+ if (Neodymium.isActive()) {
+ if (reloadPending) {
Minecraft.getMinecraft().renderGlobal.loadRenderers();
}
- if(showMemoryDebugger && mem != null) {
+ if (showMemoryDebugger && mem != null) {
GuiHelper.begin();
mem.drawInfo();
GuiHelper.end();
}
- } else if(destroyPending) {
+ } else if (destroyPending) {
destroy();
destroyPending = false;
Neodymium.renderer = null;
Minecraft.getMinecraft().renderGlobal.loadRenderers();
}
}
-
+
private void sort(boolean pass0, boolean pass1) {
- for(NeoRegion r : loadedRegionsMap.values()) {
+ for (NeoRegion r : loadedRegionsMap.values()) {
r.getRenderData().sort(eyePosX, eyePosY, eyePosZ, pass0, pass1);
}
}
-
+
private void initIndexBuffers() {
loadedRegionsList.clear();
loadedRegionsList.addAll(loadedRegionsMap.values());
loadedRegionsList.sort(Comparators.REGION_DISTANCE_COMPARATOR.setOrigin(eyePosX, eyePosY, eyePosZ));
-
- for(int i = 0; i < 2; i++) {
+
+ for (int i = 0; i < 2; i++) {
piFirst[i].limit(MAX_MESHES);
piCount[i].limit(MAX_MESHES);
int order = i == 0 ? 1 : -1;
- for(int regionI = order == 1 ? 0 : loadedRegionsList.size() - 1; regionI >= 0 && regionI < loadedRegionsList.size(); regionI += order) {
+ for (int regionI = order == 1 ? 0 : loadedRegionsList.size() - 1; regionI >= 0 && regionI < loadedRegionsList.size(); regionI += order) {
NeoRegion.RenderData region = loadedRegionsList.get(regionI).getRenderData();
region.batchFirst[i] = piFirst[i].position();
- for(Mesh mesh : region.getSentMeshes(i)) {
- WorldRenderer wr = ((ChunkMesh)mesh).wr;
- if(mesh.visible && wr.isVisible && shouldRenderMesh(mesh)) {
+ for (Mesh mesh : region.getSentMeshes(i)) {
+ WorldRenderer wr = ((ChunkMesh) mesh).wr;
+ if (mesh.visible && wr.isVisible && shouldRenderMesh(mesh)) {
int meshes = mesh.writeToIndexBuffer(piFirst[i], piCount[i], eyePosXTDiv, eyePosYTDiv, eyePosZTDiv, i);
renderedMeshes += meshes;
- for(int j = piCount[i].position() - meshes; j < piCount[i].position(); j++) {
+ for (int j = piCount[i].position() - meshes; j < piCount[i].position(); j++) {
renderedQuads += piCount[i].get(j) / 4;
}
}
@@ -211,29 +208,29 @@ public class NeoRenderer {
piCount[i].flip();
}
}
-
+
private boolean shouldRenderMesh(Mesh mesh) {
- if((Config.maxMeshesPerFrame == -1 || renderedMeshes < Config.maxMeshesPerFrame)) {
- if((!isFogEnabled() && !Config.fogOcclusionWithoutFog)
- || Config.fogOcclusion == !Config.fogOcclusion
- || mesh.distSq(
- eyePosX / 16.0,
- mesh.y + 0.5,
- eyePosZ / 16.0)
- < Math.pow((fogStartEnd.get(1)) / 16.0 + 1.0, 2)) {
+ if ((Config.maxMeshesPerFrame == -1 || renderedMeshes < Config.maxMeshesPerFrame)) {
+ if ((!isFogEnabled() && !Config.fogOcclusionWithoutFog)
+ || Config.fogOcclusion == !Config.fogOcclusion
+ || mesh.distSq(
+ eyePosX / 16.0,
+ mesh.y + 0.5,
+ eyePosZ / 16.0)
+ < Math.pow((fogStartEnd.get(1)) / 16.0 + 1.0, 2)) {
return true;
}
}
return false;
}
-
+
private void mainLoop() {
- if(Minecraft.getMinecraft().playerController.netClientHandler.doneLoadingTerrain) {
- for(Iterator<Entry<ChunkCoordIntPair, NeoRegion>> it = loadedRegionsMap.entrySet().iterator(); it.hasNext();) {
+ if (Minecraft.getMinecraft().playerController.netClientHandler.doneLoadingTerrain) {
+ for (Iterator<Entry<ChunkCoordIntPair, NeoRegion>> it = loadedRegionsMap.entrySet().iterator(); it.hasNext(); ) {
Entry<ChunkCoordIntPair, NeoRegion> kv = it.next();
NeoRegion v = kv.getValue();
-
- if(v.shouldDelete()) {
+
+ if (v.shouldDelete()) {
v.destroy();
it.remove();
} else {
@@ -242,42 +239,42 @@ public class NeoRenderer {
}
}
}
-
+
private void handleKeyboard() {
- if(Config.debugPrefix == 0 || (Config.debugPrefix != -1 && Keyboard.isKeyDown(Config.debugPrefix))) {
- if(CheatHelper.canCheat()) {
- if(Keyboard.isKeyDown(Keyboard.KEY_F) && !wasDown[Keyboard.KEY_F]) {
+ if (Config.debugPrefix == 0 || (Config.debugPrefix != -1 && Keyboard.isKeyDown(Config.debugPrefix))) {
+ if (CheatHelper.canCheat()) {
+ if (Keyboard.isKeyDown(Keyboard.KEY_F) && !wasDown[Keyboard.KEY_F]) {
rendererActive = !rendererActive;
}
- if(Keyboard.isKeyDown(Keyboard.KEY_V) && !wasDown[Keyboard.KEY_V]) {
+ if (Keyboard.isKeyDown(Keyboard.KEY_V) && !wasDown[Keyboard.KEY_V]) {
renderWorld = !renderWorld;
}
}
- if(Keyboard.isKeyDown(Keyboard.KEY_R) && !wasDown[Keyboard.KEY_R]) {
+ if (Keyboard.isKeyDown(Keyboard.KEY_R) && !wasDown[Keyboard.KEY_R]) {
reloadShader();
}
- if(Keyboard.isKeyDown(Keyboard.KEY_M) && !wasDown[Keyboard.KEY_M]) {
+ if (Keyboard.isKeyDown(Keyboard.KEY_M) && !wasDown[Keyboard.KEY_M]) {
showMemoryDebugger = !showMemoryDebugger;
}
- if(Keyboard.isKeyDown(Keyboard.KEY_P) && !wasDown[Keyboard.KEY_P]) {
+ if (Keyboard.isKeyDown(Keyboard.KEY_P) && !wasDown[Keyboard.KEY_P]) {
Util.dumpTexture();
}
- if(Keyboard.isKeyDown(Keyboard.KEY_LEFT) && !wasDown[Keyboard.KEY_LEFT]) {
+ if (Keyboard.isKeyDown(Keyboard.KEY_LEFT) && !wasDown[Keyboard.KEY_LEFT]) {
reloadPending = true;
}
- if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT) && !wasDown[Keyboard.KEY_RIGHT]) {
- if(rendererSpeedup == 0) {
+ if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT) && !wasDown[Keyboard.KEY_RIGHT]) {
+ if (rendererSpeedup == 0) {
rendererSpeedup = 300;
} else {
rendererSpeedup = 0;
}
}
}
- for(int i = 0; i < 256; i++) {
+ for (int i = 0; i < 256; i++) {
wasDown[i] = Keyboard.isKeyDown(i);
}
}
-
+
FloatBuffer modelView = BufferUtils.createFloatBuffer(16);
FloatBuffer projBuf = BufferUtils.createFloatBuffer(16);
IntBuffer viewportBuf = BufferUtils.createIntBuffer(16);
@@ -287,76 +284,100 @@ public class NeoRenderer {
Matrix4f modelViewMatrix = new Matrix4f();
Matrix4f modelViewMatrixInv = new Matrix4f();
Matrix4f projMatrix = new Matrix4f();
-
+
private void render(int pass, double alpha) {
int shader = getShaderProgram(pass);
-
- if(shader == 0) return;
-
- glBindVertexArray(VAO);
- glUseProgram(shader);
- updateUniforms(alpha, pass);
-
- if(isWireframeEnabled()) {
+
+ if (shader == 0) return;
+
+ glBindVertexArray(VAO);
+
+ if (!Compat.isShaders()) {
+ glUseProgram(shader);
+ updateUniforms(alpha, pass);
+ }
+
+ if (isWireframeEnabled()) {
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
}
-
- int u_renderOffset = glGetUniformLocation(getShaderProgram(pass), "renderOffset");
-
+
+ int u_renderOffset = -1;
+ if (!Compat.isShaders()) {
+ u_renderOffset = glGetUniformLocation(getShaderProgram(pass), "renderOffset");
+ }
+
int oldLimit = piFirst[pass].limit();
-
+
int order = pass == 0 ? 1 : -1;
- for(int regionI = order == 1 ? 0 : loadedRegionsList.size() - 1; regionI >= 0 && regionI < loadedRegionsList.size(); regionI += order) {
+ for (int regionI = order == 1 ? 0 : loadedRegionsList.size() - 1; regionI >= 0 && regionI < loadedRegionsList.size(); regionI += order) {
NeoRegion.RenderData region = loadedRegionsList.get(regionI).getRenderData();
Util.setPositionAndLimit(piFirst[pass], region.batchFirst[pass], region.batchLimit[pass]);
Util.setPositionAndLimit(piCount[pass], region.batchFirst[pass], region.batchLimit[pass]);
-
- glUniform3f(u_renderOffset, (float)(region.originX - eyePosX), (float)(region.originY - eyePosY), (float)(region.originZ - eyePosZ));
+
+ if (Compat.isShaders()) {
+ GL11.glMatrixMode(GL_MODELVIEW);
+
+ val offsetX = (float) (region.originX - eyePosX);
+ val offsetY = (float) ((region.originY - eyePosY) + 0.12);
+ val offsetZ = (float) (region.originZ - eyePosZ);
+
+ GL11.glPushMatrix();
+ GL11.glTranslatef(offsetX, offsetY, offsetZ);
+ } else {
+ glUniform3f(u_renderOffset, (float) (region.originX - eyePosX), (float) (region.originY - eyePosY), (float) (region.originZ - eyePosZ));
+ }
+
glMultiDrawArrays(GL_QUADS, piFirst[pass], piCount[pass]);
+
+ if (Compat.isShaders())
+ GL11.glPopMatrix();
}
Util.setPositionAndLimit(piFirst[pass], 0, oldLimit);
Util.setPositionAndLimit(piCount[pass], 0, oldLimit);
-
- if(isWireframeEnabled()) {
+
+ if (isWireframeEnabled()) {
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
}
-
+
+ if (!Compat.isShaders()) {
+ glUseProgram(0);
+ }
+
glBindVertexArray(0);
- glUseProgram(0);
}
-
+
private void updateGLValues() {
glGetFloat(GL_MODELVIEW_MATRIX, modelView);
-
+
glGetFloat(GL_PROJECTION_MATRIX, projBuf);
-
+
glGetInteger(GL_VIEWPORT, viewportBuf);
-
+
projMatrix.load(projBuf);
projBuf.flip();
projMatrix.invert();
projMatrix.store(projInvBuf);
projInvBuf.flip();
-
+
modelViewMatrix.load(modelView);
modelView.flip();
modelViewMatrixInv.load(modelViewMatrix).invert();
-
+
fogColorBuf.limit(16);
glGetFloat(GL_FOG_COLOR, fogColorBuf);
fogColorBuf.limit(4);
-
+
fogStartEnd.put(glGetFloat(GL_FOG_START));
fogStartEnd.put(glGetFloat(GL_FOG_END));
-
+
fogStartEnd.flip();
-
+
fogEnabled = GL11.glIsEnabled(GL11.GL_FOG) && !OFUtil.isFogOff();
}
-
+
private void updateUniforms(double alpha, int pass) {
int shaderProgram = getShaderProgram(pass);
-
+
int u_modelView = glGetUniformLocation(shaderProgram, "modelView");
int u_proj = glGetUniformLocation(shaderProgram, "proj");
int u_playerPos = glGetUniformLocation(shaderProgram, "playerPos");
@@ -374,17 +395,17 @@ public class NeoRenderer {
int u_fogStartEnd = glGetUniformLocation(shaderProgram, "fogStartEnd");
int u_fogMode = glGetUniformLocation(shaderProgram, "fogMode");
int u_fogDensity = glGetUniformLocation(shaderProgram, "fogDensity");
-
+
glUniformMatrix4(u_modelView, false, modelView);
glUniformMatrix4(u_proj, false, projBuf);
glUniformMatrix4(u_projInv, false, projInvBuf);
- glUniform4f(u_viewport, viewportBuf.get(0),viewportBuf.get(1),viewportBuf.get(2),viewportBuf.get(3));
+ glUniform4f(u_viewport, viewportBuf.get(0), viewportBuf.get(1), viewportBuf.get(2), viewportBuf.get(3));
glUniform4(u_fogColor, fogColorBuf);
glUniform2(u_fogStartEnd, fogStartEnd);
glUniform1i(u_fogMode, glGetInteger(GL_FOG_MODE));
glUniform1f(u_fogDensity, glGetFloat(GL_FOG_DENSITY));
- glUniform3f(u_playerPos, (float)eyePosX, (float)eyePosY, (float)eyePosZ);
+ glUniform3f(u_playerPos, (float) eyePosX, (float) eyePosY, (float) eyePosZ);
if (Compat.RPLE()) {
//TODO connect to RPLE gl api (once that exists)
@@ -395,7 +416,7 @@ public class NeoRenderer {
} else {
glUniform1i(u_light, 1);
}
-
+
modelView.position(0);
projBuf.position(0);
viewportBuf.position(0);
@@ -434,125 +455,180 @@ public class NeoRenderer {
attributes.addAttribute("BRIGHTNESS_GREEN", 2, 2, GL_SHORT);
attributes.addAttribute("BRIGHTNESS_BLUE", 2, 2, GL_SHORT);
}
-
+
reloadShader();
-
+
VAO = glGenVertexArrays();
glBindVertexArray(VAO);
-
+
mem = new GPUMemoryManager();
-
+
glBindBuffer(GL_ARRAY_BUFFER, mem.VBO);
- attributes.enable();
-
- for(int i = 0; i < 2; i++) {
+ // 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()) {
+ val 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);
+ } else {
+ attributes.enable();
+ }
+
+ for (int i = 0; i < 2; i++) {
piFirst[i] = BufferUtils.createIntBuffer(MAX_MESHES);
piFirst[i].flip();
piCount[i] = BufferUtils.createIntBuffer(MAX_MESHES);
piCount[i].flip();
}
-
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
-
+
return true;
}
public int getStride() {
return attributes.stride();
}
-
+
public void reloadShader(int pass, AttributeSet attributeSet) {
- for(int hasFog = 0; hasFog <= 1; hasFog++) {
+ for (int hasFog = 0; hasFog <= 1; hasFog++) {
Map<String, String> defines = new HashMap<>();
- if(hasFog == 1) {
+ if (hasFog == 1) {
defines.put("RENDER_FOG", "");
}
- if(Config.shortUV) {
+ if (Config.shortUV) {
defines.put("SHORT_UV", "");
}
if (Compat.RPLE()) {
defines.put("RPLE", "");
}
- if(pass == 0) {
+ if (pass == 0) {
defines.put("PASS_0", "");
}
attributeSet.addDefines(defines);
-
+
boolean errors = false;
-
+
int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
-
+
glShaderSource(vertexShader, Preprocessor.preprocess(Util.readFile("shaders/chunk.vert"), defines));
glCompileShader(vertexShader);
-
- if(glGetShaderi(vertexShader, GL_COMPILE_STATUS) == 0) {
+
+ if (glGetShaderi(vertexShader, GL_COMPILE_STATUS) == 0) {
System.out.println("Error compiling vertex shader: " + glGetShaderInfoLog(vertexShader, 256));
errors = true;
}
-
+
int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
-
+
glShaderSource(fragmentShader, Preprocessor.preprocess(Util.readFile("shaders/chunk.frag"), defines));
glCompileShader(fragmentShader);
-
- if(glGetShaderi(fragmentShader, GL_COMPILE_STATUS) == 0) {
+
+ if (glGetShaderi(fragmentShader, GL_COMPILE_STATUS) == 0) {
System.out.println("Error compiling fragment shader: " + glGetShaderInfoLog(fragmentShader, 256));
errors = true;
}
-
+
int newShaderProgram = glCreateProgram();
glAttachShader(newShaderProgram, vertexShader);
glAttachShader(newShaderProgram, fragmentShader);
glLinkProgram(newShaderProgram);
-
- if(glGetProgrami(newShaderProgram, GL_LINK_STATUS) == 0) {
+
+ if (glGetProgrami(newShaderProgram, GL_LINK_STATUS) == 0) {
System.out.println("Error linking shader: " + glGetShaderInfoLog(newShaderProgram, 256));
errors = true;
}
-
- if(!errors) {
+
+ if (!errors) {
((hasFog == 1) ? shaderProgramsFog : shaderProgramsNoFog)[pass] = newShaderProgram;
}
-
+
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
}
-
+
public void reloadShader() {
reloadShader(0, attributes);
reloadShader(1, attributes);
}
-
+
public void destroy() {
- if(!hasInited) return;
-
+ if (!hasInited) return;
+
glDeleteProgram(shaderProgramsFog[0]);
glDeleteProgram(shaderProgramsFog[1]);
glDeleteProgram(shaderProgramsNoFog[0]);
glDeleteProgram(shaderProgramsNoFog[1]);
glDeleteVertexArrays(VAO);
mem.destroy();
-
+
ChunkMesh.instances = 0;
ChunkMesh.usedRAM = 0;
}
-
+
public void onWorldRendererChanged(WorldRenderer wr, WorldRendererChange change) {
int x = Math.floorDiv(wr.posX, 16);
int y = Math.floorDiv(wr.posY, 16);
int z = Math.floorDiv(wr.posZ, 16);
NeoChunk neoChunk = getNeoChunk(x, z);
-
+
neoChunk.isSectionVisible[y] = change == WorldRendererChange.VISIBLE;
- if(change == WorldRendererChange.DELETED) {
+ if (change == WorldRendererChange.DELETED) {
removeMesh(neoChunk.chunkMeshes[y]);
- if(neoChunk.chunkMeshes[y] != null) {
+ if (neoChunk.chunkMeshes[y] != null) {
neoChunk.chunkMeshes[y].destroy();
neoChunk.chunkMeshes[y] = null;
neoChunk.region.meshes--;
@@ -560,63 +636,63 @@ public class NeoRenderer {
}
neoChunkChanged(neoChunk);
}
-
+
public void onWorldRendererPost(WorldRenderer wr, boolean sort) {
int x = Math.floorDiv(wr.posX, 16);
int y = Math.floorDiv(wr.posY, 16);
int z = Math.floorDiv(wr.posZ, 16);
-
- if(Minecraft.getMinecraft().theWorld.getChunkFromChunkCoords(x, z).isChunkLoaded) {
+
+ if (Minecraft.getMinecraft().theWorld.getChunkFromChunkCoords(x, z).isChunkLoaded) {
NeoChunk neoChunk = getNeoChunk(x, z);
- neoChunk.isSectionVisible[y] = ((IWorldRenderer)wr).isDrawn();
- neoChunk.putChunkMeshes(y, ((IWorldRenderer)wr).getChunkMeshes(), sort);
+ neoChunk.isSectionVisible[y] = ((IWorldRenderer) wr).isDrawn();
+ neoChunk.putChunkMeshes(y, ((IWorldRenderer) wr).getChunkMeshes(), sort);
}
}
-
+
public void onRenderFog() {
forceRenderFog = false;
}
-
+
private NeoChunk getNeoChunk(int chunkX, int chunkZ) {
return getRegionContaining(chunkX, chunkZ).getChunkAbsolute(chunkX, chunkZ);
}
-
+
private NeoRegion getRegionContaining(int chunkX, int chunkZ) {
int regionX = Math.floorDiv(chunkX, NeoRegion.SIZE);
int regionZ = Math.floorDiv(chunkZ, NeoRegion.SIZE);
ChunkCoordIntPair key = new ChunkCoordIntPair(regionX, regionZ);
-
+
NeoRegion region = loadedRegionsMap.get(key);
- if(region == null) {
+ if (region == null) {
region = NeoRegion.load(regionX, regionZ);
loadedRegionsMap.put(key, region);
}
return region;
}
-
+
public void setVisible(NeoChunk chunk, boolean visible) {
setVisible(chunk, visible, false);
}
-
+
public void setVisible(NeoChunk neoChunk, boolean visible, boolean forceCheck) {
- if(!forceCheck && visible == neoChunk.visible) return;
-
+ if (!forceCheck && visible == neoChunk.visible) return;
+
neoChunk.visible = visible;
neoChunkChanged(neoChunk);
}
-
+
public void neoChunkChanged(NeoChunk neoChunk) {
int newLOD = neoChunk.hasChunkMeshes() ? 2 : 0;
- for(int y = 0; y < 16; y++) {
- for(int pass = 0; pass < 2; pass++) {
+ for (int y = 0; y < 16; y++) {
+ for (int pass = 0; pass < 2; pass++) {
ChunkMesh cm = neoChunk.chunkMeshes[y * 2 + pass];
- if(cm != null) {
- if(neoChunk.isSectionVisible[y] && newLOD == 2) {
- if(!cm.visible) {
+ if (cm != null) {
+ if (neoChunk.isSectionVisible[y] && newLOD == 2) {
+ if (!cm.visible) {
setMeshVisible(cm, true);
}
} else {
- if(cm.visible) {
+ if (cm.visible) {
setMeshVisible(cm, false);
}
}
@@ -624,14 +700,14 @@ public class NeoRenderer {
}
}
}
-
+
protected void setMeshVisible(Mesh mesh, boolean visible) {
- if(mesh == null) return;
-
- if(mesh.visible != visible) {
+ if (mesh == null) return;
+
+ if (mesh.visible != visible) {
mesh.visible = visible;
-
- if(mesh.gpuStatus == GPUStatus.UNSENT) {
+
+ if (mesh.gpuStatus == GPUStatus.UNSENT) {
mem.sendMeshToGPU(mesh);
NeoRegion region = getRegionContaining(mesh.x, mesh.z);
region.getRenderData().getSentMeshes(mesh.pass).add(mesh);
@@ -639,17 +715,17 @@ public class NeoRenderer {
}
}
}
-
+
public void removeMesh(Mesh mesh) {
- if(mesh == null) return;
-
+ if (mesh == null) return;
+
mem.deleteMeshFromGPU(mesh);
- if(mesh.containingRegion != null) {
+ if (mesh.containingRegion != null) {
mesh.containingRegion.getRenderData().getSentMeshes(mesh.pass).remove(mesh);
}
setMeshVisible(mesh, false);
}
-
+
public List<String> getDebugText(boolean statusCommand) {
List<String> text = new ArrayList<>();
text.add(
@@ -662,41 +738,41 @@ public class NeoRenderer {
"Meshes: " + ChunkMesh.instances + " (" + ChunkMesh.usedRAM / 1024 / 1024 + "MB)",
"Rendered: " + renderedMeshes + " (" + renderedQuads / 1000 + "KQ)"
));
- if(rendererSpeedup > 0) {
+ if (rendererSpeedup > 0) {
text.add(EnumChatFormatting.YELLOW + "(!) Renderer speedup active");
}
- if(hasIncompatibilities) {
+ if (hasIncompatibilities) {
text.add(EnumChatFormatting.YELLOW + "(!) Incompatibilities");
- if(!statusCommand) {
+ if (!statusCommand) {
text.add(EnumChatFormatting.YELLOW + "Type '/neodymium status'");
}
}
return text;
}
-
+
private int getShaderProgram(int pass) {
return ((forceRenderFog || isFogEnabled()) ? shaderProgramsFog : shaderProgramsNoFog)[pass];
}
-
+
private boolean isFogEnabled() {
- switch(Config.renderFog) {
- case TRUE:
- return true;
- case FALSE:
- return false;
- default:
- return fogEnabled;
+ switch (Config.renderFog) {
+ case TRUE:
+ return true;
+ case FALSE:
+ return false;
+ default:
+ return fogEnabled;
}
}
-
+
private boolean shouldRenderInWorld(World world) {
return world != null;
}
-
+
private static boolean isWireframeEnabled() {
return Config.wireframe && CheatHelper.canCheat();
}
-
+
public static enum WorldRendererChange {
VISIBLE, INVISIBLE, DELETED
}