1.20.4 compatibility

This commit is contained in:
MeexReay 2024-04-22 18:17:31 +03:00
parent c5132221ae
commit 27627e8404
38 changed files with 2790 additions and 31 deletions

View file

@ -0,0 +1,200 @@
package themixray.repeating.mod.render;
import lombok.experimental.UtilityClass;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.util.math.Vec3d;
import themixray.repeating.mod.render.buffer.WorldBuffer;
import themixray.repeating.mod.render.shader.ShaderManager;
import java.awt.*;
import static org.lwjgl.opengl.GL33.*;
@UtilityClass
public class RenderHelper {
public WorldBuffer startLines(WorldRenderContext context) {
glEnable(GL_LINE_SMOOTH);
return new WorldBuffer(GL_LINES, ShaderManager.getPositionColorShader(), context);
}
public void endLines(WorldBuffer buffer) {
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
buffer.draw();
glDepthMask(true);
glDisable(GL_BLEND);
}
public void drawLine(WorldBuffer buffer, float x1, float y1, float z1, float x2, float y2, float z2, Color color) {
buffer.vert(x1, y1, z1, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f);
buffer.vert(x2, y2, z2, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f);
}
public static WorldBuffer startTri(WorldRenderContext context) {
return new WorldBuffer(GL_TRIANGLES, ShaderManager.getPositionColorShader(), context);
}
public static void endTri(WorldBuffer buffer) {
//glDepthRange(0, 0.7);
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDepthMask(false);
buffer.draw();
glDepthMask(true);
glEnable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDepthRange(0, 1);
}
public void drawTri(WorldBuffer buffer, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, Color color) {
buffer.vert(x1, y1, z1, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f);
buffer.vert(x2, y2, z2, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f);
buffer.vert(x3, y3, z3, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f);
}
public static void drawRectFromTri(WorldBuffer buffer,
float x1, float y1, float z1,
float x2, float y2, float z2,
float x3, float y3, float z3,
float x4, float y4, float z4,
Color color) {
drawTri(buffer,
x1, y1, z1,
x2, y2, z2,
x3, y3, z3,
color);
drawTri(buffer,
x3, y3, z3,
x4, y4, z4,
x1, y1, z1,
color);
}
public void drawRectFromLines(WorldBuffer buffer,
float x1, float y1, float z1,
float x2, float y2, float z2,
float x3, float y3, float z3,
float x4, float y4, float z4,
Color color) {
drawLine(buffer,
x1, y1, z1,
x2, y2, z2,
color);
drawLine(buffer,
x2, y2, z2,
x3, y3, z3,
color);
drawLine(buffer,
x3, y3, z3,
x4, y4, z4,
color);
drawLine(buffer,
x4, y4, z4,
x1, y1, z1,
color);
}
public void drawBoxFromTri(WorldBuffer buffer,
float x1, float y1, float z1,
float x2, float y2, float z2,
Color color) {
float[][] v = new float[][]{
new float[]{Math.min(x1, x2), Math.min(y1, y2), Math.min(z1, z2)},
new float[]{Math.max(x1, x2), Math.max(y1, y2), Math.max(z1, z2)}};
drawRectFromTri(buffer,
v[0][0], v[0][1], v[0][2],
v[1][0], v[0][1], v[0][2],
v[1][0], v[1][1], v[0][2],
v[0][0], v[1][1], v[0][2],
color);
drawRectFromTri(buffer,
v[0][0], v[0][1], v[0][2],
v[1][0], v[0][1], v[0][2],
v[1][0], v[0][1], v[1][2],
v[0][0], v[0][1], v[1][2],
color);
drawRectFromTri(buffer,
v[0][0], v[0][1], v[0][2],
v[0][0], v[0][1], v[1][2],
v[0][0], v[1][1], v[1][2],
v[0][0], v[1][1], v[0][2],
color);
drawRectFromTri(buffer,
v[0][0], v[0][1], v[1][2],
v[1][0], v[0][1], v[1][2],
v[1][0], v[1][1], v[1][2],
v[0][0], v[1][1], v[1][2],
color);
drawRectFromTri(buffer,
v[0][0], v[1][1], v[0][2],
v[1][0], v[1][1], v[0][2],
v[1][0], v[1][1], v[1][2],
v[0][0], v[1][1], v[1][2],
color);
drawRectFromTri(buffer,
v[1][0], v[0][1], v[0][2],
v[1][0], v[0][1], v[1][2],
v[1][0], v[1][1], v[1][2],
v[1][0], v[1][1], v[0][2],
color);
}
public void drawBoxFromLines(WorldBuffer buffer,
float x1, float y1, float z1,
float x2, float y2, float z2,
Color color) {
float[][] v = new float[][]{
new float[]{Math.min(x1, x2), Math.min(y1, y2), Math.min(z1, z2)},
new float[]{Math.max(x1, x2), Math.max(y1, y2), Math.max(z1, z2)}};
drawRectFromLines(buffer,
v[0][0], v[0][1], v[0][2],
v[1][0], v[0][1], v[0][2],
v[1][0], v[1][1], v[0][2],
v[0][0], v[1][1], v[0][2],
color);
drawRectFromLines(buffer,
v[0][0], v[0][1], v[0][2],
v[1][0], v[0][1], v[0][2],
v[1][0], v[0][1], v[1][2],
v[0][0], v[0][1], v[1][2],
color);
drawRectFromLines(buffer,
v[0][0], v[0][1], v[0][2],
v[0][0], v[0][1], v[1][2],
v[0][0], v[1][1], v[1][2],
v[0][0], v[1][1], v[0][2],
color);
drawRectFromLines(buffer,
v[0][0], v[0][1], v[1][2],
v[1][0], v[0][1], v[1][2],
v[1][0], v[1][1], v[1][2],
v[0][0], v[1][1], v[1][2],
color);
drawRectFromLines(buffer,
v[0][0], v[1][1], v[0][2],
v[1][0], v[1][1], v[0][2],
v[1][0], v[1][1], v[1][2],
v[0][0], v[1][1], v[1][2],
color);
drawRectFromLines(buffer,
v[1][0], v[0][1], v[0][2],
v[1][0], v[0][1], v[1][2],
v[1][0], v[1][1], v[1][2],
v[1][0], v[1][1], v[0][2],
color);
}
}

