diff --git a/build.gradle b/build.gradle index 0c4c2bc0..99c519aa 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,7 @@ dependencies { //modRuntimeOnly "maven.modrinth:nvidium:0.2.6-beta" modCompileOnly "maven.modrinth:nvidium:0.2.8-beta" - modImplementation("maven.modrinth:cloth-config:17.0.144+fabric") + modImplementation("maven.modrinth:cloth-config:18.0.145+fabric") modImplementation("maven.modrinth:modmenu:14.0.0-rc.2") @@ -94,7 +94,7 @@ dependencies { modCompileOnly("maven.modrinth:chunky:1.4.27-fabric") - modRuntimeOnly("maven.modrinth:chunky:1.4.27-fabric") + //modRuntimeOnly("maven.modrinth:chunky:1.4.27-fabric") modRuntimeOnly("maven.modrinth:spark:1.10.121-fabric") modRuntimeOnly("maven.modrinth:fabric-permissions-api:0.3.3") diff --git a/src/main/java/me/cortex/voxy/client/core/gl/shader/AutoBindingShader.java b/src/main/java/me/cortex/voxy/client/core/gl/shader/AutoBindingShader.java index 058117b8..2085a38d 100644 --- a/src/main/java/me/cortex/voxy/client/core/gl/shader/AutoBindingShader.java +++ b/src/main/java/me/cortex/voxy/client/core/gl/shader/AutoBindingShader.java @@ -1,30 +1,44 @@ package me.cortex.voxy.client.core.gl.shader; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; import me.cortex.voxy.client.core.gl.GlBuffer; +import me.cortex.voxy.client.core.gl.GlDebug; +import me.cortex.voxy.client.core.gl.GlTexture; import me.cortex.voxy.common.util.Pair; import java.util.ArrayList; import java.util.List; import java.util.Map; +import static org.lwjgl.opengl.ARBDirectStateAccess.glBindTextureUnit; +import static org.lwjgl.opengl.GL11.glBindTexture; import static org.lwjgl.opengl.GL30.glBindBufferBase; import static org.lwjgl.opengl.GL30.glBindBufferRange; import static org.lwjgl.opengl.GL31.GL_UNIFORM_BUFFER; +import static org.lwjgl.opengl.GL33.glBindSampler; import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BUFFER; //TODO: rewrite the entire shader builder system public class AutoBindingShader extends Shader { + private record BufferBinding(int target, int index, GlBuffer buffer, long offset, long size) {} + private record TextureBinding(int unit, int sampler, GlTexture texture) {} private final Map defines; private final List bindings = new ArrayList<>(); + private final List textureBindings = new ArrayList<>(); AutoBindingShader(Shader.Builder builder, int program) { super(program); this.defines = builder.defines; } + public AutoBindingShader name(String name) { + return GlDebug.name(name, this); + } + public AutoBindingShader ssbo(int index, GlBuffer binding) { return this.ssbo(index, binding, 0); } @@ -47,14 +61,42 @@ public class AutoBindingShader extends Shader { return this; } + + public AutoBindingShader texture(String define, GlTexture texture) { + return this.texture(define, -1, texture); + } + + public AutoBindingShader texture(String define, int sampler, GlTexture texture) { + return this.texture(Integer.parseInt(this.defines.get(define)), sampler, texture); + } + + public AutoBindingShader texture(int unit, int sampler, GlTexture texture) { + this.textureBindings.add(new TextureBinding(unit, sampler, texture)); + return this; + } + @Override public void bind() { super.bind(); - for (var binding : this.bindings) { - if (binding.offset == 0 && binding.size == -1) { - glBindBufferBase(binding.target, binding.index, binding.buffer.id); - } else { - glBindBufferRange(binding.target, binding.index, binding.buffer.id, binding.offset, binding.size); + if (!this.bindings.isEmpty()) { + for (var binding : this.bindings) { + if (binding.offset == 0 && binding.size == -1) { + glBindBufferBase(binding.target, binding.index, binding.buffer.id); + } else { + glBindBufferRange(binding.target, binding.index, binding.buffer.id, binding.offset, binding.size); + } + } + } + if (!this.textureBindings.isEmpty()) { + for (var binding : this.textureBindings) { + if (binding.texture != null) { + GlStateManager._activeTexture(GlConst.GL_TEXTURE0+binding.unit); + GlStateManager._bindTexture(0); + glBindTextureUnit(binding.unit, binding.texture.id); + } + if (binding.sampler != -1) { + glBindSampler(binding.unit, binding.sampler); + } } } } diff --git a/src/main/java/me/cortex/voxy/client/core/model/BakedBlockEntityModel.java b/src/main/java/me/cortex/voxy/client/core/model/BakedBlockEntityModel.java index 912cee07..ed0d4572 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/BakedBlockEntityModel.java +++ b/src/main/java/me/cortex/voxy/client/core/model/BakedBlockEntityModel.java @@ -123,7 +123,7 @@ public class BakedBlockEntityModel { } } layer.putInto(bb); - BudgetBufferRenderer.draw(bb.end()); + //BudgetBufferRenderer.draw(bb.end()); } } } diff --git a/src/main/java/me/cortex/voxy/client/core/model/BudgetBufferRenderer.java b/src/main/java/me/cortex/voxy/client/core/model/BudgetBufferRenderer.java index 79be6753..ac794c1a 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/BudgetBufferRenderer.java +++ b/src/main/java/me/cortex/voxy/client/core/model/BudgetBufferRenderer.java @@ -1,17 +1,47 @@ package me.cortex.voxy.client.core.model; +import com.mojang.blaze3d.buffers.GpuBuffer; +import com.mojang.blaze3d.pipeline.RenderPipeline; +import com.mojang.blaze3d.systems.RenderPass; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.textures.GpuTexture; import com.mojang.blaze3d.vertex.VertexFormat; -import net.minecraft.client.gl.GlGpuBuffer; +import net.minecraft.client.gl.*; import net.minecraft.client.render.BuiltBuffer; - -import static org.lwjgl.opengl.GL15C.*; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.util.Identifier; +import org.joml.Matrix4f; public class BudgetBufferRenderer { - public static void draw(BuiltBuffer buffer) { - var params = buffer.getDrawParameters(); - try (var gpuBuf = params.format().uploadImmediateIndexBuffer(buffer.getBuffer())) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ((GlGpuBuffer)RenderSystem.getSequentialBuffer(VertexFormat.DrawMode.QUADS).getIndexBuffer(params.indexCount())).id); - } + public static final RenderPipeline RENDERER_THING = RenderPipeline.builder() + .withLocation(Identifier.of("voxy","bakery/position_tex")) + .withVertexShader(Identifier.of("voxy","bakery/position_tex")) + .withFragmentShader(Identifier.of("voxy","bakery/position_tex")) + .withUniform("transform", UniformType.MATRIX4X4) + .withSampler("tex") + .withVertexFormat(VertexFormats.POSITION_TEXTURE_COLOR, VertexFormat.DrawMode.QUADS) + .build(); + public static void draw(BuiltBuffer buffer, GpuTexture tex, Matrix4f matrix) { + RenderSystem.ShapeIndexBuffer shapeIndexBuffer = RenderSystem.getSequentialBuffer(buffer.getDrawParameters().mode()); + GpuBuffer gpuBuffer = buffer.getDrawParameters().format().uploadImmediateVertexBuffer(buffer.getBuffer()); + + var res = (GlResourceManager)RenderSystem.getDevice() + .createCommandEncoder(); + res.currentProgram = null; + res.currentPipeline = RENDERER_THING; + try (RenderPass renderPass = new RenderPassImpl(res, false)) { + renderPass.setPipeline(RENDERER_THING); + renderPass.setVertexBuffer(0, gpuBuffer); + + renderPass.bindSampler("tex", tex); + renderPass.setUniform("transform", matrix); + + renderPass.setIndexBuffer(shapeIndexBuffer.getIndexBuffer(buffer.getDrawParameters().indexCount()), shapeIndexBuffer.getIndexType()); + renderPass.drawIndexed(0, buffer.getDrawParameters().indexCount()); + } + //gpuBuffer.close(); + buffer.close(); + res.currentProgram = null; + res.currentPipeline = null; } } diff --git a/src/main/java/me/cortex/voxy/client/core/model/bakery/GlViewCapture.java b/src/main/java/me/cortex/voxy/client/core/model/bakery/GlViewCapture.java new file mode 100644 index 00000000..84284e70 --- /dev/null +++ b/src/main/java/me/cortex/voxy/client/core/model/bakery/GlViewCapture.java @@ -0,0 +1,67 @@ +package me.cortex.voxy.client.core.model.bakery; + +import me.cortex.voxy.client.core.gl.GlBuffer; +import me.cortex.voxy.client.core.gl.GlFramebuffer; +import me.cortex.voxy.client.core.gl.GlTexture; +import me.cortex.voxy.client.core.gl.shader.Shader; +import me.cortex.voxy.client.core.gl.shader.ShaderType; + +import static org.lwjgl.opengl.ARBDirectStateAccess.glTextureParameteri; +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL11.GL_STENCIL_INDEX; +import static org.lwjgl.opengl.GL30.*; +import static org.lwjgl.opengl.GL43.*; + +public class GlViewCapture { + private final int width; + private final int height; + private final GlTexture colourTex; + private final GlTexture depthTex; + private final GlTexture stencilTex; + final GlFramebuffer framebuffer; + private final Shader copyOutShader; + + public GlViewCapture(int width, int height) { + this.width = width; + this.height = height; + this.colourTex = new GlTexture().store(GL_RGBA8, 1, width*3, height*2).name("ModelBakeryColour"); + this.depthTex = new GlTexture().store(GL_DEPTH24_STENCIL8, 1, width*3, height*2).name("ModelBakeryDepth"); + //TODO: FIXME: Mesa is broken when trying to read from a sampler of GL_STENCIL_INDEX + // it seems to just ignore the value set in GL_DEPTH_STENCIL_TEXTURE_MODE + glTextureParameteri(this.depthTex.id, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); + this.stencilTex = this.depthTex.createView(); + glTextureParameteri(this.depthTex.id, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); + + this.framebuffer = new GlFramebuffer().bind(GL_COLOR_ATTACHMENT0, this.colourTex).bind(GL_DEPTH_STENCIL_ATTACHMENT, this.depthTex).verify().name("ModelFramebuffer"); + + glTextureParameteri(this.stencilTex.id, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); + + this.copyOutShader = Shader.makeAuto() + .define("WIDTH", width) + .define("HEIGHT", height) + .define("COLOUR_IN_BINDING", 0) + .define("DEPTH_IN_BINDING", 1) + .define("STENCIL_IN_BINDING", 2) + .define("BUFFER_OUT_BINDING", 3) + .add(ShaderType.COMPUTE, "voxy:bakery/bufferreorder.comp") + .compile() + .name("ModelBakeryOut") + .texture("COLOUR_IN_BINDING", 0, this.colourTex) + .texture("DEPTH_IN_BINDING", 0, this.depthTex) + .texture("STENCIL_IN_BINDING", 0, this.stencilTex); + } + + public void emitToStream(int buffer, int offset) { + this.copyOutShader.bind(); + glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 3, buffer, offset, (this.width*3L)*(this.height*2L)*4L*2);//its 2*4 because colour + depth stencil + glDispatchCompute(3, 2, 1); + } + + public void free() { + this.framebuffer.free(); + this.colourTex.free(); + this.stencilTex.free(); + this.depthTex.free(); + this.copyOutShader.free(); + } +} diff --git a/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery2.java b/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery2.java new file mode 100644 index 00000000..6bc1bde8 --- /dev/null +++ b/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery2.java @@ -0,0 +1,315 @@ +package me.cortex.voxy.client.core.model.bakery; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.textures.GpuTexture; +import com.mojang.blaze3d.vertex.VertexFormat; +import me.cortex.voxy.client.core.gl.GlFramebuffer; +import me.cortex.voxy.client.core.gl.GlTexture; +import me.cortex.voxy.client.core.gl.shader.Shader; +import me.cortex.voxy.client.core.gl.shader.ShaderType; +import me.cortex.voxy.client.core.model.BakedBlockEntityModel; +import me.cortex.voxy.client.core.model.BudgetBufferRenderer; +import me.cortex.voxy.client.core.rendering.util.GlStateCapture; +import net.caffeinemc.mods.sodium.client.render.chunk.terrain.DefaultTerrainRenderPasses; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gl.GlBackend; +import net.minecraft.client.render.*; +import net.minecraft.client.render.model.BlockStateModel; +import net.minecraft.client.util.BufferAllocator; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.fluid.FluidState; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ColorHelper; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.RotationAxis; +import net.minecraft.util.math.random.LocalRandom; +import net.minecraft.world.BlockRenderView; +import net.minecraft.world.LightType; +import net.minecraft.world.biome.ColorResolver; +import net.minecraft.world.chunk.light.LightingProvider; +import org.jetbrains.annotations.Nullable; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL11C; + +import java.util.ArrayList; +import java.util.List; + +import static org.lwjgl.opengl.ARBDirectStateAccess.glBlitNamedFramebuffer; +import static org.lwjgl.opengl.ARBDirectStateAccess.glTextureParameteri; +import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_FRAMEBUFFER_BARRIER_BIT; +import static org.lwjgl.opengl.ARBShaderImageLoadStore.glMemoryBarrier; +import static org.lwjgl.opengl.GL11C.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL14C.glBlendFuncSeparate; +import static org.lwjgl.opengl.GL20C.glUniformMatrix4fv; +import static org.lwjgl.opengl.GL30.*; +import static org.lwjgl.opengl.GL43.*; + +//Builds a texture for each face of a model +public class ModelTextureBakery2 { + private static final List FACE_VIEWS = new ArrayList<>(); + private final int width; + private final int height; + private final GlViewCapture capture; + + public ModelTextureBakery2(int width, int height) { + this.width = width; + this.height = height; + this.capture = new GlViewCapture(width, height); + + //This is done to help make debugging easier + FACE_VIEWS.clear(); + AddViews(); + } + + private static void AddViews() { + //TODO: FIXME: need to bake in the correct orientation, HOWEVER some orientations require a flipped winding order!!!! + + addView(-90,0, 0, false);//Direction.DOWN + addView(90,0, 0, false);//Direction.UP + addView(0,180, 0, true);//Direction.NORTH + addView(0,0, 0, false);//Direction.SOUTH + //TODO: check these arnt the wrong way round + addView(0,90, 270, false);//Direction.EAST + addView(0,270, 270, false);//Direction.WEST + } + + private static void addView(float pitch, float yaw, float rotation, boolean flipX) { + var stack = new MatrixStack(); + stack.translate(0.5f,0.5f,0.5f); + stack.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation)); + stack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch)); + stack.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw)); + stack.translate(-0.5f,-0.5f,-0.5f); + FACE_VIEWS.add(stack); + } + + + + //TODO: For block entities, also somehow attempt to render the default block entity, e.g. chests and stuff + // cause that will result in ok looking micro details in the terrain + public void renderFacesToStream(BlockState state, long randomValue, boolean renderFluid, int streamBuffer, int streamBaseOffset) { + int[] viewport = new int[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + int oldFB = glGetInteger(GL_DRAW_FRAMEBUFFER_BINDING); + + + var model = MinecraftClient.getInstance() + .getBakedModelManager() + .getBlockModels() + .getModel(state); + + BakedBlockEntityModel entityModel = state.hasBlockEntity()?BakedBlockEntityModel.bake(state):null; + + var projection = new Matrix4f().identity().set(new float[]{ + 2,0,0,0, + 0, 2,0,0, + 0,0, -1f,0, + -1,-1,0,1, + }); + + + + RenderLayer renderLayer = null; + if (!renderFluid) { + renderLayer = RenderLayers.getBlockLayer(state); + } else { + renderLayer = RenderLayers.getFluidLayer(state.getFluidState()); + } + + + //TODO: figure out why calling this makes minecraft render black + //renderLayer.startDrawing(); + + glClearColor(0,0,0,0); + glClearDepth(1); + glClearStencil(0); + glBindFramebuffer(GL_FRAMEBUFFER, this.capture.framebuffer.id); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glEnable(GL_STENCIL_TEST); + glDepthRange(0, 1); + glDepthMask(true); + glEnable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + //glDepthFunc(GL_LESS); + + + //TODO: Find a better solution + if (renderLayer == RenderLayer.getTranslucent()) { + //Very hacky blend function to retain the effect of the applied alpha since we dont really want to apply alpha + // this is because we apply the alpha again when rendering the terrain meaning the alpha is being double applied + glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } else { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + + + //glBlendFunc(GL_ONE, GL_ONE); + + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + glStencilFunc(GL_ALWAYS, 1, 0xFF); + glStencilMask(0xFF); + + var tex = MinecraftClient.getInstance().getTextureManager().getTexture(Identifier.of("minecraft", "textures/atlas/blocks.png")).getGlTexture(); + for (int i = 0; i < FACE_VIEWS.size(); i++) { + glViewport((i%3)*this.width, (i/3)*this.height, this.width, this.height); + glBindFramebuffer(GL_FRAMEBUFFER, this.capture.framebuffer.id); + captureViewToStream(state, model, entityModel, new Matrix4f(projection).mul(FACE_VIEWS.get(i).peek().getPositionMatrix()), randomValue, i, renderFluid, tex); + } + + + //renderLayer.endDrawing(); + + glDisable(GL_STENCIL_TEST); + glDisable(GL_BLEND); + + glBindFramebuffer(GL_FRAMEBUFFER, oldFB); + + GL11C.glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT); + this.capture.emitToStream(streamBuffer, streamBaseOffset); + + /* + var target = DefaultTerrainRenderPasses.CUTOUT.getTarget(); + int boundFB = ((net.minecraft.client.texture.GlTexture) target.getColorAttachment()).getOrCreateFramebuffer(((GlBackend) RenderSystem.getDevice()).getFramebufferManager(), target.getDepthAttachment()); + glBlitNamedFramebuffer(this.capture.framebuffer.id, boundFB, 0, 0, 16*3, 16*2, 0, 0,16*3*16, 16*2*16, GL_COLOR_BUFFER_BIT, GL_NEAREST); + */ + //TODO: FIXME: fully revert the state of opengl + } + + private final BufferAllocator allocator = new BufferAllocator(786432); + private void captureViewToStream(BlockState state, BlockStateModel model, BakedBlockEntityModel blockEntityModel, Matrix4f transform, long randomValue, int face, boolean renderFluid, GpuTexture texture) { + //glActiveTexture(GL_TEXTURE0); + //glUniform1i(0, 0); + + //float[] mat = new float[4*4]; + //transform.get(mat); + //glUniformMatrix4fv(1, false, mat); + + + if (blockEntityModel != null && !renderFluid) { + blockEntityModel.renderOut(); + } + + var bb = new BufferBuilder(this.allocator, VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR) { + @Override + public void vertex(float x, float y, float z, int color, float u, float v, int overlay, int light, float normalX, float normalY, float normalZ) { + super.vertex(x, y, z, ColorHelper.getArgb(0,0,1), u, v, overlay, light, normalX, normalY, normalZ); + } + + @Override + public VertexConsumer color(int argb) { + return super.color(ColorHelper.getArgb(0,0,1)); + } + + @Override + public VertexConsumer color(int red, int green, int blue, int alpha) { + return super.color(0, 0, 1, 255); + } + }; + if (!renderFluid) { + //TODO: need to do 2 variants for quads, one which have coloured, ones that dont, might be able to pull a spare bit + // at the end whether or not a pixel should be mixed with texture + renderQuads(bb, model, new MatrixStack(), randomValue); + } else { + MinecraftClient.getInstance().getBlockRenderManager().renderFluid(BlockPos.ORIGIN, new BlockRenderView() { + @Override + public float getBrightness(Direction direction, boolean shaded) { + return 0; + } + + @Override + public LightingProvider getLightingProvider() { + return null; + } + + @Override + public int getLightLevel(LightType type, BlockPos pos) { + return 0; + } + + @Override + public int getColor(BlockPos pos, ColorResolver colorResolver) { + return 0; + } + + @Nullable + @Override + public BlockEntity getBlockEntity(BlockPos pos) { + return null; + } + + @Override + public BlockState getBlockState(BlockPos pos) { + if (pos.equals(Direction.byIndex(face).getVector())) { + return Blocks.AIR.getDefaultState(); + } + + //Fixme: + // This makes it so that the top face of water is always air, if this is commented out + // the up block will be a liquid state which makes the sides full + // if this is uncommented, that issue is fixed but e.g. stacking water layers ontop of eachother + // doesnt fill the side of the block + + //if (pos.getY() == 1) { + // return Blocks.AIR.getDefaultState(); + //} + return state; + } + + @Override + public FluidState getFluidState(BlockPos pos) { + if (pos.equals(Direction.byIndex(face).getVector())) { + return Blocks.AIR.getDefaultState().getFluidState(); + } + //if (pos.getY() == 1) { + // return Blocks.AIR.getDefaultState().getFluidState(); + //} + return state.getFluidState(); + } + + @Override + public int getHeight() { + return 0; + } + + @Override + public int getBottomY() { + return 0; + } + }, bb, state, state.getFluidState()); + } + + try { + //System.err.println("REPLACE THE UPLOADING WITH THREAD SAFE VARIENT"); + BudgetBufferRenderer.draw(bb.end(), texture, transform); + } catch (IllegalStateException e) { + //System.err.println("Got empty buffer builder! for block " + state); + } + } + + private static void renderQuads(BufferBuilder builder, BlockStateModel model, MatrixStack stack, long randomValue) { + for (Direction direction : new Direction[]{Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST, null}) { + for (var part : model.getParts(new LocalRandom(randomValue))) { + var quads = part.getQuads(direction); + for (var quad : quads) { + //TODO: mark pixels that have + int meta = 1; + builder.quad(stack.peek(), quad, ((meta >> 16) & 0xff) / 255f, ((meta >> 8) & 0xff) / 255f, (meta & 0xff) / 255f, 1.0f, 0, 0); + } + } + } + } + + public void free() { + this.capture.free(); + this.allocator.close(); + } +} diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/VoxyRenderSystem.java b/src/main/java/me/cortex/voxy/client/core/rendering/VoxyRenderSystem.java index 4dc54f90..f0af1def 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/VoxyRenderSystem.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/VoxyRenderSystem.java @@ -1,12 +1,16 @@ package me.cortex.voxy.client.core.rendering; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import me.cortex.voxy.client.config.VoxyConfig; import me.cortex.voxy.client.core.gl.Capabilities; import me.cortex.voxy.client.core.gl.GlBuffer; +import me.cortex.voxy.client.core.gl.GlTexture; import me.cortex.voxy.client.core.model.ColourDepthTextureData; import me.cortex.voxy.client.core.model.ModelBakerySubsystem; import me.cortex.voxy.client.core.model.ModelTextureBakery; +import me.cortex.voxy.client.core.model.bakery.ModelTextureBakery2; import me.cortex.voxy.client.core.rendering.building.RenderDataFactory45; import me.cortex.voxy.client.core.rendering.building.RenderGenerationService; import me.cortex.voxy.client.core.rendering.post.PostProcessing; @@ -20,10 +24,15 @@ import me.cortex.voxy.common.world.WorldEngine; import me.cortex.voxy.common.world.WorldSection; import me.cortex.voxy.common.world.other.Mapper; import me.cortex.voxy.commonImpl.VoxyCommon; +import net.caffeinemc.mods.sodium.client.render.chunk.terrain.DefaultTerrainRenderPasses; +import net.caffeinemc.mods.sodium.client.render.chunk.terrain.TerrainRenderPass; +import net.irisshaders.iris.targets.RenderTarget; import net.minecraft.block.Blocks; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gl.GlBackend; import net.minecraft.client.render.Camera; import net.minecraft.client.render.Frustum; +import net.minecraft.client.render.LightmapTextureManager; import net.minecraft.client.util.math.MatrixStack; import org.joml.Matrix4f; import org.lwjgl.opengl.GL11; @@ -34,8 +43,9 @@ import java.util.List; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; -import static org.lwjgl.opengl.GL11C.glFinish; +import static org.lwjgl.opengl.GL11C.*; import static org.lwjgl.opengl.GL30C.GL_DRAW_FRAMEBUFFER_BINDING; +import static org.lwjgl.opengl.GL30C.glBindFramebuffer; public class VoxyRenderSystem { private final RenderService renderer; @@ -94,7 +104,7 @@ public class VoxyRenderSystem { ).mulLocal(makeProjectionMatrix(16, 16*3000)); } - //private static final ModelTextureBakery mtb = new ModelTextureBakery(16, 16); + //private static final ModelTextureBakery2 mtb = new ModelTextureBakery2(16, 16); //private static final RawDownloadStream downstream = new RawDownloadStream(1<<20); public void renderOpaque(MatrixStack matrices, double cameraX, double cameraY, double cameraZ) { /* @@ -121,7 +131,7 @@ public class VoxyRenderSystem { mtb.renderFacesToStream(Blocks.GRASS_BLOCK.getDefaultState(), 123456, false, downstream.getBufferId(), allocation); downstream.submit(); downstream.tick(); - */ + */ //if (true) return; @@ -164,7 +174,12 @@ public class VoxyRenderSystem { .setScreenSize(MinecraftClient.getInstance().getFramebuffer().textureWidth, MinecraftClient.getInstance().getFramebuffer().textureHeight); viewport.frameId++; - int boundFB = GL11.glGetInteger(GL_DRAW_FRAMEBUFFER_BINDING); + + + int oldFB = GL11.glGetInteger(GL_DRAW_FRAMEBUFFER_BINDING); + + var target = DefaultTerrainRenderPasses.CUTOUT.getTarget(); + int boundFB = ((net.minecraft.client.texture.GlTexture) target.getColorAttachment()).getOrCreateFramebuffer(((GlBackend) RenderSystem.getDevice()).getFramebufferManager(), target.getDepthAttachment()); if (boundFB == 0) { throw new IllegalStateException("Cannot use the default framebuffer as cannot source from it"); } @@ -172,7 +187,7 @@ public class VoxyRenderSystem { //int boundDepthBuffer = glGetNamedFramebufferAttachmentParameteri(boundFB, GL_DEPTH_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); //TODO:FIXME!!! ?? - this.postProcessing.setup(MinecraftClient.getInstance().getFramebuffer().textureWidth, MinecraftClient.getInstance().getFramebuffer().textureHeight, boundFB); + this.postProcessing.setup(target.textureWidth, target.textureHeight, boundFB); this.renderer.renderFarAwayOpaque(viewport); @@ -184,6 +199,7 @@ public class VoxyRenderSystem { this.postProcessing.renderPost(projection, RenderSystem.getProjectionMatrix(), boundFB); + glBindFramebuffer(GlConst.GL_FRAMEBUFFER, oldFB); } public void addDebugInfo(List debug) { diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/post/PostProcessing.java b/src/main/java/me/cortex/voxy/client/core/rendering/post/PostProcessing.java index cf6ec1d8..739b6fba 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/post/PostProcessing.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/post/PostProcessing.java @@ -154,6 +154,7 @@ public class PostProcessing { mat.get(data); glUniformMatrix4fv(4, false, data);//invMVP + glActiveTexture(GL_TEXTURE0); glBindImageTexture(0, this.colourSSAO.id, 0, false,0, GL_READ_WRITE, GL_RGBA8); glActiveTexture(GL_TEXTURE1); GL11C.glBindTexture(GL_TEXTURE_2D, this.depthStencil.id); diff --git a/src/main/resources/assets/voxy/shaders/bakery/bufferreorder.comp b/src/main/resources/assets/voxy/shaders/bakery/bufferreorder.comp new file mode 100644 index 00000000..ed83fb67 --- /dev/null +++ b/src/main/resources/assets/voxy/shaders/bakery/bufferreorder.comp @@ -0,0 +1,32 @@ +#version 450 + +layout(local_size_x = WIDTH, local_size_y = HEIGHT) in; + +layout(binding = COLOUR_IN_BINDING) uniform sampler2D colourTexIn; +layout(binding = DEPTH_IN_BINDING) uniform sampler2D depthTexIn; +layout(binding = STENCIL_IN_BINDING) uniform usampler2D stencilTexIn; +layout(binding = BUFFER_OUT_BINDING, std430) writeonly restrict buffer OutBuffer { + uvec2[] outBuffer; +}; + +void main() { + uint localOutIndex = gl_LocalInvocationID.x + gl_LocalInvocationID.y*WIDTH; + uint groupOutIndex = (gl_WorkGroupID.x + gl_WorkGroupID.y*3)*(WIDTH*HEIGHT); + uint globalOutIndex = groupOutIndex+localOutIndex; + + ivec2 samplePoint = ivec2(gl_GlobalInvocationID.xy); + + uvec2 outPoint = uvec2(0); + + uvec4 colour = clamp(uvec4(texelFetch(colourTexIn, samplePoint, 0)*255), uvec4(0), uvec4(255));//TODO: check that this actually gets to the range of 255 + colour <<= uvec4(0,8,16,24);//ABGR format!!! + outPoint.x = colour.r|colour.g|colour.b|colour.a; + + float depth = clamp(texelFetch(depthTexIn, samplePoint, 0).r, 0, 1);//Opengl grumble grumble + uint stencil = texelFetch(stencilTexIn, samplePoint, 0).r; + uint value = uint(depth*((1<<24)-1))<<8; + value |= stencil; + outPoint.y = value; + + outBuffer[globalOutIndex] = outPoint; +} \ No newline at end of file diff --git a/src/main/resources/assets/voxy/shaders/bakery/position_tex.vsh b/src/main/resources/assets/voxy/shaders/bakery/position_tex.vsh index a3397d6d..7831068f 100644 --- a/src/main/resources/assets/voxy/shaders/bakery/position_tex.vsh +++ b/src/main/resources/assets/voxy/shaders/bakery/position_tex.vsh @@ -4,7 +4,7 @@ layout(location=0) in vec3 pos; layout(location=1) in vec2 uv; layout(location=2) in vec4 _metadata; -layout(location=1) uniform mat4 transform; +uniform mat4 transform; out vec2 texCoord; out flat uint metadata; diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 5a3130b2..892ae0eb 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -32,7 +32,7 @@ "common.voxy.mixins.json" ], "depends": { - "minecraft": "1.21.4", + "minecraft": "1.21.5", "fabricloader": ">=0.14.22", "fabric-api": ">=0.91.1", "cloth-config": ">=13", diff --git a/src/main/resources/voxy.accesswidener b/src/main/resources/voxy.accesswidener index aaf665c0..fda1138c 100644 --- a/src/main/resources/voxy.accesswidener +++ b/src/main/resources/voxy.accesswidener @@ -25,4 +25,7 @@ accessible field net/minecraft/world/chunk/PalettedContainer data Lnet/minecraft accessible field net/minecraft/world/chunk/PalettedContainer$Data storage Lnet/minecraft/util/collection/PaletteStorage; accessible field net/minecraft/world/chunk/PalettedContainer$Data palette Lnet/minecraft/world/chunk/Palette; -accessible field net/minecraft/client/gl/GlGpuBuffer id I \ No newline at end of file +accessible field net/minecraft/client/gl/GlGpuBuffer id I + +accessible field net/minecraft/client/gl/GlResourceManager currentProgram Lnet/minecraft/client/gl/ShaderProgram; +accessible field net/minecraft/client/gl/GlResourceManager currentPipeline Lcom/mojang/blaze3d/pipeline/RenderPipeline; \ No newline at end of file