Skip to content
Open
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
2 changes: 1 addition & 1 deletion common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ dependencies {

compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5'

modCompileOnly "curse.maven:irisshaders-455508:${iris_version}"
//modCompileOnly "curse.maven:irisshaders-455508:${iris_version}"
}

test {
Expand Down
23 changes: 20 additions & 3 deletions common/src/main/java/pro/mikey/xray/core/ChunkScanTask.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pro.mikey.xray.core;

import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
Expand All @@ -15,13 +16,20 @@ public class ChunkScanTask implements Runnable {

private final int startX;
private final int startZ;
private final boolean iscore;

public ChunkScanTask(Level level, ChunkPos pos) {
public ChunkScanTask(Level level, ChunkPos pos, boolean core) {
// Move the chunk pos to block pos by multiplying by 16
this.startX = pos.x << 4;
this.startZ = pos.z << 4;

this.level = level;
this.iscore = core;
}

private boolean isNetherDimension() {
ResourceKey<Level> dimensionKey = level.dimension();
return dimensionKey == Level.NETHER;
}

@Override
Expand All @@ -39,8 +47,16 @@ public void run() {
state = level.getBlockState(pos);
fluidState = state.getFluidState();

if ((fluidState.getType() == Fluids.LAVA || fluidState.getType() == Fluids.FLOWING_LAVA) && ScanController.INSTANCE.isLavaActive()) {
renderQueue.add(new OutlineRenderTarget(pos.getX(), pos.getY(), pos.getZ(), 0xffff0000));
if (( fluidState.getType() == Fluids.LAVA || fluidState.getType() == Fluids.FLOWING_LAVA) && ScanController.INSTANCE.isLavaActive()) {
if (iscore){
if (isNetherDimension()) {
if (pos.getY() > 31){
renderQueue.add(new OutlineRenderTarget(pos.getX(), pos.getY(), pos.getZ(), 0xffff0000));
}
} else {
renderQueue.add(new OutlineRenderTarget(pos.getX(), pos.getY(), pos.getZ(), 0xffff0000));
}
}
continue;
}

Expand All @@ -51,6 +67,7 @@ public void run() {
for (var target : ScanController.INSTANCE.scanStore.activeScanTargets()) {
if (target.matches(level, pos, state, fluidState)) {
renderQueue.add(new OutlineRenderTarget(pos.getX(), pos.getY(), pos.getZ(), target.colorInt()));
break;
}
}
}
Expand Down
274 changes: 197 additions & 77 deletions common/src/main/java/pro/mikey/xray/core/OutlineRender.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
import net.minecraft.resources.Identifier;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.level.block.Block;

import org.joml.Matrix4f;
import org.joml.Matrix4fStack;
import org.joml.Vector3f;
Expand All @@ -28,101 +30,203 @@
public class OutlineRender {
private static final RenderSystem.AutoStorageIndexBuffer indices = RenderSystem.getSequentialBuffer(VertexFormat.Mode.LINES);
private static final Map<ChunkPos, VBOHolder> vertexBuffers = new HashMap<>();
private static final Map<ChunkPos, VBOHolder> vertexBuffersa = new HashMap<>();

private static final Set<ChunkPos> chunksToRefresh = Collections.synchronizedSet(new HashSet<>());
private static final Set<ChunkPos> chunksToRefresha = Collections.synchronizedSet(new HashSet<>());
private static final Object CHUNKS_TO_REFRESH_LOCK = new Object();
private static final Object CHUNKS_TO_REFRESH_LOCKA = new Object();
private static final VoxelShape BLOCK = Block.box(0.1D, 0.1D, 0.1D, 15.9D, 15.9D, 15.9D);

public static void renderBlocks(PoseStack poseStack) {
if (!ScanController.INSTANCE.isXRayActive() || Minecraft.getInstance().player == null) {
return;
}

if (ScanController.INSTANCE.syncRenderList.isEmpty()) {
return;
}

if (!chunksToRefresh.isEmpty()) {
// Clear the vertex buffers for the chunks that need to be refreshed
for (ChunkPos pos : chunksToRefresh) {
VBOHolder holder = vertexBuffers.remove(pos);
if (holder != null) {
holder.close();
//return;
} else {
if (!chunksToRefresh.isEmpty()) {
synchronized (CHUNKS_TO_REFRESH_LOCK) {
// Clear the vertex buffers for the chunks that need to be refreshed
for (ChunkPos pos : chunksToRefresh) {
VBOHolder holder = vertexBuffers.remove(pos);
if (holder != null) {
holder.close();
}
}

chunksToRefresh.clear();
}
}

chunksToRefresh.clear();

// Clone the entrySet to avoid concurrent modification exceptions
var entries = new ArrayList<>(ScanController.INSTANCE.syncRenderList.entrySet());

for (var chunkWithBlockData : entries) {
var chunkPos = chunkWithBlockData.getKey();
var blocksWithProps = chunkWithBlockData.getValue();

if (blocksWithProps.isEmpty()) {
continue;
}

VBOHolder holder = vertexBuffers.get(chunkPos);
if (holder == null) {
BufferBuilder bufferBuilder = Tesselator.getInstance().begin(RenderPipelines.LINES.getVertexFormatMode(), RenderPipelines.LINES.getVertexFormat());

// More concurrent modification exceptions can happen here, so we clone the list
var blockPropsClone = new ArrayList<>(blocksWithProps);

for (var blockProps : blockPropsClone) {
if (blockProps == null) {
continue;
}

final int x = blockProps.x(), y = blockProps.y(), z = blockProps.z();

ShapeRenderer.renderShape(poseStack, bufferBuilder, BLOCK, x, y, z, blockProps.color(), 1f);
}

try (MeshData meshData = bufferBuilder.buildOrThrow()) {
int indexCount = meshData.drawState().indexCount();
GpuBuffer vertexBuffer = RenderSystem.getDevice()
.createBuffer(() -> "Xray vertex buffer", GpuBuffer.USAGE_VERTEX, meshData.vertexBuffer());

vertexBuffers.put(chunkPos, new VBOHolder(vertexBuffer, indexCount));
}
}

holder = vertexBuffers.get(chunkPos);
if (holder == null || holder.vertexBuffer == null || holder.indexCount == 0) {
continue;
}

Vec3 playerPos = Minecraft.getInstance().gameRenderer.getMainCamera().position().reverse();

Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack();
GpuTextureView colorTextureView = Minecraft.getInstance().getMainRenderTarget().getColorTextureView();
GpuTextureView depthTextureView = Minecraft.getInstance().getMainRenderTarget().getDepthTextureView();

matrix4fStack.pushMatrix();
matrix4fStack.translate((float) playerPos.x(), (float) playerPos.y(), (float) playerPos.z());
GpuBufferSlice[] gpubufferslice = RenderSystem.getDynamicUniforms().writeTransforms(new DynamicUniforms.Transform(new Matrix4f(matrix4fStack), new Vector4f(1.0F, 1.0F, 1.0F, 1.0F), new Vector3f(), new Matrix4f()));

GL11.glDisable(GL11.GL_DEPTH_TEST);
RenderSystem.setShaderFog(gpubufferslice[0]);

GpuBuffer gpuBuffer = indices.getBuffer(holder.indexCount);
try (RenderPass renderPass = RenderSystem.getDevice()
.createCommandEncoder()
.createRenderPass(() -> "xray", colorTextureView, OptionalInt.empty(), depthTextureView, OptionalDouble.empty())) {

RenderSystem.bindDefaultUniforms(renderPass);
renderPass.setVertexBuffer(0, holder.vertexBuffer);
renderPass.setIndexBuffer(gpuBuffer, indices.type());
renderPass.setUniform("DynamicTransforms", gpubufferslice[0]);
renderPass.setPipeline(RenderPipelines.LINES);
renderPass.drawIndexed(0, 0, holder.indexCount, 1);
}

GL11.glEnable(GL11.GL_DEPTH_TEST);
matrix4fStack.popMatrix();
}
}

// Clone the entrySet to avoid concurrent modification exceptions
var entries = new ArrayList<>(ScanController.INSTANCE.syncRenderList.entrySet());

for (var chunkWithBlockData : entries) {
var chunkPos = chunkWithBlockData.getKey();
var blocksWithProps = chunkWithBlockData.getValue();

if (blocksWithProps.isEmpty()) {
continue;
//
if (ScanController.INSTANCE.syncRenderLista.isEmpty()) {
return;
} else {
if (!chunksToRefresha.isEmpty()) {
synchronized (CHUNKS_TO_REFRESH_LOCKA) {
// Clear the vertex buffers for the chunks that need to be refreshed
for (ChunkPos pos : chunksToRefresha) {
VBOHolder holder = vertexBuffersa.remove(pos);
if (holder != null) {
holder.close();
}
}

chunksToRefresha.clear();
}
}

VBOHolder holder = vertexBuffers.get(chunkPos);
if (holder == null) {
BufferBuilder bufferBuilder = Tesselator.getInstance().begin(RenderPipelines.LINES.getVertexFormatMode(), RenderPipelines.LINES.getVertexFormat());

// More concurrent modification exceptions can happen here, so we clone the list
var blockPropsClone = new ArrayList<>(blocksWithProps);

for (var blockProps : blockPropsClone) {
if (blockProps == null) {
continue;

// Clone the entrySet to avoid concurrent modification exceptions
var entries = new ArrayList<>(ScanController.INSTANCE.syncRenderLista.entrySet());

for (var chunkWithBlockData : entries) {
var chunkPos = chunkWithBlockData.getKey();
var blocksWithProps = chunkWithBlockData.getValue();

if (blocksWithProps.isEmpty()) {
continue;
}

VBOHolder holder = vertexBuffersa.get(chunkPos);
if (holder == null) {
BufferBuilder bufferBuilder = Tesselator.getInstance().begin(RenderPipelines.LINES.getVertexFormatMode(), RenderPipelines.LINES.getVertexFormat());

// More concurrent modification exceptions can happen here, so we clone the list
var blockPropsClone = new ArrayList<>(blocksWithProps);

for (var blockProps : blockPropsClone) {
if (blockProps == null) {
continue;
}

final int x = blockProps.x(), y = blockProps.y(), z = blockProps.z();

ShapeRenderer.renderShape(poseStack, bufferBuilder, BLOCK, x, y, z, blockProps.color(), 1f);
}

try (MeshData meshData = bufferBuilder.buildOrThrow()) {
int indexCount = meshData.drawState().indexCount();
GpuBuffer vertexBuffer = RenderSystem.getDevice()
.createBuffer(() -> "Xray vertex buffer", GpuBuffer.USAGE_VERTEX, meshData.vertexBuffer());

vertexBuffersa.put(chunkPos, new VBOHolder(vertexBuffer, indexCount));
} catch (Exception e) {
}

final int x = blockProps.x(), y = blockProps.y(), z = blockProps.z();

ShapeRenderer.renderShape(poseStack, bufferBuilder, Shapes.block(), x, y, z, blockProps.color(), 1f);
}

try (MeshData meshData = bufferBuilder.buildOrThrow()) {
int indexCount = meshData.drawState().indexCount();
GpuBuffer vertexBuffer = RenderSystem.getDevice()
.createBuffer(() -> "Xray vertex buffer", GpuBuffer.USAGE_VERTEX, meshData.vertexBuffer());

vertexBuffers.put(chunkPos, new VBOHolder(vertexBuffer, indexCount));

holder = vertexBuffersa.get(chunkPos);
if (holder == null || holder.vertexBuffer == null || holder.indexCount == 0) {
continue;
}

Vec3 playerPos = Minecraft.getInstance().gameRenderer.getMainCamera().position().reverse();

Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack();
GpuTextureView colorTextureView = Minecraft.getInstance().getMainRenderTarget().getColorTextureView();
GpuTextureView depthTextureView = Minecraft.getInstance().getMainRenderTarget().getDepthTextureView();

matrix4fStack.pushMatrix();
matrix4fStack.translate((float) playerPos.x(), (float) playerPos.y(), (float) playerPos.z());
GpuBufferSlice[] gpubufferslice = RenderSystem.getDynamicUniforms().writeTransforms(new DynamicUniforms.Transform(new Matrix4f(matrix4fStack), new Vector4f(1.0F, 1.0F, 1.0F, 1.0F), new Vector3f(), new Matrix4f()));

GL11.glDisable(GL11.GL_DEPTH_TEST);
RenderSystem.setShaderFog(gpubufferslice[0]);

GpuBuffer gpuBuffer = indices.getBuffer(holder.indexCount);
try (RenderPass renderPass = RenderSystem.getDevice()
.createCommandEncoder()
.createRenderPass(() -> "xray", colorTextureView, OptionalInt.empty(), depthTextureView, OptionalDouble.empty())) {

RenderSystem.bindDefaultUniforms(renderPass);
renderPass.setVertexBuffer(0, holder.vertexBuffer);
renderPass.setIndexBuffer(gpuBuffer, indices.type());
renderPass.setUniform("DynamicTransforms", gpubufferslice[0]);
renderPass.setPipeline(RenderPipelines.LINES);
renderPass.drawIndexed(0, 0, holder.indexCount, 1);
}

GL11.glEnable(GL11.GL_DEPTH_TEST);
matrix4fStack.popMatrix();
}
}

holder = vertexBuffers.get(chunkPos);
if (holder == null || holder.vertexBuffer == null || holder.indexCount == 0) {
continue;
}

Vec3 playerPos = Minecraft.getInstance().gameRenderer.getMainCamera().position().reverse();

Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack();
GpuTextureView colorTextureView = Minecraft.getInstance().getMainRenderTarget().getColorTextureView();
GpuTextureView depthTextureView = Minecraft.getInstance().getMainRenderTarget().getDepthTextureView();

matrix4fStack.pushMatrix();
matrix4fStack.translate((float) playerPos.x(), (float) playerPos.y(), (float) playerPos.z());
GpuBufferSlice[] gpubufferslice = RenderSystem.getDynamicUniforms().writeTransforms(new DynamicUniforms.Transform(new Matrix4f(matrix4fStack), new Vector4f(1.0F, 1.0F, 1.0F, 1.0F), new Vector3f(), new Matrix4f()));

GL11.glDisable(GL11.GL_DEPTH_TEST);
RenderSystem.setShaderFog(gpubufferslice[0]);

GpuBuffer gpuBuffer = indices.getBuffer(holder.indexCount);
try (RenderPass renderPass = RenderSystem.getDevice()
.createCommandEncoder()
.createRenderPass(() -> "xray", colorTextureView, OptionalInt.empty(), depthTextureView, OptionalDouble.empty())) {

RenderSystem.bindDefaultUniforms(renderPass);
renderPass.setVertexBuffer(0, holder.vertexBuffer);
renderPass.setIndexBuffer(gpuBuffer, indices.type());
renderPass.setUniform("DynamicTransforms", gpubufferslice[0]);
renderPass.setPipeline(RenderPipelines.LINES);
renderPass.drawIndexed(0, 0, holder.indexCount, 1);
}

GL11.glEnable(GL11.GL_DEPTH_TEST);
matrix4fStack.popMatrix();
}
}

public static void clearVBOs() {
Expand All @@ -132,18 +236,34 @@ public static void clearVBOs() {
}
}
vertexBuffers.clear();
for (VBOHolder holder : vertexBuffersa.values()) {
if (holder != null) {
holder.close();
}
}
vertexBuffersa.clear();
}

public static void clearVBOsFor(List<ChunkPos> removedChunks) {
if (removedChunks.isEmpty()) {
return;
}

chunksToRefresh.addAll(removedChunks);
synchronized (CHUNKS_TO_REFRESH_LOCK) {
chunksToRefresh.addAll(removedChunks);
}
}

public static void refreshVBOForChunk(ChunkPos pos) {
chunksToRefresh.add(pos);
synchronized (CHUNKS_TO_REFRESH_LOCK) {
chunksToRefresh.add(pos);
}
}

public static void refreshVBOForChunka(ChunkPos pos) {
synchronized (CHUNKS_TO_REFRESH_LOCKA) {
chunksToRefresha.add(pos);
}
}

private record VBOHolder(GpuBuffer vertexBuffer, int indexCount) implements Closeable {
Expand Down
Loading