View file

@ -0,0 +1,13 @@
package themixray.repeating.mod.render;
import lombok.experimental.UtilityClass;
import themixray.repeating.mod.render.buffer.BufferManager;
import themixray.repeating.mod.render.shader.ShaderManager;
@UtilityClass
public class RenderSystem {
public static void init() {
BufferManager.init();
ShaderManager.init();
}
}

View file

@ -0,0 +1,48 @@
package themixray.repeating.mod.render.buffer;
import lombok.experimental.UtilityClass;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import java.nio.FloatBuffer;
import static org.lwjgl.opengl.GL33.*;
@UtilityClass
public class BufferManager {
private int vao;
private int vbo;
private int prevVao;
public void init() {
ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
vao = glGenVertexArrays();
vbo = glGenBuffers();
});
}
public static void bindBuffer() {
glBindBuffer(GL_ARRAY_BUFFER, vbo);
}
public static void unbindBuffer() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
public static void writeBuffer(FloatBuffer buffer) {
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
}
public static void draw(int drawMode, int verts) {
glDrawArrays(drawMode, 0, verts);
}
public static void bind() {
prevVao = glGetInteger(GL_VERTEX_ARRAY_BINDING);
glBindVertexArray(vao);
}
public static void unbind() {
glBindVertexArray(prevVao);
}
}

View file

@ -0,0 +1,30 @@
package themixray.repeating.mod.render.buffer;
import lombok.Getter;
public class Vertex {
@Getter
private float x;
@Getter
private float y;
@Getter
private float z;
@Getter
private float r;
@Getter
private float g;
@Getter
private float b;
@Getter
private float a;
public Vertex(float x, float y, float z, float r, float g, float b, float a) {
this.x = x;
this.y = y;
this.z = z;
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
}

View file

@ -0,0 +1,82 @@
package themixray.repeating.mod.render.buffer;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.util.math.Vec3d;
import org.apache.commons.lang3.ArrayUtils;
import org.joml.Matrix4f;
import org.lwjgl.BufferUtils;
import themixray.repeating.mod.render.shader.Shader;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import static org.lwjgl.opengl.GL33.*;
public class WorldBuffer {
private final List<Vertex> vertices = new ArrayList<>();
private final int drawMode;
private final Shader shader;
private FloatBuffer projectionMatrix;
private final Vec3d cameraPos;
public WorldBuffer(int drawMode, Shader shader, WorldRenderContext worldRenderContext) {
this.drawMode = drawMode;
this.shader = shader;
this.cameraPos = worldRenderContext.camera().getPos();
makeProjectionMatrix(worldRenderContext.projectionMatrix(), worldRenderContext.matrixStack().peek().getPositionMatrix());
}
public void vert(float x, float y, float z, float r, float g, float b, float a) {
vertices.add(new Vertex(x - (float) cameraPos.x, y - (float) cameraPos.y, z - (float) cameraPos.z, r, g, b, a));
}
public void draw() {
BufferManager.bind();
BufferManager.bindBuffer();
BufferManager.writeBuffer(getBuffer());
applyProjectionMatrix();
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, vertices.size() * 3 * 4L);
glEnableVertexAttribArray(1);
BufferManager.unbindBuffer();
shader.bind();
BufferManager.draw(drawMode, this.vertices.size());
shader.unbind();
BufferManager.unbind();
}
private FloatBuffer getBuffer() {
FloatBuffer floatBuffer = BufferUtils.createFloatBuffer(vertices.size() * 7);
ArrayList<Float> floats = new ArrayList<>();
for (Vertex vertex : vertices) {
floats.add(vertex.getX());
floats.add(vertex.getY());
floats.add(vertex.getZ());
}
for (Vertex vertex : vertices) {
floats.add(vertex.getR());
floats.add(vertex.getG());
floats.add(vertex.getB());
floats.add(vertex.getA());
}
Float[] floatArray = new Float[floats.size()];
floats.toArray(floatArray);
floatBuffer.put(ArrayUtils.toPrimitive(floatArray));
return floatBuffer.flip();
}
private void makeProjectionMatrix(Matrix4f projectionMatrix, Matrix4f viewModelMatrix) {
this.projectionMatrix = projectionMatrix.mul(viewModelMatrix).get(BufferUtils.createFloatBuffer(16));
}
private void applyProjectionMatrix() {
shader.uniformMatrix4f("u_projection", projectionMatrix);
}
}

