Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ public class LuminRenderPipelines {
.withCull(false)
.build();

public final static RenderPipeline ROUND_RECT = RenderPipeline.builder(RenderPipelines.MATRICES_PROJECTION_SNIPPET)
.withLocation(ResourceLocationUtils.getIdentifier("pipelines/round_rectangle"))
.withVertexFormat(LuminVertexFormats.ROUND_RECT, VertexFormat.Mode.QUADS)
.withVertexShader(ResourceLocationUtils.getIdentifier("round_rectangle"))
.withFragmentShader(ResourceLocationUtils.getIdentifier("round_rectangle"))
.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST)
.withCull(false)
.build();

public static void onRegisterRenderPipelines(RegisterRenderPipelinesEvent event) {
event.registerPipeline(RECTANGLE);
}
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/com/github/lumin/graphics/LuminVertexFormats.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.github.lumin.graphics;

import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.blaze3d.vertex.VertexFormatElement;

import static com.mojang.blaze3d.vertex.VertexFormatElement.register;

public class LuminVertexFormats {

public static final VertexFormatElement ROUND_INNER_RECT =
register(7, 2, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.UV, 4);

public static final VertexFormatElement ROUND_RADIUS =
register(8, 3, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.UV, 1);


public static final VertexFormat ROUND_RECT = VertexFormat.builder()
.add("Position", VertexFormatElement.POSITION)
.add("Color", VertexFormatElement.COLOR)
.add("InnerRect", ROUND_INNER_RECT)
.add("Radius", ROUND_RADIUS)
.build();

}
44 changes: 44 additions & 0 deletions src/main/java/com/github/lumin/graphics/buffer/LuminBuffer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.github.lumin.graphics.buffer;

import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.systems.RenderSystem;

import java.nio.ByteBuffer;

public class LuminBuffer {

private final GpuBuffer gpuBuffer;

private GpuBuffer.MappedView mappedBuffer;

public LuminBuffer(long size, @GpuBuffer.Usage int usage) {

gpuBuffer = RenderSystem.getDevice().createBuffer(
() -> "lumin-buffer",
GpuBuffer.USAGE_MAP_WRITE | GpuBuffer.USAGE_COPY_DST | usage,
size
);

mappedBuffer = RenderSystem.getDevice().createCommandEncoder().mapBuffer(
gpuBuffer, false, true
);

}

public ByteBuffer getMappedBuffer() {
return mappedBuffer.data();
}

public void unmap() {
mappedBuffer.close();
}

public GpuBuffer getGpuBuffer() {
return gpuBuffer;
}

public void close() {
gpuBuffer.close();
}

}
84 changes: 71 additions & 13 deletions src/main/java/com/github/lumin/graphics/renderers/RectRenderer.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,94 @@
package com.github.lumin.graphics.renderers;

import com.github.lumin.graphics.LuminRenderPipelines;
import com.github.lumin.graphics.LuminRenderSystem;
import com.github.lumin.graphics.LuminRenderTypes;
import com.github.lumin.graphics.buffer.LuminBuffer;
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.rendertype.TextureTransform;
import net.minecraft.util.ARGB;
import org.joml.Vector3f;
import org.joml.Vector4f;
import org.lwjgl.system.MemoryUtil;

import java.awt.*;
import java.util.OptionalDouble;
import java.util.OptionalInt;

public class RectRenderer implements IRenderer {

private BufferBuilder bufferBuilder = Tesselator.getInstance()
.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
private static final long BUFFER_SIZE = 1024 * 1024;
private final LuminBuffer buffer = new LuminBuffer(BUFFER_SIZE, GpuBuffer.USAGE_VERTEX);
private long currentOffset = 0;
private int vertexCount = 0;

public void addRect(float x, float y, float width, float height, Color color) {
bufferBuilder.addVertex(x, y, 0.0f).setColor(color.getRGB());
bufferBuilder.addVertex(x + width, y, 0.0f).setColor(color.getRGB());
bufferBuilder.addVertex(x + width, y + height, 0.0f).setColor(color.getRGB());
bufferBuilder.addVertex(x, y + height, 0.0f).setColor(color.getRGB());
int argb = ARGB.toABGR(color.getRGB());

addVertex(x, y, argb);
addVertex(x, y + height, argb);
addVertex(x + width, y + height, argb);
addVertex(x + width, y, argb);
}

private void addVertex(float vx, float vy, int color) {
long baseAddr = MemoryUtil.memAddress(buffer.getMappedBuffer());
long p = baseAddr + currentOffset;

MemoryUtil.memPutFloat(p, vx);
MemoryUtil.memPutFloat(p + 4, vy);
MemoryUtil.memPutFloat(p + 8, 0.0f);
MemoryUtil.memPutInt(p + 12, color);

currentOffset += 16;
vertexCount++;
}

@Override
public void draw() {
if (vertexCount == 0) return;
LuminRenderSystem.applyOrthoProjection();

MeshData meshData = bufferBuilder.build();
if (meshData == null) return;
RenderTarget target = Minecraft.getInstance().getMainRenderTarget();
if (target.getColorTextureView() == null) return;

LuminRenderTypes.RECTANGLE.draw(meshData);
final var indexCount = vertexCount / 4 * 6;

RenderSystem.AutoStorageIndexBuffer autoIndices =
RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS);
GpuBuffer ibo = autoIndices.getBuffer(indexCount);

GpuBufferSlice dynamicUniforms = RenderSystem.getDynamicUniforms().writeTransform(
RenderSystem.getModelViewMatrix(),
new Vector4f(1, 1, 1, 1),
new Vector3f(0, 0, 0),
TextureTransform.DEFAULT_TEXTURING.getMatrix()
);

if (target.getColorTextureView() == null) return;
try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass(
() -> "Rect Draw",
target.getColorTextureView(), OptionalInt.empty(),
target.getDepthTextureView(), OptionalDouble.empty())
) {
pass.setPipeline(LuminRenderPipelines.RECTANGLE);

RenderSystem.bindDefaultUniforms(pass);
pass.setUniform("DynamicTransforms", dynamicUniforms);

pass.setVertexBuffer(0, buffer.getGpuBuffer());
pass.setIndexBuffer(ibo, autoIndices.type());
pass.drawIndexed(0, 0, indexCount, 1);
}
}

