diff --git a/src/main/java/me/cortex/voxy/client/core/gl/GlFramebuffer.java b/src/main/java/me/cortex/voxy/client/core/gl/GlFramebuffer.java index 81eff80e..25d926ba 100644 --- a/src/main/java/me/cortex/voxy/client/core/gl/GlFramebuffer.java +++ b/src/main/java/me/cortex/voxy/client/core/gl/GlFramebuffer.java @@ -3,6 +3,7 @@ package me.cortex.voxy.client.core.gl; import me.cortex.voxy.common.util.TrackedObject; import static org.lwjgl.opengl.GL45C.*; +import static org.lwjgl.opengl.GL45C.glNamedFramebufferDrawBuffers; public class GlFramebuffer extends TrackedObject { public final int id; @@ -24,6 +25,11 @@ public class GlFramebuffer extends TrackedObject { return this; } + public GlFramebuffer setDrawBuffers(int... buffers) { + glNamedFramebufferDrawBuffers(this.id, buffers); + return this; + } + @Override public void free() { super.free0(); diff --git a/src/main/java/me/cortex/voxy/client/core/gl/GlTexture.java b/src/main/java/me/cortex/voxy/client/core/gl/GlTexture.java index b1c3d46b..8994aaea 100644 --- a/src/main/java/me/cortex/voxy/client/core/gl/GlTexture.java +++ b/src/main/java/me/cortex/voxy/client/core/gl/GlTexture.java @@ -99,7 +99,7 @@ public class GlTexture extends TrackedObject { private long getEstimatedSize() { this.assertAllocated(); long elemSize = switch (this.format) { - case GL_RGBA8, GL_DEPTH24_STENCIL8, GL_R32F -> 4; + case GL_R32UI, GL_RGBA8, GL_DEPTH24_STENCIL8, GL_R32F -> 4; case GL_DEPTH_COMPONENT24 -> 4;//TODO: check this is right???? case GL_DEPTH_COMPONENT32F -> 4; case GL_DEPTH_COMPONENT32 -> 4; diff --git a/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java b/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java index 786d21eb..1f34ffd1 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java +++ b/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java @@ -414,7 +414,15 @@ public class ModelFactory { faceModelData |= ((!faceCoversFullBlock)&&blockRenderLayer != BlockRenderLayer.TRANSLUCENT)?1<<23:0;//Alpha discard override, translucency doesnt have alpha discard - + //Bits 24,25 are tint metadata + if (colourProvider!=null) {//We have a tint + int tintState = TextureUtils.computeFaceTint(textureData[face], checkMode); + if (tintState == 2) {//Partial tint + faceModelData |= 1<<24; + } else if (tintState == 3) {//Full tint + faceModelData |= 2<<24; + } + } MemoryUtil.memPutInt(faceUploadPtr, faceModelData); } diff --git a/src/main/java/me/cortex/voxy/client/core/model/TextureUtils.java b/src/main/java/me/cortex/voxy/client/core/model/TextureUtils.java index 0e200e55..40bbe9f5 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/TextureUtils.java +++ b/src/main/java/me/cortex/voxy/client/core/model/TextureUtils.java @@ -38,6 +38,37 @@ public class TextureUtils { throw new IllegalArgumentException(); } + + //0: nothing written + //1: none tinted + //2: some tinted + //3: all tinted + public static int computeFaceTint(ColourDepthTextureData texture, int checkMode) { + boolean allTinted = true; + boolean someTinted = false; + boolean wasWriten = false; + + final var colourData = texture.colour(); + final var depthData = texture.depth(); + for (int i = 0; i < colourData.length; i++) { + if (!wasPixelWritten(texture, checkMode, i)) { + continue; + } + if ((colourData[i]&0xFFFFFF) == 0 || (colourData[i]>>>24)==0) {//If the pixel is fully black (or translucent) + continue; + } + boolean pixelTinited = (depthData[i]&(1<<7))!=0; + wasWriten |= true; + allTinted &= pixelTinited; + someTinted |= pixelTinited; + + } + if (!wasWriten) { + return 0; + } + return someTinted?(allTinted?3:2):1; + } + public static final int DEPTH_MODE_AVG = 1; public static final int DEPTH_MODE_MAX = 2; public static final int DEPTH_MODE_MIN = 3; 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 index de3fc3b3..ebf2f194 100644 --- 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 @@ -7,8 +7,7 @@ import me.cortex.voxy.client.core.gl.shader.ShaderType; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; -import static org.lwjgl.opengl.ARBDirectStateAccess.glTextureParameteri; -import static org.lwjgl.opengl.ARBDirectStateAccess.nglClearNamedFramebufferfv; +import static org.lwjgl.opengl.ARBDirectStateAccess.*; import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_FRAMEBUFFER_BARRIER_BIT; import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_PIXEL_BUFFER_BARRIER_BIT; import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; @@ -25,12 +24,14 @@ public class GlViewCapture { private final GlTexture colourTex; private final GlTexture depthTex; private final GlTexture stencilTex; + private final GlTexture metaTex; final GlFramebuffer framebuffer; private final Shader copyOutShader; public GlViewCapture(int width, int height) { this.width = width; this.height = height; + this.metaTex = new GlTexture().store(GL_R32UI, 1, width*3, height*2).name("ModelBakeryMetadata"); 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 @@ -39,22 +40,27 @@ public class GlViewCapture { 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"); + this.framebuffer = new GlFramebuffer().bind(GL_COLOR_ATTACHMENT0, this.colourTex).bind(GL_COLOR_ATTACHMENT1, this.metaTex).setDrawBuffers(GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1).bind(GL_DEPTH_STENCIL_ATTACHMENT, this.depthTex).verify().name("ModelFramebuffer"); glTextureParameteri(this.stencilTex.id, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); glTextureParameteri(this.stencilTex.id, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTextureParameteri(this.stencilTex.id, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTextureParameteri(this.metaTex.id, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTextureParameteri(this.metaTex.id, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + 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) + .define("META_IN_BINDING", 3) + .define("BUFFER_OUT_BINDING", 4) .add(ShaderType.COMPUTE, "voxy:bakery/bufferreorder.comp") .compile() .name("ModelBakeryOut") + .texture("META_IN_BINDING", 0, this.metaTex) .texture("COLOUR_IN_BINDING", 0, this.colourTex) .texture("DEPTH_IN_BINDING", 0, this.depthTex) .texture("STENCIL_IN_BINDING", 0, this.stencilTex); @@ -62,10 +68,10 @@ public class GlViewCapture { 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 + glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 4, buffer, offset, (this.width*3L)*(this.height*2L)*4L*2);//its 2*4 because colour + depth stencil glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT|GL_TEXTURE_UPDATE_BARRIER_BIT|GL_PIXEL_BUFFER_BARRIER_BIT|GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);//Am not sure if barriers are right glDispatchCompute(3, 2, 1); - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 3, 0, 0, 4);//WHY DOES THIS FIX FUCKING BINDING ISSUES HERE WHEN DOING THIS IN THE RENDER SYSTEM DOESNT + glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 4, 0, 0, 4);//WHY DOES THIS FIX FUCKING BINDING ISSUES HERE WHEN DOING THIS IN THE RENDER SYSTEM DOESNT } public void clear() { @@ -74,6 +80,9 @@ public class GlViewCapture { MemoryUtil.memPutLong(ptr, 0); MemoryUtil.memPutLong(ptr+8, 0); nglClearNamedFramebufferfv(this.framebuffer.id, GL_COLOR, 0, ptr); + nglClearNamedFramebufferuiv(this.framebuffer.id, GL_COLOR, 1, ptr); + //TODO: fix the draw buffer thing maybe? it might need todo multiple clears + //nglClearNamedFramebufferfv(this.framebuffer.id, GL_COLOR, 0, ptr); } glClearNamedFramebufferfi(this.framebuffer.id, GL_DEPTH_STENCIL, 0, 1.0f, 0); } @@ -83,6 +92,7 @@ public class GlViewCapture { this.colourTex.free(); this.stencilTex.free(); this.depthTex.free(); + this.metaTex.free(); this.copyOutShader.free(); } } diff --git a/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java b/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java index 9168f9d6..53fbab78 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java +++ b/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java @@ -71,9 +71,7 @@ public class ModelTextureBakery { for (var part : model.getParts(new LocalRandom(42L))) { var quads = part.getQuads(direction); for (var quad : quads) { - //TODO: add meta specifiying quad has a tint - //quad.hasTint() - this.vc.quad(quad, meta); + this.vc.quad(quad, meta|(quad.hasTint()?4:0)); } } } @@ -81,6 +79,7 @@ public class ModelTextureBakery { private void bakeFluidState(BlockState state, BlockRenderLayer layer, int face) { + //TODO: somehow set the tint flag aswell this.vc.setDefaultMeta(getMetaFromLayer(layer));//Set the meta while baking MinecraftClient.getInstance().getBlockRenderManager().renderFluid(BlockPos.ORIGIN, new BlockRenderView() { @Override diff --git a/src/main/resources/assets/voxy/shaders/bakery/bufferreorder.comp b/src/main/resources/assets/voxy/shaders/bakery/bufferreorder.comp index ed83fb67..16c783ff 100644 --- a/src/main/resources/assets/voxy/shaders/bakery/bufferreorder.comp +++ b/src/main/resources/assets/voxy/shaders/bakery/bufferreorder.comp @@ -2,6 +2,7 @@ layout(local_size_x = WIDTH, local_size_y = HEIGHT) in; +layout(binding = META_IN_BINDING) uniform usampler2D metaTexIn; layout(binding = COLOUR_IN_BINDING) uniform sampler2D colourTexIn; layout(binding = DEPTH_IN_BINDING) uniform sampler2D depthTexIn; layout(binding = STENCIL_IN_BINDING) uniform usampler2D stencilTexIn; @@ -24,8 +25,11 @@ void main() { float depth = clamp(texelFetch(depthTexIn, samplePoint, 0).r, 0, 1);//Opengl grumble grumble uint stencil = texelFetch(stencilTexIn, samplePoint, 0).r; + uint metadata = texelFetch(metaTexIn, samplePoint, 0).r; uint value = uint(depth*((1<<24)-1))<<8; - value |= stencil; + value |= stencil&0xFFu; + //Use the very top bit of the stencil to mask if its tinted + value |= (metadata&1u)<<7; outPoint.y = value; outBuffer[globalOutIndex] = outPoint; diff --git a/src/main/resources/assets/voxy/shaders/bakery/position_tex.fsh b/src/main/resources/assets/voxy/shaders/bakery/position_tex.fsh index 833700e1..01721362 100644 --- a/src/main/resources/assets/voxy/shaders/bakery/position_tex.fsh +++ b/src/main/resources/assets/voxy/shaders/bakery/position_tex.fsh @@ -3,11 +3,13 @@ layout(location=0) uniform sampler2D tex; in vec2 texCoord; in flat uint metadata; -out vec4 colour; +layout(location=0) out vec4 colour; +layout(location=1) out uvec4 metaOut; void main() { colour = texture(tex, texCoord, ((~metadata>>1)&1u)*-16.0f); if (colour.a < 0.001f && ((metadata&1u)!=0)) { discard; } + metaOut = uvec4((metadata>>2)&1u);//Write if it is or isnt tinted }