View file

@ -0,0 +1,42 @@
package themixray.repeating.mod.render.shader;
import lombok.Getter;
import java.nio.FloatBuffer;
import static org.lwjgl.opengl.GL33.*;
public class Shader {
@Getter
private final int id;
public Shader(String name) {
int v = ShaderManager.loadShaderProgram(name, ShaderManager.ShaderType.VERTEX);
int f = ShaderManager.loadShaderProgram(name, ShaderManager.ShaderType.FRAGMENT);
this.id = glCreateProgram();
glAttachShader(id, v);
glAttachShader(id, f);
glLinkProgram(id);
}
public void bind() {
glUseProgram(id);
}
public void unbind() {
glUseProgram(0);
}
public void uniformMatrix4f(String name, FloatBuffer matrix) {
bind();
glUniformMatrix4fv(glGetUniformLocation(id, name), false, matrix);
unbind();
}
public void uniformValue2f(String name, float value1, float value2) {
bind();
glUniform2f(glGetUniformLocation(id, name), value1, value2);
unbind();
}
}

View file

@ -0,0 +1,97 @@
package themixray.repeating.mod.render.shader;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.TextureUtil;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.GlImportProcessor;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceFactory;
import net.minecraft.util.Identifier;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.system.MemoryUtil;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import static org.lwjgl.opengl.GL33.*;
@UtilityClass
public class ShaderManager {
@Getter
private Shader positionColorShader;
public void init() {
ClientLifecycleEvents.CLIENT_STARTED.register(client -> loadShaders());
}
private void loadShaders() {
positionColorShader = new Shader("position_color");
}
public int loadShaderProgram(String name, ShaderType type) {
try {
boolean file_present = true;
ResourceFactory resourceFactory = MinecraftClient.getInstance().getResourceManager();
Optional<Resource> resource = resourceFactory.getResource(new Identifier("renderer", "shader/" + name + type.fileExtension));
int i = glCreateShader(type.glType);
if (resource.isPresent()) {
GlStateManager.glShaderSource(i, new GlImportProcessor() {
@SneakyThrows
@Nullable
@Override
public String loadImport(boolean inline, String name) {
return IOUtils.toString(resource.get().getInputStream(), StandardCharsets.UTF_8);
}
}.readSource(readResourceAsString(resource.get().getInputStream())));
} else file_present = false;
glCompileShader(i);
if (glGetShaderi(i, GL_COMPILE_STATUS) == 0 || !file_present) {
String shaderInfo = StringUtils.trim(glGetShaderInfoLog(i, 32768));
throw new IOException("Couldn't compile " + type.name + " program (" + name + ") : " + shaderInfo);
}
return i;
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
private String readResourceAsString(InputStream inputStream) {
ByteBuffer byteBuffer = null;
try {
byteBuffer = TextureUtil.readResource(inputStream);
int i = byteBuffer.position();
byteBuffer.rewind();
return MemoryUtil.memASCII(byteBuffer, i);
} catch (IOException ignored) {
} finally {
if (byteBuffer != null) {
MemoryUtil.memFree(byteBuffer);
}
}
return null;
}
public enum ShaderType {
VERTEX("vertex", ".vsh", GL_VERTEX_SHADER),
FRAGMENT("fragment", ".fsh", GL_FRAGMENT_SHADER);
private final String name;
private final String fileExtension;
private final int glType;
ShaderType(String name, String fileExtension, int glType) {
this.name = name;
this.fileExtension = fileExtension;
this.glType = glType;
}
}
}