@Override
public void clear() {
bufferBuilder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
vertexCount = 0;
currentOffset = 0;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package com.github.lumin.graphics.renderers;

import com.github.lumin.graphics.LuminRenderPipelines;
import com.github.lumin.graphics.LuminRenderSystem;
import com.github.lumin.graphics.buffer.LuminBuffer;
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.rendertype.TextureTransform;
import net.minecraft.util.ARGB;
import org.joml.Vector3f;
import org.joml.Vector4f;
import org.lwjgl.system.MemoryUtil;

import java.awt.*;
import java.util.OptionalDouble;
import java.util.OptionalInt;

public class RoundRectRenderer implements IRenderer {

private static final long BUFFER_SIZE = 2 * 1024 * 1024;
private final LuminBuffer buffer = new LuminBuffer(BUFFER_SIZE, GpuBuffer.USAGE_VERTEX);

public void addRoundRect(float x, float y, float width, float height, float radius, Color color) {
float x2 = x + width;
float y2 = y + height;

float expand = radius + 1.0f;
float vx1 = x - expand;
float vy1 = y - expand;
float vx2 = x2 + expand;
float vy2 = y2 + expand;

int argb = color.getRGB();

addVertex(vx1, vy1, x, y, x2, y2, radius, argb);
addVertex(vx1, vy2, x, y, x2, y2, radius, argb);
addVertex(vx2, vy2, x, y, x2, y2, radius, argb);
addVertex(vx2, vy1, x, y, x2, y2, radius, argb);
}

private long currentOffset = 0;
private int vertexCount = 0;

private void addVertex(float vx, float vy, float x1, float y1, float x2, float y2, float radius, int color) {
long baseAddr = MemoryUtil.memAddress(buffer.getMappedBuffer());
long p = baseAddr + currentOffset;

MemoryUtil.memPutFloat(p, vx);
MemoryUtil.memPutFloat(p + 4, vy);
MemoryUtil.memPutFloat(p + 8, 0.0f);

MemoryUtil.memPutInt(p + 12, ARGB.toABGR(color));

MemoryUtil.memPutFloat(p + 16, x1);
MemoryUtil.memPutFloat(p + 20, y1);
MemoryUtil.memPutFloat(p + 24, x2);
MemoryUtil.memPutFloat(p + 28, y2);

MemoryUtil.memPutFloat(p + 32, radius);

currentOffset += 36;
vertexCount++;
}

@Override
public void draw() {
LuminRenderSystem.applyOrthoProjection();

RenderTarget target = Minecraft.getInstance().getMainRenderTarget();
if (target.getColorTextureView() == null) return;

final var indexCount = vertexCount / 4 * 6;

RenderSystem.AutoStorageIndexBuffer autoIndices =
RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS);
GpuBuffer ibo = autoIndices.getBuffer(indexCount);

GpuBufferSlice dynamicUniforms = RenderSystem.getDynamicUniforms().writeTransform(
RenderSystem.getModelViewMatrix(),
new Vector4f(1, 1, 1, 1),
new Vector3f(0, 0, 0),
TextureTransform.DEFAULT_TEXTURING.getMatrix()
);

try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass(
() -> "Round Rect Draw",
target.getColorTextureView(), OptionalInt.empty(),
target.getDepthTextureView(), OptionalDouble.empty())
) {
pass.setPipeline(LuminRenderPipelines.ROUND_RECT);

RenderSystem.bindDefaultUniforms(pass);
pass.setUniform("DynamicTransforms", dynamicUniforms);
pass.setVertexBuffer(0, buffer.getGpuBuffer());
pass.setIndexBuffer(ibo, autoIndices.type());

pass.drawIndexed(0, 0, indexCount, 1);
}
}

@Override
public void clear() {
vertexCount = 0;
currentOffset = 0;
}
}
Loading