diff --git a/build.gradle b/build.gradle index 2f68c914c..3f9e6b94d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.6.11' + id 'fabric-loom' version '1.9.2' id 'maven-publish' } @@ -23,7 +23,6 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - // Needed in order to load mod namespace ext.includeModule = { name -> var module = fabricApi.module(name, project.fabric_version) modImplementation(module) @@ -32,8 +31,11 @@ dependencies { includeModule("fabric-api-base") includeModule("fabric-resource-loader-v0") - includeModule("fabric-rendering-fluids-v1") includeModule("fabric-rendering-v1") + includeModule("fabric-renderer-api-v1") + includeModule("fabric-rendering-fluids-v1") + includeModule("fabric-rendering-data-attachment-v1") + includeModule("fabric-block-view-api-v2") } project.ext.lwjglVersion = "3.3.3" diff --git a/gradle.properties b/gradle.properties index 83d8ea876..1f7b34789 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,14 +4,14 @@ org.gradle.parallel=true # Fabric Properties # check these on https://fabricmc.net/develop -minecraft_version=1.21 -yarn_mappings=1.21+build.1 -loader_version=0.16.5 +minecraft_version=1.21.1 +yarn_mappings=1.21.1+build.3 +loader_version=0.16.9 # Fabric API -fabric_version=0.102.0+1.21 +fabric_version=0.114.0+1.21.1 # Mod Properties -mod_version = 0.4.8_dev +mod_version = 0.5.3-dev maven_group = net.vulkanmod -archives_base_name = VulkanMod_1.21 +archives_base_name = VulkanMod_1.21.1 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f..a4b76b953 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23a4..cea7a793a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a426..f3b75f3b0 100644 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30dbd..9d21a2183 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/src/main/java/net/vulkanmod/Initializer.java b/src/main/java/net/vulkanmod/Initializer.java index e99a46eb1..ea9360265 100644 --- a/src/main/java/net/vulkanmod/Initializer.java +++ b/src/main/java/net/vulkanmod/Initializer.java @@ -1,10 +1,12 @@ package net.vulkanmod; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.renderer.v1.RendererAccess; import net.fabricmc.loader.api.FabricLoader; import net.vulkanmod.config.Config; import net.vulkanmod.config.Platform; import net.vulkanmod.config.video.VideoModeManager; +import net.vulkanmod.render.chunk.build.frapi.VulkanModRenderer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -35,6 +37,8 @@ public void onInitializeClient() { .resolve("vulkanmod_settings.json"); CONFIG = loadConfig(configPath); + + RendererAccess.INSTANCE.registerRenderer(VulkanModRenderer.INSTANCE); } private static Config loadConfig(Path path) { diff --git a/src/main/java/net/vulkanmod/config/Config.java b/src/main/java/net/vulkanmod/config/Config.java index b265f6d58..f59034624 100644 --- a/src/main/java/net/vulkanmod/config/Config.java +++ b/src/main/java/net/vulkanmod/config/Config.java @@ -16,10 +16,10 @@ public class Config { public int frameQueueSize = 2; public VideoModeSet.VideoMode videoMode = VideoModeManager.getFirstAvailable().getVideoMode(); - public boolean windowedFullscreen = false; + public int windowMode = 0; public int advCulling = 2; - public boolean indirectDraw = false; + public boolean indirectDraw = true; public boolean uniqueOpaqueLayer = true; public boolean entityCulling = true; @@ -27,6 +27,8 @@ public class Config { public int ambientOcclusion = 1; + public boolean backFaceCulling = true; + public void write() { if(!Files.exists(CONFIG_PATH.getParent())) { diff --git a/src/main/java/net/vulkanmod/config/gui/GuiRenderer.java b/src/main/java/net/vulkanmod/config/gui/GuiRenderer.java index 7dce13097..b4b3216c1 100644 --- a/src/main/java/net/vulkanmod/config/gui/GuiRenderer.java +++ b/src/main/java/net/vulkanmod/config/gui/GuiRenderer.java @@ -20,9 +20,10 @@ public abstract class GuiRenderer { public static Font font; public static GuiGraphics guiGraphics; public static PoseStack pose; - public static BufferBuilder bufferBuilder; - public static boolean batching = false; + + private static boolean batching = false; + private static boolean drawing = false; public static void setPoseStack(PoseStack poseStack) { pose = poseStack; @@ -61,16 +62,14 @@ public static void fill(float x0, float y0, float x1, float y1, float z, int col RenderSystem.setShader(GameRenderer::getPositionColorShader); - if (!batching) - bufferBuilder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + setupBufferBuilder(); bufferBuilder.addVertex(matrix4f, x0, y0, z).setColor(r, g, b, a); bufferBuilder.addVertex(matrix4f, x0, y1, z).setColor(r, g, b, a); bufferBuilder.addVertex(matrix4f, x1, y1, z).setColor(r, g, b, a); bufferBuilder.addVertex(matrix4f, x1, y0, z).setColor(r, g, b, a); - if (!batching) - BufferUploader.drawWithShader(bufferBuilder.buildOrThrow()); + submitIfNeeded(); } public static void fillGradient(float x0, float y0, float x1, float y1, int color1, int color2) { @@ -89,18 +88,14 @@ public static void fillGradient(float x0, float y0, float x1, float y1, float z, Matrix4f matrix4f = pose.last().pose(); - RenderSystem.setShader(GameRenderer::getPositionColorShader); - - if (!batching) - bufferBuilder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + setupBufferBuilder(); bufferBuilder.addVertex(matrix4f, x0, y0, z).setColor(r1, g1, b1, a1); bufferBuilder.addVertex(matrix4f, x0, y1, z).setColor(r2, g2, b2, a2); bufferBuilder.addVertex(matrix4f, x1, y1, z).setColor(r2, g2, b2, a2); bufferBuilder.addVertex(matrix4f, x1, y0, z).setColor(r1, g1, b1, a1); - if (!batching) - BufferUploader.drawWithShader(bufferBuilder.buildOrThrow()); + submitIfNeeded(); } public static void renderBoxBorder(float x0, float y0, float width, float height, float borderWidth, int color) { @@ -147,13 +142,43 @@ public static int getMaxTextWidth(Font font, List list) { return maxWidth; } - public static void beginBatch(VertexFormat.Mode mode, VertexFormat format) { - bufferBuilder = Tesselator.getInstance().begin(mode, format); + public static void beginBatch() { batching = true; } public static void endBatch() { - BufferUploader.drawWithShader(bufferBuilder.buildOrThrow()); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + MeshData meshData = bufferBuilder.build(); + + if (meshData != null) { + BufferUploader.drawWithShader(meshData); + meshData.close(); + } + batching = false; + drawing = false; + } + + public static void flush() { + guiGraphics.flush(); + + if (batching) { + endBatch(); + } + } + + private static void setupBufferBuilder() { + if (!batching || !drawing) { + bufferBuilder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + drawing = true; + } + } + + private static void submitIfNeeded() { + if (!batching) { + RenderSystem.setShader(GameRenderer::getPositionColorShader); + BufferUploader.drawWithShader(bufferBuilder.buildOrThrow()); + drawing = false; + } } } diff --git a/src/main/java/net/vulkanmod/config/gui/VOptionList.java b/src/main/java/net/vulkanmod/config/gui/VOptionList.java index f114dee64..854f1f59a 100644 --- a/src/main/java/net/vulkanmod/config/gui/VOptionList.java +++ b/src/main/java/net/vulkanmod/config/gui/VOptionList.java @@ -272,6 +272,8 @@ protected void renderList(int mouseX, int mouseY) { rowTop += entry.getTotalHeight(); } + + GuiRenderer.flush(); } private Entry getEntry(int j) { diff --git a/src/main/java/net/vulkanmod/config/option/Options.java b/src/main/java/net/vulkanmod/config/option/Options.java index b84b7d3a2..e21141237 100644 --- a/src/main/java/net/vulkanmod/config/option/Options.java +++ b/src/main/java/net/vulkanmod/config/option/Options.java @@ -8,7 +8,9 @@ import net.vulkanmod.config.gui.OptionBlock; import net.vulkanmod.config.video.VideoModeManager; import net.vulkanmod.config.video.VideoModeSet; +import net.vulkanmod.config.video.WindowMode; import net.vulkanmod.render.chunk.build.light.LightMode; +import net.vulkanmod.render.vertex.TerrainRenderType; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.device.DeviceManager; @@ -76,19 +78,18 @@ public static OptionBlock[] getVideoOpts() { new OptionBlock("", new Option[]{ resolutionOption, RefreshRate, - new SwitchOption(Component.translatable("options.fullscreen"), + new CyclingOption<>(Component.translatable("vulkanmod.options.windowMode"), + WindowMode.values(), value -> { - minecraftOptions.fullscreen().set(value); -// window.toggleFullScreen(); - fullscreenDirty = true; - }, - () -> minecraftOptions.fullscreen().get()), - new SwitchOption(Component.translatable("vulkanmod.options.windowedFullscreen"), - value -> { - config.windowedFullscreen = value; + boolean exclusiveFullscreen = value == WindowMode.EXCLUSIVE_FULLSCREEN; + minecraftOptions.fullscreen() + .set(exclusiveFullscreen); + + config.windowMode = value.mode; fullscreenDirty = true; }, - () -> config.windowedFullscreen), + () -> WindowMode.fromValue(config.windowMode)) + .setTranslator(value -> Component.translatable(WindowMode.getComponentName(value))), new RangeOption(Component.translatable("options.framerateLimit"), 10, 260, 10, value -> Component.nullToEmpty(value == 260 ? @@ -252,10 +253,18 @@ public static OptionBlock[] getOptimizationOpts() { new SwitchOption(Component.translatable("vulkanmod.options.uniqueOpaqueLayer"), value -> { config.uniqueOpaqueLayer = value; + TerrainRenderType.updateMapping(); minecraft.levelRenderer.allChanged(); }, () -> config.uniqueOpaqueLayer) .setTooltip(Component.translatable("vulkanmod.options.uniqueOpaqueLayer.tooltip")), + new SwitchOption(Component.translatable("vulkanmod.options.backfaceCulling"), + value -> { + config.backFaceCulling = value; + Minecraft.getInstance().levelRenderer.allChanged(); + }, + () -> config.backFaceCulling) + .setTooltip(Component.translatable("vulkanmod.options.backfaceCulling.tooltip")), new SwitchOption(Component.translatable("vulkanmod.options.indirectDraw"), value -> config.indirectDraw = value, () -> config.indirectDraw) diff --git a/src/main/java/net/vulkanmod/config/video/WindowMode.java b/src/main/java/net/vulkanmod/config/video/WindowMode.java new file mode 100644 index 000000000..621f06dea --- /dev/null +++ b/src/main/java/net/vulkanmod/config/video/WindowMode.java @@ -0,0 +1,31 @@ +package net.vulkanmod.config.video; + +public enum WindowMode { + WINDOWED(0), + WINDOWED_FULLSCREEN(1), + EXCLUSIVE_FULLSCREEN(2); + + public final int mode; + + WindowMode(int mode) { + this.mode = mode; + } + + public static WindowMode fromValue(int value) { + return switch (value) { + case 0 -> WINDOWED; + case 1 -> WINDOWED_FULLSCREEN; + case 2 -> EXCLUSIVE_FULLSCREEN; + + default -> throw new IllegalStateException("Unexpected value: " + value); + }; + } + + public static String getComponentName(WindowMode windowMode) { + return switch (windowMode) { + case WINDOWED -> "vulkanmod.options.windowMode.windowed"; + case WINDOWED_FULLSCREEN -> "vulkanmod.options.windowMode.windowedFullscreen"; + case EXCLUSIVE_FULLSCREEN -> "options.fullscreen"; + }; + } +} diff --git a/src/main/java/net/vulkanmod/gl/GlFramebuffer.java b/src/main/java/net/vulkanmod/gl/GlFramebuffer.java index 0201441ec..b61995a00 100644 --- a/src/main/java/net/vulkanmod/gl/GlFramebuffer.java +++ b/src/main/java/net/vulkanmod/gl/GlFramebuffer.java @@ -7,6 +7,7 @@ import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.framebuffer.Framebuffer; import net.vulkanmod.vulkan.framebuffer.RenderPass; +import net.vulkanmod.vulkan.texture.ImageUtil; import net.vulkanmod.vulkan.texture.VulkanImage; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL30; @@ -15,46 +16,42 @@ import static org.lwjgl.vulkan.VK11.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; public class GlFramebuffer { - private static int ID_COUNTER = 1; + private static int idCounter = 1; + private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); - private static int boundId = 0; private static GlFramebuffer boundFramebuffer; + private static GlFramebuffer readFramebuffer; public static void resetBoundFramebuffer() { boundFramebuffer = null; - boundId = 0; } public static void beginRendering(GlFramebuffer glFramebuffer) { - Renderer.getInstance().beginRendering(glFramebuffer.renderPass, glFramebuffer.framebuffer); + boolean begunRendering = glFramebuffer.beginRendering(); - Framebuffer framebuffer = glFramebuffer.framebuffer; - int viewWidth = framebuffer.getWidth(); - int viewHeight = framebuffer.getHeight(); + if (begunRendering) { + Framebuffer framebuffer = glFramebuffer.framebuffer; + int viewWidth = framebuffer.getWidth(); + int viewHeight = framebuffer.getHeight(); - Renderer.setInvertedViewport(0, 0, viewWidth, viewHeight); - Renderer.setScissor(0, 0, viewWidth, viewHeight); + Renderer.setInvertedViewport(0, 0, viewWidth, viewHeight); + Renderer.setScissor(0, 0, viewWidth, viewHeight); - // TODO: invert cull instead of disabling - VRenderSystem.disableCull(); + // TODO: invert cull instead of disabling + VRenderSystem.disableCull(); + } - boundId = glFramebuffer.id; + boundFramebuffer = glFramebuffer; } public static int genFramebufferId() { - int id = ID_COUNTER; + int id = idCounter; map.put(id, new GlFramebuffer(id)); - ID_COUNTER++; + idCounter++; return id; } public static void bindFramebuffer(int target, int id) { - // target - // 36160 GL_FRAMEBUFFER - // 36161 GL_RENDERBUFFER - - if (boundId == id) - return; if (id == 0) { Renderer.getInstance().endRenderPass(); @@ -65,7 +62,6 @@ public static void bindFramebuffer(int target, int id) { } boundFramebuffer = null; - boundId = 0; return; } @@ -74,11 +70,19 @@ public static void bindFramebuffer(int target, int id) { if (glFramebuffer == null) throw new NullPointerException("No Framebuffer with ID: %d ".formatted(id)); - if (glFramebuffer.framebuffer != null) { - beginRendering(glFramebuffer); + switch (target) { + case GL30.GL_DRAW_FRAMEBUFFER , GL30.GL_FRAMEBUFFER -> { + if (glFramebuffer.framebuffer != null) { + beginRendering(glFramebuffer); + } + + boundFramebuffer = glFramebuffer; + } + case GL30.GL_READ_FRAMEBUFFER -> { + readFramebuffer = glFramebuffer; + } } - boundFramebuffer = glFramebuffer; } public static void deleteFramebuffer(int id) { @@ -91,7 +95,7 @@ public static void deleteFramebuffer(int id) { if (boundFramebuffer == null) throw new NullPointerException("bound framebuffer is null"); - boundFramebuffer.cleanUp(); + boundFramebuffer.cleanUp(true); boundFramebuffer = null; } @@ -116,6 +120,11 @@ public static void framebufferRenderbuffer(int target, int attachment, int rende boundFramebuffer.setAttachmentRenderbuffer(attachment, renderbuffer); } + public static void glBlitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) { + // TODO: add missing parameters + ImageUtil.blitFramebuffer(boundFramebuffer.colorAttachment, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1); + } + public static int glCheckFramebufferStatus(int target) { //TODO return GL30.GL_FRAMEBUFFER_COMPLETE; @@ -154,9 +163,8 @@ void setAttachmentTexture(int attachment, int texture) { return; switch (attachment) { - case (GL30.GL_COLOR_ATTACHMENT0) -> this.setColorAttachment(glTexture); - - case (GL30.GL_DEPTH_ATTACHMENT) -> this.setDepthAttachment(glTexture); + case (GL30.GL_COLOR_ATTACHMENT0) -> this.setColorAttachment(glTexture.getVulkanImage()); + case (GL30.GL_DEPTH_ATTACHMENT) -> this.setDepthAttachment(glTexture.getVulkanImage()); default -> throw new IllegalStateException("Unexpected value: " + attachment); } @@ -172,33 +180,21 @@ void setAttachmentRenderbuffer(int attachment, int texture) { return; switch (attachment) { - case (GL30.GL_COLOR_ATTACHMENT0) -> this.setColorAttachment(renderbuffer); - - case (GL30.GL_DEPTH_ATTACHMENT) -> this.setDepthAttachment(renderbuffer); + case (GL30.GL_COLOR_ATTACHMENT0) -> this.setColorAttachment(renderbuffer.getVulkanImage()); + case (GL30.GL_DEPTH_ATTACHMENT) -> this.setDepthAttachment(renderbuffer.getVulkanImage()); default -> throw new IllegalStateException("Unexpected value: " + attachment); } } - void setColorAttachment(GlTexture texture) { - this.colorAttachment = texture.vulkanImage; - createAndBind(); - } - - void setDepthAttachment(GlTexture texture) { - //TODO check if texture is in depth format - this.depthAttachment = texture.vulkanImage; - createAndBind(); - } - - void setColorAttachment(GlRenderbuffer texture) { - this.colorAttachment = texture.vulkanImage; + void setColorAttachment(VulkanImage image) { + this.colorAttachment = image; createAndBind(); } - void setDepthAttachment(GlRenderbuffer texture) { + void setDepthAttachment(VulkanImage image) { //TODO check if texture is in depth format - this.depthAttachment = texture.vulkanImage; + this.depthAttachment = image; createAndBind(); } @@ -208,7 +204,7 @@ void createAndBind() { return; if (this.framebuffer != null) { - this.cleanUp(); + this.cleanUp(false); } boolean hasDepthImage = this.depthAttachment != null; @@ -237,8 +233,8 @@ public RenderPass getRenderPass() { return renderPass; } - void cleanUp() { - this.framebuffer.cleanUp(false); + void cleanUp(boolean freeAttachments) { + this.framebuffer.cleanUp(freeAttachments); this.renderPass.cleanUp(); this.framebuffer = null; diff --git a/src/main/java/net/vulkanmod/gl/GlTexture.java b/src/main/java/net/vulkanmod/gl/GlTexture.java index 4658fbc70..ae7f2be19 100644 --- a/src/main/java/net/vulkanmod/gl/GlTexture.java +++ b/src/main/java/net/vulkanmod/gl/GlTexture.java @@ -23,6 +23,10 @@ public class GlTexture { private static GlTexture boundTexture; private static int activeTexture = 0; + private static int unpackRowLength; + private static int unpackSkipRows; + private static int unpackSkipPixels; + public static void bindIdToImage(int id, VulkanImage vulkanImage) { GlTexture texture = map.get(id); texture.vulkanImage = vulkanImage; @@ -79,7 +83,9 @@ public static void texImage2D(int target, int level, int internalFormat, int wid if (checkParams(level, width, height)) return; - boundTexture.allocateIfNeeded(width, height, internalFormat, type); + boundTexture.updateParams(level, width, height, internalFormat, type); + boundTexture.allocateIfNeeded(); + VTextureSelector.bindTexture(activeTexture, boundTexture.vulkanImage); texSubImage2D(target, level, 0, 0, width, height, format, type, pixels); @@ -89,7 +95,9 @@ public static void texImage2D(int target, int level, int internalFormat, int wid if (checkParams(level, width, height)) return; - boundTexture.allocateIfNeeded(width, height, internalFormat, type); + boundTexture.updateParams(level, width, height, internalFormat, type); + boundTexture.allocateIfNeeded(); + VTextureSelector.bindTexture(activeTexture, boundTexture.vulkanImage); texSubImage2D(target, level, 0, 0, width, height, format, type, pixels); @@ -99,11 +107,6 @@ private static boolean checkParams(int level, int width, int height) { if (width == 0 || height == 0) return true; - // TODO: levels - if (level != 0) { -// throw new UnsupportedOperationException(); - return true; - } return false; } @@ -127,14 +130,16 @@ public static void texSubImage2D(int target, int level, int xOffset, int yOffset } if (src != null) - boundTexture.uploadSubImage(xOffset, yOffset, width, height, format, src); + boundTexture.uploadSubImage(level, xOffset, yOffset, width, height, format, src); } private static ByteBuffer getByteBuffer(int width, int height, long pixels) { ByteBuffer src; // TODO: hardcoded format size int formatSize = 4; - src = MemoryUtil.memByteBuffer(pixels, width * height * formatSize); + int rowLength = unpackRowLength != 0 ? unpackRowLength : width; + int offset = (unpackSkipRows * rowLength + unpackSkipPixels) * formatSize; + src = MemoryUtil.memByteBuffer(pixels + offset, (rowLength * height - unpackSkipPixels) * formatSize); return src; } @@ -157,13 +162,16 @@ public static void texSubImage2D(int target, int level, int xOffset, int yOffset } if (src != null) - boundTexture.uploadSubImage(xOffset, yOffset, width, height, format, src); + boundTexture.uploadSubImage(level, xOffset, yOffset, width, height, format, src); } public static void texParameteri(int target, int pName, int param) { if (target != GL11.GL_TEXTURE_2D) throw new UnsupportedOperationException("target != GL_TEXTURE_2D not supported"); + if (boundTexture == null) + return; + switch (pName) { case GL30.GL_TEXTURE_MAX_LEVEL -> boundTexture.setMaxLevel(param); case GL30.GL_TEXTURE_MAX_LOD -> boundTexture.setMaxLod(param); @@ -197,6 +205,14 @@ public static int getTexLevelParameter(int target, int level, int pName) { }; } + public static void pixelStoreI(int pName, int value) { + switch (pName) { + case GL11.GL_UNPACK_ROW_LENGTH -> unpackRowLength = value; + case GL11.GL_UNPACK_SKIP_ROWS -> unpackSkipRows = value; + case GL11.GL_UNPACK_SKIP_PIXELS -> unpackSkipPixels = value; + } + } + public static void generateMipmap(int target) { if (target != GL11.GL_TEXTURE_2D) throw new UnsupportedOperationException("target != GL_TEXTURE_2D not supported"); @@ -234,7 +250,9 @@ public static GlTexture getBoundTexture() { final int id; VulkanImage vulkanImage; - int internalFormat; + + int width, height; + int vkFormat; boolean needsUpdate = false; int maxLevel = 0; @@ -247,14 +265,27 @@ public GlTexture(int id) { this.id = id; } - void allocateIfNeeded(int width, int height, int internalFormat, int type) { - this.internalFormat = internalFormat; - int vkFormat = GlUtil.vulkanFormat(internalFormat, type); + void updateParams(int level, int width, int height, int internalFormat, int type) { + if (level > this.maxLevel) { + this.maxLevel = level; + + this.needsUpdate = true; + } + + if (level == 0) { + int vkFormat = GlUtil.vulkanFormat(internalFormat, type); - needsUpdate |= vulkanImage == null || - vulkanImage.width != width || vulkanImage.height != height || - vkFormat != vulkanImage.format; + if (this.vulkanImage == null || this.width != width || this.height != height || vkFormat != vulkanImage.format) { + this.width = width; + this.height = height; + this.vkFormat = vkFormat; + this.needsUpdate = true; + } + } + } + + void allocateIfNeeded() { if (needsUpdate) { allocateImage(width, height, vkFormat); updateSampler(); @@ -267,17 +298,19 @@ void allocateImage(int width, int height, int vkFormat) { if (this.vulkanImage != null) this.vulkanImage.free(); - if (VulkanImage.isDepthFormat(vkFormat)) - this.vulkanImage = VulkanImage.createDepthImage(vkFormat, - width, height, + if (VulkanImage.isDepthFormat(vkFormat)) { + this.vulkanImage = VulkanImage.createDepthImage( + vkFormat, width, height, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, false, true); - else + } + else { this.vulkanImage = new VulkanImage.Builder(width, height) .setMipLevels(maxLevel + 1) .setFormat(vkFormat) .addUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) .createVulkanImage(); + } } void updateSampler() { @@ -297,7 +330,7 @@ void updateSampler() { vulkanImage.updateTextureSampler(maxLod, samplerFlags); } - private void uploadSubImage(int xOffset, int yOffset, int width, int height, int format, ByteBuffer pixels) { + private void uploadSubImage(int level, int xOffset, int yOffset, int width, int height, int format, ByteBuffer pixels) { ByteBuffer src; if (format == GL11.GL_RGB && vulkanImage.format == VK_FORMAT_R8G8B8A8_UNORM) { src = GlUtil.RGBtoRGBA_buffer(pixels); @@ -307,7 +340,7 @@ private void uploadSubImage(int xOffset, int yOffset, int width, int height, int src = pixels; } - this.vulkanImage.uploadSubTextureAsync(0, width, height, xOffset, yOffset, 0, 0, 0, src); + this.vulkanImage.uploadSubTextureAsync(level, width, height, xOffset, yOffset, 0, 0, unpackRowLength, src); if (src != pixels) { MemoryUtil.memFree(src); diff --git a/src/main/java/net/vulkanmod/interfaces/ExtendedRenderTarget.java b/src/main/java/net/vulkanmod/interfaces/ExtendedRenderTarget.java deleted file mode 100644 index f5da47f6d..000000000 --- a/src/main/java/net/vulkanmod/interfaces/ExtendedRenderTarget.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.vulkanmod.interfaces; - -import net.vulkanmod.vulkan.framebuffer.RenderPass; - -public interface ExtendedRenderTarget { - - boolean isBound(); - - RenderPass getRenderPass(); -} diff --git a/src/main/java/net/vulkanmod/interfaces/ShaderMixed.java b/src/main/java/net/vulkanmod/interfaces/ShaderMixed.java index e1676144f..e05a698d4 100644 --- a/src/main/java/net/vulkanmod/interfaces/ShaderMixed.java +++ b/src/main/java/net/vulkanmod/interfaces/ShaderMixed.java @@ -1,8 +1,25 @@ package net.vulkanmod.interfaces; +import net.minecraft.client.renderer.ShaderInstance; import net.vulkanmod.vulkan.shader.GraphicsPipeline; +import net.vulkanmod.vulkan.shader.descriptor.UBO; +import net.vulkanmod.vulkan.util.MappedBuffer; + +import java.util.function.Supplier; public interface ShaderMixed { + static ShaderMixed of(ShaderInstance compiledShaderProgram) { + return (ShaderMixed) compiledShaderProgram; + } + + void setPipeline(GraphicsPipeline graphicsPipeline); + GraphicsPipeline getPipeline(); + + void setupUniformSuppliers(UBO ubo); + + Supplier getUniformSupplier(String name); + + void setDoUniformsUpdate(); } diff --git a/src/main/java/net/vulkanmod/interfaces/biome/BiomeManagerExtended.java b/src/main/java/net/vulkanmod/interfaces/biome/BiomeManagerExtended.java new file mode 100644 index 000000000..6cb365021 --- /dev/null +++ b/src/main/java/net/vulkanmod/interfaces/biome/BiomeManagerExtended.java @@ -0,0 +1,13 @@ +package net.vulkanmod.interfaces.biome; + +import net.minecraft.world.level.biome.BiomeManager; + +public interface BiomeManagerExtended { + + static BiomeManagerExtended of(BiomeManager biomeManager) { + return (BiomeManagerExtended) biomeManager; + } + + long getBiomeZoomSeed(); + +} diff --git a/src/main/java/net/vulkanmod/interfaces/color/BlockColorsExtended.java b/src/main/java/net/vulkanmod/interfaces/color/BlockColorsExtended.java new file mode 100644 index 000000000..69579509e --- /dev/null +++ b/src/main/java/net/vulkanmod/interfaces/color/BlockColorsExtended.java @@ -0,0 +1,13 @@ +package net.vulkanmod.interfaces.color; + +import net.minecraft.client.color.block.BlockColors; +import net.vulkanmod.render.chunk.build.color.BlockColorRegistry; + +public interface BlockColorsExtended { + + static BlockColorsExtended from(BlockColors blockColors) { + return (BlockColorsExtended) blockColors; + } + + BlockColorRegistry getColorResolverMap(); +} diff --git a/src/main/java/net/vulkanmod/mixin/chunk/RenderBuffersM.java b/src/main/java/net/vulkanmod/mixin/chunk/RenderBuffersM.java deleted file mode 100644 index 743885028..000000000 --- a/src/main/java/net/vulkanmod/mixin/chunk/RenderBuffersM.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.vulkanmod.mixin.chunk; - -import net.minecraft.client.renderer.RenderBuffers; -import net.minecraft.client.renderer.SectionBufferBuilderPool; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(RenderBuffers.class) -public class RenderBuffersM { - - @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/SectionBufferBuilderPool;allocate(I)Lnet/minecraft/client/renderer/SectionBufferBuilderPool;")) - private SectionBufferBuilderPool red2(int i) { - return null; - } -} diff --git a/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java b/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java new file mode 100644 index 000000000..18e653849 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java @@ -0,0 +1,15 @@ +package net.vulkanmod.mixin.chunk; + +import net.minecraft.client.renderer.SectionBufferBuilderPool; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@Mixin(SectionBufferBuilderPool.class) +public class SectionBufferBuilderPoolM { + + @ModifyVariable(method = "allocate", at = @At("STORE"), ordinal = 1) + private static int skipAllocation(int value) { + return 0; + } +} diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/EffectInstanceM.java b/src/main/java/net/vulkanmod/mixin/compatibility/EffectInstanceM.java index 1e3d2827b..a38d9d62f 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/EffectInstanceM.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/EffectInstanceM.java @@ -17,15 +17,12 @@ import net.vulkanmod.vulkan.shader.Pipeline; import net.vulkanmod.vulkan.shader.layout.Uniform; import net.vulkanmod.vulkan.shader.descriptor.UBO; -import net.vulkanmod.vulkan.shader.parser.GlslConverter; +import net.vulkanmod.vulkan.shader.converter.GlslConverter; import net.vulkanmod.vulkan.util.MappedBuffer; import org.apache.commons.io.IOUtils; import org.lwjgl.opengl.GL30; import org.lwjgl.system.MemoryUtil; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; @@ -38,7 +35,6 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.function.IntSupplier; @@ -60,9 +56,9 @@ public class EffectInstanceM { @Shadow @Final private Map samplerMap; @Shadow @Final private String name; - private static GraphicsPipeline lastPipeline; - private GraphicsPipeline pipeline; + @Unique private static GraphicsPipeline lastPipeline; + @Unique private GraphicsPipeline pipeline; @Inject(method = "", at = @At(value = "INVOKE", @@ -86,13 +82,11 @@ private EffectProgram redirectShader(ResourceProvider resourceProvider, Program. */ @Overwrite public void close() { - for (com.mojang.blaze3d.shaders.Uniform uniform : this.uniforms) { uniform.close(); } - //TODO -// ProgramManager.releaseProgram(this); + this.pipeline.scheduleCleanUp(); } private void createShaders(ResourceProvider resourceManager, String vertexShader, String fragShader) { @@ -110,14 +104,13 @@ private void createShaders(ResourceProvider resourceManager, String vertexShader inputStream = resource.open(); String fshSrc = IOUtils.toString(inputStream, StandardCharsets.UTF_8); - //TODO GlslConverter converter = new GlslConverter(); converter.process(vshSrc, fshSrc); - UBO ubo = converter.getUBO(); + UBO ubo = converter.createUBO(); this.setUniformSuppliers(ubo); - Pipeline.Builder builder = new Pipeline.Builder(DefaultVertexFormat.POSITION); + Pipeline.Builder builder = new Pipeline.Builder(DefaultVertexFormat.POSITION, this.name); builder.setUniforms(Collections.singletonList(ubo), converter.getSamplerList()); builder.compileShaders(this.name, converter.getVshConverted(), converter.getFshConverted()); diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java index 3328002fc..369eba7c9 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java @@ -1,15 +1,14 @@ package net.vulkanmod.mixin.compatibility.gl; import net.vulkanmod.gl.GlTexture; +import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11C; import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.NativeType; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; import org.jetbrains.annotations.Nullable; import java.nio.ByteBuffer; @@ -24,6 +23,16 @@ public class GL11M { */ @Overwrite(remap = false) public static void glScissor(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height) { + Renderer.setScissor(x, y, width, height); + } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glViewport(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int w, @NativeType("GLsizei") int h) { + Renderer.setViewport(x, y, w, h); } /** @@ -61,7 +70,7 @@ public static int glGenTextures() { @NativeType("GLboolean") @Overwrite(remap = false) public static boolean glIsEnabled(@NativeType("GLenum") int cap) { - return false; + return true; } /** @@ -183,6 +192,15 @@ public static int glGetTexLevelParameteri(@NativeType("GLenum") int target, @Nat return GlTexture.getTexLevelParameter(target, level, pname); } + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glPixelStorei(@NativeType("GLenum") int pname, @NativeType("GLint") int param) { + GlTexture.pixelStoreI(pname, param); + } + /** * @author * @reason @@ -269,4 +287,13 @@ public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLi public static void glCopyTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height) { // TODO } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glBlendFunc(@NativeType("GLenum") int sfactor, @NativeType("GLenum") int dfactor) { + // TODO + } } diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL30M.java b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL30M.java index 1a34e6bb9..fc4a2ce07 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL30M.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL30M.java @@ -4,6 +4,7 @@ import net.vulkanmod.gl.GlRenderbuffer; import net.vulkanmod.gl.GlTexture; import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL30C; import org.lwjgl.system.NativeType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -76,6 +77,15 @@ public static int glCheckFramebufferStatus(@NativeType("GLenum") int target) { return GlFramebuffer.glCheckFramebufferStatus(target); } + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glBlitFramebuffer(@NativeType("GLint") int srcX0, @NativeType("GLint") int srcY0, @NativeType("GLint") int srcX1, @NativeType("GLint") int srcY1, @NativeType("GLint") int dstX0, @NativeType("GLint") int dstY0, @NativeType("GLint") int dstX1, @NativeType("GLint") int dstY1, @NativeType("GLbitfield") int mask, @NativeType("GLenum") int filter) { + GlFramebuffer.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + } + //RENDER BUFFER /** diff --git a/src/main/java/net/vulkanmod/mixin/matrix/PoseAccessor.java b/src/main/java/net/vulkanmod/mixin/matrix/PoseAccessor.java new file mode 100644 index 000000000..cc2acf61a --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/matrix/PoseAccessor.java @@ -0,0 +1,12 @@ +package net.vulkanmod.mixin.matrix; + +import com.mojang.blaze3d.vertex.PoseStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(PoseStack.Pose.class) +public interface PoseAccessor { + + @Accessor("trustedNormals") + boolean trustedNormals(); +} diff --git a/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java b/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java index 232c0a436..a381125a6 100644 --- a/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java +++ b/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java @@ -56,7 +56,8 @@ public static void drawWithShader(MeshData meshData) { renderer.bindGraphicsPipeline(pipeline); VTextureSelector.bindShaderTextures(pipeline); renderer.uploadAndBindUBOs(pipeline); - Renderer.getDrawer().draw(meshData.vertexBuffer(), parameters.mode(), parameters.format(), parameters.vertexCount()); + + Renderer.getDrawer().draw(meshData.vertexBuffer(), meshData.indexBuffer(), parameters.mode(), parameters.format(), parameters.vertexCount()); } meshData.close(); @@ -74,7 +75,7 @@ public static void draw(MeshData meshData) { Pipeline pipeline = renderer.getBoundPipeline(); renderer.uploadAndBindUBOs(pipeline); - Renderer.getDrawer().draw(meshData.vertexBuffer(), parameters.mode(), parameters.format(), parameters.vertexCount()); + Renderer.getDrawer().draw(meshData.vertexBuffer(), null, parameters.mode(), parameters.format(), parameters.vertexCount()); } meshData.close(); diff --git a/src/main/java/net/vulkanmod/mixin/render/GameRendererMixin.java b/src/main/java/net/vulkanmod/mixin/render/GameRendererMixin.java index 63cc0fa94..d516895d6 100644 --- a/src/main/java/net/vulkanmod/mixin/render/GameRendererMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/GameRendererMixin.java @@ -1,14 +1,9 @@ package net.vulkanmod.mixin.render; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.mojang.blaze3d.shaders.Program; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; -import com.mojang.datafixers.util.Pair; -import net.fabricmc.fabric.api.client.rendering.v1.CoreShaderRegistrationCallback; -import net.fabricmc.fabric.impl.client.rendering.FabricShaderProgram; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.ShaderInstance; import net.minecraft.server.packs.resources.ResourceProvider; @@ -18,14 +13,9 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.io.IOException; -import java.util.List; import java.util.Map; -import java.util.function.Consumer; @Mixin(GameRenderer.class) public abstract class GameRendererMixin { @@ -36,61 +26,9 @@ public abstract class GameRendererMixin { @Shadow private @Nullable static ShaderInstance positionColorShader; @Shadow private @Nullable static ShaderInstance positionTexShader; @Shadow private @Nullable static ShaderInstance positionTexColorShader; - @Shadow private @Nullable static ShaderInstance particleShader; - @Shadow private @Nullable static ShaderInstance rendertypeSolidShader; - @Shadow private @Nullable static ShaderInstance rendertypeCutoutMippedShader; - @Shadow private @Nullable static ShaderInstance rendertypeCutoutShader; - @Shadow private @Nullable static ShaderInstance rendertypeTranslucentShader; - @Shadow private @Nullable static ShaderInstance rendertypeTranslucentMovingBlockShader; - @Shadow private @Nullable static ShaderInstance rendertypeArmorCutoutNoCullShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntitySolidShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityCutoutShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityCutoutNoCullShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityCutoutNoCullZOffsetShader; - @Shadow private @Nullable static ShaderInstance rendertypeItemEntityTranslucentCullShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityTranslucentCullShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityTranslucentShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityTranslucentEmissiveShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntitySmoothCutoutShader; - @Shadow private @Nullable static ShaderInstance rendertypeBeaconBeamShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityDecalShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityNoOutlineShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityShadowShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityAlphaShader; - @Shadow private @Nullable static ShaderInstance rendertypeEyesShader; - @Shadow private @Nullable static ShaderInstance rendertypeEnergySwirlShader; - @Shadow private @Nullable static ShaderInstance rendertypeLeashShader; - @Shadow private @Nullable static ShaderInstance rendertypeWaterMaskShader; - @Shadow private @Nullable static ShaderInstance rendertypeOutlineShader; - @Shadow private @Nullable static ShaderInstance rendertypeArmorGlintShader; - @Shadow private @Nullable static ShaderInstance rendertypeArmorEntityGlintShader; - @Shadow private @Nullable static ShaderInstance rendertypeGlintTranslucentShader; - @Shadow private @Nullable static ShaderInstance rendertypeGlintShader; - @Shadow private @Nullable static ShaderInstance rendertypeGlintDirectShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityGlintShader; - @Shadow private @Nullable static ShaderInstance rendertypeEntityGlintDirectShader; @Shadow private @Nullable static ShaderInstance rendertypeTextShader; - @Shadow private @Nullable static ShaderInstance rendertypeTextIntensityShader; - @Shadow private @Nullable static ShaderInstance rendertypeTextSeeThroughShader; - @Shadow private @Nullable static ShaderInstance rendertypeTextIntensitySeeThroughShader; - @Shadow private @Nullable static ShaderInstance rendertypeLightningShader; - @Shadow private @Nullable static ShaderInstance rendertypeTripwireShader; - @Shadow private @Nullable static ShaderInstance rendertypeEndPortalShader; - @Shadow private @Nullable static ShaderInstance rendertypeEndGatewayShader; - @Shadow private @Nullable static ShaderInstance rendertypeLinesShader; - @Shadow private @Nullable static ShaderInstance rendertypeCrumblingShader; - @Shadow private static @Nullable ShaderInstance rendertypeBreezeWindShader; - @Shadow private static @Nullable ShaderInstance rendertypeCloudsShader; - - @Shadow private static @Nullable ShaderInstance rendertypeTextBackgroundShader; - @Shadow private static @Nullable ShaderInstance rendertypeTextBackgroundSeeThroughShader; @Shadow private static @Nullable ShaderInstance rendertypeGuiShader; @Shadow private static @Nullable ShaderInstance rendertypeGuiOverlayShader; - @Shadow private static @Nullable ShaderInstance rendertypeGuiTextHighlightShader; - @Shadow private static @Nullable ShaderInstance rendertypeGuiGhostRecipeOverlayShader; - - @Shadow private @Nullable static ShaderInstance positionColorLightmapShader; - @Shadow private @Nullable static ShaderInstance positionColorTexLightmapShader; @Shadow public ShaderInstance blitShader; @@ -98,228 +36,6 @@ public abstract class GameRendererMixin { @Shadow public abstract float getRenderDistance(); - @Shadow protected abstract void loadBlurEffect(ResourceProvider resourceProvider); - - @Inject(method = "reloadShaders", at = @At("HEAD"), cancellable = true) - public void reloadShaders(ResourceProvider provider, CallbackInfo ci) { - RenderSystem.assertOnRenderThread(); - - List>> pairs = Lists.newArrayListWithCapacity(this.shaders.size()); - - try { - pairs.add( - Pair.of(new ShaderInstance(provider, "particle", DefaultVertexFormat.PARTICLE), - (shaderInstance) -> particleShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "position", DefaultVertexFormat.POSITION), - (shaderInstance) -> positionShader = shaderInstance)); - - ShaderInstance positionColor = new ShaderInstance(provider, "position_color", DefaultVertexFormat.POSITION_COLOR); - pairs.add( - Pair.of( - positionColor, - (shaderInstance) -> positionColorShader = shaderInstance)); - - // These aren't used -// pairs.add( -// Pair.of(new ShaderInstance(provider, "position_color_lightmap", DefaultVertexFormat.POSITION_COLOR_LIGHTMAP), -// (shaderInstance) -> positionColorLightmapShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "position_color_tex_lightmap", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), - (shaderInstance) -> positionColorTexLightmapShader = shaderInstance)); - - pairs.add( - Pair.of(new ShaderInstance(provider, "position_tex", DefaultVertexFormat.POSITION_TEX), - (shaderInstance) -> positionTexShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "position_tex_color", DefaultVertexFormat.POSITION_TEX_COLOR), - (shaderInstance) -> positionTexColorShader = shaderInstance)); -// pairs.add( -// Pair.of(new ShaderInstance(provider, "position_tex_lightmap_color", DefaultVertexFormat.POSITION_TEX_LIGHTMAP_COLOR), -// (shaderInstance) -> positionTexLightmapColorShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_solid", DefaultVertexFormat.BLOCK), - (shaderInstance) -> rendertypeSolidShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_cutout_mipped", DefaultVertexFormat.BLOCK), - (shaderInstance) -> rendertypeCutoutMippedShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_cutout", DefaultVertexFormat.BLOCK), - (shaderInstance) -> rendertypeCutoutShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_translucent", DefaultVertexFormat.BLOCK), - (shaderInstance) -> rendertypeTranslucentShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_translucent_moving_block", DefaultVertexFormat.BLOCK), - (shaderInstance) -> rendertypeTranslucentMovingBlockShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_armor_cutout_no_cull", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeArmorCutoutNoCullShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_solid", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEntitySolidShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_cutout", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEntityCutoutShader = shaderInstance)); - - // No diff in these shaders - ShaderInstance entity_no_cull = new ShaderInstance(provider, "rendertype_entity_cutout_no_cull", DefaultVertexFormat.NEW_ENTITY); - pairs.add( - Pair.of(entity_no_cull, - (shaderInstance) -> rendertypeEntityCutoutNoCullShader = shaderInstance)); - pairs.add( - Pair.of(entity_no_cull, - (shaderInstance) -> rendertypeEntityCutoutNoCullZOffsetShader = shaderInstance)); - - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_item_entity_translucent_cull", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeItemEntityTranslucentCullShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_translucent_cull", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEntityTranslucentCullShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_translucent", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEntityTranslucentShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_translucent_emissive", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEntityTranslucentEmissiveShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_smooth_cutout", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEntitySmoothCutoutShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_beacon_beam", DefaultVertexFormat.BLOCK), - (shaderInstance) -> rendertypeBeaconBeamShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_decal", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEntityDecalShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_no_outline", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEntityNoOutlineShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_shadow", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEntityShadowShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_alpha", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEntityAlphaShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_eyes", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEyesShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_energy_swirl", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeEnergySwirlShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_leash", DefaultVertexFormat.POSITION_COLOR_LIGHTMAP), - (shaderInstance) -> rendertypeLeashShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_water_mask", DefaultVertexFormat.POSITION), - (shaderInstance) -> rendertypeWaterMaskShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_outline", DefaultVertexFormat.POSITION_TEX_COLOR), - (shaderInstance) -> rendertypeOutlineShader = shaderInstance)); -// pairs.add(Pair.of(new ShaderInstance(provider, "rendertype_armor_glint", DefaultVertexFormat.POSITION_TEX), (shaderInstance) -> { -// rendertypeArmorGlintShader = shaderInstance; -// })); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_armor_entity_glint", DefaultVertexFormat.POSITION_TEX), - (shaderInstance) -> rendertypeArmorEntityGlintShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_glint_translucent", DefaultVertexFormat.POSITION_TEX), - (shaderInstance) -> rendertypeGlintTranslucentShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_glint", DefaultVertexFormat.POSITION_TEX), - (shaderInstance) -> rendertypeGlintShader = shaderInstance)); -// pairs.add(Pair.of(new ShaderInstance(provider, "rendertype_glint_direct", DefaultVertexFormat.POSITION_TEX), (shaderInstance) -> { -// rendertypeGlintDirectShader = shaderInstance; -// })); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_glint", DefaultVertexFormat.POSITION_TEX), - (shaderInstance) -> rendertypeEntityGlintShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_entity_glint_direct", DefaultVertexFormat.POSITION_TEX), - (shaderInstance) -> rendertypeEntityGlintDirectShader = shaderInstance)); - - //Text - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_text", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), - (shaderInstance) -> rendertypeTextShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_text_background", DefaultVertexFormat.POSITION_COLOR_LIGHTMAP), - (shaderInstance) -> rendertypeTextBackgroundShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_text_intensity", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), - (shaderInstance) -> rendertypeTextIntensityShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_text_see_through", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), - (shaderInstance) -> rendertypeTextSeeThroughShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_text_background_see_through", DefaultVertexFormat.POSITION_COLOR_LIGHTMAP), - (shaderInstance) -> rendertypeTextBackgroundSeeThroughShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_text_intensity_see_through", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), - (shaderInstance) -> rendertypeTextIntensitySeeThroughShader = shaderInstance)); - - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_lightning", DefaultVertexFormat.POSITION_COLOR), - (shaderInstance) -> rendertypeLightningShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_tripwire", DefaultVertexFormat.BLOCK), - (shaderInstance) -> rendertypeTripwireShader = shaderInstance)); - ShaderInstance endPortalShader = new ShaderInstance(provider, "rendertype_end_portal", DefaultVertexFormat.POSITION); - pairs.add( - Pair.of(endPortalShader, - (shaderInstance) -> rendertypeEndPortalShader = shaderInstance)); - pairs.add( - Pair.of(endPortalShader, - (shaderInstance) -> rendertypeEndGatewayShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_clouds", DefaultVertexFormat.POSITION_TEX_COLOR_NORMAL), - (shaderInstance) -> rendertypeCloudsShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_lines", DefaultVertexFormat.POSITION_COLOR_NORMAL), - (shaderInstance) -> rendertypeLinesShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_crumbling", DefaultVertexFormat.BLOCK), - (shaderInstance) -> rendertypeCrumblingShader = shaderInstance)); - - pairs.add( - Pair.of(positionColor, - (shaderInstance) -> rendertypeGuiShader = shaderInstance)); - pairs.add( - Pair.of(positionColor, - (shaderInstance) -> rendertypeGuiOverlayShader = shaderInstance)); - pairs.add( - Pair.of(positionColor, - (shaderInstance) -> rendertypeGuiTextHighlightShader = shaderInstance)); - pairs.add( - Pair.of(positionColor, - (shaderInstance) -> rendertypeGuiGhostRecipeOverlayShader = shaderInstance)); - pairs.add( - Pair.of(new ShaderInstance(provider, "rendertype_energy_swirl", DefaultVertexFormat.NEW_ENTITY), - (shaderInstance) -> rendertypeBreezeWindShader = shaderInstance)); - - // FRAPI shader loading - CoreShaderRegistrationCallback.RegistrationContext context = (id, vertexFormat, loadCallback) -> { - ShaderInstance program = new FabricShaderProgram(provider, id, vertexFormat); - pairs.add(Pair.of(program, loadCallback)); - }; - CoreShaderRegistrationCallback.EVENT.invoker().registerShaders(context); - - this.loadBlurEffect(provider); - } catch (IOException ioexception) { - pairs.forEach((pair) -> pair.getFirst().close()); - throw new RuntimeException("could not reload shaders", ioexception); - } - - this.shutdownShaders(); - pairs.forEach((pair) -> { - ShaderInstance shaderinstance = pair.getFirst(); - this.shaders.put(shaderinstance.getName(), shaderinstance); - pair.getSecond().accept(shaderinstance); - }); - - ci.cancel(); - } - /** * @author * @reason diff --git a/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java b/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java index 59fcef1d3..594a3cfaf 100644 --- a/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java +++ b/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java @@ -9,10 +9,11 @@ import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; import org.jetbrains.annotations.Nullable; -import org.lwjgl.opengl.GL20; import org.lwjgl.system.MemoryUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; import java.nio.ByteBuffer; import java.nio.IntBuffer; @@ -99,8 +100,8 @@ public static void _disableCull() { /** * @author */ - @Overwrite(remap = false) - public static void _viewport(int x, int y, int width, int height) { + @Redirect(method = "_viewport", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL11;glViewport(IIII)V"), remap = false) + private static void _viewport(int x, int y, int width, int height) { Renderer.setViewport(x, y, width, height); } @@ -126,6 +127,7 @@ public static int _getError() { */ @Overwrite(remap = false) public static void _texImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, @Nullable IntBuffer pixels) { + RenderSystem.assertOnRenderThreadOrInit(); GlTexture.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels != null ? MemoryUtil.memByteBuffer(pixels) : null); } @@ -134,7 +136,8 @@ public static void _texImage2D(int target, int level, int internalFormat, int wi */ @Overwrite(remap = false) public static void _texSubImage2D(int target, int level, int offsetX, int offsetY, int width, int height, int format, int type, long pixels) { - + RenderSystem.assertOnRenderThreadOrInit(); + GlTexture.texSubImage2D(target, level, offsetX, offsetY, width, height, format, type, pixels); } /** @@ -175,6 +178,8 @@ public static int _getTexLevelParameter(int i, int j, int k) { @Overwrite(remap = false) public static void _pixelStore(int pname, int param) { //Used during upload to set copy offsets + RenderSystem.assertOnRenderThreadOrInit(); + GlTexture.pixelStoreI(pname, param); } /** diff --git a/src/main/java/net/vulkanmod/mixin/render/LevelRendererMixin.java b/src/main/java/net/vulkanmod/mixin/render/LevelRendererMixin.java deleted file mode 100644 index f397ee81f..000000000 --- a/src/main/java/net/vulkanmod/mixin/render/LevelRendererMixin.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.vulkanmod.mixin.render; - -import com.google.gson.JsonSyntaxException; -import com.mojang.blaze3d.pipeline.RenderTarget; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.PostChain; -import net.minecraft.resources.ResourceLocation; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.io.IOException; - -@Mixin(LevelRenderer.class) -public abstract class LevelRendererMixin { - - @Shadow private @Nullable PostChain entityEffect; - - @Shadow @Final private Minecraft minecraft; - - @Shadow @Nullable private RenderTarget entityTarget; - - @Shadow @Final private static Logger LOGGER; - -// /** -// * @author -// */ -// @Overwrite -// public void initOutline() { -// if (this.entityEffect != null) { -// this.entityEffect.close(); -// } -// -//// ResourceLocation resourceLocation = new ResourceLocation("shaders/post/entity_outline.json"); -//// -//// try { -//// this.entityEffect = new PostChain(this.minecraft.getTextureManager(), this.minecraft.getResourceManager(), this.minecraft.getMainRenderTarget(), resourceLocation); -//// this.entityEffect.resize(this.minecraft.getWindow().getWidth(), this.minecraft.getWindow().getHeight()); -//// this.entityTarget = this.entityEffect.getTempTarget("final"); -//// } catch (IOException var3) { -//// LOGGER.warn("Failed to load shader: {}", resourceLocation, var3); -//// this.entityEffect = null; -//// this.entityTarget = null; -//// } catch (JsonSyntaxException var4) { -//// LOGGER.warn("Failed to parse shader: {}", resourceLocation, var4); -//// this.entityEffect = null; -//// this.entityTarget = null; -//// } -// } - -} \ No newline at end of file diff --git a/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java b/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java index 85c22cfef..2b42bbcdd 100644 --- a/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java @@ -1,15 +1,12 @@ package net.vulkanmod.mixin.render; -import com.mojang.blaze3d.pipeline.RenderTarget; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.TimerQuery; -import net.minecraft.Util; import net.minecraft.client.GraphicsStatus; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; import net.minecraft.client.main.GameConfig; import net.vulkanmod.Initializer; -import net.vulkanmod.render.texture.SpriteUtil; +import net.vulkanmod.render.texture.SpriteUpdateUtil; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.Vulkan; import org.objectweb.asm.Opcodes; @@ -20,7 +17,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.Optional; @@ -28,70 +24,29 @@ @Mixin(Minecraft.class) public class MinecraftMixin { - @Shadow public boolean noRender; @Shadow @Final public Options options; @Inject(method = "", at = @At(value = "RETURN")) private void forceGraphicsMode(GameConfig gameConfig, CallbackInfo ci) { var graphicsModeOption = this.options.graphicsMode(); - if(graphicsModeOption.get() == GraphicsStatus.FABULOUS) { + if (graphicsModeOption.get() == GraphicsStatus.FABULOUS) { Initializer.LOGGER.error("Fabulous graphics mode not supported, forcing Fancy"); graphicsModeOption.set(GraphicsStatus.FANCY); } } - @Inject(method = "runTick", at = @At(value = "HEAD")) - private void resetBuffers(boolean bl, CallbackInfo ci) { - Renderer.getInstance().preInitFrame(); - } - - //Main target (framebuffer) ops - @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;clear(IZ)V")) - private void beginRender(int i, boolean bl) { - RenderSystem.clear(i, bl); - Renderer.getInstance().beginFrame(); - } - - @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/Window;updateDisplay()V", shift = At.Shift.BEFORE)) - private void submitRender(boolean tick, CallbackInfo ci) { - Renderer.getInstance().endFrame(); - } - - @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;bindWrite(Z)V")) - private void redirectMainTarget1(RenderTarget instance, boolean bl) { - Renderer.getInstance().getMainPass().mainTargetBindWrite(); - } - - @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;unbindWrite()V")) - private void redirectMainTarget2(RenderTarget instance) { - Renderer.getInstance().getMainPass().mainTargetUnbindWrite(); - } - - @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;blitToScreen(II)V")) - private void removeBlit(RenderTarget instance, int i, int j) { - } - - - @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Ljava/lang/Thread;yield()V")) - private void removeThreadYield() { - } - - @Inject(method = "getFramerateLimit", at = @At("HEAD"), cancellable = true) - private void limitWhenMinimized(CallbackInfoReturnable cir) { - if(this.noRender) cir.setReturnValue(10); - } - @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/TimerQuery;getInstance()Ljava/util/Optional;")) private Optional removeTimer() { return Optional.empty(); } @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;tick()V"), - locals = LocalCapture.CAPTURE_FAILHARD) + locals = LocalCapture.CAPTURE_FAILHARD) private void redirectResourceTick(boolean bl, CallbackInfo ci, Runnable runnable, int i, int j) { int n = Math.min(10, i) - 1; - SpriteUtil.setDoUpload(j == n); + boolean doUpload = j == n; + SpriteUpdateUtil.setDoUpload(doUpload); } @Inject(method = "close", at = @At(value = "HEAD")) @@ -99,16 +54,9 @@ public void close(CallbackInfo ci) { Vulkan.waitIdle(); } - @Inject(method = "close", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/VirtualScreen;close()V")) public void close2(CallbackInfo ci) { Vulkan.cleanUp(); - Util.shutdownExecutors(); - } - - @Redirect(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;emergencySave()V")) - private void skipEmergencySave(Minecraft instance) { - } @Inject(method = "resizeDisplay", at = @At("HEAD")) @@ -116,8 +64,8 @@ public void onResolutionChanged(CallbackInfo ci) { Renderer.scheduleSwapChainUpdate(); } - //Fixes crash when minimizing window before setScreen is called + // Fixes crash when minimizing window before setScreen is called @Redirect(method = "setScreen", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;noRender:Z", opcode = Opcodes.PUTFIELD)) - private void keepVar(Minecraft instance, boolean value) { } + private void keepVar(Minecraft instance, boolean value) {} } diff --git a/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java b/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java index 4a431ca1c..2fd1cfa7d 100644 --- a/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java @@ -14,8 +14,6 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; import java.util.function.Consumer; @@ -29,14 +27,16 @@ public abstract class RenderSystemMixin { @Shadow @Final private static Matrix4fStack modelViewStack; @Shadow private static Matrix4f modelViewMatrix; @Shadow private static Matrix4f textureMatrix; - @Shadow @Final private static int[] shaderTextures; + @Shadow @Final private static float[] shaderColor; @Shadow @Final private static Vector3f[] shaderLightDirections; - @Shadow @Final private static float[] shaderFogColor; @Shadow private static @Nullable Thread renderThread; + @Shadow public static VertexSorting vertexSorting; + @Shadow private static VertexSorting savedVertexSorting; + @Shadow public static void assertOnRenderThread() { } @@ -136,18 +136,6 @@ public static void clearDepth(double d) { VRenderSystem.clearDepth(d); } - @Redirect(method = "flipFrame", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwSwapBuffers(J)V"), remap = false) - private static void removeSwapBuffers(long window) { - } - - /** - * @author - */ - @Overwrite(remap = false) - public static void viewport(int x, int y, int width, int height) { - Renderer.setViewport(x, y, width, height); - } - /** * @author */ @@ -288,9 +276,9 @@ public static void disableCull() { * @author */ @Overwrite(remap = false) - public static void polygonMode(final int i, final int j) { + public static void polygonMode(final int face, final int mode) { assertOnRenderThread(); - VRenderSystem.setPolygonModeGL(i); + VRenderSystem.setPolygonModeGL(mode); } /** @@ -372,12 +360,14 @@ public static void setProjectionMatrix(Matrix4f projectionMatrix, VertexSorting if (!isOnRenderThread()) { recordRenderCall(() -> { RenderSystemMixin.projectionMatrix = matrix4f; + RenderSystem.vertexSorting = vertexSorting; VRenderSystem.applyProjectionMatrix(matrix4f); VRenderSystem.calculateMVP(); }); } else { RenderSystemMixin.projectionMatrix = matrix4f; + RenderSystem.vertexSorting = vertexSorting; VRenderSystem.applyProjectionMatrix(matrix4f); VRenderSystem.calculateMVP(); @@ -443,6 +433,7 @@ public static void applyModelViewMatrix() { @Overwrite(remap = false) private static void _restoreProjectionMatrix() { projectionMatrix = savedProjectionMatrix; + vertexSorting = savedVertexSorting; VRenderSystem.applyProjectionMatrix(projectionMatrix); VRenderSystem.calculateMVP(); diff --git a/src/main/java/net/vulkanmod/mixin/render/ShaderInstanceM.java b/src/main/java/net/vulkanmod/mixin/render/ShaderInstanceM.java index ec2fa3f1e..375647f74 100644 --- a/src/main/java/net/vulkanmod/mixin/render/ShaderInstanceM.java +++ b/src/main/java/net/vulkanmod/mixin/render/ShaderInstanceM.java @@ -1,29 +1,30 @@ package net.vulkanmod.mixin.render; +import com.google.gson.JsonObject; +import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.shaders.Program; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ShaderInstance; +import net.minecraft.client.renderer.texture.AbstractTexture; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceProvider; import net.vulkanmod.Initializer; import net.vulkanmod.interfaces.ShaderMixed; +import net.vulkanmod.render.shader.ShaderLoadUtil; import net.vulkanmod.vulkan.shader.GraphicsPipeline; import net.vulkanmod.vulkan.shader.Pipeline; import net.vulkanmod.vulkan.shader.descriptor.UBO; import net.vulkanmod.vulkan.shader.layout.Uniform; -import net.vulkanmod.vulkan.shader.parser.GlslConverter; +import net.vulkanmod.vulkan.shader.converter.GlslConverter; import net.vulkanmod.vulkan.util.MappedBuffer; import org.apache.commons.io.IOUtils; import org.jetbrains.annotations.Nullable; import org.lwjgl.system.MemoryUtil; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; @@ -33,6 +34,7 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.function.Supplier; @@ -46,7 +48,6 @@ public class ShaderInstanceM implements ShaderMixed { @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform PROJECTION_MATRIX; @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform COLOR_MODULATOR; @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform LINE_WIDTH; - @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform GLINT_ALPHA; @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform FOG_START; @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform FOG_END; @@ -56,12 +57,15 @@ public class ShaderInstanceM implements ShaderMixed { @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform GAME_TIME; @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform SCREEN_SIZE; - private String vsPath; - private String fsName; + @Shadow @Final private Map samplerMap; + @Shadow @Final private List samplerLocations; + @Shadow @Final private List samplerNames; - private GraphicsPipeline pipeline; - boolean isLegacy = false; + @Unique private String vsPath; + @Unique private String fsName; + @Unique private GraphicsPipeline pipeline; + @Unique boolean doUniformUpdate = false; public GraphicsPipeline getPipeline() { return pipeline; @@ -69,23 +73,23 @@ public GraphicsPipeline getPipeline() { @Inject(method = "", at = @At("RETURN")) private void create(ResourceProvider resourceProvider, String name, VertexFormat format, CallbackInfo ci) { + String configName = name; + JsonObject config = ShaderLoadUtil.getJsonConfig("core", configName); - try { - if (Pipeline.class.getResourceAsStream(String.format("/assets/vulkanmod/shaders/minecraft/core/%s/%s.json", name, name)) == null) { - createLegacyShader(resourceProvider, format); - return; - } - - String path = String.format("minecraft/core/%s/%s", name, name); - Pipeline.Builder pipelineBuilder = new Pipeline.Builder(format, path); - pipelineBuilder.parseBindingsJSON(); - pipelineBuilder.compileShaders(); - this.pipeline = pipelineBuilder.createGraphicsPipeline(); - } catch (Exception e) { - System.out.printf("Error on shader %s creation\n", name); - e.printStackTrace(); - throw e; + if (config == null) { + createLegacyShader(resourceProvider, format); + return; } + + Pipeline.Builder builder = new Pipeline.Builder(format, configName); + builder.setUniformSupplierGetter(info -> this.getUniformSupplier(info.name)); + + builder.parseBindings(config); + + ShaderLoadUtil.loadShaders(builder, config, configName, "core"); + + GraphicsPipeline pipeline = builder.createGraphicsPipeline(); + this.pipeline = pipeline; } @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ShaderInstance;getOrCreate(Lnet/minecraft/server/packs/resources/ResourceProvider;Lcom/mojang/blaze3d/shaders/Program$Type;Ljava/lang/String;)Lcom/mojang/blaze3d/shaders/Program;")) @@ -123,9 +127,30 @@ public void close() { */ @Overwrite public void apply() { - if (!this.isLegacy) + if (!this.doUniformUpdate) return; + for(int j = 0; j < this.samplerLocations.size(); ++j) { + String string = this.samplerNames.get(j); + if (this.samplerMap.get(string) != null) { + RenderSystem.activeTexture(33984 + j); + Object object = this.samplerMap.get(string); + int texId = -1; + if (object instanceof RenderTarget) { + texId = ((RenderTarget)object).getColorTextureId(); + } else if (object instanceof AbstractTexture) { + texId = ((AbstractTexture)object).getId(); + } else if (object instanceof Integer) { + texId = (Integer)object; + } + + if (texId != -1) { + RenderSystem.bindTexture(texId); + RenderSystem.setShaderTexture(j, texId); + } + } + } + if (this.MODEL_VIEW_MATRIX != null) { this.MODEL_VIEW_MATRIX.set(RenderSystem.getModelViewMatrix()); } @@ -182,20 +207,20 @@ public void apply() { @Overwrite public void clear() {} - private void setUniformSuppliers(UBO ubo) { - + public void setupUniformSuppliers(UBO ubo) { for (Uniform vUniform : ubo.getUniforms()) { com.mojang.blaze3d.shaders.Uniform uniform = this.uniformMap.get(vUniform.getName()); - if (uniform == null) { - Initializer.LOGGER.error(String.format("Error: field %s not present in uniform map", vUniform.getName())); - continue; - } - Supplier supplier; ByteBuffer byteBuffer; - if (uniform.getType() <= 3) { + if (uniform == null) { + Initializer.LOGGER.error(String.format("Error: field %s not present in uniform map", vUniform.getName())); + + int size = vUniform.getSize(); + byteBuffer = MemoryUtil.memAlloc(size * 4); + } + else if (uniform.getType() <= 3) { byteBuffer = MemoryUtil.memByteBuffer(uniform.getIntBuffer()); } else if (uniform.getType() <= 10) { byteBuffer = MemoryUtil.memByteBuffer(uniform.getFloatBuffer()); @@ -212,6 +237,41 @@ private void setUniformSuppliers(UBO ubo) { } + public Supplier getUniformSupplier(String name) { + com.mojang.blaze3d.shaders.Uniform uniform1 = this.uniformMap.get(name); + + if (uniform1 == null) { + Initializer.LOGGER.error(String.format("Error: field %s not present in uniform map", name)); + return null; + } + + Supplier supplier; + ByteBuffer byteBuffer; + + if (uniform1.getType() <= 3) { + byteBuffer = MemoryUtil.memByteBuffer(uniform1.getIntBuffer()); + } else if (uniform1.getType() <= 10) { + byteBuffer = MemoryUtil.memByteBuffer(uniform1.getFloatBuffer()); + } else { + throw new RuntimeException("out of bounds value for uniform " + uniform1); + } + + MappedBuffer mappedBuffer = MappedBuffer.createFromBuffer(byteBuffer); + supplier = () -> mappedBuffer; + + return supplier; + } + + @Override + public void setDoUniformsUpdate() { + this.doUniformUpdate = true; + } + + @Override + public void setPipeline(GraphicsPipeline graphicsPipeline) { + this.pipeline = graphicsPipeline; + } + private void createLegacyShader(ResourceProvider resourceProvider, VertexFormat format) { try { String vertPath = this.vsPath + ".vsh"; @@ -228,15 +288,14 @@ private void createLegacyShader(ResourceProvider resourceProvider, VertexFormat Pipeline.Builder builder = new Pipeline.Builder(format, this.name); converter.process(vshSrc, fshSrc); - UBO ubo = converter.getUBO(); - this.setUniformSuppliers(ubo); + UBO ubo = converter.createUBO(); + this.setupUniformSuppliers(ubo); builder.setUniforms(Collections.singletonList(ubo), converter.getSamplerList()); builder.compileShaders(this.name, converter.getVshConverted(), converter.getFshConverted()); this.pipeline = builder.createGraphicsPipeline(); - this.isLegacy = true; - + this.doUniformUpdate = true; } catch (Exception e) { Initializer.LOGGER.error("Error on shader {} conversion/compilation", this.name); e.printStackTrace(); diff --git a/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java b/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java new file mode 100644 index 000000000..7ec047b32 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java @@ -0,0 +1,18 @@ +package net.vulkanmod.mixin.render.biome; + +import net.minecraft.world.level.biome.BiomeManager; +import net.vulkanmod.interfaces.biome.BiomeManagerExtended; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(BiomeManager.class) +public class BiomeManagerM implements BiomeManagerExtended { + + @Shadow @Final private long biomeZoomSeed; + + @Override + public long getBiomeZoomSeed() { + return this.biomeZoomSeed; + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/block/BakedQuadM.java b/src/main/java/net/vulkanmod/mixin/render/block/BakedQuadM.java index 9c315f1be..1f012d472 100644 --- a/src/main/java/net/vulkanmod/mixin/render/block/BakedQuadM.java +++ b/src/main/java/net/vulkanmod/mixin/render/block/BakedQuadM.java @@ -3,7 +3,9 @@ import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.Direction; -import net.vulkanmod.render.model.quad.QuadView; +import net.vulkanmod.render.chunk.build.frapi.helper.NormalHelper; +import net.vulkanmod.render.chunk.cull.QuadFacing; +import net.vulkanmod.render.model.quad.ModelQuadView; import net.vulkanmod.render.model.quad.ModelQuadFlags; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -15,16 +17,23 @@ import static net.vulkanmod.render.model.quad.ModelQuad.VERTEX_SIZE; @Mixin(BakedQuad.class) -public class BakedQuadM implements QuadView { +public class BakedQuadM implements ModelQuadView { @Shadow @Final protected int[] vertices; @Shadow @Final protected Direction direction; @Shadow @Final protected int tintIndex; + private int flags; + private int normal; + private QuadFacing facing; @Inject(method = "", at = @At("RETURN")) - private void onInit(int[] vertices, int tintIndex, Direction direction, TextureAtlasSprite textureAtlasSprite, boolean shade, CallbackInfo ci) { - this.flags = ModelQuadFlags.getQuadFlags(vertices, direction); + private void onInit(int[] vertices, int tintIndex, Direction face, TextureAtlasSprite textureAtlasSprite, boolean shade, CallbackInfo ci) { + this.flags = ModelQuadFlags.getQuadFlags(this, face); + + int packedNormal = NormalHelper.computePackedNormal(this); + this.normal = packedNormal; + this.facing = QuadFacing.fromNormal(packedNormal); } @Override @@ -67,11 +76,26 @@ public int getColorIndex() { return this.tintIndex; } + @Override + public Direction lightFace() { + return this.direction; + } + @Override public Direction getFacingDirection() { return this.direction; } + @Override + public QuadFacing getQuadFacing() { + return this.facing; + } + + @Override + public int getNormal() { + return this.normal; + } + @Override public boolean isTinted() { return this.tintIndex != -1; diff --git a/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java b/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java new file mode 100644 index 000000000..a5680870a --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java @@ -0,0 +1,50 @@ +package net.vulkanmod.mixin.render.clouds; + +import com.mojang.blaze3d.vertex.*; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.*; +import net.minecraft.server.packs.resources.ResourceManager; +import net.vulkanmod.render.profiling.Profiler; +import net.vulkanmod.render.sky.CloudRenderer; +import org.jetbrains.annotations.Nullable; +import org.joml.Matrix4f; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(LevelRenderer.class) +public abstract class LevelRendererM { + + @Shadow private int ticks; + @Shadow private @Nullable ClientLevel level; + + @Unique + private CloudRenderer cloudRenderer; + + @Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true) + public void renderClouds(PoseStack poseStack, Matrix4f modelView, Matrix4f projection, float partialTicks, double camX, double camY, double camZ, CallbackInfo ci) { + if (this.cloudRenderer == null) { + this.cloudRenderer = new CloudRenderer(); + } + + this.cloudRenderer.renderClouds(this.level, poseStack, modelView, projection, this.ticks, partialTicks, camX, camY, camZ); + Profiler.getMainProfiler().pop(); + ci.cancel(); + } + + @Inject(method = "allChanged", at = @At("RETURN")) + private void onAllChanged(CallbackInfo ci) { + if (this.cloudRenderer != null) { + this.cloudRenderer.resetBuffer(); + } + } + + @Inject(method = "onResourceManagerReload", at = @At("RETURN")) + private void onReload(ResourceManager resourceManager, CallbackInfo ci) { + if (this.cloudRenderer != null) { + this.cloudRenderer.loadTexture(); + } + } + +} diff --git a/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java b/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java new file mode 100644 index 000000000..b3480e5c9 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java @@ -0,0 +1,29 @@ +package net.vulkanmod.mixin.render.color; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.block.BlockColors; +import net.minecraft.world.level.block.Block; +import net.vulkanmod.interfaces.color.BlockColorsExtended; +import net.vulkanmod.render.chunk.build.color.BlockColorRegistry; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(BlockColors.class) +public class BlockColorsM implements BlockColorsExtended { + + @Unique + private BlockColorRegistry colorResolvers = new BlockColorRegistry(); + + @Inject(method = "register", at = @At("RETURN")) + private void onRegister(BlockColor blockColor, Block[] blocks, CallbackInfo ci) { + this.colorResolvers.register(blockColor, blocks); + } + + @Override + public BlockColorRegistry getColorResolverMap() { + return this.colorResolvers; + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartM.java b/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartM.java index 7ad232bbc..ecb2ffe27 100644 --- a/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartM.java +++ b/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartM.java @@ -6,7 +6,7 @@ import net.vulkanmod.interfaces.ExtendedVertexBuilder; import net.vulkanmod.interfaces.ModelPartCubeMixed; import net.vulkanmod.render.model.CubeModel; -import net.vulkanmod.render.vertex.VertexUtil; +import net.vulkanmod.render.vertex.format.I32_SNorm; import net.vulkanmod.vulkan.util.ColorUtil; import org.joml.Matrix3f; import org.joml.Matrix4f; @@ -52,7 +52,7 @@ public void renderCubes(PoseStack.Pose pose, VertexConsumer vertexConsumer, int matrix3f.transform(this.normal.set(polygon.normal)); this.normal.normalize(); - int packedNormal = VertexUtil.packNormal(normal.x(), normal.y(), normal.z()); + int packedNormal = I32_SNorm.packNormal(normal.x(), normal.y(), normal.z()); ModelPart.Vertex[] vertices = polygon.vertices; diff --git a/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java b/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java new file mode 100644 index 000000000..6184f7902 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java @@ -0,0 +1,61 @@ +package net.vulkanmod.mixin.render.frame; + +import com.mojang.blaze3d.pipeline.RenderTarget; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.Minecraft; +import net.vulkanmod.vulkan.Renderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Minecraft.class) +public class MinecraftMixin { + + @Shadow public boolean noRender; + + @Inject(method = "runTick", at = @At(value = "HEAD")) + private void preFrameOps(boolean bl, CallbackInfo ci) { + Renderer.getInstance().preInitFrame(); + } + + // Main target (framebuffer) ops + @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;clear(IZ)V")) + private void beginRender(int i, boolean bl) { + RenderSystem.clear(i, bl); + Renderer.getInstance().beginFrame(); + } + + @Inject(method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;Z)V", at = @At(value = "RETURN")) + private void beginRender2(CallbackInfo ci) { + Renderer.getInstance().beginFrame(); + } + + @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;bindWrite(Z)V")) + private void redirectMainTarget1(RenderTarget instance, boolean bl) { + Renderer.getInstance().getMainPass().mainTargetBindWrite(); + } + + @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;unbindWrite()V")) + private void redirectMainTarget2(RenderTarget instance) { + Renderer.getInstance().getMainPass().mainTargetUnbindWrite(); + } + + @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;blitToScreen(II)V")) + private void removeBlit(RenderTarget instance, int i, int j) { + } + + + @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Ljava/lang/Thread;yield()V")) + private void removeThreadYield() { + } + + @Inject(method = "getFramerateLimit", at = @At("HEAD"), cancellable = true) + private void limitWhenMinimized(CallbackInfoReturnable cir) { + if (this.noRender) + cir.setReturnValue(10); + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/frame/RenderSystemMixin.java b/src/main/java/net/vulkanmod/mixin/render/frame/RenderSystemMixin.java new file mode 100644 index 000000000..f4ca167b9 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/frame/RenderSystemMixin.java @@ -0,0 +1,16 @@ +package net.vulkanmod.mixin.render.frame; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.vulkanmod.vulkan.Renderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(RenderSystem.class) +public class RenderSystemMixin { + + @Redirect(method = "flipFrame", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwSwapBuffers(J)V"), remap = false) + private static void endFrame(long window) { + Renderer.getInstance().endFrame(); + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/BakedModelM.java b/src/main/java/net/vulkanmod/mixin/render/frapi/BakedModelM.java new file mode 100644 index 000000000..b8decdc33 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/BakedModelM.java @@ -0,0 +1,29 @@ +package net.vulkanmod.mixin.render.frapi; + +import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; +import net.vulkanmod.render.chunk.build.frapi.render.AbstractBlockRenderContext; +import net.vulkanmod.render.chunk.build.frapi.render.ItemRenderContext; +import org.spongepowered.asm.mixin.Mixin; + +import java.util.function.Supplier; + +@Mixin(BakedModel.class) +public interface BakedModelM extends FabricBakedModel { + + @Override + default void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + ((AbstractBlockRenderContext) context).emitBlockQuads((BakedModel) this, state, randomSupplier, context); + } + + @Override + default void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { + ((ItemRenderContext) context).emitItemQuads((BakedModel) this, null, randomSupplier); + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java new file mode 100644 index 000000000..1eca3abcf --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java @@ -0,0 +1,14 @@ +package net.vulkanmod.mixin.render.frapi; + +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.world.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(ItemRenderer.class) +public interface ItemRendererAccessor { + @Invoker("hasAnimatedTexture") + static boolean hasAnimatedTexture(ItemStack stack) { + throw new AssertionError(); + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererMixin.java b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererMixin.java new file mode 100644 index 000000000..5ab645091 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererMixin.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.mixin.render.frapi; + +import net.vulkanmod.render.chunk.build.frapi.render.ItemRenderContext; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.color.item.ItemColors; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import com.mojang.blaze3d.vertex.PoseStack; + +@Mixin(ItemRenderer.class) +public abstract class ItemRendererMixin { + @Final + @Shadow + private ItemColors itemColors; + + @Unique + private final ThreadLocal fabric_contexts = ThreadLocal.withInitial(() -> new ItemRenderContext(itemColors)); + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/BakedModel;isCustomRenderer()Z"), method = "render", cancellable = true) + public void hook_renderItem(ItemStack stack, ItemDisplayContext transformMode, boolean invert, PoseStack matrixStack, MultiBufferSource vertexConsumerProvider, int light, int overlay, BakedModel model, CallbackInfo ci) { + if (!model.isVanillaAdapter()) { + fabric_contexts.get().renderModel(stack, transformMode, invert, matrixStack, vertexConsumerProvider, light, overlay, model); + matrixStack.popPose(); + ci.cancel(); + } + } +} \ No newline at end of file diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/ModelBlockRendererM.java b/src/main/java/net/vulkanmod/mixin/render/frapi/ModelBlockRendererM.java new file mode 100644 index 000000000..d89759594 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/ModelBlockRendererM.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.mixin.render.frapi; + +import net.vulkanmod.render.chunk.build.frapi.render.BlockRenderContext; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.block.ModelBlockRenderer; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; + +@Mixin(ModelBlockRenderer.class) +public abstract class ModelBlockRendererM { + + // TODO ThreadLocal look ups are slow, same goes for ItemRendererMixin + @Unique + private final ThreadLocal fabric_contexts = ThreadLocal.withInitial(BlockRenderContext::new); + + @Inject(at = @At("HEAD"), method = "tesselateBlock", cancellable = true) + private void hookRender(BlockAndTintGetter blockView, BakedModel model, BlockState state, BlockPos pos, PoseStack matrix, VertexConsumer buffer, boolean cull, RandomSource rand, long seed, int overlay, CallbackInfo ci) { + if (!model.isVanillaAdapter()) { + BlockRenderContext context = fabric_contexts.get(); + context.render(blockView, model, state, pos, matrix, buffer, cull, rand, seed, overlay); + ci.cancel(); + } + } + +} diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/fluid/FluidRenderingImplMixin.java b/src/main/java/net/vulkanmod/mixin/render/frapi/fluid/FluidRenderingImplMixin.java new file mode 100644 index 000000000..4565922c9 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/fluid/FluidRenderingImplMixin.java @@ -0,0 +1,26 @@ +package net.vulkanmod.mixin.render.frapi.fluid; + +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; +import net.fabricmc.fabric.impl.client.rendering.fluid.FluidRenderingImpl; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FluidState; +import net.vulkanmod.render.chunk.build.renderer.DefaultFluidRenderers; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +@SuppressWarnings("UnstableApiUsage") +@Mixin(FluidRenderingImpl.class) +public class FluidRenderingImplMixin { + + /** + * @author + * @reason + */ + @Overwrite + public static void renderDefault(FluidRenderHandler handler, BlockAndTintGetter world, BlockPos pos, VertexConsumer vertexConsumer, BlockState blockState, FluidState fluidState) { + DefaultFluidRenderers.add(handler); + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/particle/SingleQuadParticleM.java b/src/main/java/net/vulkanmod/mixin/render/particle/SingleQuadParticleM.java index 9ffe1077f..220b9235d 100644 --- a/src/main/java/net/vulkanmod/mixin/render/particle/SingleQuadParticleM.java +++ b/src/main/java/net/vulkanmod/mixin/render/particle/SingleQuadParticleM.java @@ -20,12 +20,16 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; @Mixin(SingleQuadParticle.class) public abstract class SingleQuadParticleM extends Particle { @Shadow protected float quadSize; + @Unique private final Quaternionf quaternionf = new Quaternionf(); + @Unique private final Vector3f vector3f = new Vector3f(); + @Shadow protected abstract float getU0(); @Shadow protected abstract float getU1(); @Shadow protected abstract float getV0(); @@ -33,6 +37,8 @@ public abstract class SingleQuadParticleM extends Particle { @Shadow public abstract float getQuadSize(float f); + @Shadow public abstract SingleQuadParticle.FacingCameraMode getFacingCameraMode(); + protected SingleQuadParticleM(ClientLevel clientLevel, double d, double e, double f, double g, double h, double i) { super(clientLevel, d, e, f, g, h, i); this.quadSize = 0.1F * (this.random.nextFloat() * 0.5F + 0.5F) * 2.0F; @@ -48,7 +54,7 @@ public void render(VertexConsumer vertexConsumer, Camera camera, float f) { double ly = (Mth.lerp(f, this.yo, this.y)); double lz = (Mth.lerp(f, this.zo, this.z)); - if(cull(WorldRenderer.getInstance(), (float) lx, (float) ly, (float) lz)) + if (cull(WorldRenderer.getInstance(), lx, ly, lz)) return; Vec3 vec3 = camera.getPosition(); @@ -56,24 +62,18 @@ public void render(VertexConsumer vertexConsumer, Camera camera, float f) { float offsetY = (float) (ly - vec3.y()); float offsetZ = (float) (lz - vec3.z()); - Quaternionf quaternionf; + quaternionf.identity(); + this.getFacingCameraMode().setRotation(quaternionf, camera, f); if (this.roll != 0.0F) { - quaternionf = new Quaternionf(camera.rotation()); quaternionf.rotateZ(Mth.lerp(f, this.oRoll, this.roll)); - } else { - quaternionf = camera.rotation(); } - Vector3f[] vector3fs = new Vector3f[]{new Vector3f(-1.0F, -1.0F, 0.0F), new Vector3f(-1.0F, 1.0F, 0.0F), new Vector3f(1.0F, 1.0F, 0.0F), new Vector3f(1.0F, -1.0F, 0.0F)}; - float j = this.getQuadSize(f); - - for(int k = 0; k < 4; ++k) { - Vector3f vector3f = vector3fs[k]; - vector3f.rotate(quaternionf); - vector3f.mul(j); - vector3f.add(offsetX, offsetY, offsetZ); - } + this.renderRotatedQuad(vertexConsumer, quaternionf, offsetX, offsetY, offsetZ, f); + } + @Unique + private void renderRotatedQuad(VertexConsumer vertexConsumer, Quaternionf quaternionf, float x, float y, float z, float f) { + float j = this.getQuadSize(f); float u0 = this.getU0(); float u1 = this.getU1(); float v0 = this.getV0(); @@ -83,10 +83,22 @@ public void render(VertexConsumer vertexConsumer, Camera camera, float f) { ExtendedVertexBuilder vertexBuilder = (ExtendedVertexBuilder)vertexConsumer; int packedColor = ColorUtil.RGBA.pack(this.rCol, this.gCol, this.bCol, this.alpha); - vertexBuilder.vertex(vector3fs[1].x(), vector3fs[1].y(), vector3fs[1].z(), u1, v0, packedColor, light); - vertexBuilder.vertex(vector3fs[0].x(), vector3fs[0].y(), vector3fs[0].z(), u1, v1, packedColor, light); - vertexBuilder.vertex(vector3fs[3].x(), vector3fs[3].y(), vector3fs[3].z(), u0, v1, packedColor, light); - vertexBuilder.vertex(vector3fs[2].x(), vector3fs[2].y(), vector3fs[2].z(), u0, v0, packedColor, light); + this.renderVertex(vertexBuilder, quaternionf, x, y, z, 1.0F, -1.0F, j, u1, v1, packedColor, light); + this.renderVertex(vertexBuilder, quaternionf, x, y, z, 1.0F, 1.0F, j, u1, v0, packedColor, light); + this.renderVertex(vertexBuilder, quaternionf, x, y, z, -1.0F, 1.0F, j, u0, v0, packedColor, light); + this.renderVertex(vertexBuilder, quaternionf, x, y, z, -1.0F, -1.0F, j, u0, v1, packedColor, light); + } + + @Unique + private void renderVertex( + ExtendedVertexBuilder vertexConsumer, Quaternionf quaternionf, float x, float y, float z, float i, float j, float k, float u, float v, int color, int light + ) { + vector3f.set(i, j, 0.0f) + .rotate(quaternionf) + .mul(k) + .add(x, y, z); + + vertexConsumer.vertex(vector3f.x(), vector3f.y(), vector3f.z(), u, v, color, light); } protected int getLightColor(float f) { @@ -94,7 +106,7 @@ protected int getLightColor(float f) { return this.level.hasChunkAt(blockPos) ? LevelRenderer.getLightColor(this.level, blockPos) : 0; } - private boolean cull(WorldRenderer worldRenderer, float x, float y, float z) { + private boolean cull(WorldRenderer worldRenderer, double x, double y, double z) { RenderSection section = worldRenderer.getSectionGrid().getSectionAtBlockPos((int) x, (int) y, (int) z); return section != null && section.getLastFrame() != worldRenderer.getLastFrame(); } diff --git a/src/main/java/net/vulkanmod/mixin/render/target/MainTargetMixin.java b/src/main/java/net/vulkanmod/mixin/render/target/MainTargetMixin.java index ff10c3d45..5d5dbf1fd 100644 --- a/src/main/java/net/vulkanmod/mixin/render/target/MainTargetMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/target/MainTargetMixin.java @@ -21,6 +21,8 @@ public MainTargetMixin(boolean useDepth) { */ @Overwrite private void createFrameBuffer(int width, int height) { + this.frameBufferId = 0; + this.viewWidth = width; this.viewHeight = height; this.width = width; diff --git a/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java b/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java index 9dd3134b4..7c1ebabd9 100644 --- a/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java @@ -5,10 +5,8 @@ import com.mojang.blaze3d.systems.RenderSystem; import net.vulkanmod.gl.GlFramebuffer; import net.vulkanmod.gl.GlTexture; -import net.vulkanmod.interfaces.ExtendedRenderTarget; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.framebuffer.Framebuffer; -import net.vulkanmod.vulkan.framebuffer.RenderPass; import net.vulkanmod.vulkan.texture.VTextureSelector; import net.vulkanmod.vulkan.util.DrawUtil; import org.lwjgl.opengl.GL30; @@ -20,7 +18,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(RenderTarget.class) -public abstract class RenderTargetMixin implements ExtendedRenderTarget { +public abstract class RenderTargetMixin { @Shadow public int viewWidth; @Shadow public int viewHeight; @@ -142,16 +140,6 @@ private void injClear(CallbackInfoReturnable cir) { applyClear(); } - @Override - public boolean isBound() { - return bound; - } - - @Override - public RenderPass getRenderPass() { - return GlFramebuffer.getFramebuffer(this.frameBufferId).getRenderPass(); - } - @Unique private void applyClear() { if (this.needClear) { diff --git a/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java b/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java index 4f7335a4c..a7e5c696e 100644 --- a/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java +++ b/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java @@ -1,13 +1,16 @@ package net.vulkanmod.mixin.render.vertex; import com.mojang.blaze3d.vertex.*; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.core.Vec3i; import net.vulkanmod.interfaces.ExtendedVertexBuilder; -import net.vulkanmod.render.vertex.VertexUtil; +import net.vulkanmod.mixin.matrix.PoseAccessor; +import net.vulkanmod.render.util.MathUtil; +import net.vulkanmod.render.vertex.format.I32_SNorm; +import net.vulkanmod.vulkan.util.ColorUtil; +import org.joml.Matrix4f; import org.lwjgl.system.MemoryUtil; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.*; @Mixin(BufferBuilder.class) public abstract class BufferBuilderM @@ -143,11 +146,65 @@ public void addVertex(float x, float y, float z, int color, float u, float v, in MemoryUtil.memPutInt(ptr + i, light); - int temp = VertexUtil.packNormal(normalX, normalY, normalZ); + int temp = I32_SNorm.packNormal(normalX, normalY, normalZ); MemoryUtil.memPutInt(ptr + i + 4, temp); } else { VertexConsumer.super.addVertex(x, y, z, color, u, v, overlay, light, normalX, normalY, normalZ); } } + @Override + public void putBulkData(PoseStack.Pose matrixEntry, BakedQuad quad, float[] brightness, float red, float green, + float blue, float alpha, int[] lights, int overlay, boolean useQuadColorData) { + putQuadData(matrixEntry, quad, brightness, red, green, blue, alpha, lights, overlay, useQuadColorData); + } + + @SuppressWarnings("UnreachableCode") + @Unique + private void putQuadData(PoseStack.Pose matrixEntry, BakedQuad quad, float[] brightness, float red, float green, float blue, float alpha, int[] lights, int overlay, boolean useQuadColorData) { + int[] quadData = quad.getVertices(); + Vec3i vec3i = quad.getDirection().getNormal(); + Matrix4f matrix4f = matrixEntry.pose(); + + boolean trustedNormals = ((PoseAccessor)(Object)matrixEntry).trustedNormals(); + int normal = MathUtil.packTransformedNorm(matrixEntry.normal(), trustedNormals, vec3i.getX(), vec3i.getY(), vec3i.getZ()); + + for (int k = 0; k < 4; ++k) { + float r, g, b; + + float quadR, quadG, quadB; + + int i = k * 8; + float x = Float.intBitsToFloat(quadData[i]); + float y = Float.intBitsToFloat(quadData[i + 1]); + float z = Float.intBitsToFloat(quadData[i + 2]); + + float tx = MathUtil.transformX(matrix4f, x, y, z); + float ty = MathUtil.transformY(matrix4f, x, y, z); + float tz = MathUtil.transformZ(matrix4f, x, y, z); + + if (useQuadColorData) { + int color = quadData[i + 3]; + quadR = ColorUtil.RGBA.unpackR(color); + quadG = ColorUtil.RGBA.unpackG(color); + quadB = ColorUtil.RGBA.unpackB(color); + r = quadR * brightness[k] * red; + g = quadG * brightness[k] * green; + b = quadB * brightness[k] * blue; + } else { + r = brightness[k] * red; + g = brightness[k] * green; + b = brightness[k] * blue; + } + + int color = ColorUtil.RGBA.pack(r, g, b, alpha); + + int light = lights[k]; + float u = Float.intBitsToFloat(quadData[i + 4]); + float v = Float.intBitsToFloat(quadData[i + 5]); + + this.vertex(tx, ty, tz, color, u, v, overlay, light, normal); + } + } + } diff --git a/src/main/java/net/vulkanmod/mixin/render/vertex/VertexBufferM.java b/src/main/java/net/vulkanmod/mixin/render/vertex/VertexBufferM.java index e9da55500..e355ccadd 100644 --- a/src/main/java/net/vulkanmod/mixin/render/vertex/VertexBufferM.java +++ b/src/main/java/net/vulkanmod/mixin/render/vertex/VertexBufferM.java @@ -20,7 +20,7 @@ public class VertexBufferM { @Inject(method = "", at = @At("RETURN")) private void constructor(VertexBuffer.Usage usage, CallbackInfo ci) { - vbo = new VBO(); + vbo = new VBO(usage); } @Redirect(method = "", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_glGenBuffers()I")) diff --git a/src/main/java/net/vulkanmod/mixin/render/vertex/VertexConsumerM.java b/src/main/java/net/vulkanmod/mixin/render/vertex/VertexConsumerM.java deleted file mode 100644 index c3ec70b34..000000000 --- a/src/main/java/net/vulkanmod/mixin/render/vertex/VertexConsumerM.java +++ /dev/null @@ -1,71 +0,0 @@ -package net.vulkanmod.mixin.render.vertex; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.core.Vec3i; -import net.vulkanmod.render.vertex.VertexUtil; -import net.vulkanmod.vulkan.util.ColorUtil; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(VertexConsumer.class) -public interface VertexConsumerM { - - - @Shadow void addVertex(float f, float g, float h, int i, float j, float k, int l, int m, float n, float o, float p); - - /** - * @author - */ - @Overwrite - default void putBulkData(PoseStack.Pose matrixEntry, BakedQuad quad, float[] brightness, float red, float green, float blue, float alpha, int[] lights, int overlay, boolean useQuadColorData) { - int[] js = quad.getVertices(); - Vec3i vec3i = quad.getDirection().getNormal(); - Vector3f normal = new Vector3f(vec3i.getX(), vec3i.getY(), vec3i.getZ()); - Matrix4f matrix4f = matrixEntry.pose(); - normal.mul(matrixEntry.normal()); - - int j = js.length / 8; - - for (int k = 0; k < j; ++k) { - float r, g, b; - - float quadR, quadG, quadB; - - int i = k * 8; - float x = Float.intBitsToFloat(js[i]); - float y = Float.intBitsToFloat(js[i + 1]); - float z = Float.intBitsToFloat(js[i + 2]); - - if (useQuadColorData) { - quadR = ColorUtil.RGBA.unpackR(js[i + 3]); - quadG = ColorUtil.RGBA.unpackG(js[i + 3]); - quadB = ColorUtil.RGBA.unpackB(js[i + 3]); - r = quadR * brightness[k] * red; - g = quadG * brightness[k] * green; - b = quadB * brightness[k] * blue; - } else { - r = brightness[k] * red; - g = brightness[k] * green; - b = brightness[k] * blue; - } - - int color = ColorUtil.RGBA.pack(r, g, b, alpha); - - int light = lights[k]; - float u = Float.intBitsToFloat(js[i + 4]); - float v = Float.intBitsToFloat(js[i + 5]); - - Vector4f vector4f = new Vector4f(x, y, z, 1.0f); - vector4f.mul(matrix4f); - - this.addVertex(vector4f.x(), vector4f.y(), vector4f.z(), color, u, v, overlay, light, normal.x(), normal.y(), normal.z()); - } - - } -} diff --git a/src/main/java/net/vulkanmod/mixin/texture/MSpriteContents.java b/src/main/java/net/vulkanmod/mixin/texture/MSpriteContents.java deleted file mode 100644 index 8148c95f6..000000000 --- a/src/main/java/net/vulkanmod/mixin/texture/MSpriteContents.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.vulkanmod.mixin.texture; - -import com.mojang.blaze3d.platform.NativeImage; -import net.minecraft.client.renderer.texture.SpriteContents; -import net.vulkanmod.render.texture.SpriteUtil; -import net.vulkanmod.vulkan.texture.VTextureSelector; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(SpriteContents.class) -public class MSpriteContents { - - @Inject(method = "upload", at = @At("HEAD"), cancellable = true) - private void checkUpload(int i, int j, int k, int l, NativeImage[] nativeImages, CallbackInfo ci) { - if(!SpriteUtil.shouldUpload()) - ci.cancel(); - - SpriteUtil.addTransitionedLayout(VTextureSelector.getBoundTexture(0)); - } -} diff --git a/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java b/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java index 395c3cdc1..70e9347af 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java +++ b/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java @@ -47,6 +47,7 @@ public static void prepareImage(NativeImage.InternalGlFormat internalGlFormat, i image = new VulkanImage.Builder(width, height) .setMipLevels(mipLevels + 1) + .setFormat(internalGlFormat) .setLinearFiltering(false) .setClamp(false) .createVulkanImage(); diff --git a/src/main/java/net/vulkanmod/mixin/texture/image/MNativeImage.java b/src/main/java/net/vulkanmod/mixin/texture/image/MNativeImage.java index cc4537bcd..31a01f58f 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/image/MNativeImage.java +++ b/src/main/java/net/vulkanmod/mixin/texture/image/MNativeImage.java @@ -2,10 +2,9 @@ import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.systems.RenderSystem; -import net.vulkanmod.vulkan.Vulkan; +import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.texture.ImageUtil; import net.vulkanmod.vulkan.texture.VTextureSelector; -import net.vulkanmod.vulkan.texture.VulkanImage; import net.vulkanmod.vulkan.util.ColorUtil; import org.lwjgl.system.MemoryUtil; import org.spongepowered.asm.mixin.Final; @@ -91,7 +90,7 @@ public void downloadTexture(int level, boolean removeAlpha) { int v = MemoryUtil.memGetInt(this.pixels + l); //TODO - if(Vulkan.getSwapChain().isBGRAformat) + if(Renderer.getInstance().getSwapChain().isBGRAformat) v = ColorUtil.BGRAtoRGBA(v); v = v | 255 << this.format.alphaOffset(); diff --git a/src/main/java/net/vulkanmod/mixin/texture/update/GameRendererM.java b/src/main/java/net/vulkanmod/mixin/texture/update/GameRendererM.java new file mode 100644 index 000000000..bb0ce2b69 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/texture/update/GameRendererM.java @@ -0,0 +1,27 @@ +package net.vulkanmod.mixin.texture.update; + +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; +import net.vulkanmod.render.texture.ImageUploadHelper; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(GameRenderer.class) +public abstract class GameRendererM { + + @Shadow + @Final + Minecraft minecraft; + + @Inject(method = "render", at = @At("HEAD")) + private void onRender(DeltaTracker deltaTracker, boolean bl, CallbackInfo ci) { + if (this.minecraft.noRender || !(bl && this.minecraft.level != null && this.minecraft.isGameLoadFinished())) { + ImageUploadHelper.INSTANCE.submitCommands(); + } + } +} diff --git a/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java b/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java new file mode 100644 index 000000000..5cfadf94b --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java @@ -0,0 +1,210 @@ +package net.vulkanmod.mixin.texture.update; + +import com.mojang.blaze3d.platform.NativeImage; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.util.Mth; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.LivingEntity; +import net.vulkanmod.gl.GlTexture; +import net.vulkanmod.mixin.texture.image.NativeImageAccessor; +import net.vulkanmod.render.texture.ImageUploadHelper; +import net.vulkanmod.vulkan.queue.CommandPool; +import org.joml.Vector3f; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(LightTexture.class) +public class MLightTexture { + @Shadow @Final private Minecraft minecraft; + @Shadow @Final private GameRenderer renderer; + + @Shadow private boolean updateLightTexture; + @Shadow private float blockLightRedFlicker; + + @Shadow @Final private DynamicTexture lightTexture; + @Shadow @Final private NativeImage lightPixels; + + + private Vector3f[] tempVecs; + + @Inject(method = "", at = @At("RETURN")) + private void onInit(GameRenderer gameRenderer, Minecraft minecraft, CallbackInfo ci) { + this.tempVecs = new Vector3f[]{new Vector3f(), new Vector3f(), new Vector3f()}; + } + + /** + * @author + * @reason + */ + @Overwrite + public void turnOnLightLayer() { + RenderSystem.setShaderTexture(2, this.lightTexture.getId()); + } + + @SuppressWarnings("UnreachableCode") + @Inject(method = "updateLightTexture", at = @At("HEAD"), cancellable = true) + public void updateLightTexture(float partialTicks, CallbackInfo ci) { + if (this.updateLightTexture) { + this.updateLightTexture = false; + + this.minecraft.getProfiler().push("lightTex"); + + // TODO: Other mods might be changing lightmap behaviour, we can't be aware of that here + + ClientLevel clientLevel = this.minecraft.level; + if (clientLevel != null) { + float skyDarken = clientLevel.getSkyDarken(1.0F); + float skyFlashTime; + if (clientLevel.getSkyFlashTime() > 0) { + skyFlashTime = 1.0F; + } else { + skyFlashTime = skyDarken * 0.95F + 0.05F; + } + + float darknessEffectScale = this.minecraft.options.darknessEffectScale().get().floatValue(); + float darknessGamma = this.getDarknessGamma(partialTicks) * darknessEffectScale; + float darknessScale = this.calculateDarknessScale(this.minecraft.player, darknessGamma, partialTicks) * darknessEffectScale; + float waterVision = this.minecraft.player.getWaterVision(); + float nightVisionFactor; + if (this.minecraft.player.hasEffect(MobEffects.NIGHT_VISION)) { + nightVisionFactor = GameRenderer.getNightVisionScale(this.minecraft.player, partialTicks); + } else if (waterVision > 0.0F && this.minecraft.player.hasEffect(MobEffects.CONDUIT_POWER)) { + nightVisionFactor = waterVision; + } else { + nightVisionFactor = 0.0F; + } + +// Vector3f skyLightColor = new Vector3f(skyDarken, skyDarken, 1.0F).lerp(new Vector3f(1.0F, 1.0F, 1.0F), 0.35F); + skyDarken = lerp(skyDarken, 1.0f, 0.35f); + Vector3f skyLightColor = this.tempVecs[0].set(skyDarken, skyDarken, 1.0F); + float redFlicker = this.blockLightRedFlicker + 1.5F; + Vector3f lightColor = this.tempVecs[1]; + + float gamma = this.minecraft.options.gamma().get().floatValue(); + float darkenWorldAmount = this.renderer.getDarkenWorldAmount(partialTicks); + boolean forceBrightLightmap = clientLevel.effects().forceBrightLightmap(); + float ambientLight = clientLevel.dimensionType().ambientLight(); + + long ptr = ((NativeImageAccessor)(Object)this.lightPixels).getPixels(); + int width = this.lightPixels.getWidth(); + + Vector3f tVec3f = this.tempVecs[2]; + + for(int y = 0; y < 16; ++y) { + float brY = getBrightness(ambientLight, y) * skyFlashTime; + + for(int x = 0; x < 16; ++x) { + float brX = getBrightness(ambientLight, x) * redFlicker; + float t = brX * ((brX * 0.6F + 0.4F) * 0.6F + 0.4F); + float u = brX * (brX * brX * 0.6F + 0.4F); + lightColor.set(brX, t, u); + + if (forceBrightLightmap) { + lightColor.lerp(tVec3f.set(0.99F, 1.12F, 1.0F), 0.25F); + clampColor(lightColor); + } else { + tVec3f.set(skyLightColor).mul(brY); + lightColor.add(tVec3f); + + tVec3f.set(0.75F, 0.75F, 0.75F); + lightColor.lerp(tVec3f, 0.04F); + + if (darkenWorldAmount > 0.0F) { + tVec3f.set(lightColor).mul(0.7F, 0.6F, 0.6F); + lightColor.lerp(tVec3f, darkenWorldAmount); + } + } + + if (nightVisionFactor > 0.0F) { + // scale up uniformly until 1.0 is hit by one of the colors + float maxComponent = Math.max(lightColor.x(), Math.max(lightColor.y(), lightColor.z())); + if (maxComponent < 1.0F) { + float brightColor = 1.0F / maxComponent; + tVec3f.set(lightColor).mul(brightColor); + lightColor.lerp(tVec3f, nightVisionFactor); + } + } + + if (!forceBrightLightmap) { + lightColor.add(-darknessScale, -darknessScale, -darknessScale); + clampColor(lightColor); + } + + tVec3f.set(this.notGamma(lightColor.x), this.notGamma(lightColor.y), this.notGamma(lightColor.z)); + lightColor.lerp(tVec3f, Math.max(0.0F, gamma - darknessGamma)); + + lightColor.lerp(tVec3f.set(0.75F, 0.75F, 0.75F), 0.04F); + clampColor(lightColor); + + lightColor.mul(255.0F); + int r = (int)lightColor.x(); + int g = (int)lightColor.y(); + int b = (int)lightColor.z(); + + MemoryUtil.memPutInt(ptr + (((long) y * width + x) * 4L), 0xFF000000 | b << 16 | g << 8 | r); + } + } + + CommandPool.CommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer(); + this.lightTexture.upload(); + + try (MemoryStack stack = MemoryStack.stackPush()) { + GlTexture.getTexture(this.lightTexture.getId()).getVulkanImage().readOnlyLayout(stack, commandBuffer.getHandle()); + } + + ImageUploadHelper.INSTANCE.submitCommands(); + + this.minecraft.getProfiler().pop(); + } + } + + ci.cancel(); + } + + @Unique + private float getDarknessGamma(float f) { + MobEffectInstance mobEffectInstance = this.minecraft.player.getEffect(MobEffects.DARKNESS); + return mobEffectInstance != null ? mobEffectInstance.getBlendFactor(this.minecraft.player, f) : 0.0F; + } + + @Unique + private float calculateDarknessScale(LivingEntity livingEntity, float f, float g) { + float h = 0.45F * f; + return Math.max(0.0F, Mth.cos(((float)livingEntity.tickCount - g) * (float) Math.PI * 0.025F) * h); + } + + @Unique + private static float lerp(float a, float x, float t) { + return (x - a) * t + a; + } + + @Unique + private static void clampColor(Vector3f vector3f) { + vector3f.set(Mth.clamp(vector3f.x, 0.0F, 1.0F), Mth.clamp(vector3f.y, 0.0F, 1.0F), Mth.clamp(vector3f.z, 0.0F, 1.0F)); + } + + @Unique + private float notGamma(float f) { + float g = 1.0F - f; + g = g * g; + return 1.0F - g * g; + } + + @Unique + private static float getBrightness(float ambientLight, int i) { + float f = (float)i / 15.0F; + float g = f / (4.0F - 3.0F * f); + return Mth.lerp(ambientLight, g, 1.0F); + } + +} diff --git a/src/main/java/net/vulkanmod/mixin/texture/update/MSpriteContents.java b/src/main/java/net/vulkanmod/mixin/texture/update/MSpriteContents.java new file mode 100644 index 000000000..ea6603d66 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/texture/update/MSpriteContents.java @@ -0,0 +1,37 @@ +package net.vulkanmod.mixin.texture.update; + +import net.minecraft.client.renderer.texture.SpriteContents; +import net.vulkanmod.render.texture.SpriteUpdateUtil; +import net.vulkanmod.vulkan.texture.VTextureSelector; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(SpriteContents.Ticker.class) +public class MSpriteContents { + + @Shadow int subFrame; + @Shadow int frame; + @Shadow @Final SpriteContents.AnimatedTexture animationInfo; + + @Inject(method = "tickAndUpload", at = @At("HEAD"), cancellable = true) + private void checkUpload(int i, int j, CallbackInfo ci) { + if (!SpriteUpdateUtil.doUploadFrame()) { + // Update animations frames even if no upload is scheduled + ++this.subFrame; + SpriteContents.FrameInfo frameInfo = this.animationInfo.frames.get(this.frame); + if (this.subFrame >= frameInfo.time) { + this.frame = (this.frame + 1) % this.animationInfo.frames.size(); + this.subFrame = 0; + } + + ci.cancel(); + } + else { + SpriteUpdateUtil.addTransitionedLayout(VTextureSelector.getBoundTexture()); + } + } +} diff --git a/src/main/java/net/vulkanmod/mixin/texture/MTextureManager.java b/src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java similarity index 61% rename from src/main/java/net/vulkanmod/mixin/texture/MTextureManager.java rename to src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java index f0baa1c9e..551f797ee 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/MTextureManager.java +++ b/src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java @@ -1,10 +1,9 @@ -package net.vulkanmod.mixin.texture; +package net.vulkanmod.mixin.texture.update; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.texture.Tickable; -import net.vulkanmod.render.texture.SpriteUtil; +import net.vulkanmod.render.texture.SpriteUpdateUtil; import net.vulkanmod.vulkan.Renderer; -import net.vulkanmod.vulkan.device.DeviceManager; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -26,14 +25,10 @@ public void tick() { return; //Debug D - if (SpriteUtil.shouldUpload()) - DeviceManager.getGraphicsQueue().startRecording(); for (Tickable tickable : this.tickableTextures) { tickable.tick(); } - if (SpriteUtil.shouldUpload()) { - SpriteUtil.transitionLayouts(DeviceManager.getGraphicsQueue().getCommandBuffer().getHandle()); - DeviceManager.getGraphicsQueue().endRecordingAndSubmit(); - } + + SpriteUpdateUtil.transitionLayouts(); } } diff --git a/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java b/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java index 280f914d0..842c44fd2 100644 --- a/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java +++ b/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java @@ -5,7 +5,7 @@ import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.core.Direction; import net.vulkanmod.interfaces.ExtendedVertexBuilder; -import net.vulkanmod.render.vertex.VertexUtil; +import net.vulkanmod.render.vertex.format.I32_SNorm; import org.joml.Matrix3f; import org.joml.Matrix4f; import org.joml.Vector3f; @@ -115,9 +115,9 @@ private void checkDelegates(VertexConsumer vertexConsumer, PoseStack.Pose pose, @Override public void vertex(float x, float y, float z, int packedColor, float u, float v, int overlay, int light, int packedNormal) { - float nx = VertexUtil.unpackN1(packedNormal); - float ny = VertexUtil.unpackN2(packedNormal); - float nz = VertexUtil.unpackN3(packedNormal); + float nx = I32_SNorm.unpackX(packedNormal); + float ny = I32_SNorm.unpackY(packedNormal); + float nz = I32_SNorm.unpackZ(packedNormal); normal.set(nx, ny, nz); position.set(x, y , z, 1.0f); diff --git a/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java b/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java index 72ef9ae12..5f4c71ce8 100644 --- a/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java +++ b/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java @@ -8,6 +8,7 @@ import net.vulkanmod.config.video.VideoModeManager; import net.vulkanmod.config.option.Options; import net.vulkanmod.config.video.VideoModeSet; +import net.vulkanmod.config.video.WindowMode; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.Vulkan; @@ -163,7 +164,7 @@ private void setMode() { this.wasOnFullscreen = true; } } - else if (config.windowedFullscreen) { + else if (config.windowMode == WindowMode.WINDOWED_FULLSCREEN.mode) { VideoModeSet.VideoMode videoMode = VideoModeManager.getOsVideoMode(); if (!this.wasOnFullscreen) { diff --git a/src/main/java/net/vulkanmod/render/PipelineManager.java b/src/main/java/net/vulkanmod/render/PipelineManager.java index 52b037fdb..97bca6f33 100644 --- a/src/main/java/net/vulkanmod/render/PipelineManager.java +++ b/src/main/java/net/vulkanmod/render/PipelineManager.java @@ -1,27 +1,28 @@ package net.vulkanmod.render; +import com.google.gson.JsonObject; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.renderer.RenderType; import net.vulkanmod.render.chunk.build.thread.ThreadBuilderPack; +import net.vulkanmod.render.shader.ShaderLoadUtil; import net.vulkanmod.render.vertex.CustomVertexFormat; import net.vulkanmod.render.vertex.TerrainRenderType; import net.vulkanmod.vulkan.shader.GraphicsPipeline; import net.vulkanmod.vulkan.shader.Pipeline; -import net.vulkanmod.vulkan.shader.SPIRVUtils; import java.util.function.Function; -import static net.vulkanmod.vulkan.shader.SPIRVUtils.compileShaderAbsoluteFile; - public abstract class PipelineManager { - private static final String shaderPath = SPIRVUtils.class.getResource("/assets/vulkanmod/shaders/").toExternalForm(); - public static VertexFormat TERRAIN_VERTEX_FORMAT; + public static VertexFormat terrainVertexFormat; public static void setTerrainVertexFormat(VertexFormat format) { - TERRAIN_VERTEX_FORMAT = format; + terrainVertexFormat = format; } - static GraphicsPipeline terrainShaderEarlyZ, terrainShader, fastBlitPipeline; + static GraphicsPipeline + terrainShader, terrainShaderEarlyZ, + fastBlitPipeline, cloudsPipeline; private static Function shaderGetter; @@ -33,26 +34,24 @@ public static void init() { } public static void setDefaultShader() { - setShaderGetter(renderType -> renderType == TerrainRenderType.TRANSLUCENT ? terrainShaderEarlyZ : terrainShader); + setShaderGetter( + renderType -> renderType == TerrainRenderType.TRANSLUCENT ? terrainShaderEarlyZ : terrainShader); } private static void createBasicPipelines() { - terrainShaderEarlyZ = createPipeline("terrain","terrain", "terrain_Z", TERRAIN_VERTEX_FORMAT); - terrainShader = createPipeline("terrain", "terrain", "terrain", TERRAIN_VERTEX_FORMAT); - fastBlitPipeline = createPipeline("blit", "blit", "blit", CustomVertexFormat.NONE); + terrainShaderEarlyZ = createPipeline("terrain_earlyZ", terrainVertexFormat); + terrainShader = createPipeline("terrain", terrainVertexFormat); + fastBlitPipeline = createPipeline("blit", CustomVertexFormat.NONE); + cloudsPipeline = createPipeline("clouds", DefaultVertexFormat.POSITION_COLOR); } - private static GraphicsPipeline createPipeline(String baseName, String vertName, String fragName,VertexFormat vertexFormat) { - String pathB = String.format("basic/%s/%s", baseName, baseName); - String pathV = String.format("basic/%s/%s", baseName, vertName); - String pathF = String.format("basic/%s/%s", baseName, fragName); + private static GraphicsPipeline createPipeline(String configName, VertexFormat vertexFormat) { + Pipeline.Builder pipelineBuilder = new Pipeline.Builder(vertexFormat, configName); - Pipeline.Builder pipelineBuilder = new Pipeline.Builder(vertexFormat, pathB); - pipelineBuilder.parseBindingsJSON(); + JsonObject config = ShaderLoadUtil.getJsonConfig("basic", configName); + pipelineBuilder.parseBindings(config); - SPIRVUtils.SPIRV vertShaderSPIRV = compileShaderAbsoluteFile(String.format("%s%s.vsh", shaderPath, pathV), SPIRVUtils.ShaderKind.VERTEX_SHADER); - SPIRVUtils.SPIRV fragShaderSPIRV = compileShaderAbsoluteFile(String.format("%s%s.fsh", shaderPath, pathF), SPIRVUtils.ShaderKind.FRAGMENT_SHADER); - pipelineBuilder.setSPIRVs(vertShaderSPIRV, fragShaderSPIRV); + ShaderLoadUtil.loadShaders(pipelineBuilder, config, configName, "basic"); return pipelineBuilder.createGraphicsPipeline(); } @@ -73,11 +72,18 @@ public static GraphicsPipeline getTerrainIndirectShader(RenderType renderType) { return terrainShaderEarlyZ; } - public static GraphicsPipeline getFastBlitPipeline() { return fastBlitPipeline; } + public static GraphicsPipeline getFastBlitPipeline() { + return fastBlitPipeline; + } + + public static GraphicsPipeline getCloudsPipeline() { + return cloudsPipeline; + } public static void destroyPipelines() { terrainShaderEarlyZ.cleanUp(); terrainShader.cleanUp(); fastBlitPipeline.cleanUp(); + cloudsPipeline.cleanUp(); } } diff --git a/src/main/java/net/vulkanmod/render/VBO.java b/src/main/java/net/vulkanmod/render/VBO.java index 1ebc59660..4a45326c6 100644 --- a/src/main/java/net/vulkanmod/render/VBO.java +++ b/src/main/java/net/vulkanmod/render/VBO.java @@ -9,10 +9,10 @@ import net.vulkanmod.interfaces.ShaderMixed; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; -import net.vulkanmod.vulkan.memory.AutoIndexBuffer; -import net.vulkanmod.vulkan.memory.IndexBuffer; -import net.vulkanmod.vulkan.memory.MemoryTypes; -import net.vulkanmod.vulkan.memory.VertexBuffer; +import net.vulkanmod.vulkan.memory.*; +import net.vulkanmod.vulkan.memory.buffer.IndexBuffer; +import net.vulkanmod.vulkan.memory.buffer.VertexBuffer; +import net.vulkanmod.vulkan.memory.buffer.index.AutoIndexBuffer; import net.vulkanmod.vulkan.shader.GraphicsPipeline; import net.vulkanmod.vulkan.shader.Pipeline; import net.vulkanmod.vulkan.texture.VTextureSelector; @@ -22,6 +22,7 @@ @Environment(EnvType.CLIENT) public class VBO { + private final MemoryType memoryType; private VertexBuffer vertexBuffer; private IndexBuffer indexBuffer; @@ -29,9 +30,12 @@ public class VBO { private int vertexCount; private VertexFormat.Mode mode; + AutoIndexBuffer autoIndexBuffer; private boolean autoIndexed = false; - public VBO() {} + public VBO(com.mojang.blaze3d.vertex.VertexBuffer.Usage usage) { + this.memoryType = usage == com.mojang.blaze3d.vertex.VertexBuffer.Usage.STATIC ? MemoryTypes.GPU_MEM : MemoryTypes.HOST_MEM; + } public void upload(MeshData meshData) { MeshData.DrawState parameters = meshData.drawState(); @@ -49,9 +53,9 @@ public void upload(MeshData meshData) { private void uploadVertexBuffer(MeshData.DrawState parameters, ByteBuffer data) { if (data != null) { if (this.vertexBuffer != null) - this.vertexBuffer.freeBuffer(); + this.vertexBuffer.scheduleFree(); - this.vertexBuffer = new VertexBuffer(data.remaining(), MemoryTypes.GPU_MEM); + this.vertexBuffer = new VertexBuffer(data.remaining(), this.memoryType); this.vertexBuffer.copyToVertexBuffer(parameters.format().getVertexSize(), parameters.vertexCount(), data); } } @@ -84,19 +88,20 @@ public void uploadIndexBuffer(ByteBuffer data) { default -> throw new IllegalStateException("Unexpected draw mode: %s".formatted(this.mode)); } - if (this.indexBuffer != null && !this.autoIndexed) - this.indexBuffer.freeBuffer(); + if (this.indexBuffer != null && !this.autoIndexed) { + this.indexBuffer.scheduleFree(); + } if (autoIndexBuffer != null) { autoIndexBuffer.checkCapacity(this.vertexCount); - this.indexBuffer = autoIndexBuffer.getIndexBuffer(); + this.autoIndexBuffer = autoIndexBuffer; } this.autoIndexed = true; } else { if (this.indexBuffer != null) - this.indexBuffer.freeBuffer(); + this.indexBuffer.scheduleFree(); this.indexBuffer = new IndexBuffer(data.remaining(), MemoryTypes.GPU_MEM); this.indexBuffer.copyBuffer(data); @@ -128,10 +133,19 @@ public void drawWithShader(Matrix4f MV, Matrix4f P, GraphicsPipeline pipeline) { VTextureSelector.bindShaderTextures(pipeline); renderer.uploadAndBindUBOs(pipeline); - if (this.indexBuffer != null) - Renderer.getDrawer().drawIndexed(this.vertexBuffer, this.indexBuffer, this.indexCount); - else + IndexBuffer indexBuffer; + if (this.autoIndexBuffer != null) { + indexBuffer = this.autoIndexBuffer.getIndexBuffer(); + } else { + indexBuffer = this.indexBuffer; + } + + if (indexBuffer != null) { + Renderer.getDrawer().drawIndexed(this.vertexBuffer, indexBuffer, this.indexCount); + } + else { Renderer.getDrawer().draw(this.vertexBuffer, this.vertexCount); + } VRenderSystem.applyMVP(RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix()); @@ -154,11 +168,11 @@ public void close() { if (this.vertexCount <= 0) return; - this.vertexBuffer.freeBuffer(); + this.vertexBuffer.scheduleFree(); this.vertexBuffer = null; if (!this.autoIndexed) { - this.indexBuffer.freeBuffer(); + this.indexBuffer.scheduleFree(); this.indexBuffer = null; } diff --git a/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java b/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java index 26e6bb1e8..85400a8f1 100644 --- a/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java +++ b/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java @@ -11,11 +11,11 @@ public class ChunkArea { public final int index; + final DrawBuffers drawBuffers; final Vector3i position; final byte[] frustumBuffer = new byte[64]; - int sectionsContained = 0; - DrawBuffers drawBuffers; + int sectionsContained = 0; //Help JIT optimisations by hardcoding the queue size to the max possible ChunkArea limit public final StaticQueue sectionQueue = new StaticQueue<>(512); @@ -142,11 +142,15 @@ public void removeSection() { this.sectionsContained--; if (this.sectionsContained == 0) { - this.releaseBuffers(); + this.drawBuffers.releaseBuffers(); } } public void releaseBuffers() { this.drawBuffers.releaseBuffers(); } + + public void free() { + this.drawBuffers.free(); + } } diff --git a/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java b/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java index aa17b5047..4b79212b6 100644 --- a/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java +++ b/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java @@ -12,6 +12,8 @@ public class ChunkAreaManager { public static final int WIDTH = 8; public static final int HEIGHT = 8; + public static final int AREA_SIZE = WIDTH * WIDTH * HEIGHT; + public static final int AREA_SH_XZ = Util.flooredLog(WIDTH); public static final int AREA_SH_Y = Util.flooredLog(HEIGHT); @@ -29,6 +31,10 @@ public class ChunkAreaManager { int prevX; int prevZ; + private final CircularIntList xList; + private final CircularIntList zList; + private final CircularIntList.RangeIterator xComplIterator; + public ChunkAreaManager(int width, int height, int minHeight) { this.minHeight = minHeight; this.sectionGridWidth = width; @@ -59,6 +65,10 @@ public ChunkAreaManager(int width, int height, int minHeight) { this.prevX = Integer.MIN_VALUE; this.prevZ = Integer.MIN_VALUE; + + this.xList = new CircularIntList(this.xzSize); + this.zList = new CircularIntList(this.xzSize); + this.xComplIterator = this.xList.createRangeIterator(); } public void repositionAreas(int secX, int secZ) { @@ -73,8 +83,11 @@ public void repositionAreas(int secX, int secZ) { int zAbsChunkIndex = zS - this.xzSize / 2; int zStart = Math.floorMod(zAbsChunkIndex, this.xzSize); - CircularIntList xList = new CircularIntList(this.xzSize, xStart); - CircularIntList zList = new CircularIntList(this.xzSize, zStart); + CircularIntList xList = this.xList; + CircularIntList zList = this.zList; + xList.updateStartIdx(xStart); + zList.updateStartIdx(zStart); + CircularIntList.OwnIterator xIterator = xList.iterator(); CircularIntList.OwnIterator zIterator = zList.iterator(); @@ -104,9 +117,10 @@ public void repositionAreas(int secX, int secZ) { zRangeEnd = -deltaZ - 1; } - CircularIntList.RangeIterator xRangeIterator = xList.rangeIterator(xRangeStart, xRangeEnd); - CircularIntList.RangeIterator xComplIterator = xList.rangeIterator(xComplStart, xComplEnd); - CircularIntList.RangeIterator zRangeIterator = zList.rangeIterator(zRangeStart, zRangeEnd); + CircularIntList.RangeIterator xRangeIterator = xList.getRangeIterator(xRangeStart, xRangeEnd); + CircularIntList.RangeIterator zRangeIterator = zList.getRangeIterator(zRangeStart, zRangeEnd); + CircularIntList.RangeIterator xComplIterator = this.xComplIterator; + xComplIterator.update(xComplStart, xComplEnd); xAbsChunkIndex = xS - this.xzSize / 2 + xRangeStart; for (int xRelativeIndex; xRangeIterator.hasNext(); xAbsChunkIndex++) { @@ -121,12 +135,7 @@ public void repositionAreas(int secX, int secZ) { int z1 = (zAbsChunkIndex << (AREA_SH_XZ + SEC_SH)); for (int yRel = 0; yRel < this.ySize; ++yRel) { - int y1 = this.minHeight + (yRel << (AREA_SH_Y + SEC_SH)); - ChunkArea chunkArea = this.chunkAreasArr[this.getAreaIndex(xRelativeIndex, yRel, zRelativeIndex)]; - - chunkArea.setPosition(x1, y1, z1); - chunkArea.releaseBuffers(); - + this.moveArea(xRelativeIndex, yRel, zRelativeIndex, x1, z1); } } } @@ -144,12 +153,7 @@ public void repositionAreas(int secX, int secZ) { int z1 = (zAbsChunkIndex << (AREA_SH_XZ + SEC_SH)); for (int yRel = 0; yRel < this.ySize; ++yRel) { - int y1 = this.minHeight + (yRel << (AREA_SH_Y + SEC_SH)); - ChunkArea chunkArea = this.chunkAreasArr[this.getAreaIndex(xRelativeIndex, yRel, zRelativeIndex)]; - - chunkArea.setPosition(x1, y1, z1); - chunkArea.releaseBuffers(); - + this.moveArea(xRelativeIndex, yRel, zRelativeIndex, x1, z1); } } } @@ -158,6 +162,14 @@ public void repositionAreas(int secX, int secZ) { this.prevZ = zS; } + private void moveArea(int xRelativeIndex, int yRel, int zRelativeIndex, int x1, int z1) { + int y1 = this.minHeight + (yRel << (AREA_SH_Y + SEC_SH)); + ChunkArea chunkArea = this.chunkAreasArr[this.getAreaIndex(xRelativeIndex, yRel, zRelativeIndex)]; + + chunkArea.setPosition(x1, y1, z1); + chunkArea.releaseBuffers(); + } + public ChunkArea getChunkArea(RenderSection section, int x, int y, int z) { ChunkArea chunkArea; @@ -195,9 +207,9 @@ private int getAreaIndex(int x, int y, int z) { return (z * this.ySize + y) * this.xzSize + x; } - public void releaseAllBuffers() { + public void freeAllBuffers() { for (ChunkArea chunkArea : this.chunkAreasArr) { - chunkArea.releaseBuffers(); + chunkArea.free(); } } @@ -229,11 +241,12 @@ public String[] getStats() { } } - vbSize /= 1024 * 1024; - vbUsed /= 1024 * 1024; - ibSize /= 1024 * 1024; - ibUsed /= 1024 * 1024; - frag /= 1024 * 1024; + final int div = 1024 * 1024; + vbSize /= div; + vbUsed /= div; + ibSize /= div; + ibUsed /= div; + frag /= div; return new String[]{ String.format("Vertex Buffers: %d/%d MB", vbUsed, vbSize), diff --git a/src/main/java/net/vulkanmod/render/chunk/RenderSection.java b/src/main/java/net/vulkanmod/render/chunk/RenderSection.java index a1c54fca8..81dca75d9 100644 --- a/src/main/java/net/vulkanmod/render/chunk/RenderSection.java +++ b/src/main/java/net/vulkanmod/render/chunk/RenderSection.java @@ -6,14 +6,17 @@ import net.minecraft.client.Minecraft; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; +import net.vulkanmod.render.chunk.buffer.AreaBuffer; import net.vulkanmod.render.chunk.buffer.DrawBuffers; +import net.vulkanmod.render.chunk.buffer.DrawParametersBuffer; import net.vulkanmod.render.chunk.build.RenderRegion; import net.vulkanmod.render.chunk.build.RenderRegionBuilder; -import net.vulkanmod.render.chunk.build.TaskDispatcher; +import net.vulkanmod.render.chunk.build.task.TaskDispatcher; import net.vulkanmod.render.chunk.build.task.BuildTask; import net.vulkanmod.render.chunk.build.task.ChunkTask; import net.vulkanmod.render.chunk.build.task.CompiledSection; import net.vulkanmod.render.chunk.build.task.SortTransparencyTask; +import net.vulkanmod.render.chunk.cull.QuadFacing; import net.vulkanmod.render.chunk.graph.GraphDirections; import net.vulkanmod.render.chunk.util.Util; import net.vulkanmod.render.vertex.TerrainRenderType; @@ -29,6 +32,7 @@ public class RenderSection { public byte frustumIndex; public short lastFrame = -1; private short lastFrame2 = -1; + public short inAreaIndex; public byte adjDirs; public RenderSection @@ -47,8 +51,6 @@ public class RenderSection { public int xOffset, yOffset, zOffset; - private final DrawBuffers.DrawParameters[] drawParametersArray; - // Graph-info public byte mainDir; public byte directions; @@ -60,11 +62,6 @@ public RenderSection(int index, int x, int y, int z) { this.xOffset = x; this.yOffset = y; this.zOffset = z; - - this.drawParametersArray = new DrawBuffers.DrawParameters[TerrainRenderType.VALUES.length]; - for (int i = 0; i < this.drawParametersArray.length; ++i) { - this.drawParametersArray[i] = new DrawBuffers.DrawParameters(); - } } public void setOrigin(int x, int y, int z) { @@ -297,8 +294,20 @@ public int zOffset() { return zOffset; } - public DrawBuffers.DrawParameters getDrawParameters(TerrainRenderType renderType) { - return drawParametersArray[renderType.ordinal()]; + public void resetDrawParameters(TerrainRenderType renderType) { + for (int i = 0; i < QuadFacing.COUNT; ++i) { + DrawBuffers drawBuffers = this.chunkArea.getDrawBuffers(); + long ptr = DrawParametersBuffer.getParamsPtr(drawBuffers.getDrawParamsPtr(), this.inAreaIndex, renderType.ordinal(), i); + + AreaBuffer areaBuffer = drawBuffers.getAreaBuffer(renderType); + int vertexOffset = DrawParametersBuffer.getVertexOffset(ptr); + if (areaBuffer != null && vertexOffset != -1) { + int segmentOffset = vertexOffset * DrawBuffers.VERTEX_SIZE; + areaBuffer.setSegmentFree(segmentOffset); + } + + DrawParametersBuffer.resetParameters(ptr); + } } public void setChunkArea(ChunkArea chunkArea) { @@ -339,6 +348,10 @@ public byte getVisibilityDirs() { return (byte) (this.visibility >> (Util.getOppositeDirIdx(this.mainDir) << 3)); } + public long getVisibility() { + return visibility; + } + public boolean isCompletelyEmpty() { return this.completelyEmpty; } @@ -355,8 +368,7 @@ public void updateGlobalBlockEntities(Collection fullSet) { Set set1; Set sectionSet; synchronized (globalBlockEntitiesMap) { - sectionSet = globalBlockEntitiesMap.computeIfAbsent(this, - (section) -> new ObjectOpenHashSet<>()); + sectionSet = globalBlockEntitiesMap.computeIfAbsent(this, (section) -> new ObjectOpenHashSet<>()); } if (sectionSet.size() != fullSet.size() || !sectionSet.containsAll(fullSet)) { @@ -385,8 +397,12 @@ private void resetDrawParameters() { if (this.chunkArea == null) return; - for (TerrainRenderType r : TerrainRenderType.VALUES) { - this.getDrawParameters(r).reset(this.chunkArea, r); + long basePtr = this.chunkArea.getDrawBuffers().getDrawParamsPtr(); + for (TerrainRenderType renderType : TerrainRenderType.VALUES) { + for (QuadFacing facing : QuadFacing.VALUES) { + long ptr = DrawParametersBuffer.getParamsPtr(basePtr, this.inAreaIndex, renderType.ordinal(), facing.ordinal()); + DrawParametersBuffer.resetParameters(ptr); + } } } @@ -418,6 +434,10 @@ public short getLastFrame() { return this.lastFrame; } + public short getLastFrame2() { + return this.lastFrame2; + } + static class CompileStatus { CompiledSection compiledSection = CompiledSection.UNCOMPILED; BuildTask buildTask; diff --git a/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java b/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java index 54ee8d3ed..b6d142b22 100644 --- a/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java +++ b/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java @@ -23,6 +23,10 @@ public class SectionGrid { private int prevSecX; private int prevSecZ; + private final CircularIntList xList; + private final CircularIntList zList; + private final CircularIntList.RangeIterator xComplIterator; + public SectionGrid(Level level, int viewDistance) { this.level = level; this.setViewDistance(viewDistance); @@ -31,6 +35,10 @@ public SectionGrid(Level level, int viewDistance) { this.prevSecX = Integer.MIN_VALUE; this.prevSecZ = Integer.MIN_VALUE; + + this.xList = new CircularIntList(this.gridWidth); + this.zList = new CircularIntList(this.gridWidth); + this.xComplIterator = this.xList.createRangeIterator(); } protected void createChunks() { @@ -53,8 +61,8 @@ protected void createChunks() { } } - public void releaseAllBuffers() { - this.chunkAreaManager.releaseAllBuffers(); + public void freeAllBuffers() { + this.chunkAreaManager.freeAllBuffers(); } private int getChunkIndex(int x, int y, int z) { @@ -86,8 +94,11 @@ public void repositionCamera(double x, double z) { int zAbsChunkIndex = secZ - this.gridWidth / 2; int zStart = Math.floorMod(zAbsChunkIndex, this.gridWidth); - CircularIntList xList = new CircularIntList(this.gridWidth, xStart); - CircularIntList zList = new CircularIntList(this.gridWidth, zStart); + CircularIntList xList = this.xList; + CircularIntList zList = this.zList; + xList.updateStartIdx(xStart); + zList.updateStartIdx(zStart); + CircularIntList.OwnIterator xIterator = xList.iterator(); CircularIntList.OwnIterator zIterator = zList.iterator(); @@ -117,9 +128,10 @@ public void repositionCamera(double x, double z) { zRangeEnd = -dz - 1; } - CircularIntList.RangeIterator xRangeIterator = xList.rangeIterator(xRangeStart, xRangeEnd); - CircularIntList.RangeIterator xComplIterator = xList.rangeIterator(xComplStart, xComplEnd); - CircularIntList.RangeIterator zRangeIterator = zList.rangeIterator(zRangeStart, zRangeEnd); + CircularIntList.RangeIterator xRangeIterator = xList.getRangeIterator(xRangeStart, xRangeEnd); + CircularIntList.RangeIterator zRangeIterator = zList.getRangeIterator(zRangeStart, zRangeEnd); + CircularIntList.RangeIterator xComplIterator = this.xComplIterator; + xComplIterator.update(xComplStart, xComplEnd); xAbsChunkIndex = secX - (this.gridWidth >> 1) + xRangeStart; for (int xRelativeIndex; xRangeIterator.hasNext(); xAbsChunkIndex++) { @@ -133,19 +145,9 @@ public void repositionCamera(double x, double z) { zRelativeIndex = zIterator.next(); int z1 = (zAbsChunkIndex << 4); - for (int yRel = 0; - yRel < this.gridHeight; ++yRel) { - int y1 = this.level.getMinBuildHeight() + (yRel << 4); - RenderSection renderSection = this.sections[this.getChunkIndex(xRelativeIndex, yRel, zRelativeIndex)]; - - renderSection.setOrigin(x1, y1, z1); - - this.unsetNeighbours(renderSection); - - this.setNeighbours(renderSection, xList, zList, xRangeIterator.getCurrentIndex(), zIterator.getCurrentIndex(), - xRelativeIndex, yRel, zRelativeIndex); - - this.setChunkArea(renderSection, x1, y1, z1); + for (int yRel = 0; yRel < this.gridHeight; ++yRel) { + moveSection(xRelativeIndex, yRel, zRelativeIndex, x1, z1, + xList, zList, xRangeIterator.getCurrentIndex(), zIterator.getCurrentIndex()); } } } @@ -162,26 +164,45 @@ public void repositionCamera(double x, double z) { zRelativeIndex = zRangeIterator.next(); int z1 = (zAbsChunkIndex << 4); - for (int yRel = 0; - yRel < this.gridHeight; ++yRel) { - int y1 = this.level.getMinBuildHeight() + (yRel << 4); - RenderSection renderSection = this.sections[this.getChunkIndex(xRelativeIndex, yRel, zRelativeIndex)]; + for (int yRel = 0; yRel < this.gridHeight; ++yRel) { + moveSection(xRelativeIndex, yRel, zRelativeIndex, x1, z1, + xList, zList, xComplIterator.getCurrentIndex(), zRangeIterator.getCurrentIndex()); + } + } + } - renderSection.setOrigin(x1, y1, z1); + this.prevSecX = secX; + this.prevSecZ = secZ; + } - this.unsetNeighbours(renderSection); + private void moveSection(int xRelativeIndex, int yRel, int zRelativeIndex, + int x1, int z1, + CircularIntList xList, CircularIntList zList, + int xCurrentIdx, int zCurrentIdx) { - this.setNeighbours(renderSection, xList, zList, xComplIterator.getCurrentIndex(), zRangeIterator.getCurrentIndex(), - xRelativeIndex, yRel, zRelativeIndex); + int y1 = this.level.getMinBuildHeight() + (yRel << 4); + RenderSection renderSection = this.sections[this.getChunkIndex(xRelativeIndex, yRel, zRelativeIndex)]; - this.setChunkArea(renderSection, x1, y1, z1); + this.unsetNeighbours(renderSection); - } - } + renderSection.setOrigin(x1, y1, z1); + + this.setNeighbours(renderSection, xList, zList, xCurrentIdx, zCurrentIdx, + xRelativeIndex, yRel, zRelativeIndex); + + ChunkArea oldArea = renderSection.getChunkArea(); + + if (oldArea != null) { + oldArea.removeSection(); } - this.prevSecX = secX; - this.prevSecZ = secZ; + ChunkArea chunkArea = this.chunkAreaManager.getChunkArea(renderSection, x1, y1, z1); + chunkArea.addSection(); + renderSection.setChunkArea(chunkArea); + + renderSection.inAreaIndex = (short) (((x1 - chunkArea.position.x()) >> 4) + + (((z1 - chunkArea.position.z()) >> 4) * 8 + ((y1 - chunkArea.position.y()) >> 4)) * 8); + } private void setNeighbours(RenderSection section, CircularIntList xList, CircularIntList zList, diff --git a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java index c7fe74ef1..06fb17ec7 100644 --- a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java @@ -26,9 +26,8 @@ import net.vulkanmod.Initializer; import net.vulkanmod.render.PipelineManager; import net.vulkanmod.render.chunk.buffer.DrawBuffers; -import net.vulkanmod.render.chunk.build.BlockRenderer; import net.vulkanmod.render.chunk.build.RenderRegionBuilder; -import net.vulkanmod.render.chunk.build.TaskDispatcher; +import net.vulkanmod.render.chunk.build.task.TaskDispatcher; import net.vulkanmod.render.chunk.build.task.ChunkTask; import net.vulkanmod.render.chunk.graph.SectionGraph; import net.vulkanmod.render.profiling.BuildTimeProfiler; @@ -36,9 +35,9 @@ import net.vulkanmod.render.vertex.TerrainRenderType; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; -import net.vulkanmod.vulkan.memory.Buffer; -import net.vulkanmod.vulkan.memory.IndexBuffer; -import net.vulkanmod.vulkan.memory.IndirectBuffer; +import net.vulkanmod.vulkan.memory.buffer.Buffer; +import net.vulkanmod.vulkan.memory.buffer.IndexBuffer; +import net.vulkanmod.vulkan.memory.buffer.IndirectBuffer; import net.vulkanmod.vulkan.memory.MemoryTypes; import net.vulkanmod.vulkan.shader.GraphicsPipeline; import net.vulkanmod.vulkan.texture.VTextureSelector; @@ -92,8 +91,7 @@ private WorldRenderer(RenderBuffers renderBuffers) { this.taskDispatcher = new TaskDispatcher(); ChunkTask.setTaskDispatcher(this.taskDispatcher); allocateIndirectBuffers(); - - BlockRenderer.setBlockColors(this.minecraft.getBlockColors()); + TerrainRenderType.updateMapping(); Renderer.getInstance().addOnResizeCallback(() -> { if (this.indirectBuffers.length != Renderer.getFramesNum()) @@ -103,16 +101,13 @@ private WorldRenderer(RenderBuffers renderBuffers) { private void allocateIndirectBuffers() { if (this.indirectBuffers != null) - Arrays.stream(this.indirectBuffers).forEach(Buffer::freeBuffer); + Arrays.stream(this.indirectBuffers).forEach(Buffer::scheduleFree); this.indirectBuffers = new IndirectBuffer[Renderer.getFramesNum()]; for (int i = 0; i < this.indirectBuffers.length; ++i) { this.indirectBuffers[i] = new IndirectBuffer(1000000, MemoryTypes.HOST_MEM); -// this.indirectBuffers[i] = new IndirectBuffer(1000000, MemoryTypes.GPU_MEM); } - -// uniformBuffers = new UniformBuffers(100000, MemoryTypes.GPU_MEM); } public static WorldRenderer init(RenderBuffers renderBuffers) { @@ -199,7 +194,6 @@ public void setupRenderer(Camera camera, Frustum frustum, boolean isCapturedFrus } this.indirectBuffers[Renderer.getCurrentFrame()].reset(); -// this.uniformBuffers.reset(); this.minecraft.getProfiler().pop(); profiler.pop(); @@ -242,7 +236,7 @@ public void allChanged() { this.renderDistance = this.minecraft.options.getEffectiveRenderDistance(); if (this.sectionGrid != null) { - this.sectionGrid.releaseAllBuffers(); + this.sectionGrid.freeAllBuffers(); } this.taskDispatcher.clearBatchQueue(); @@ -278,7 +272,7 @@ public void setLevel(@Nullable ClientLevel level) { this.allChanged(); } else { if (this.sectionGrid != null) { - this.sectionGrid.releaseAllBuffers(); + this.sectionGrid.freeAllBuffers(); this.sectionGrid = null; } @@ -338,9 +332,9 @@ public void renderSectionLayer(RenderType renderType, double camX, double camY, renderer.uploadAndBindUBOs(pipeline); if (indirectDraw) - drawBuffers.buildDrawBatchesIndirect(indirectBuffers[currentFrame], queue, terrainRenderType); + drawBuffers.buildDrawBatchesIndirect(cameraPos, indirectBuffers[currentFrame], queue, terrainRenderType); else - drawBuffers.buildDrawBatchesDirect(queue, terrainRenderType); + drawBuffers.buildDrawBatchesDirect(cameraPos, queue, terrainRenderType); } } } @@ -352,7 +346,7 @@ public void renderSectionLayer(RenderType renderType, double camX, double camY, //Need to reset push constants in case the pipeline will still be used for rendering if (!indirectDraw) { - VRenderSystem.setChunkOffset(0, 0, 0); + VRenderSystem.setModelOffset(0, 0, 0); renderer.pushConstants(pipeline); } @@ -468,7 +462,7 @@ public String getChunkStatistics() { public void cleanUp() { if (indirectBuffers != null) - Arrays.stream(indirectBuffers).forEach(Buffer::freeBuffer); + Arrays.stream(indirectBuffers).forEach(Buffer::scheduleFree); } } diff --git a/src/main/java/net/vulkanmod/render/chunk/buffer/AreaBuffer.java b/src/main/java/net/vulkanmod/render/chunk/buffer/AreaBuffer.java index b19f3a112..c2c02db66 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/AreaBuffer.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/AreaBuffer.java @@ -4,6 +4,9 @@ import net.vulkanmod.Initializer; import net.vulkanmod.render.chunk.util.Util; import net.vulkanmod.vulkan.memory.*; +import net.vulkanmod.vulkan.memory.buffer.Buffer; +import net.vulkanmod.vulkan.memory.buffer.IndexBuffer; +import net.vulkanmod.vulkan.memory.buffer.VertexBuffer; import org.apache.logging.log4j.Logger; import java.nio.ByteBuffer; @@ -49,7 +52,7 @@ private Buffer allocateBuffer() { return buffer; } - public Segment upload(ByteBuffer byteBuffer, int oldOffset, DrawBuffers.DrawParameters drawParameters) { + public Segment upload(ByteBuffer byteBuffer, int oldOffset, long paramsPtr) { // Free old segment if (oldOffset != -1) { // Need to delay segment freeing since it might be still used by prev frames in flight @@ -81,7 +84,7 @@ public Segment upload(ByteBuffer byteBuffer, int oldOffset, DrawBuffers.DrawPara segment.free = false; this.usedSegments.put(segment.offset, segment); - segment.drawParameters = drawParameters; + segment.paramsPtr = paramsPtr; Buffer dst = this.buffer; UploadManager.INSTANCE.recordUpload(dst, segment.offset, size, byteBuffer); @@ -115,7 +118,7 @@ public Segment reallocate(int uploadSize) { int oldSize = this.size; int minIncrement = this.size >> 3; - minIncrement = Util.align(minIncrement, this.elementSize); + minIncrement = (int) Util.align(minIncrement, this.elementSize); int increment = Math.max(minIncrement, uploadSize << 1); @@ -132,7 +135,7 @@ public Segment reallocate(int uploadSize) { // TODO: moving only used segments causes corruption // moveUsedSegments(dst); - this.buffer.freeBuffer(); + this.buffer.scheduleFree(); this.buffer = dst; if (last.isFree()) { @@ -227,7 +230,7 @@ public void setSegmentFree(int offset) { this.used -= segment.size; segment.free = true; - segment.drawParameters = null; + segment.paramsPtr = -1; Segment next = segment.next; if (next != null && next.isFree()) { @@ -254,13 +257,11 @@ private void mergeSegments(Segment segment, Segment next) { } private void updateDrawParams(Segment segment) { - DrawBuffers.DrawParameters params = segment.drawParameters; - int elementOffset = segment.offset / elementSize; if (this.usage == Usage.VERTEX.usage) { - params.vertexOffset = elementOffset; + DrawParametersBuffer.setVertexOffset(segment.paramsPtr, elementOffset); } else { - params.firstIndex = elementOffset; + DrawParametersBuffer.setFirstIndex(segment.paramsPtr, elementOffset); } } @@ -269,7 +270,7 @@ public long getId() { } public void freeBuffer() { - this.buffer.freeBuffer(); + this.buffer.scheduleFree(); } public int fragmentation() { @@ -351,7 +352,7 @@ public int getUsed() { public static class Segment { int offset, size; boolean free = true; - DrawBuffers.DrawParameters drawParameters; + long paramsPtr; Segment next, prev; diff --git a/src/main/java/net/vulkanmod/render/chunk/buffer/DrawBuffers.java b/src/main/java/net/vulkanmod/render/chunk/buffer/DrawBuffers.java index 8556e0426..24f3c9550 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/DrawBuffers.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/DrawBuffers.java @@ -1,14 +1,17 @@ package net.vulkanmod.render.chunk.buffer; +import net.minecraft.world.phys.Vec3; +import net.vulkanmod.Initializer; import net.vulkanmod.render.PipelineManager; -import net.vulkanmod.render.chunk.ChunkArea; +import net.vulkanmod.render.chunk.ChunkAreaManager; import net.vulkanmod.render.chunk.RenderSection; import net.vulkanmod.render.chunk.build.UploadBuffer; +import net.vulkanmod.render.chunk.cull.QuadFacing; import net.vulkanmod.render.chunk.util.StaticQueue; import net.vulkanmod.render.vertex.CustomVertexFormat; import net.vulkanmod.render.vertex.TerrainRenderType; import net.vulkanmod.vulkan.Renderer; -import net.vulkanmod.vulkan.memory.IndirectBuffer; +import net.vulkanmod.vulkan.memory.buffer.IndirectBuffer; import net.vulkanmod.vulkan.shader.Pipeline; import org.joml.Vector3i; import org.lwjgl.system.MemoryStack; @@ -21,8 +24,13 @@ import static org.lwjgl.vulkan.VK10.*; public class DrawBuffers { - private static final int VERTEX_SIZE = PipelineManager.TERRAIN_VERTEX_FORMAT.getVertexSize(); - private static final int INDEX_SIZE = Short.BYTES; + public static final int VERTEX_SIZE = PipelineManager.terrainVertexFormat.getVertexSize(); + public static final int INDEX_SIZE = Short.BYTES; + + private static final int CMD_STRIDE = 32; + + private static final long cmdBufferPtr = MemoryUtil.nmemAlignedAlloc(CMD_STRIDE, (long) ChunkAreaManager.AREA_SIZE * QuadFacing.COUNT * CMD_STRIDE); + private final int index; private final Vector3i origin; private final int minHeight; @@ -31,36 +39,75 @@ public class DrawBuffers { AreaBuffer indexBuffer; private final EnumMap vertexBuffers = new EnumMap<>(TerrainRenderType.class); + long drawParamsPtr; + final int[] sectionIndices = new int[512]; + final int[] masks = new int[512]; + //Need ugly minHeight Parameter to fix custom world heights (exceeding 384 Blocks in total) public DrawBuffers(int index, Vector3i origin, int minHeight) { this.index = index; this.origin = origin; this.minHeight = minHeight; + + this.drawParamsPtr = DrawParametersBuffer.allocateBuffer(); } public void upload(RenderSection section, UploadBuffer buffer, TerrainRenderType renderType) { - DrawParameters drawParameters = section.getDrawParameters(renderType); - int vertexOffset = drawParameters.vertexOffset; - int firstIndex = -1; - - if (!buffer.indexOnly) { - AreaBuffer.Segment segment = this.getAreaBufferOrAlloc(renderType).upload(buffer.getVertexBuffer(), vertexOffset, drawParameters); - vertexOffset = segment.offset / VERTEX_SIZE; + var vertexBuffers = buffer.getVertexBuffers(); - drawParameters.baseInstance = encodeSectionOffset(section.xOffset(), section.yOffset(), section.zOffset()); - } + if (buffer.indexOnly) { + long paramsPtr = DrawParametersBuffer.getParamsPtr(this.drawParamsPtr, section.inAreaIndex, renderType.ordinal(), QuadFacing.UNDEFINED.ordinal()); - if (!buffer.autoIndices) { - if (this.indexBuffer == null) - this.indexBuffer = new AreaBuffer(AreaBuffer.Usage.INDEX, 60000, INDEX_SIZE); + int firstIndex = DrawParametersBuffer.getFirstIndex(paramsPtr); + int indexCount = DrawParametersBuffer.getIndexCount(paramsPtr); - AreaBuffer.Segment segment = this.indexBuffer.upload(buffer.getIndexBuffer(), drawParameters.firstIndex, drawParameters); + int oldOffset = indexCount > 0 ? firstIndex : -1; + AreaBuffer.Segment segment = this.indexBuffer.upload(buffer.getIndexBuffer(), oldOffset, paramsPtr); firstIndex = segment.offset / INDEX_SIZE; + + DrawParametersBuffer.setFirstIndex(paramsPtr, firstIndex); + + buffer.release(); + return; } - drawParameters.indexCount = buffer.indexCount; - drawParameters.firstIndex = firstIndex; - drawParameters.vertexOffset = vertexOffset; + for (int i = 0; i < QuadFacing.COUNT; i++) { + long paramPtr = DrawParametersBuffer.getParamsPtr(this.drawParamsPtr, section.inAreaIndex, renderType.ordinal(), i); + + int vertexOffset = DrawParametersBuffer.getVertexOffset(paramPtr); + int firstIndex = 0; + int indexCount = 0; + + var vertexBuffer = vertexBuffers[i]; + int vertexCount = 0; + + if (vertexBuffer != null) { + AreaBuffer.Segment segment = this.getAreaBufferOrAlloc(renderType).upload(vertexBuffer, vertexOffset, paramPtr); + vertexOffset = segment.offset / VERTEX_SIZE; + + int baseInstance = encodeSectionOffset(section.xOffset(), section.yOffset(), section.zOffset()); + DrawParametersBuffer.setBaseInstance(paramPtr, baseInstance); + + vertexCount = vertexBuffer.limit() / VERTEX_SIZE; + indexCount = vertexCount * 6 / 4; + } + + if (i == QuadFacing.UNDEFINED.ordinal() && !buffer.autoIndices) { + if (this.indexBuffer == null) { + this.indexBuffer = new AreaBuffer(AreaBuffer.Usage.INDEX, 60000, INDEX_SIZE); + } + + int oldOffset = DrawParametersBuffer.getIndexCount(paramPtr) > 0 ? DrawParametersBuffer.getFirstIndex(paramPtr) : -1; + AreaBuffer.Segment segment = this.indexBuffer.upload(buffer.getIndexBuffer(), oldOffset, paramPtr); + firstIndex = segment.offset / INDEX_SIZE; + } else { + Renderer.getDrawer().getQuadsIndexBuffer().checkCapacity(vertexCount); + } + + DrawParametersBuffer.setIndexCount(paramPtr, indexCount); + DrawParametersBuffer.setFirstIndex(paramPtr, firstIndex); + DrawParametersBuffer.setVertexOffset(paramPtr, vertexOffset); + } buffer.release(); } @@ -94,7 +141,7 @@ private int encodeSectionOffset(int xOffset, int yOffset, int zOffset) { } // TODO: refactor - public static final float POS_OFFSET = PipelineManager.TERRAIN_VERTEX_FORMAT == CustomVertexFormat.COMPRESSED_TERRAIN ? 4.0f : 0.0f; + public static final float POS_OFFSET = PipelineManager.terrainVertexFormat == CustomVertexFormat.COMPRESSED_TERRAIN ? 4.0f : 0.0f; private void updateChunkAreaOrigin(VkCommandBuffer commandBuffer, Pipeline pipeline, double camX, double camY, double camZ, MemoryStack stack) { float xOffset = (float) ((this.origin.x) + POS_OFFSET - camX); @@ -110,73 +157,225 @@ private void updateChunkAreaOrigin(VkCommandBuffer commandBuffer, Pipeline pipel vkCmdPushConstants(commandBuffer, pipeline.getLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, byteBuffer); } - public void buildDrawBatchesIndirect(IndirectBuffer indirectBuffer, StaticQueue queue, TerrainRenderType terrainRenderType) { + public void buildDrawBatchesIndirect(Vec3 cameraPos, IndirectBuffer indirectBuffer, StaticQueue queue, TerrainRenderType terrainRenderType) { + long bufferPtr = cmdBufferPtr; - try (MemoryStack stack = MemoryStack.stackPush()) { + boolean isTranslucent = terrainRenderType == TerrainRenderType.TRANSLUCENT; + boolean backFaceCulling = Initializer.CONFIG.backFaceCulling && !isTranslucent; - ByteBuffer byteBuffer = stack.malloc(20 * queue.size()); - long bufferPtr = MemoryUtil.memAddress0(byteBuffer); + int drawCount = 0; - boolean isTranslucent = terrainRenderType == TerrainRenderType.TRANSLUCENT; + long drawParamsBasePtr = this.drawParamsPtr + (terrainRenderType.ordinal() * DrawParametersBuffer.SECTIONS * DrawParametersBuffer.FACINGS) * DrawParametersBuffer.STRIDE; + final long facingsStride = DrawParametersBuffer.FACINGS * DrawParametersBuffer.STRIDE; - int drawCount = 0; + int count = 0; + if (backFaceCulling) { for (var iterator = queue.iterator(isTranslucent); iterator.hasNext(); ) { + final RenderSection section = iterator.next(); + sectionIndices[count] = section.inAreaIndex; + masks[count] = getMask(cameraPos, section); + count++; + } + + long ptr = bufferPtr; + + for (int j = 0; j < count; ++j) { + final int sectionIdx = sectionIndices[j]; + + int mask = masks[j]; + + long drawParamsBasePtr2 = drawParamsBasePtr + (sectionIdx * facingsStride); + + for (int i = 0; i < QuadFacing.COUNT; i++) { + + if ((mask & 1 << i) == 0) { + drawParamsBasePtr2 += DrawParametersBuffer.STRIDE; + continue; + } + + long drawParamsPtr = drawParamsBasePtr2; + + final int indexCount = DrawParametersBuffer.getIndexCount(drawParamsPtr); + final int firstIndex = DrawParametersBuffer.getFirstIndex(drawParamsPtr); + final int vertexOffset = DrawParametersBuffer.getVertexOffset(drawParamsPtr); + final int baseInstance = DrawParametersBuffer.getBaseInstance(drawParamsPtr); + + drawParamsBasePtr2 += DrawParametersBuffer.STRIDE; + + if (indexCount <= 0) { + continue; + } + + MemoryUtil.memPutInt(ptr, indexCount); + MemoryUtil.memPutInt(ptr + 4, 1); + MemoryUtil.memPutInt(ptr + 8, firstIndex); + MemoryUtil.memPutInt(ptr + 12, vertexOffset); + MemoryUtil.memPutInt(ptr + 16, baseInstance); + + ptr += CMD_STRIDE; + drawCount++; + } + } + + } + else { + for (var iterator = queue.iterator(isTranslucent); iterator.hasNext(); ) { final RenderSection section = iterator.next(); - final DrawParameters drawParameters = section.getDrawParameters(terrainRenderType); - if (drawParameters.indexCount <= 0) + sectionIndices[count] = section.inAreaIndex; + count++; + } + + final int facing = 6; + final long facingOffset = facing * DrawParametersBuffer.STRIDE; + drawParamsBasePtr += facingOffset; + + long ptr = bufferPtr; + for (int i = 0; i < count; ++i) { + int sectionIdx = sectionIndices[i]; + + long drawParamsPtr = drawParamsBasePtr + (sectionIdx * facingsStride); + + final int indexCount = DrawParametersBuffer.getIndexCount(drawParamsPtr); + final int firstIndex = DrawParametersBuffer.getFirstIndex(drawParamsPtr); + final int vertexOffset = DrawParametersBuffer.getVertexOffset(drawParamsPtr); + final int baseInstance = DrawParametersBuffer.getBaseInstance(drawParamsPtr); + + if (indexCount <= 0) { continue; + } - long ptr = bufferPtr + (drawCount * 20L); - MemoryUtil.memPutInt(ptr, drawParameters.indexCount); + MemoryUtil.memPutInt(ptr, indexCount); MemoryUtil.memPutInt(ptr + 4, 1); - MemoryUtil.memPutInt(ptr + 8, drawParameters.firstIndex == -1 ? 0 : drawParameters.firstIndex); - MemoryUtil.memPutInt(ptr + 12, drawParameters.vertexOffset); - MemoryUtil.memPutInt(ptr + 16, drawParameters.baseInstance); + MemoryUtil.memPutInt(ptr + 8, firstIndex); + MemoryUtil.memPutInt(ptr + 12, vertexOffset); + MemoryUtil.memPutInt(ptr + 16, baseInstance); + ptr += CMD_STRIDE; drawCount++; } + } - if (drawCount == 0) return; + if (drawCount == 0) { + return; + } + + ByteBuffer byteBuffer = MemoryUtil.memByteBuffer(cmdBufferPtr, queue.size() * QuadFacing.COUNT * CMD_STRIDE); + indirectBuffer.recordCopyCmd(byteBuffer.position(0)); + + vkCmdDrawIndexedIndirect(Renderer.getCommandBuffer(), indirectBuffer.getId(), indirectBuffer.getOffset(), drawCount, CMD_STRIDE); + } + + public void buildDrawBatchesDirect(Vec3 cameraPos, StaticQueue queue, TerrainRenderType terrainRenderType) { + boolean isTranslucent = terrainRenderType == TerrainRenderType.TRANSLUCENT; + boolean backFaceCulling = Initializer.CONFIG.backFaceCulling && !isTranslucent; - indirectBuffer.recordCopyCmd(byteBuffer.position(0)); + VkCommandBuffer commandBuffer = Renderer.getCommandBuffer(); + + long drawParamsBasePtr = this.drawParamsPtr + (terrainRenderType.ordinal() * DrawParametersBuffer.SECTIONS * DrawParametersBuffer.FACINGS) * DrawParametersBuffer.STRIDE; + final long facingsStride = DrawParametersBuffer.FACINGS * DrawParametersBuffer.STRIDE; + + int count = 0; + if (backFaceCulling) { + for (var iterator = queue.iterator(isTranslucent); iterator.hasNext(); ) { + final RenderSection section = iterator.next(); + sectionIndices[count] = section.inAreaIndex; + masks[count] = getMask(cameraPos, section); + count++; + } + + for (int j = 0; j < count; ++j) { + final int sectionIdx = sectionIndices[j]; + + int mask = masks[j]; + + long drawParamsBasePtr2 = drawParamsBasePtr + (sectionIdx * facingsStride); + + for (int i = 0; i < QuadFacing.COUNT; i++) { + + if ((mask & 1 << i) == 0) { + drawParamsBasePtr2 += DrawParametersBuffer.STRIDE; + continue; + } + + long drawParamsPtr = drawParamsBasePtr2; + + final int indexCount = DrawParametersBuffer.getIndexCount(drawParamsPtr); + final int firstIndex = DrawParametersBuffer.getFirstIndex(drawParamsPtr); + final int vertexOffset = DrawParametersBuffer.getVertexOffset(drawParamsPtr); + final int baseInstance = DrawParametersBuffer.getBaseInstance(drawParamsPtr); + + drawParamsBasePtr2 += DrawParametersBuffer.STRIDE; + + if (indexCount <= 0) { + continue; + } + + vkCmdDrawIndexed(commandBuffer, indexCount, 1, firstIndex, vertexOffset, baseInstance); + } + } - vkCmdDrawIndexedIndirect(Renderer.getCommandBuffer(), indirectBuffer.getId(), indirectBuffer.getOffset(), drawCount, 20); } + else { + final int facing = 6; + final long facingOffset = facing * DrawParametersBuffer.STRIDE; + drawParamsBasePtr += facingOffset; + for (var iterator = queue.iterator(isTranslucent); iterator.hasNext(); ) { + final RenderSection section = iterator.next(); - } + sectionIndices[count] = section.inAreaIndex; + count++; + } - public void buildDrawBatchesDirect(StaticQueue queue, TerrainRenderType renderType) { - boolean isTranslucent = renderType == TerrainRenderType.TRANSLUCENT; - VkCommandBuffer commandBuffer = Renderer.getCommandBuffer(); + for (int i = 0; i < count; ++i) { + int sectionIdx = sectionIndices[i]; + + long drawParamsPtr = drawParamsBasePtr + (sectionIdx * facingsStride); - for (var iterator = queue.iterator(isTranslucent); iterator.hasNext(); ) { - final RenderSection section = iterator.next(); - final DrawParameters drawParameters = section.getDrawParameters(renderType); + final int indexCount = DrawParametersBuffer.getIndexCount(drawParamsPtr); + final int firstIndex = DrawParametersBuffer.getFirstIndex(drawParamsPtr); + final int vertexOffset = DrawParametersBuffer.getVertexOffset(drawParamsPtr); + final int baseInstance = DrawParametersBuffer.getBaseInstance(drawParamsPtr); - if (drawParameters.indexCount <= 0) - continue; + if (indexCount <= 0) { + continue; + } - final int firstIndex = drawParameters.firstIndex == -1 ? 0 : drawParameters.firstIndex; - vkCmdDrawIndexed(commandBuffer, drawParameters.indexCount, 1, firstIndex, drawParameters.vertexOffset, drawParameters.baseInstance); + vkCmdDrawIndexed(commandBuffer, indexCount, 1, firstIndex, vertexOffset, baseInstance); + } } } - public void bindBuffers(VkCommandBuffer commandBuffer, Pipeline pipeline, TerrainRenderType terrainRenderType, double camX, double camY, double camZ) { + private int getMask(Vec3 camera, RenderSection section) { + final int secX = section.xOffset; + final int secY = section.yOffset; + final int secZ = section.zOffset; + int mask = 1 << QuadFacing.UNDEFINED.ordinal(); + + mask |= camera.x - secX >= 0 ? 1 << QuadFacing.X_POS.ordinal() : 0; + mask |= camera.y - secY >= 0 ? 1 << QuadFacing.Y_POS.ordinal() : 0; + mask |= camera.z - secZ >= 0 ? 1 << QuadFacing.Z_POS.ordinal() : 0; + mask |= camera.x - (secX + 16) < 0 ? 1 << QuadFacing.X_NEG.ordinal() : 0; + mask |= camera.y - (secY + 16) < 0 ? 1 << QuadFacing.Y_NEG.ordinal() : 0; + mask |= camera.z - (secZ + 16) < 0 ? 1 << QuadFacing.Z_NEG.ordinal() : 0; + + return mask; + } + + public void bindBuffers(VkCommandBuffer commandBuffer, Pipeline pipeline, TerrainRenderType terrainRenderType, double camX, double camY, double camZ) { try (MemoryStack stack = MemoryStack.stackPush()) { var vertexBuffer = getAreaBuffer(terrainRenderType); nvkCmdBindVertexBuffers(commandBuffer, 0, 1, stack.npointer(vertexBuffer.getId()), stack.npointer(0)); updateChunkAreaOrigin(commandBuffer, pipeline, camX, camY, camZ, stack); } - if (terrainRenderType == TerrainRenderType.TRANSLUCENT) { + if (terrainRenderType == TerrainRenderType.TRANSLUCENT && this.indexBuffer != null) { vkCmdBindIndexBuffer(commandBuffer, this.indexBuffer.getId(), 0, VK_INDEX_TYPE_UINT16); } - } public void releaseBuffers() { @@ -193,6 +392,12 @@ public void releaseBuffers() { this.allocated = false; } + public void free() { + this.releaseBuffers(); + + DrawParametersBuffer.freeBuffer(this.drawParamsPtr); + } + public boolean isAllocated() { return !this.vertexBuffers.isEmpty(); } @@ -205,25 +410,8 @@ public AreaBuffer getIndexBuffer() { return indexBuffer; } - public static class DrawParameters { - int indexCount = 0; - int firstIndex = -1; - int vertexOffset = -1; - int baseInstance; - - public DrawParameters() {} - - public void reset(ChunkArea chunkArea, TerrainRenderType r) { - AreaBuffer areaBuffer = chunkArea.getDrawBuffers().getAreaBuffer(r); - if (areaBuffer != null && this.vertexOffset != -1) { - int segmentOffset = this.vertexOffset * VERTEX_SIZE; - areaBuffer.setSegmentFree(segmentOffset); - } - - this.indexCount = 0; - this.firstIndex = -1; - this.vertexOffset = -1; - } + public long getDrawParamsPtr() { + return drawParamsPtr; } } diff --git a/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java b/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java new file mode 100644 index 000000000..f26c2420d --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java @@ -0,0 +1,77 @@ +package net.vulkanmod.render.chunk.buffer; + +import net.vulkanmod.render.chunk.ChunkAreaManager; +import net.vulkanmod.render.chunk.cull.QuadFacing; +import net.vulkanmod.render.vertex.TerrainRenderType; +import org.lwjgl.system.MemoryUtil; + +public abstract class DrawParametersBuffer { + static final long INDEX_COUNT_OFFSET = 0; + static final long FIRST_INDEX_OFFSET = 4; + static final long VERTEX_OFFSET_OFFSET = 8; + static final long BASE_INSTANCE_OFFSET = 12; + + public static final long STRIDE = 16; + + static final int SECTIONS = ChunkAreaManager.AREA_SIZE; + static final int FACINGS = 7; + + public static long allocateBuffer() { + int size = (int) (ChunkAreaManager.AREA_SIZE * TerrainRenderType.VALUES.length * QuadFacing.COUNT * DrawParametersBuffer.STRIDE); + long drawParamsPtr = MemoryUtil.nmemAlignedAlloc(32, size); + + for (long ptr = drawParamsPtr; ptr < drawParamsPtr + size; ptr += DrawParametersBuffer.STRIDE) { + DrawParametersBuffer.resetParameters(ptr); + } + + return drawParamsPtr; + } + + public static void freeBuffer(long ptr) { + MemoryUtil.nmemAlignedFree(ptr); + } + + public static long getParamsPtr(long basePtr, int section, int renderType, int facing) { + return basePtr + (((renderType * SECTIONS + section) * FACINGS) + facing) * STRIDE; + } + + public static void resetParameters(long ptr) { + setIndexCount(ptr, 0); + setFirstIndex(ptr, 0); + setVertexOffset(ptr, -1); + setBaseInstance(ptr, 0); + } + + public static void setIndexCount(long ptr, int value) { + MemoryUtil.memPutInt(ptr + INDEX_COUNT_OFFSET, value); + } + + public static void setFirstIndex(long ptr, int value) { + MemoryUtil.memPutInt(ptr + FIRST_INDEX_OFFSET, value); + } + + public static void setVertexOffset(long ptr, int value) { + MemoryUtil.memPutInt(ptr + VERTEX_OFFSET_OFFSET, value); + } + + public static void setBaseInstance(long ptr, int value) { + MemoryUtil.memPutInt(ptr + BASE_INSTANCE_OFFSET, value); + } + + public static int getIndexCount(long ptr) { + return MemoryUtil.memGetInt(ptr + INDEX_COUNT_OFFSET); + } + + public static int getFirstIndex(long ptr) { + return MemoryUtil.memGetInt(ptr + FIRST_INDEX_OFFSET); + } + + public static int getVertexOffset(long ptr) { + return MemoryUtil.memGetInt(ptr + VERTEX_OFFSET_OFFSET); + } + + public static int getBaseInstance(long ptr) { + return MemoryUtil.memGetInt(ptr + BASE_INSTANCE_OFFSET); + } + +} diff --git a/src/main/java/net/vulkanmod/render/chunk/buffer/UploadManager.java b/src/main/java/net/vulkanmod/render/chunk/buffer/UploadManager.java index 9f14e3ccd..5ab8bee72 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/UploadManager.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/UploadManager.java @@ -4,8 +4,8 @@ import net.vulkanmod.vulkan.Synchronization; import net.vulkanmod.vulkan.Vulkan; import net.vulkanmod.vulkan.device.DeviceManager; -import net.vulkanmod.vulkan.memory.Buffer; -import net.vulkanmod.vulkan.memory.StagingBuffer; +import net.vulkanmod.vulkan.memory.buffer.Buffer; +import net.vulkanmod.vulkan.memory.buffer.StagingBuffer; import net.vulkanmod.vulkan.queue.CommandPool; import net.vulkanmod.vulkan.queue.Queue; import net.vulkanmod.vulkan.queue.TransferQueue; @@ -43,13 +43,12 @@ public void submitUploads() { } public void recordUpload(Buffer buffer, long dstOffset, long bufferSize, ByteBuffer src) { - beginCommands(); - - VkCommandBuffer commandBuffer = this.commandBuffer.getHandle(); - StagingBuffer stagingBuffer = Vulkan.getStagingBuffer(); stagingBuffer.copyBuffer((int) bufferSize, src); + beginCommands(); + VkCommandBuffer commandBuffer = this.commandBuffer.getHandle(); + if (!this.dstBuffers.add(buffer.getId())) { try (MemoryStack stack = MemoryStack.stackPush()) { VkMemoryBarrier.Buffer barrier = VkMemoryBarrier.calloc(1, stack); @@ -75,7 +74,7 @@ public void copyBuffer(Buffer src, Buffer dst) { copyBuffer(src, 0, dst, 0, src.getBufferSize()); } - public void copyBuffer(Buffer src, int srcOffset, Buffer dst, int dstOffset, int size) { + public void copyBuffer(Buffer src, long srcOffset, Buffer dst, long dstOffset, long size) { beginCommands(); VkCommandBuffer commandBuffer = this.commandBuffer.getHandle(); diff --git a/src/main/java/net/vulkanmod/render/chunk/build/BlockRenderer.java b/src/main/java/net/vulkanmod/render/chunk/build/BlockRenderer.java deleted file mode 100644 index 7c3e95405..000000000 --- a/src/main/java/net/vulkanmod/render/chunk/build/BlockRenderer.java +++ /dev/null @@ -1,216 +0,0 @@ -package net.vulkanmod.render.chunk.build; - -import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap; -import net.minecraft.client.Minecraft; -import net.minecraft.client.color.block.BlockColors; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Vec3i; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.shapes.BooleanOp; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.vulkanmod.render.chunk.build.light.LightPipeline; -import net.vulkanmod.render.chunk.build.light.data.QuadLightData; -import net.vulkanmod.render.chunk.build.thread.BuilderResources; -import net.vulkanmod.render.model.quad.QuadUtils; -import net.vulkanmod.render.model.quad.QuadView; -import net.vulkanmod.render.vertex.TerrainBufferBuilder; -import net.vulkanmod.render.vertex.VertexUtil; -import net.vulkanmod.vulkan.util.ColorUtil; -import org.joml.Vector3f; - -import java.util.List; - -public class BlockRenderer { - - static final Direction[] DIRECTIONS = Direction.values(); - private static BlockColors blockColors; - - RandomSource randomSource = RandomSource.createNewThreadLocalInstance(); - - Vector3f pos; - BlockPos blockPos; - BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); - - BuilderResources resources; - - BlockState blockState; - - public void setResources(BuilderResources resources) { - this.resources = resources; - } - - final Object2ByteLinkedOpenHashMap occlusionCache = new Object2ByteLinkedOpenHashMap<>(2048, 0.25F) { - protected void rehash(int i) { - } - }; - - public BlockRenderer() { - occlusionCache.defaultReturnValue((byte) 127); - } - - public static void setBlockColors(BlockColors blockColors) { - BlockRenderer.blockColors = blockColors; - } - - public void renderBlock(BlockState blockState, BlockPos blockPos, Vector3f pos, TerrainBufferBuilder bufferBuilder) { - this.pos = pos; - this.blockPos = blockPos; - this.blockState = blockState; - - long seed = blockState.getSeed(blockPos); - - BakedModel model = Minecraft.getInstance().getBlockRenderer().getBlockModel(blockState); - tessellateBlock(model, bufferBuilder, seed); - } - - public void tessellateBlock(BakedModel bakedModel, TerrainBufferBuilder bufferBuilder, long seed) { - Vec3 offset = blockState.getOffset(resources.region, blockPos); - - pos.add((float) offset.x, (float) offset.y, (float) offset.z); - - boolean useAO = Minecraft.useAmbientOcclusion() && blockState.getLightEmission() == 0 && bakedModel.useAmbientOcclusion(); - LightPipeline lightPipeline = useAO ? resources.smoothLightPipeline : resources.flatLightPipeline; - - //noinspection ForLoopReplaceableByForEach - for (int i = 0; i < DIRECTIONS.length; ++i) { - Direction direction = DIRECTIONS[i]; - - randomSource.setSeed(seed); - List quads = bakedModel.getQuads(blockState, direction, randomSource); - - if (!quads.isEmpty()) { - mutableBlockPos.setWithOffset(blockPos, direction); - if (shouldRenderFace(blockState, direction, mutableBlockPos)) { - renderModelFace(bufferBuilder, quads, lightPipeline, direction); - } - } - } - - randomSource.setSeed(seed); - List quads = bakedModel.getQuads(blockState, null, randomSource); - if (!quads.isEmpty()) { - renderModelFace(bufferBuilder, quads, lightPipeline, null); - } - } - - private void renderModelFace(TerrainBufferBuilder bufferBuilder, List quads, LightPipeline lightPipeline, Direction cullFace) { - QuadLightData quadLightData = resources.quadLightData; - - for (int i = 0; i < quads.size(); ++i) { - BakedQuad bakedQuad = quads.get(i); - QuadView quadView = (QuadView) bakedQuad; - lightPipeline.calculate(quadView, blockPos, quadLightData, cullFace, bakedQuad.getDirection(), bakedQuad.isShade()); - putQuadData(bufferBuilder, quadView, quadLightData); - } - } - - private void putQuadData(TerrainBufferBuilder bufferBuilder, QuadView quadView, QuadLightData quadLightData) { - float r, g, b; - if (quadView.isTinted()) { - int color = blockColors.getColor(blockState, resources.region, blockPos, quadView.getColorIndex()); - r = ColorUtil.ARGB.unpackR(color); - g = ColorUtil.ARGB.unpackG(color); - b = ColorUtil.ARGB.unpackB(color); - } else { - r = 1.0F; - g = 1.0F; - b = 1.0F; - } - - putQuadData(bufferBuilder, pos, quadView, quadLightData, r, g, b); - } - - public static void putQuadData(TerrainBufferBuilder bufferBuilder, Vector3f pos, QuadView quad, QuadLightData quadLightData, float red, float green, float blue) { - Vec3i normal = quad.getFacingDirection().getNormal(); - int packedNormal = VertexUtil.packNormal(normal.getX(), normal.getY(), normal.getZ()); - - float[] brightnessArr = quadLightData.br; - int[] lights = quadLightData.lm; - - // Rotate triangles if needed to fix AO anisotropy - int idx = QuadUtils.getIterationStartIdx(brightnessArr, lights); - - bufferBuilder.ensureCapacity(); - - for (byte i = 0; i < 4; ++i) { - final float x = pos.x() + quad.getX(idx); - final float y = pos.y() + quad.getY(idx); - final float z = pos.z() + quad.getZ(idx); - - final float r, g, b; - final float quadR, quadG, quadB; - - final int quadColor = quad.getColor(idx); - quadR = ColorUtil.RGBA.unpackR(quadColor); - quadG = ColorUtil.RGBA.unpackG(quadColor); - quadB = ColorUtil.RGBA.unpackB(quadColor); - - final float brightness = brightnessArr[idx]; - r = quadR * brightness * red; - g = quadG * brightness * green; - b = quadB * brightness * blue; - - final int color = ColorUtil.RGBA.pack(r, g, b, 1.0f); - final int light = lights[idx]; - final float u = quad.getU(idx); - final float v = quad.getV(idx); - - bufferBuilder.vertex(x, y, z, color, u, v, light, packedNormal); - - idx = (idx + 1) & 0b11; - } - - } - - public boolean shouldRenderFace(BlockState blockState, Direction direction, BlockPos adjPos) { - BlockGetter blockGetter = resources.region; - BlockState adjBlockState = blockGetter.getBlockState(adjPos); - - if (blockState.skipRendering(adjBlockState, direction)) { - return false; - } - - if (adjBlockState.canOcclude()) { - VoxelShape shape = blockState.getFaceOcclusionShape(blockGetter, blockPos, direction); - - if (shape.isEmpty()) - return true; - - VoxelShape adjShape = adjBlockState.getFaceOcclusionShape(blockGetter, adjPos, direction.getOpposite()); - - if (adjShape.isEmpty()) - return true; - - if (shape == Shapes.block() && adjShape == Shapes.block()) { - return false; - } - - Block.BlockStatePairKey blockStatePairKey = new Block.BlockStatePairKey(blockState, adjBlockState, direction); - - byte b = occlusionCache.getAndMoveToFirst(blockStatePairKey); - if (b != 127) { - return b != 0; - } else { - boolean bl = Shapes.joinIsNotEmpty(shape, adjShape, BooleanOp.ONLY_FIRST); - - if (occlusionCache.size() == 2048) { - occlusionCache.removeLastByte(); - } - - occlusionCache.putAndMoveToFirst(blockStatePairKey, (byte) (bl ? 1 : 0)); - return bl; - } - } - - return true; - } -} - diff --git a/src/main/java/net/vulkanmod/render/chunk/build/RenderRegion.java b/src/main/java/net/vulkanmod/render/chunk/build/RenderRegion.java index 79a65a152..94a19358b 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/RenderRegion.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/RenderRegion.java @@ -1,5 +1,6 @@ package net.vulkanmod.render.chunk.build; +import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -16,6 +17,8 @@ import net.minecraft.world.level.levelgen.DebugLevelSource; import net.minecraft.world.level.lighting.LevelLightEngine; import net.minecraft.world.level.material.FluidState; +import net.vulkanmod.render.chunk.build.biome.BiomeData; +import net.vulkanmod.render.chunk.build.color.TintCache; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -23,7 +26,7 @@ import java.util.Map; import java.util.function.Function; -public class RenderRegion implements BlockAndTintGetter { +public class RenderRegion implements BlockAndTintGetter, RenderAttachedBlockView { public static final int WIDTH = 3; public static final int SIZE = WIDTH * WIDTH * WIDTH; @@ -43,13 +46,15 @@ public class RenderRegion implements BlockAndTintGetter { private final BlockState[] blockData; private final DataLayer[][] lightData; + private BiomeData biomeData; private TintCache tintCache; private final Map blockEntityMap; private final Function blockStateGetter; - RenderRegion(Level level, int x, int y, int z, PalettedContainer[] blockData, DataLayer[][] lightData, Map blockEntityMap) { + RenderRegion(Level level, int x, int y, int z, PalettedContainer[] blockData, DataLayer[][] lightData, + BiomeData biomeData, Map blockEntityMap) { this.level = level; this.minSecX = x - 1; @@ -64,6 +69,7 @@ public class RenderRegion implements BlockAndTintGetter { this.blockDataContainers = blockData; this.lightData = lightData; + this.biomeData = biomeData; this.blockEntityMap = blockEntityMap; this.blockData = new BlockState[BLOCK_COUNT]; @@ -76,14 +82,14 @@ public class RenderRegion implements BlockAndTintGetter { public void loadBlockStates() { Arrays.fill(blockData, Blocks.AIR.defaultBlockState()); - for(int x = 0; x <= 2; ++x) { - for(int z = 0; z <= 2; ++z) { - for(int y = 0; y <= 2; ++y) { + for (int x = 0; x <= 2; ++x) { + for (int z = 0; z <= 2; ++z) { + for (int y = 0; y <= 2; ++y) { final int idx = getSectionIdx(x, y, z); PalettedContainer container = blockDataContainers[idx]; - if(container == null) + if (container == null) continue; int absBlockX = (x + minSecX) << 4; @@ -99,8 +105,8 @@ public void loadBlockStates() { int tMaxZ = Math.min(maxZ, absBlockZ + 16); loadSectionBlockStates(container, blockData, - tMinX, tMinY, tMinZ, tMaxX, tMaxY, tMaxZ); - + tMinX, tMinY, tMinZ, tMaxX, tMaxY, tMaxZ); + } } } @@ -124,7 +130,7 @@ void loadSectionBlockStates(PalettedContainer container, BlockState[ public void initTintCache(TintCache tintCache) { this.tintCache = tintCache; - this.tintCache.init(blendRadius, minSecX + 1, minSecY + 1, minSecZ + 1); + this.tintCache.init(biomeData, blendRadius, minSecX + 1, minSecY + 1, minSecZ + 1); } public BlockState getBlockState(BlockPos blockPos) { diff --git a/src/main/java/net/vulkanmod/render/chunk/build/RenderRegionBuilder.java b/src/main/java/net/vulkanmod/render/chunk/build/RenderRegionBuilder.java index adf6db694..dc3317636 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/RenderRegionBuilder.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/RenderRegionBuilder.java @@ -10,6 +10,8 @@ import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; +import net.vulkanmod.interfaces.biome.BiomeManagerExtended; +import net.vulkanmod.render.chunk.build.biome.BiomeData; public class RenderRegionBuilder { private static final DataLayer DEFAULT_SKY_LIGHT_DATA_LAYER = new DataLayer(15); @@ -26,7 +28,7 @@ public RenderRegion createRegion(Level level, int secX, int secY, int secZ) { if (section == null || section.hasOnlyAir()) return null; - var entityMap = levelChunk.getBlockEntities(); + var blockEntityMap = levelChunk.getBlockEntities(); int minSecX = secX - 1; int minSecZ = secZ - 1; @@ -39,6 +41,9 @@ public RenderRegion createRegion(Level level, int secX, int secY, int secZ) { DataLayer[][] lightData = new DataLayer[RenderRegion.SIZE][2 /* Light types */]; + long biomeZoomSeed = BiomeManagerExtended.of(level.getBiomeManager()).getBiomeZoomSeed(); + BiomeData biomeData = new BiomeData(biomeZoomSeed, minSecX, minSecY, minSecZ); + final int minHeightSec = level.getMinBuildHeight() >> 4; for (int x = minSecX; x <= maxSecX; ++x) { for (int z = minSecZ; z <= maxSecZ; ++z) { @@ -60,11 +65,13 @@ public RenderRegion createRegion(Level level, int secX, int secY, int secZ) { DataLayer[] dataLayers = getSectionDataLayers(level, pos); lightData[idx] = dataLayers; + + biomeData.getBiomeData(level, section, relX, relY, relZ); } } } - return new RenderRegion(level, secX, secY, secZ, blockData, lightData, entityMap); + return new RenderRegion(level, secX, secY, secZ, blockData, lightData, biomeData, blockEntityMap); } private DataLayer[] getSectionDataLayers(Level level, SectionPos pos) { diff --git a/src/main/java/net/vulkanmod/render/chunk/build/TintCache.java b/src/main/java/net/vulkanmod/render/chunk/build/TintCache.java deleted file mode 100644 index 2c296f955..000000000 --- a/src/main/java/net/vulkanmod/render/chunk/build/TintCache.java +++ /dev/null @@ -1,136 +0,0 @@ -package net.vulkanmod.render.chunk.build; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BiomeColors; -import net.minecraft.core.BlockPos; -import net.minecraft.util.Mth; -import net.minecraft.world.level.ColorResolver; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.biome.Biome; -import net.vulkanmod.render.chunk.WorldRenderer; -import net.vulkanmod.render.chunk.build.biome.BoxBlur; - -import java.util.Arrays; -import java.util.function.BiFunction; - -public class TintCache { - private static final int SECTION_WIDTH = 16; - - private final Layer[] layers = new Layer[SECTION_WIDTH]; - - private int blendRadius, totalWidth; - private int secX, secY, secZ; - private int minX, minZ; - private int maxX, maxZ; - - private int dataSize; - private int[] temp; - - public TintCache() { - Arrays.fill(layers, new Layer()); - } - - public void init(int blendRadius, int secX, int secY, int secZ) { - this.blendRadius = Minecraft.getInstance().options.biomeBlendRadius().get(); - this.totalWidth = (blendRadius * 2) + 16; - - this.secX = secX; - this.secY = secY; - this.secZ = secZ; - - minX = (secX << 4) - blendRadius; - minZ = (secZ << 4) - blendRadius; - maxX = (secX << 4) + 16 + blendRadius; - maxZ = (secZ << 4) + 16 + blendRadius; - - int size = totalWidth * totalWidth; - - if(size != dataSize) { - this.dataSize = size; - for (Layer layer : layers) { - layer.allocate(size); - } - temp = new int[size]; - } else { - for (Layer layer : layers) { - layer.invalidate(); - } - } - } - - public int getColor(BlockPos blockPos, ColorResolver colorResolver) { - int relY = blockPos.getY() & 15; - Layer layer = layers[relY]; - if(layer.invalidated) - calculateLayer(relY); - - int[] values = layer.getValues(colorResolver); - int relX = blockPos.getX() & 15; - int relZ = blockPos.getZ() & 15; - int idx = totalWidth * (relZ + blendRadius) + (relX + blendRadius); - return values[idx]; - } - - public void calculateLayer(int y) { - Level level = WorldRenderer.getLevel(); - Layer layer = layers[y]; - - BlockPos.MutableBlockPos blockPos = new BlockPos.MutableBlockPos(); - int absY = (secY << 4) + y; - - Biome tB = level.getBiome(blockPos.set(minX, absY, minZ)).value(); - boolean mixed = false; - for (int absZ = minZ; absZ < maxZ ; absZ++) { - for (int absX = minX; absX < maxX ; absX++) { - blockPos.set(absX, absY, absZ); - Biome biome = level.getBiome(blockPos).value(); - - if (biome != tB) - mixed = true; - - final int idx = (absX - minX) + (absZ - minZ) * totalWidth; - layer.grass[idx] = biome.getGrassColor(absX, absZ); - layer.foliage[idx] = biome.getFoliageColor(); - layer.water[idx] = biome.getWaterColor(); - } - } - - if(mixed && blendRadius > 0) { - BoxBlur.blur(layer.grass, temp, SECTION_WIDTH, blendRadius); - BoxBlur.blur(layer.foliage, temp, SECTION_WIDTH, blendRadius); - BoxBlur.blur(layer.water, temp, SECTION_WIDTH, blendRadius); - } - - layer.invalidated = false; - } - - static class Layer { - private boolean invalidated = true; - - private int[] grass; - private int[] foliage; - private int[] water; - - void allocate(int size) { - grass = new int[size]; - foliage = new int[size]; - water = new int[size]; - invalidate(); - } - - void invalidate() { - this.invalidated = true; - } - - public int[] getValues(ColorResolver colorResolver) { - if(colorResolver == BiomeColors.GRASS_COLOR_RESOLVER) - return grass; - else if(colorResolver == BiomeColors.FOLIAGE_COLOR_RESOLVER) - return foliage; - else if(colorResolver == BiomeColors.WATER_COLOR_RESOLVER) - return water; - - throw new IllegalArgumentException("Unexpected resolver: " + colorResolver.toString()); - } - } -} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/UploadBuffer.java b/src/main/java/net/vulkanmod/render/chunk/build/UploadBuffer.java index cd8b72404..3254b19c4 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/UploadBuffer.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/UploadBuffer.java @@ -1,7 +1,9 @@ package net.vulkanmod.render.chunk.build; +import net.vulkanmod.render.chunk.cull.QuadFacing; import net.vulkanmod.render.chunk.util.BufferUtil; import net.vulkanmod.render.vertex.TerrainBufferBuilder; +import net.vulkanmod.render.vertex.TerrainBuilder; import org.lwjgl.system.MemoryUtil; import java.nio.ByteBuffer; @@ -10,32 +12,43 @@ public class UploadBuffer { public final int indexCount; public final boolean autoIndices; public final boolean indexOnly; - private final ByteBuffer vertexBuffer; + private final ByteBuffer[] vertexBuffers; private final ByteBuffer indexBuffer; - public UploadBuffer(TerrainBufferBuilder.RenderedBuffer renderedBuffer) { - TerrainBufferBuilder.DrawState drawState = renderedBuffer.drawState(); + public UploadBuffer(TerrainBuilder terrainBuilder, TerrainBuilder.DrawState drawState) { this.indexCount = drawState.indexCount(); this.autoIndices = drawState.sequentialIndex(); this.indexOnly = drawState.indexOnly(); - if (!this.indexOnly) - this.vertexBuffer = BufferUtil.clone(renderedBuffer.vertexBuffer()); - else - this.vertexBuffer = null; + if (!this.indexOnly) { + this.vertexBuffers = new ByteBuffer[QuadFacing.COUNT]; - if (!drawState.sequentialIndex()) - this.indexBuffer = BufferUtil.clone(renderedBuffer.indexBuffer()); - else + for (int i = 0; i < QuadFacing.COUNT; i++) { + var bufferBuilder = terrainBuilder.getBufferBuilder(i); + + if (bufferBuilder.getVertices() > 0) { + this.vertexBuffers[i] = BufferUtil.clone(bufferBuilder.getBuffer()); + } + } + } + else { + this.vertexBuffers = null; + } + + if (!drawState.sequentialIndex()) { + this.indexBuffer = BufferUtil.clone(terrainBuilder.getIndexBuffer()); + } + else { this.indexBuffer = null; + } } public int indexCount() { return indexCount; } - public ByteBuffer getVertexBuffer() { - return vertexBuffer; + public ByteBuffer[] getVertexBuffers() { + return vertexBuffers; } public ByteBuffer getIndexBuffer() { @@ -43,8 +56,12 @@ public ByteBuffer getIndexBuffer() { } public void release() { - if (vertexBuffer != null) - MemoryUtil.memFree(vertexBuffer); + if (vertexBuffers != null) + for (var vertexBuffer : vertexBuffers) { + if (vertexBuffer != null) + MemoryUtil.memFree(vertexBuffer); + } + if (indexBuffer != null) MemoryUtil.memFree(indexBuffer); } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/biome/BiomeData.java b/src/main/java/net/vulkanmod/render/chunk/build/biome/BiomeData.java new file mode 100644 index 000000000..166f4b3a8 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/biome/BiomeData.java @@ -0,0 +1,153 @@ +package net.vulkanmod.render.chunk.build.biome; + +import net.minecraft.core.registries.Registries; +import net.minecraft.util.LinearCongruentialGenerator; +import net.minecraft.util.Mth; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.vulkanmod.render.chunk.build.RenderRegion; +import org.joml.Vector3f; + +public class BiomeData { + private static final int ZOOM_LENGTH = 4; + private static final int BIOMES_PER_SECTION = 4 * 4 * 4; + private static final int SIZE = RenderRegion.SIZE * BIOMES_PER_SECTION; + + Biome[] biomes = new Biome[SIZE]; + private final long biomeZoomSeed; + + int secX, secY, secZ; + + // Cached cell offsets + Vector3f[] offsets = new Vector3f[SIZE]; + + public BiomeData(long biomeZoomSeed, int secX, int secY, int secZ) { + this.biomeZoomSeed = biomeZoomSeed; + this.secX = secX; + this.secY = secY; + this.secZ = secZ; + } + + public void getBiomeData(Level level, LevelChunkSection chunkSection, int secX, int secY, int secZ) { + Biome defaultValue = level.registryAccess() + .registryOrThrow(Registries.BIOME) + .getHolderOrThrow(Biomes.PLAINS) + .value(); + + int baseIdx = getRelativeSectionIdx(secX, secY, secZ); + + for (int x = 0; x < 4; x++) { + for (int y = 0; y < 4; y++) { + for (int z = 0; z < 4; z++) { + int relIdx = getRelativeIdx(x, y, z); + int idx = baseIdx + relIdx; + + if (chunkSection != null) { + biomes[idx] = chunkSection.getNoiseBiome(x, y, z) + .value(); + } + else { + biomes[idx] = defaultValue; + } + + } + } + } + + } + + public Biome getBiome(int blockX, int blockY, int blockZ) { + int x = blockX - 2; + int y = blockY - 2; + int z = blockZ - 2; + + int zoomX = x >> 2; + int zoomY = y >> 2; + int zoomZ = z >> 2; + + float fracZoomX = (x & 3) * 0.25f; + float fracZoomY = (y & 3) * 0.25f; + float fracZoomZ = (z & 3) * 0.25f; + + int closestCellIdx = 0; + double closestDistance = Double.POSITIVE_INFINITY; + + for (int i = 0; i < 8; ++i) { + boolean dirX = (i & 4) != 0; + boolean dirY = (i & 2) != 0; + boolean dirZ = (i & 1) != 0; + + int cellX = dirX ? zoomX + 1 : zoomX; + int cellY = dirY ? zoomY + 1 : zoomY; + int cellZ = dirZ ? zoomZ + 1 : zoomZ; + + float fCellX = dirX ? fracZoomX - 1.0f : fracZoomX; + float fCellY = dirY ? fracZoomY - 1.0f : fracZoomY; + float fCellZ = dirZ ? fracZoomZ - 1.0f : fracZoomZ; + + int baseSectionIdx = getSectionIdx(cellX >> 2, cellY >> 2, cellZ >> 2); + int cellIdx = baseSectionIdx + getRelativeIdx(cellX & 3, cellY & 3, cellZ & 3); + + Vector3f offset = getOffset(baseSectionIdx, cellX, cellY, cellZ); + float distance = Mth.square(fCellX + offset.x()) + Mth.square(fCellY + offset.y()) + Mth.square(fCellZ + offset.z()); + + if (closestDistance > distance) { + closestCellIdx = cellIdx; + closestDistance = distance; + } + } + + return this.biomes[closestCellIdx]; + } + + private int getSectionIdx(int secX, int secY, int secZ) { + return getRelativeSectionIdx(secX - this.secX, secY - this.secY, secZ - this.secZ); + } + + private Vector3f getOffset(int baseIndex, int cellX, int cellY, int cellZ) { + int relCellX = cellX & 3; + int relCellY = cellY & 3; + int relCellZ = cellZ & 3; + int idx = baseIndex + getRelativeIdx(relCellX, relCellY, relCellZ); + + if (this.offsets[idx] == null) { + this.offsets[idx] = computeCellOffset(this.biomeZoomSeed, cellX, cellY, cellZ); + } + + return this.offsets[idx]; + } + + private static Vector3f computeCellOffset(long l, int cellX, int cellY, int cellZ) { + long seed; + seed = LinearCongruentialGenerator.next(l, cellX); + seed = LinearCongruentialGenerator.next(seed, cellY); + seed = LinearCongruentialGenerator.next(seed, cellZ); + seed = LinearCongruentialGenerator.next(seed, cellX); + seed = LinearCongruentialGenerator.next(seed, cellY); + seed = LinearCongruentialGenerator.next(seed, cellZ); + + float xOffset = getFiddle(seed); + seed = LinearCongruentialGenerator.next(seed, l); + float yOffset = getFiddle(seed); + seed = LinearCongruentialGenerator.next(seed, l); + float zOffset = getFiddle(seed); + + return new Vector3f(xOffset, yOffset, zOffset); + } + + private static float getFiddle(long l) { + float d = Math.floorMod(l >> 24, 1024) * (1.0f / 1024.0f); + return (d - 0.5f) * 0.9f; + } + + private static int getRelativeSectionIdx(int x, int y, int z) { + return ((x * RenderRegion.WIDTH * RenderRegion.WIDTH) + (y * RenderRegion.WIDTH) + z) * BIOMES_PER_SECTION; + } + + private static int getRelativeIdx(int x, int y, int z) { + return (x * ZOOM_LENGTH * ZOOM_LENGTH) + (y * ZOOM_LENGTH) + z; + } + +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/color/BlockColorRegistry.java b/src/main/java/net/vulkanmod/render/chunk/build/color/BlockColorRegistry.java new file mode 100644 index 000000000..b8ec0ca39 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/color/BlockColorRegistry.java @@ -0,0 +1,21 @@ +package net.vulkanmod.render.chunk.build.color; + +import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.world.level.block.Block; + +public class BlockColorRegistry { + + private final Reference2ReferenceOpenHashMap map = new Reference2ReferenceOpenHashMap<>(); + + public void register(BlockColor blockColor, Block... blocks) { + for (Block block : blocks) { + this.map.put(block, blockColor); + } + } + + public BlockColor getBlockColor(Block block) { + return this.map.get(block); + } + +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/biome/BoxBlur.java b/src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java similarity index 96% rename from src/main/java/net/vulkanmod/render/chunk/build/biome/BoxBlur.java rename to src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java index 7c484acf8..f86333de7 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/biome/BoxBlur.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java @@ -1,6 +1,6 @@ -package net.vulkanmod.render.chunk.build.biome; +package net.vulkanmod.render.chunk.build.color; -public class BoxBlur { +public abstract class BoxBlur { public static void blur(int[] buffer, int[] temp, int width, int filterRadius) { horizontalBlur(buffer, temp, 0, width, filterRadius); diff --git a/src/main/java/net/vulkanmod/render/chunk/build/color/TintCache.java b/src/main/java/net/vulkanmod/render/chunk/build/color/TintCache.java new file mode 100644 index 000000000..2a8828d44 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/color/TintCache.java @@ -0,0 +1,162 @@ +package net.vulkanmod.render.chunk.build.color; + +import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BiomeColors; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.ColorResolver; +import net.minecraft.world.level.biome.Biome; +import net.vulkanmod.render.chunk.build.biome.BiomeData; + +import java.util.Arrays; + +public class TintCache { + private static final int SECTION_WIDTH = 16; + + private final Reference2ReferenceOpenHashMap layers; + + private BiomeData biomeData; + private int blendRadius, totalWidth; + private int secX, secY, secZ; + private int minX, minZ; + private int maxX, maxZ; + + private int dataSize; + private int[] temp; + + public TintCache() { + this.layers = new Reference2ReferenceOpenHashMap<>(); + + // Default resolvers + this.layers.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, allocateLayers()); + this.layers.put(BiomeColors.GRASS_COLOR_RESOLVER, allocateLayers()); + this.layers.put(BiomeColors.WATER_COLOR_RESOLVER, allocateLayers()); + } + + public void init(BiomeData biomeData, int blendRadius, int secX, int secY, int secZ) { + this.biomeData = biomeData; + this.blendRadius = Minecraft.getInstance().options.biomeBlendRadius().get(); + this.totalWidth = (blendRadius * 2) + 16; + + this.secX = secX; + this.secY = secY; + this.secZ = secZ; + + this.minX = (secX << 4) - blendRadius; + this.minZ = (secZ << 4) - blendRadius; + this.maxX = (secX << 4) + 16 + blendRadius; + this.maxZ = (secZ << 4) + 16 + blendRadius; + + int size = totalWidth * totalWidth; + + if (size != this.dataSize) { + this.dataSize = size; + + for (Layer[] layers : layers.values()) { + for (Layer layer : layers) { + layer.allocate(size); + } + } + + this.temp = new int[size]; + } + else { + for (Layer[] layers : layers.values()) { + for (Layer layer : layers) { + layer.invalidate(); + } + } + } + } + + public int getColor(BlockPos blockPos, ColorResolver colorResolver) { + int relY = blockPos.getY() & 15; + + if (!this.layers.containsKey(colorResolver)) { + addResolver(colorResolver); + } + + Layer layer = this.layers.get(colorResolver)[relY]; + + if (layer.invalidated) { + calculateLayer(layer, colorResolver, relY); + } + + int[] values = layer.getValues(); + + int relX = blockPos.getX() & 15; + int relZ = blockPos.getZ() & 15; + int idx = this.totalWidth * (relZ + this.blendRadius) + (relX + this.blendRadius); + return values[idx]; + } + + private void addResolver(ColorResolver colorResolver) { + Layer[] layers1 = allocateLayers(); + + for (Layer layer : layers1) { + layer.allocate(this.dataSize); + } + + this.layers.put(colorResolver, layers1); + } + + private Layer[] allocateLayers() { + Layer[] layers = new Layer[SECTION_WIDTH]; + + Arrays.fill(layers, new Layer()); + return layers; + } + + private void calculateLayer(Layer layer, ColorResolver colorResolver, int y) { + int absY = (secY << 4) + y; + + int[] values = layer.values; + + for (int absZ = minZ; absZ < maxZ; absZ++) { + for (int absX = minX; absX < maxX; absX++) { + Biome biome = this.biomeData.getBiome(absX, absY, absZ); + + final int idx = (absX - minX) + (absZ - minZ) * totalWidth; + values[idx] = colorResolver.getColor(biome, absX, absZ); + } + } + + if (blendRadius > 0) { + this.applyBlur(values); + } + + layer.invalidated = false; + } + + private void applyBlur(int[] buffer) { + int value = buffer[0]; + boolean needsBlur = false; + for (int i = 1; i < buffer.length; ++i) { + if (value != buffer[i]) { + needsBlur = true; + break; + } + } + + if (needsBlur) + BoxBlur.blur(buffer, temp, SECTION_WIDTH, blendRadius); + } + + static class Layer { + private boolean invalidated = true; + private int[] values; + + void allocate(int size) { + this.values = new int[size]; + invalidate(); + } + + void invalidate() { + this.invalidated = true; + } + + public int[] getValues() { + return this.values; + } + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/VulkanModRenderer.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/VulkanModRenderer.java new file mode 100644 index 000000000..e2a335109 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/VulkanModRenderer.java @@ -0,0 +1,55 @@ +package net.vulkanmod.render.chunk.build.frapi; + +import java.util.HashMap; + +import net.minecraft.resources.ResourceLocation; + +import net.fabricmc.fabric.api.renderer.v1.Renderer; +import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; +import net.vulkanmod.render.chunk.build.frapi.material.MaterialFinderImpl; +import net.vulkanmod.render.chunk.build.frapi.material.RenderMaterialImpl; +import net.vulkanmod.render.chunk.build.frapi.mesh.MeshBuilderImpl; + +/** + * The Fabric default renderer implementation. Supports all + * features defined in the API except shaders and offers no special materials. + */ +public class VulkanModRenderer implements Renderer { + public static final VulkanModRenderer INSTANCE = new VulkanModRenderer(); + + public static final RenderMaterial MATERIAL_STANDARD = INSTANCE.materialFinder().find(); + + static { + INSTANCE.registerMaterial(RenderMaterial.MATERIAL_STANDARD, MATERIAL_STANDARD); + } + + private final HashMap materialMap = new HashMap<>(); + + private VulkanModRenderer() {} + + @Override + public MeshBuilder meshBuilder() { + return new MeshBuilderImpl(); + } + + @Override + public MaterialFinder materialFinder() { + return new MaterialFinderImpl(); + } + + @Override + public RenderMaterial materialById(ResourceLocation id) { + return materialMap.get(id); + } + + @Override + public boolean registerMaterial(ResourceLocation id, RenderMaterial material) { + if (materialMap.containsKey(id)) return false; + + // cast to prevent acceptance of impostor implementations + materialMap.put(id, (RenderMaterialImpl) material); + return true; + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/ColorHelper.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/ColorHelper.java new file mode 100644 index 000000000..2723331b2 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/ColorHelper.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.helper; + +import java.nio.ByteOrder; + +/** + * Static routines of general utility for renderer implementations. + * Renderers are not required to use these helpers, but they were + * designed to be usable without the default renderer. + */ +public abstract class ColorHelper { + private ColorHelper() { } + + private static final boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + + /** Component-wise multiply. Components need to be in same order in both inputs! */ + public static int multiplyColor(int color1, int color2) { + if (color1 == -1) { + return color2; + } else if (color2 == -1) { + return color1; + } + + final int alpha = ((color1 >>> 24) & 0xFF) * ((color2 >>> 24) & 0xFF) / 0xFF; + final int red = ((color1 >>> 16) & 0xFF) * ((color2 >>> 16) & 0xFF) / 0xFF; + final int green = ((color1 >>> 8) & 0xFF) * ((color2 >>> 8) & 0xFF) / 0xFF; + final int blue = (color1 & 0xFF) * (color2 & 0xFF) / 0xFF; + + return (alpha << 24) | (red << 16) | (green << 8) | blue; + } + + /** Multiplies three lowest components by shade. High byte (usually alpha) unchanged. */ + public static int multiplyRGB(int color, float shade) { + final int alpha = ((color >>> 24) & 0xFF); + final int red = (int) (((color >>> 16) & 0xFF) * shade); + final int green = (int) (((color >>> 8) & 0xFF) * shade); + final int blue = (int) ((color & 0xFF) * shade); + + return (alpha << 24) | (red << 16) | (green << 8) | blue; + } + + /** + * Component-wise max. + */ + public static int maxBrightness(int b0, int b1) { + if (b0 == 0) return b1; + if (b1 == 0) return b0; + + return Math.max(b0 & 0xFFFF, b1 & 0xFFFF) | Math.max(b0 & 0xFFFF0000, b1 & 0xFFFF0000); + } + + /* + Renderer color format: ARGB (0xAARRGGBB) + Vanilla color format (little endian): ABGR (0xAABBGGRR) + Vanilla color format (big endian): RGBA (0xRRGGBBAA) + + Why does the vanilla color format change based on endianness? + See VertexConsumer#quad. Quad data is loaded as integers into + a native byte order buffer. Color is read directly from bytes + 12, 13, 14 of each vertex. A different byte order will yield + different results. + + The renderer always uses ARGB because the API color methods + always consume and return ARGB. Vanilla block and item colors + also use ARGB. + */ + + /** + * Converts from ARGB color to ABGR color if little endian or RGBA color if big endian. + */ + public static int toVanillaColor(int color) { + if (color == -1) { + return -1; + } + + if (BIG_ENDIAN) { + // ARGB to RGBA + return ((color & 0x00FFFFFF) << 8) | ((color & 0xFF000000) >>> 24); + } else { + // ARGB to ABGR + return (color & 0xFF00FF00) | ((color & 0x00FF0000) >>> 16) | ((color & 0x000000FF) << 16); + } + } + + /** + * Converts to ARGB color from ABGR color if little endian or RGBA color if big endian. + */ + public static int fromVanillaColor(int color) { + if (color == -1) { + return -1; + } + + if (BIG_ENDIAN) { + // RGBA to ARGB + return ((color & 0xFFFFFF00) >>> 8) | ((color & 0x000000FF) << 24); + } else { + // ABGR to ARGB + return (color & 0xFF00FF00) | ((color & 0x00FF0000) >>> 16) | ((color & 0x000000FF) << 16); + } + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/GeometryHelper.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/GeometryHelper.java new file mode 100644 index 000000000..66e8a805e --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/GeometryHelper.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.helper; + +import static net.minecraft.util.Mth.equal; + +import org.joml.Vector3f; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.core.Direction.AxisDirection; + +/** + * Static routines of general utility for renderer implementations. + * Renderers are not required to use these helpers, but they were + * designed to be usable without the default renderer. + */ +public abstract class GeometryHelper { + private GeometryHelper() { } + + /** set when a quad touches all four corners of a unit cube. */ + public static final int CUBIC_FLAG = 1; + + /** set when a quad is parallel to (but not necessarily on) a its light face. */ + public static final int AXIS_ALIGNED_FLAG = CUBIC_FLAG << 1; + + /** set when a quad is coplanar with its light face. Implies {@link #AXIS_ALIGNED_FLAG} */ + public static final int LIGHT_FACE_FLAG = AXIS_ALIGNED_FLAG << 1; + + /** how many bits quad header encoding should reserve for encoding geometry flags. */ + public static final int FLAG_BIT_COUNT = 3; + + private static final float EPS_MIN = 0.0001f; + private static final float EPS_MAX = 1.0f - EPS_MIN; + + /** + * Analyzes the quad and returns a value with some combination + * of {@link #AXIS_ALIGNED_FLAG}, {@link #LIGHT_FACE_FLAG} and {@link #CUBIC_FLAG}. + * Intended use is to optimize lighting when the geometry is regular. + * Expects convex quads with all points co-planar. + */ + public static int computeShapeFlags(QuadView quad) { + Direction lightFace = quad.lightFace(); + int bits = 0; + + if (isQuadParallelToFace(lightFace, quad)) { + bits |= AXIS_ALIGNED_FLAG; + + if (isParallelQuadOnFace(lightFace, quad)) { + bits |= LIGHT_FACE_FLAG; + } + } + + if (isQuadCubic(lightFace, quad)) { + bits |= CUBIC_FLAG; + } + + return bits; + } + + /** + * Returns true if quad is parallel to the given face. + * Does not validate quad winding order. + * Expects convex quads with all points co-planar. + */ + public static boolean isQuadParallelToFace(Direction face, QuadView quad) { + int i = face.getAxis().ordinal(); + final float val = quad.posByIndex(0, i); + return equal(val, quad.posByIndex(1, i)) && equal(val, quad.posByIndex(2, i)) && equal(val, quad.posByIndex(3, i)); + } + + /** + * True if quad - already known to be parallel to a face - is actually coplanar with it. + * For compatibility with vanilla resource packs, also true if quad is outside the face. + * + *

Test will be unreliable if not already parallel, use {@link #isQuadParallelToFace(Direction, QuadView)} + * for that purpose. Expects convex quads with all points co-planar. + */ + public static boolean isParallelQuadOnFace(Direction lightFace, QuadView quad) { + final float x = quad.posByIndex(0, lightFace.getAxis().ordinal()); + return lightFace.getAxisDirection() == AxisDirection.POSITIVE ? x >= EPS_MAX : x <= EPS_MIN; + } + + /** + * Returns true if quad is truly a quad (not a triangle) and fills a full block cross-section. + * If known to be true, allows use of a simpler/faster AO lighting algorithm. + * + *

Does not check if quad is actually coplanar with the light face, nor does it check that all + * quad vertices are coplanar with each other. + * + *

Expects convex quads with all points co-planar. + */ + public static boolean isQuadCubic(Direction lightFace, QuadView quad) { + int a, b; + + switch (lightFace) { + case EAST: + case WEST: + a = 1; + b = 2; + break; + case UP: + case DOWN: + a = 0; + b = 2; + break; + case SOUTH: + case NORTH: + a = 1; + b = 0; + break; + default: + // handle WTF case + return false; + } + + return confirmSquareCorners(a, b, quad); + } + + /** + * Used by {@link #isQuadCubic(Direction, QuadView)}. + * True if quad touches all four corners of unit square. + * + *

For compatibility with resource packs that contain models with quads exceeding + * block boundaries, considers corners outside the block to be at the corners. + */ + private static boolean confirmSquareCorners(int aCoordinate, int bCoordinate, QuadView quad) { + int flags = 0; + + for (int i = 0; i < 4; i++) { + final float a = quad.posByIndex(i, aCoordinate); + final float b = quad.posByIndex(i, bCoordinate); + + if (a <= EPS_MIN) { + if (b <= EPS_MIN) { + flags |= 1; + } else if (b >= EPS_MAX) { + flags |= 2; + } else { + return false; + } + } else if (a >= EPS_MAX) { + if (b <= EPS_MIN) { + flags |= 4; + } else if (b >= EPS_MAX) { + flags |= 8; + } else { + return false; + } + } else { + return false; + } + } + + return flags == 15; + } + + /** + * Identifies the face to which the quad is most closely aligned. + * This mimics the value that {@link BakedQuad#getDirection()} returns, and is + * used in the vanilla renderer for all diffuse lighting. + * + *

Derived from the quad face normal and expects convex quads with all points co-planar. + */ + public static Direction lightFace(QuadView quad) { + final Vector3f normal = quad.faceNormal(); + switch (GeometryHelper.longestAxis(normal)) { + case X: + return normal.x() > 0 ? Direction.EAST : Direction.WEST; + + case Y: + return normal.y() > 0 ? Direction.UP : Direction.DOWN; + + case Z: + return normal.z() > 0 ? Direction.SOUTH : Direction.NORTH; + + default: + // handle WTF case + return Direction.UP; + } + } + + /** + * Simple 4-way compare, doesn't handle NaN values. + */ + public static float min(float a, float b, float c, float d) { + final float x = a < b ? a : b; + final float y = c < d ? c : d; + return x < y ? x : y; + } + + /** + * Simple 4-way compare, doesn't handle NaN values. + */ + public static float max(float a, float b, float c, float d) { + final float x = a > b ? a : b; + final float y = c > d ? c : d; + return x > y ? x : y; + } + + /** + * @see #longestAxis(float, float, float) + */ + public static Axis longestAxis(Vector3f vec) { + return longestAxis(vec.x(), vec.y(), vec.z()); + } + + /** + * Identifies the largest (max absolute magnitude) component (X, Y, Z) in the given vector. + */ + public static Axis longestAxis(float normalX, float normalY, float normalZ) { + Axis result = Axis.Y; + float longest = Math.abs(normalY); + float a = Math.abs(normalX); + + if (a > longest) { + result = Axis.X; + longest = a; + } + + return Math.abs(normalZ) > longest + ? Axis.Z : result; + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/NormalHelper.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/NormalHelper.java new file mode 100644 index 000000000..bf6deebb7 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/NormalHelper.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.helper; + +import net.vulkanmod.render.model.quad.ModelQuadView; +import net.vulkanmod.render.vertex.format.I32_SNorm; +import org.jetbrains.annotations.NotNull; +import org.joml.Vector3f; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import net.minecraft.core.Direction; +import net.minecraft.core.Vec3i; +import net.minecraft.util.Mth; + +/** + * Static routines of general utility for renderer implementations. + * Renderers are not required to use these helpers, but they were + * designed to be usable without the default renderer. + */ +public abstract class NormalHelper { + private NormalHelper() { } + + private static final float PACK = 127.0f; + private static final float UNPACK = 1.0f / PACK; + + /** + * Stores a normal plus an extra value as a quartet of signed bytes. + * This is the same normal format that vanilla rendering expects. + * The extra value is for use by shaders. + */ + public static int packNormal(float x, float y, float z, float w) { + x = Mth.clamp(x, -1, 1); + y = Mth.clamp(y, -1, 1); + z = Mth.clamp(z, -1, 1); + w = Mth.clamp(w, -1, 1); + + return ((int) (x * PACK) & 0xFF) | (((int) (y * PACK) & 0xFF) << 8) | (((int) (z * PACK) & 0xFF) << 16) | (((int) (w * PACK) & 0xFF) << 24); + } + + /** + * Version of {@link #packNormal(float, float, float, float)} that accepts a vector type. + */ + public static int packNormal(Vector3f normal, float w) { + return packNormal(normal.x(), normal.y(), normal.z(), w); + } + + /** + * Like {@link #packNormal(float, float, float, float)}, but without a {@code w} value. + */ + public static int packNormal(float x, float y, float z) { + x = Mth.clamp(x, -1, 1); + y = Mth.clamp(y, -1, 1); + z = Mth.clamp(z, -1, 1); + + return ((int) (x * PACK) & 0xFF) | (((int) (y * PACK) & 0xFF) << 8) | (((int) (z * PACK) & 0xFF) << 16); + } + + /** + * Like {@link #packNormal(Vector3f, float)}, but without a {@code w} value. + */ + public static int packNormal(Vector3f normal) { + return packNormal(normal.x(), normal.y(), normal.z()); + } + + public static float unpackNormalX(int packedNormal) { + return ((byte) (packedNormal & 0xFF)) * UNPACK; + } + + public static float unpackNormalY(int packedNormal) { + return ((byte) ((packedNormal >>> 8) & 0xFF)) * UNPACK; + } + + public static float unpackNormalZ(int packedNormal) { + return ((byte) ((packedNormal >>> 16) & 0xFF)) * UNPACK; + } + + public static float unpackNormalW(int packedNormal) { + return ((byte) ((packedNormal >>> 24) & 0xFF)) * UNPACK; + } + + public static void unpackNormal(int packedNormal, Vector3f target) { + target.set(unpackNormalX(packedNormal), unpackNormalY(packedNormal), unpackNormalZ(packedNormal)); + } + + /** + * Computes the face normal of the given quad and saves it in the provided non-null vector. + * If {@link QuadView#nominalFace()} is set will optimize by confirming quad is parallel to that + * face and, if so, use the standard normal for that face direction. + * + *

Will work with triangles also. Assumes counter-clockwise winding order, which is the norm. + * Expects convex quads with all points co-planar. + */ + public static void computeFaceNormal(@NotNull Vector3f saveTo, QuadView q) { + final Direction nominalFace = q.nominalFace(); + + if (nominalFace != null && GeometryHelper.isQuadParallelToFace(nominalFace, q)) { + Vec3i vec = nominalFace.getNormal(); + saveTo.set(vec.getX(), vec.getY(), vec.getZ()); + return; + } + + final float x0 = q.x(0); + final float y0 = q.y(0); + final float z0 = q.z(0); + final float x1 = q.x(1); + final float y1 = q.y(1); + final float z1 = q.z(1); + final float x2 = q.x(2); + final float y2 = q.y(2); + final float z2 = q.z(2); + final float x3 = q.x(3); + final float y3 = q.y(3); + final float z3 = q.z(3); + + final float dx0 = x2 - x0; + final float dy0 = y2 - y0; + final float dz0 = z2 - z0; + final float dx1 = x3 - x1; + final float dy1 = y3 - y1; + final float dz1 = z3 - z1; + + float normX = dy0 * dz1 - dz0 * dy1; + float normY = dz0 * dx1 - dx0 * dz1; + float normZ = dx0 * dy1 - dy0 * dx1; + + float l = (float) Math.sqrt(normX * normX + normY * normY + normZ * normZ); + + if (l != 0) { + normX /= l; + normY /= l; + normZ /= l; + } + + saveTo.set(normX, normY, normZ); + } + + public static int computePackedNormal(ModelQuadView q) { + final float x0 = q.getX(0); + final float y0 = q.getY(0); + final float z0 = q.getZ(0); + final float x1 = q.getX(1); + final float y1 = q.getY(1); + final float z1 = q.getZ(1); + final float x2 = q.getX(2); + final float y2 = q.getY(2); + final float z2 = q.getZ(2); + final float x3 = q.getX(3); + final float y3 = q.getY(3); + final float z3 = q.getZ(3); + + final float dx0 = x2 - x0; + final float dy0 = y2 - y0; + final float dz0 = z2 - z0; + final float dx1 = x3 - x1; + final float dy1 = y3 - y1; + final float dz1 = z3 - z1; + + float normX = dy0 * dz1 - dz0 * dy1; + float normY = dz0 * dx1 - dx0 * dz1; + float normZ = dx0 * dy1 - dy0 * dx1; + + float l = (float) Math.sqrt(normX * normX + normY * normY + normZ * normZ); + + if (l != 0) { + normX /= l; + normY /= l; + normZ /= l; + } + + return I32_SNorm.packNormal(normX, normY, normZ); + } + + public static int packedNormalFromDirection(Direction direction) { + Vec3i normal = direction.getNormal(); + + return I32_SNorm.packNormal(normal.getX(), normal.getY(), normal.getZ()); + } + + public static void unpackNormalTo(int packedNormal, Vector3f normal) { + normal.set(I32_SNorm.unpackX(packedNormal), I32_SNorm.unpackY(packedNormal), I32_SNorm.unpackZ(packedNormal)); + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/TextureHelper.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/TextureHelper.java new file mode 100644 index 000000000..bc622cd92 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/helper/TextureHelper.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.helper; + +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.Direction; + +/** + * Handles most texture-baking use cases for model loaders and model libraries + * via {@link #bakeSprite(MutableQuadView, TextureAtlasSprite, int)}. Also used by the API + * itself to implement automatic block-breaking models for enhanced models. + */ +public class TextureHelper { + private TextureHelper() { } + + private static final float NORMALIZER = 1f / 16f; + + /** + * Bakes textures in the provided vertex data, handling UV locking, + * rotation, interpolation, etc. Textures must not be already baked. + */ + public static void bakeSprite(MutableQuadView quad, TextureAtlasSprite sprite, int bakeFlags) { + if (quad.nominalFace() != null && (MutableQuadView.BAKE_LOCK_UV & bakeFlags) != 0) { + // Assigns normalized UV coordinates based on vertex positions + applyModifier(quad, UVLOCKERS[quad.nominalFace().get3DDataValue()]); + } else if ((MutableQuadView.BAKE_NORMALIZED & bakeFlags) == 0) { // flag is NOT set, UVs are assumed to not be normalized yet as is the default, normalize through dividing by 16 + // Scales from 0-16 to 0-1 + applyModifier(quad, (q, i) -> q.uv(i, q.u(i) * NORMALIZER, q.v(i) * NORMALIZER)); + } + + final int rotation = bakeFlags & 3; + + if (rotation != 0) { + // Rotates texture around the center of sprite. + // Assumes normalized coordinates. + applyModifier(quad, ROTATIONS[rotation]); + } + + if ((MutableQuadView.BAKE_FLIP_U & bakeFlags) != 0) { + // Inverts U coordinates. Assumes normalized (0-1) values. + applyModifier(quad, (q, i) -> q.uv(i, 1 - q.u(i), q.v(i))); + } + + if ((MutableQuadView.BAKE_FLIP_V & bakeFlags) != 0) { + // Inverts V coordinates. Assumes normalized (0-1) values. + applyModifier(quad, (q, i) -> q.uv(i, q.u(i), 1 - q.v(i))); + } + + interpolate(quad, sprite); + } + + /** + * Faster than sprite method. Sprite computes span and normalizes inputs each call, + * so we'd have to denormalize before we called, only to have the sprite renormalize immediately. + */ + private static void interpolate(MutableQuadView q, TextureAtlasSprite sprite) { + final float uMin = sprite.getU0(); + final float uSpan = sprite.getU1() - uMin; + final float vMin = sprite.getV0(); + final float vSpan = sprite.getV1() - vMin; + + for (int i = 0; i < 4; i++) { + q.uv(i, uMin + q.u(i) * uSpan, vMin + q.v(i) * vSpan); + } + } + + @FunctionalInterface + private interface VertexModifier { + void apply(MutableQuadView quad, int vertexIndex); + } + + private static void applyModifier(MutableQuadView quad, VertexModifier modifier) { + for (int i = 0; i < 4; i++) { + modifier.apply(quad, i); + } + } + + private static final VertexModifier[] ROTATIONS = new VertexModifier[] { + null, + (q, i) -> q.uv(i, q.v(i), 1 - q.u(i)), //90 + (q, i) -> q.uv(i, 1 - q.u(i), 1 - q.v(i)), //180 + (q, i) -> q.uv(i, 1 - q.v(i), q.u(i)) // 270 + }; + + private static final VertexModifier[] UVLOCKERS = new VertexModifier[6]; + + static { + UVLOCKERS[Direction.EAST.get3DDataValue()] = (q, i) -> q.uv(i, 1 - q.z(i), 1 - q.y(i)); + UVLOCKERS[Direction.WEST.get3DDataValue()] = (q, i) -> q.uv(i, q.z(i), 1 - q.y(i)); + UVLOCKERS[Direction.NORTH.get3DDataValue()] = (q, i) -> q.uv(i, 1 - q.x(i), 1 - q.y(i)); + UVLOCKERS[Direction.SOUTH.get3DDataValue()] = (q, i) -> q.uv(i, q.x(i), 1 - q.y(i)); + UVLOCKERS[Direction.DOWN.get3DDataValue()] = (q, i) -> q.uv(i, q.x(i), 1 - q.z(i)); + UVLOCKERS[Direction.UP.get3DDataValue()] = (q, i) -> q.uv(i, q.x(i), q.z(i)); + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/material/MaterialFinderImpl.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/material/MaterialFinderImpl.java new file mode 100644 index 000000000..91b510452 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/material/MaterialFinderImpl.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.material; + +import java.util.Objects; + +import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; +import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; +import net.fabricmc.fabric.api.renderer.v1.material.MaterialView; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode; +import net.fabricmc.fabric.api.util.TriState; + +public class MaterialFinderImpl extends MaterialViewImpl implements MaterialFinder { + private static int defaultBits = 0; + + static { + MaterialFinderImpl finder = new MaterialFinderImpl(); + finder.ambientOcclusion(TriState.DEFAULT); + finder.glint(TriState.DEFAULT); + defaultBits = finder.bits; + + if (!areBitsValid(defaultBits)) { + throw new AssertionError("Default MaterialFinder bits are not valid!"); + } + } + + public MaterialFinderImpl() { + super(defaultBits); + } + + @Override + public MaterialFinder blendMode(BlendMode blendMode) { + Objects.requireNonNull(blendMode, "BlendMode may not be null"); + + bits = (bits & ~BLEND_MODE_MASK) | (blendMode.ordinal() << BLEND_MODE_BIT_OFFSET); + return this; + } + + @Override + public MaterialFinder disableColorIndex(boolean disable) { + bits = disable ? (bits | COLOR_DISABLE_FLAG) : (bits & ~COLOR_DISABLE_FLAG); + return this; + } + + @Override + public MaterialFinder emissive(boolean isEmissive) { + bits = isEmissive ? (bits | EMISSIVE_FLAG) : (bits & ~EMISSIVE_FLAG); + return this; + } + + @Override + public MaterialFinder disableDiffuse(boolean disable) { + bits = disable ? (bits | DIFFUSE_FLAG) : (bits & ~DIFFUSE_FLAG); + return this; + } + + @Override + public MaterialFinder ambientOcclusion(TriState mode) { + Objects.requireNonNull(mode, "ambient occlusion TriState may not be null"); + + bits = (bits & ~AO_MASK) | (mode.ordinal() << AO_BIT_OFFSET); + return this; + } + + @Override + public MaterialFinder glint(TriState mode) { + Objects.requireNonNull(mode, "glint TriState may not be null"); + + bits = (bits & ~GLINT_MASK) | (mode.ordinal() << GLINT_BIT_OFFSET); + return this; + } + + @Override + public MaterialFinder shadeMode(ShadeMode mode) { + Objects.requireNonNull(mode, "ShadeMode may not be null"); + + bits = (bits & ~SHADE_MODE_MASK) | (mode.ordinal() << SHADE_MODE_BIT_OFFSET); + return this; + } + + @Override + public MaterialFinder copyFrom(MaterialView material) { + bits = ((MaterialViewImpl) material).bits; + return this; + } + + @Override + public MaterialFinder clear() { + bits = defaultBits; + return this; + } + + @Override + public RenderMaterial find() { + return RenderMaterialImpl.byIndex(bits); + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/material/MaterialViewImpl.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/material/MaterialViewImpl.java new file mode 100644 index 000000000..0ae070574 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/material/MaterialViewImpl.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.material; + +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.bitMask; + +import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; +import net.fabricmc.fabric.api.renderer.v1.material.MaterialView; +import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode; +import net.fabricmc.fabric.api.util.TriState; +import net.minecraft.util.Mth; + +/** + * Default implementation of the standard render materials. + * The underlying representation is simply an int with bit-wise + * packing of the various material properties. This offers + * easy/fast interning via int/object hashmap. + */ +public class MaterialViewImpl implements MaterialView { + private static final BlendMode[] BLEND_MODES = BlendMode.values(); + private static final int BLEND_MODE_COUNT = BLEND_MODES.length; + private static final TriState[] TRI_STATES = TriState.values(); + private static final int TRI_STATE_COUNT = TRI_STATES.length; + private static final ShadeMode[] SHADE_MODES = ShadeMode.values(); + private static final int SHADE_MODE_COUNT = SHADE_MODES.length; + + protected static final int BLEND_MODE_BIT_LENGTH = Mth.ceillog2(BLEND_MODE_COUNT); + protected static final int COLOR_DISABLE_BIT_LENGTH = 1; + protected static final int EMISSIVE_BIT_LENGTH = 1; + protected static final int DIFFUSE_BIT_LENGTH = 1; + protected static final int AO_BIT_LENGTH = Mth.ceillog2(TRI_STATE_COUNT); + protected static final int GLINT_BIT_LENGTH = Mth.ceillog2(TRI_STATE_COUNT); + protected static final int SHADE_MODE_BIT_LENGTH = Mth.ceillog2(SHADE_MODE_COUNT); + + protected static final int BLEND_MODE_BIT_OFFSET = 0; + protected static final int COLOR_DISABLE_BIT_OFFSET = BLEND_MODE_BIT_OFFSET + BLEND_MODE_BIT_LENGTH; + protected static final int EMISSIVE_BIT_OFFSET = COLOR_DISABLE_BIT_OFFSET + COLOR_DISABLE_BIT_LENGTH; + protected static final int DIFFUSE_BIT_OFFSET = EMISSIVE_BIT_OFFSET + EMISSIVE_BIT_LENGTH; + protected static final int AO_BIT_OFFSET = DIFFUSE_BIT_OFFSET + DIFFUSE_BIT_LENGTH; + protected static final int GLINT_BIT_OFFSET = AO_BIT_OFFSET + AO_BIT_LENGTH; + protected static final int SHADE_MODE_BIT_OFFSET = GLINT_BIT_OFFSET + GLINT_BIT_LENGTH; + public static final int TOTAL_BIT_LENGTH = SHADE_MODE_BIT_OFFSET + SHADE_MODE_BIT_LENGTH; + + protected static final int BLEND_MODE_MASK = bitMask(BLEND_MODE_BIT_LENGTH, BLEND_MODE_BIT_OFFSET); + protected static final int COLOR_DISABLE_FLAG = bitMask(COLOR_DISABLE_BIT_LENGTH, COLOR_DISABLE_BIT_OFFSET); + protected static final int EMISSIVE_FLAG = bitMask(EMISSIVE_BIT_LENGTH, EMISSIVE_BIT_OFFSET); + protected static final int DIFFUSE_FLAG = bitMask(DIFFUSE_BIT_LENGTH, DIFFUSE_BIT_OFFSET); + protected static final int AO_MASK = bitMask(AO_BIT_LENGTH, AO_BIT_OFFSET); + protected static final int GLINT_MASK = bitMask(GLINT_BIT_LENGTH, GLINT_BIT_OFFSET); + protected static final int SHADE_MODE_MASK = bitMask(SHADE_MODE_BIT_LENGTH, SHADE_MODE_BIT_OFFSET); + + protected static boolean areBitsValid(int bits) { + int blendMode = (bits & BLEND_MODE_MASK) >>> BLEND_MODE_BIT_OFFSET; + int ao = (bits & AO_MASK) >>> AO_BIT_OFFSET; + int glint = (bits & GLINT_MASK) >>> GLINT_BIT_OFFSET; + int shadeMode = (bits & SHADE_MODE_MASK) >>> SHADE_MODE_BIT_OFFSET; + + return blendMode < BLEND_MODE_COUNT + && ao < TRI_STATE_COUNT + && glint < TRI_STATE_COUNT + && shadeMode < SHADE_MODE_COUNT; + } + + protected int bits; + + protected MaterialViewImpl(int bits) { + this.bits = bits; + } + + @Override + public BlendMode blendMode() { + return BLEND_MODES[(bits & BLEND_MODE_MASK) >>> BLEND_MODE_BIT_OFFSET]; + } + + @Override + public boolean disableColorIndex() { + return (bits & COLOR_DISABLE_FLAG) != 0; + } + + @Override + public boolean emissive() { + return (bits & EMISSIVE_FLAG) != 0; + } + + @Override + public boolean disableDiffuse() { + return (bits & DIFFUSE_FLAG) != 0; + } + + @Override + public TriState ambientOcclusion() { + return TRI_STATES[(bits & AO_MASK) >>> AO_BIT_OFFSET]; + } + + @Override + public TriState glint() { + return TRI_STATES[(bits & GLINT_MASK) >>> GLINT_BIT_OFFSET]; + } + + @Override + public ShadeMode shadeMode() { + return SHADE_MODES[(bits & SHADE_MODE_MASK) >>> SHADE_MODE_BIT_OFFSET]; + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/material/RenderMaterialImpl.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/material/RenderMaterialImpl.java new file mode 100644 index 000000000..17e4602bb --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/material/RenderMaterialImpl.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.material; + +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; + +public class RenderMaterialImpl extends MaterialViewImpl implements RenderMaterial { + public static final int VALUE_COUNT = 1 << TOTAL_BIT_LENGTH; + private static final RenderMaterialImpl[] BY_INDEX = new RenderMaterialImpl[VALUE_COUNT]; + + static { + for (int i = 0; i < VALUE_COUNT; i++) { + if (areBitsValid(i)) { + BY_INDEX[i] = new RenderMaterialImpl(i); + } + } + } + + private RenderMaterialImpl(int bits) { + super(bits); + } + + public int index() { + return bits; + } + + public static RenderMaterialImpl byIndex(int index) { + return BY_INDEX[index]; + } + + public static RenderMaterialImpl setDisableDiffuse(RenderMaterialImpl material, boolean disable) { + if (material.disableDiffuse() != disable) { + return byIndex(disable ? (material.bits | DIFFUSE_FLAG) : (material.bits & ~DIFFUSE_FLAG)); + } + + return material; + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/EncodingFormat.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/EncodingFormat.java new file mode 100644 index 000000000..f1cf763cc --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/EncodingFormat.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.mesh; + +import com.google.common.base.Preconditions; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.VertexFormat; +import org.jetbrains.annotations.Nullable; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; +import net.vulkanmod.render.chunk.build.frapi.helper.GeometryHelper; +import net.vulkanmod.render.chunk.build.frapi.material.MaterialViewImpl; +import net.vulkanmod.render.chunk.build.frapi.material.RenderMaterialImpl; +import net.minecraft.core.Direction; +import net.minecraft.util.Mth; + +/** + * Holds all the array offsets and bit-wise encoders/decoders for + * packing/unpacking quad data in an array of integers. + * All of this is implementation-specific - that's why it isn't a "helper" class. + */ +public abstract class EncodingFormat { + private EncodingFormat() { } + + static final int HEADER_BITS = 0; + static final int HEADER_FACE_NORMAL = 1; + static final int HEADER_COLOR_INDEX = 2; + static final int HEADER_TAG = 3; + public static final int HEADER_STRIDE = 4; + + static final int VERTEX_X; + static final int VERTEX_Y; + static final int VERTEX_Z; + static final int VERTEX_COLOR; + static final int VERTEX_U; + static final int VERTEX_V; + static final int VERTEX_LIGHTMAP; + static final int VERTEX_NORMAL; + public static final int VERTEX_STRIDE; + + public static final int QUAD_STRIDE; + public static final int QUAD_STRIDE_BYTES; + public static final int TOTAL_STRIDE; + + static { + final VertexFormat format = DefaultVertexFormat.BLOCK; + VERTEX_X = HEADER_STRIDE + 0; + VERTEX_Y = HEADER_STRIDE + 1; + VERTEX_Z = HEADER_STRIDE + 2; + VERTEX_COLOR = HEADER_STRIDE + 3; + VERTEX_U = HEADER_STRIDE + 4; + VERTEX_V = VERTEX_U + 1; + VERTEX_LIGHTMAP = HEADER_STRIDE + 6; + VERTEX_NORMAL = HEADER_STRIDE + 7; + VERTEX_STRIDE = format.getVertexSize() / 4; + QUAD_STRIDE = VERTEX_STRIDE * 4; + QUAD_STRIDE_BYTES = QUAD_STRIDE * 4; + TOTAL_STRIDE = HEADER_STRIDE + QUAD_STRIDE; + + Preconditions.checkState(VERTEX_STRIDE == QuadView.VANILLA_VERTEX_STRIDE, "Indigo vertex stride (%s) mismatched with rendering API (%s)", VERTEX_STRIDE, QuadView.VANILLA_VERTEX_STRIDE); + Preconditions.checkState(QUAD_STRIDE == QuadView.VANILLA_QUAD_STRIDE, "Indigo quad stride (%s) mismatched with rendering API (%s)", QUAD_STRIDE, QuadView.VANILLA_QUAD_STRIDE); + } + + /** used for quick clearing of quad buffers. */ + static final int[] EMPTY = new int[TOTAL_STRIDE]; + + private static final int DIRECTION_COUNT = Direction.values().length; + private static final int NULLABLE_DIRECTION_COUNT = DIRECTION_COUNT + 1; + + private static final int CULL_BIT_LENGTH = Mth.ceillog2(NULLABLE_DIRECTION_COUNT); + private static final int LIGHT_BIT_LENGTH = Mth.ceillog2(DIRECTION_COUNT); + private static final int NORMALS_BIT_LENGTH = 4; + private static final int GEOMETRY_BIT_LENGTH = GeometryHelper.FLAG_BIT_COUNT; + private static final int MATERIAL_BIT_LENGTH = MaterialViewImpl.TOTAL_BIT_LENGTH; + + private static final int CULL_BIT_OFFSET = 0; + private static final int LIGHT_BIT_OFFSET = CULL_BIT_OFFSET + CULL_BIT_LENGTH; + private static final int NORMALS_BIT_OFFSET = LIGHT_BIT_OFFSET + LIGHT_BIT_LENGTH; + private static final int GEOMETRY_BIT_OFFSET = NORMALS_BIT_OFFSET + NORMALS_BIT_LENGTH; + private static final int MATERIAL_BIT_OFFSET = GEOMETRY_BIT_OFFSET + GEOMETRY_BIT_LENGTH; + private static final int TOTAL_BIT_LENGTH = MATERIAL_BIT_OFFSET + MATERIAL_BIT_LENGTH; + + private static final int CULL_MASK = bitMask(CULL_BIT_LENGTH, CULL_BIT_OFFSET); + private static final int LIGHT_MASK = bitMask(LIGHT_BIT_LENGTH, LIGHT_BIT_OFFSET); + private static final int NORMALS_MASK = bitMask(NORMALS_BIT_LENGTH, NORMALS_BIT_OFFSET); + private static final int GEOMETRY_MASK = bitMask(GEOMETRY_BIT_LENGTH, GEOMETRY_BIT_OFFSET); + private static final int MATERIAL_MASK = bitMask(MATERIAL_BIT_LENGTH, MATERIAL_BIT_OFFSET); + + static { + Preconditions.checkArgument(TOTAL_BIT_LENGTH <= 32, "Indigo header encoding bit count (%s) exceeds integer bit length)", TOTAL_STRIDE); + } + + public static int bitMask(int bitLength, int bitOffset) { + return ((1 << bitLength) - 1) << bitOffset; + } + + @Nullable + static Direction cullFace(int bits) { + return ModelHelper.faceFromIndex((bits & CULL_MASK) >>> CULL_BIT_OFFSET); + } + + static int cullFace(int bits, @Nullable Direction face) { + return (bits & ~CULL_MASK) | (ModelHelper.toFaceIndex(face) << CULL_BIT_OFFSET); + } + + static Direction lightFace(int bits) { + return ModelHelper.faceFromIndex((bits & LIGHT_MASK) >>> LIGHT_BIT_OFFSET); + } + + static int lightFace(int bits, Direction face) { + return (bits & ~LIGHT_MASK) | (ModelHelper.toFaceIndex(face) << LIGHT_BIT_OFFSET); + } + + /** indicate if vertex normal has been set - bits correspond to vertex ordinals. */ + static int normalFlags(int bits) { + return (bits & NORMALS_MASK) >>> NORMALS_BIT_OFFSET; + } + + static int normalFlags(int bits, int normalFlags) { + return (bits & ~NORMALS_MASK) | ((normalFlags << NORMALS_BIT_OFFSET) & NORMALS_MASK); + } + + static int geometryFlags(int bits) { + return (bits & GEOMETRY_MASK) >>> GEOMETRY_BIT_OFFSET; + } + + static int geometryFlags(int bits, int geometryFlags) { + return (bits & ~GEOMETRY_MASK) | ((geometryFlags << GEOMETRY_BIT_OFFSET) & GEOMETRY_MASK); + } + + static RenderMaterialImpl material(int bits) { + return RenderMaterialImpl.byIndex((bits & MATERIAL_MASK) >>> MATERIAL_BIT_OFFSET); + } + + static int material(int bits, RenderMaterialImpl material) { + return (bits & ~MATERIAL_MASK) | (material.index() << MATERIAL_BIT_OFFSET); + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MeshBuilderImpl.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MeshBuilderImpl.java new file mode 100644 index 000000000..b5119de51 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MeshBuilderImpl.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.mesh; + +import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; +import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; + +/** + * Our implementation of {@link MeshBuilder}, used for static mesh creation and baking. + * Not much to it - mainly it just needs to grow the int[] array as quads are appended + * and maintain/provide a properly-configured {@link net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView} instance. + * All the encoding and other work is handled in the quad base classes. + * The one interesting bit is in {@link Maker#emitDirectly()}. + */ +public class MeshBuilderImpl implements MeshBuilder { + private int[] data = new int[256]; + private int index = 0; + private int limit = data.length; + private final Maker maker = new Maker(); + + public MeshBuilderImpl() { + ensureCapacity(EncodingFormat.TOTAL_STRIDE); + maker.data = data; + maker.baseIndex = index; + maker.clear(); + } + + protected void ensureCapacity(int stride) { + if (stride > limit - index) { + limit *= 2; + final int[] bigger = new int[limit]; + System.arraycopy(data, 0, bigger, 0, index); + data = bigger; + maker.data = data; + } + } + + @Override + public QuadEmitter getEmitter() { + maker.clear(); + return maker; + } + + @Override + public Mesh build() { + final int[] packed = new int[index]; + System.arraycopy(data, 0, packed, 0, index); + index = 0; + maker.baseIndex = index; + maker.clear(); + return new MeshImpl(packed); + } + + /** + * Our base classes are used differently so we define final + * encoding steps in subtypes. This will be a static mesh used + * at render time so we want to capture all geometry now and + * apply non-location-dependent lighting. + */ + private class Maker extends MutableQuadViewImpl { + @Override + public void emitDirectly() { + computeGeometry(); + index += EncodingFormat.TOTAL_STRIDE; + ensureCapacity(EncodingFormat.TOTAL_STRIDE); + baseIndex = index; + } + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MeshImpl.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MeshImpl.java new file mode 100644 index 000000000..ff23f44f7 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MeshImpl.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.mesh; + +import java.util.function.Consumer; + +import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; + +/** + * Implementation of {@link Mesh}. + * The way we encode meshes makes it very simple. + */ +public class MeshImpl implements Mesh { + /** Used to satisfy external calls to {@link #forEach(Consumer)}. */ + private final ThreadLocal cursorPool = ThreadLocal.withInitial(QuadViewImpl::new); + + final int[] data; + + MeshImpl(int[] data) { + this.data = data; + } + + @Override + public void forEach(Consumer consumer) { + forEach(consumer, cursorPool.get()); + } + + /** + * The renderer can call this with its own cursor + * to avoid the performance hit of a thread-local lookup. + * Also means renderer can hold final references to quad buffers. + */ + void forEach(Consumer consumer, QuadViewImpl cursor) { + final int limit = data.length; + int index = 0; + cursor.data = this.data; + + while (index < limit) { + cursor.baseIndex = index; + cursor.load(); + consumer.accept(cursor); + index += EncodingFormat.TOTAL_STRIDE; + } + } + + @Override + public void outputTo(QuadEmitter emitter) { + MutableQuadViewImpl e = (MutableQuadViewImpl) emitter; + final int[] data = this.data; + final int limit = data.length; + int index = 0; + + while (index < limit) { + System.arraycopy(data, index, e.data, e.baseIndex, EncodingFormat.TOTAL_STRIDE); + e.load(); + e.emitDirectly(); + index += EncodingFormat.TOTAL_STRIDE; + } + + e.clear(); + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableQuadViewImpl.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableQuadViewImpl.java new file mode 100644 index 000000000..6c83814bd --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableQuadViewImpl.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.mesh; + +import net.vulkanmod.render.chunk.build.frapi.VulkanModRenderer; +import net.vulkanmod.render.model.quad.ModelQuadView; +import org.jetbrains.annotations.Nullable; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import net.vulkanmod.render.chunk.build.frapi.helper.ColorHelper; +import net.vulkanmod.render.chunk.build.frapi.helper.NormalHelper; +import net.vulkanmod.render.chunk.build.frapi.helper.TextureHelper; +import net.vulkanmod.render.chunk.build.frapi.material.RenderMaterialImpl; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.Direction; + +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.*; + +/** + * Almost-concrete implementation of a mutable quad. The only missing part is {@link #emitDirectly()}, + * because that depends on where/how it is used. (Mesh encoding vs. render-time transformation). + * + *

In many cases an instance of this class is used as an "editor quad". The editor quad's + * {@link #emitDirectly()} method calls some other internal method that transforms the quad + * data and then buffers it. Transformations should be the same as they would be in a vanilla + * render - the editor is serving mainly as a way to access vertex data without magical + * numbers. It also allows for a consistent interface for those transformations. + */ +public abstract class MutableQuadViewImpl extends QuadViewImpl implements QuadEmitter { + public void clear() { + System.arraycopy(EMPTY, 0, data, baseIndex, EncodingFormat.TOTAL_STRIDE); + isGeometryInvalid = true; + nominalFace = null; + normalFlags(0); + tag(0); + colorIndex(-1); + cullFace(null); + material(VulkanModRenderer.MATERIAL_STANDARD); + } + + @Override + public MutableQuadViewImpl pos(int vertexIndex, float x, float y, float z) { + final int index = baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_X; + data[index] = Float.floatToRawIntBits(x); + data[index + 1] = Float.floatToRawIntBits(y); + data[index + 2] = Float.floatToRawIntBits(z); + isGeometryInvalid = true; + return this; + } + + @Override + public MutableQuadViewImpl color(int vertexIndex, int color) { + data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_COLOR] = color; + return this; + } + + @Override + public MutableQuadViewImpl uv(int vertexIndex, float u, float v) { + final int i = baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_U; + data[i] = Float.floatToRawIntBits(u); + data[i + 1] = Float.floatToRawIntBits(v); + return this; + } + + @Override + public MutableQuadViewImpl spriteBake(TextureAtlasSprite sprite, int bakeFlags) { + TextureHelper.bakeSprite(this, sprite, bakeFlags); + return this; + } + + @Override + public MutableQuadViewImpl lightmap(int vertexIndex, int lightmap) { + data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_LIGHTMAP] = lightmap; + return this; + } + + protected void normalFlags(int flags) { + data[baseIndex + HEADER_BITS] = EncodingFormat.normalFlags(data[baseIndex + HEADER_BITS], flags); + } + + @Override + public MutableQuadViewImpl normal(int vertexIndex, float x, float y, float z) { + normalFlags(normalFlags() | (1 << vertexIndex)); + data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_NORMAL] = NormalHelper.packNormal(x, y, z); + return this; + } + + /** + * Internal helper method. Copies face normals to vertex normals lacking one. + */ + public final void populateMissingNormals() { + final int normalFlags = this.normalFlags(); + + if (normalFlags == 0b1111) return; + + final int packedFaceNormal = packedFaceNormal(); + + for (int v = 0; v < 4; v++) { + if ((normalFlags & (1 << v)) == 0) { + data[baseIndex + v * VERTEX_STRIDE + VERTEX_NORMAL] = packedFaceNormal; + } + } + + normalFlags(0b1111); + } + + @Override + public final MutableQuadViewImpl cullFace(@Nullable Direction face) { + data[baseIndex + HEADER_BITS] = EncodingFormat.cullFace(data[baseIndex + HEADER_BITS], face); + nominalFace(face); + return this; + } + + @Override + public final MutableQuadViewImpl nominalFace(@Nullable Direction face) { + nominalFace = face; + return this; + } + + @Override + public final MutableQuadViewImpl material(RenderMaterial material) { + if (material == null) { + material = VulkanModRenderer.MATERIAL_STANDARD; + } + + data[baseIndex + HEADER_BITS] = EncodingFormat.material(data[baseIndex + HEADER_BITS], (RenderMaterialImpl) material); + return this; + } + + @Override + public final MutableQuadViewImpl colorIndex(int colorIndex) { + data[baseIndex + HEADER_COLOR_INDEX] = colorIndex; + return this; + } + + @Override + public final MutableQuadViewImpl tag(int tag) { + data[baseIndex + HEADER_TAG] = tag; + return this; + } + + @Override + public MutableQuadViewImpl copyFrom(QuadView quad) { + final QuadViewImpl q = (QuadViewImpl) quad; + q.computeGeometry(); + + System.arraycopy(q.data, q.baseIndex, data, baseIndex, EncodingFormat.TOTAL_STRIDE); + faceNormal.set(q.faceNormal); + nominalFace = q.nominalFace; + isGeometryInvalid = false; + return this; + } + + @Override + public final MutableQuadViewImpl fromVanilla(int[] quadData, int startIndex) { + System.arraycopy(quadData, startIndex, data, baseIndex + HEADER_STRIDE, VANILLA_QUAD_STRIDE); + isGeometryInvalid = true; + + int colorIndex = baseIndex + VERTEX_COLOR; + + for (int i = 0; i < 4; i++) { + data[colorIndex] = ColorHelper.fromVanillaColor(data[colorIndex]); + colorIndex += VERTEX_STRIDE; + } + + return this; + } + + @Override + public final MutableQuadViewImpl fromVanilla(BakedQuad quad, RenderMaterial material, @Nullable Direction cullFace) { + fromVanilla(quad.getVertices(), 0); + data[baseIndex + HEADER_BITS] = EncodingFormat.cullFace(0, cullFace); + nominalFace(quad.getDirection()); + colorIndex(quad.getTintIndex()); + + if (!quad.isShade()) { + material = RenderMaterialImpl.setDisableDiffuse((RenderMaterialImpl) material, true); + } + + material(material); + tag(0); + + // Copy data from BakedQuad instead of calculating properties + ModelQuadView quadView = (ModelQuadView) quad; + int normal = quadView.getNormal(); + data[baseIndex + HEADER_FACE_NORMAL] = normal; + NormalHelper.unpackNormalTo(normal, faceNormal); + + Direction lightFace = quadView.lightFace(); + data[baseIndex + HEADER_BITS] = EncodingFormat.lightFace(data[baseIndex + HEADER_BITS], lightFace); + + data[baseIndex + HEADER_BITS] = EncodingFormat.geometryFlags(data[baseIndex + HEADER_BITS], quadView.getFlags()); + + this.facing = quadView.getQuadFacing(); + + this.isGeometryInvalid = false; + return this; + } + + /** + * Emit the quad without clearing the underlying data. + * Geometry is not guaranteed to be valid when called, but can be computed by calling {@link #computeGeometry()}. + */ + public abstract void emitDirectly(); + + @Override + public final MutableQuadViewImpl emit() { + emitDirectly(); + clear(); + return this; + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/QuadViewImpl.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/QuadViewImpl.java new file mode 100644 index 000000000..526e45b61 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/QuadViewImpl.java @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.mesh; + +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.HEADER_BITS; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.HEADER_COLOR_INDEX; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.HEADER_FACE_NORMAL; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.HEADER_STRIDE; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.HEADER_TAG; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.QUAD_STRIDE; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.VERTEX_COLOR; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.VERTEX_LIGHTMAP; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.VERTEX_NORMAL; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.VERTEX_STRIDE; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.VERTEX_U; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.VERTEX_V; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.VERTEX_X; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.VERTEX_Y; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.VERTEX_Z; + +import net.vulkanmod.render.chunk.cull.QuadFacing; +import net.vulkanmod.render.model.quad.ModelQuadFlags; +import net.vulkanmod.render.model.quad.ModelQuadView; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector2f; +import org.joml.Vector3f; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import net.vulkanmod.render.chunk.build.frapi.helper.ColorHelper; +import net.vulkanmod.render.chunk.build.frapi.helper.GeometryHelper; +import net.vulkanmod.render.chunk.build.frapi.helper.NormalHelper; +import net.vulkanmod.render.chunk.build.frapi.material.RenderMaterialImpl; +import net.minecraft.core.Direction; + +/** + * Base class for all quads / quad makers. Handles the ugly bits + * of maintaining and encoding the quad state. + */ +public class QuadViewImpl implements QuadView, ModelQuadView { + @Nullable + protected Direction nominalFace; + /** True when face normal, light face, or geometry flags may not match geometry. */ + protected boolean isGeometryInvalid = true; + protected final Vector3f faceNormal = new Vector3f(); + + /** Size and where it comes from will vary in subtypes. But in all cases quad is fully encoded to array. */ + protected int[] data; + + /** Beginning of the quad. Also the header index. */ + protected int baseIndex = 0; + + protected QuadFacing facing; + + /** + * Decodes necessary state from the backing data array. + * The encoded data must contain valid computed geometry. + */ + public void load() { + isGeometryInvalid = false; + nominalFace = lightFace(); + NormalHelper.unpackNormal(packedFaceNormal(), faceNormal); + facing = QuadFacing.fromNormal(faceNormal); + } + + protected void computeGeometry() { + if (isGeometryInvalid) { + isGeometryInvalid = false; + + NormalHelper.computeFaceNormal(faceNormal, this); + data[baseIndex + HEADER_FACE_NORMAL] = NormalHelper.packNormal(faceNormal); + + // depends on face normal + Direction lightFace = GeometryHelper.lightFace(this); + data[baseIndex + HEADER_BITS] = EncodingFormat.lightFace(data[baseIndex + HEADER_BITS], lightFace); + + // depends on light face + data[baseIndex + HEADER_BITS] = EncodingFormat.geometryFlags(data[baseIndex + HEADER_BITS], ModelQuadFlags.getQuadFlags(this, lightFace)); + + facing = QuadFacing.fromNormal(faceNormal); + } + } + + /** gets flags used for lighting - lazily computed via {@link GeometryHelper#computeShapeFlags(QuadView)}. */ + public int geometryFlags() { + computeGeometry(); + return EncodingFormat.geometryFlags(data[baseIndex + HEADER_BITS]); + } + + public boolean hasShade() { + return !material().disableDiffuse(); + } + + @Override + public float x(int vertexIndex) { + return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_X]); + } + + @Override + public float y(int vertexIndex) { + return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_Y]); + } + + @Override + public float z(int vertexIndex) { + return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_Z]); + } + + @Override + public float posByIndex(int vertexIndex, int coordinateIndex) { + return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_X + coordinateIndex]); + } + + @Override + public Vector3f copyPos(int vertexIndex, @Nullable Vector3f target) { + if (target == null) { + target = new Vector3f(); + } + + final int index = baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_X; + target.set(Float.intBitsToFloat(data[index]), Float.intBitsToFloat(data[index + 1]), Float.intBitsToFloat(data[index + 2])); + return target; + } + + @Override + public int color(int vertexIndex) { + return data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_COLOR]; + } + + @Override + public float u(int vertexIndex) { + return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_U]); + } + + @Override + public float v(int vertexIndex) { + return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_V]); + } + + @Override + public Vector2f copyUv(int vertexIndex, @Nullable Vector2f target) { + if (target == null) { + target = new Vector2f(); + } + + final int index = baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_U; + target.set(Float.intBitsToFloat(data[index]), Float.intBitsToFloat(data[index + 1])); + return target; + } + + @Override + public int lightmap(int vertexIndex) { + return data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_LIGHTMAP]; + } + + public int normalFlags() { + return EncodingFormat.normalFlags(data[baseIndex + HEADER_BITS]); + } + + @Override + public boolean hasNormal(int vertexIndex) { + return (normalFlags() & (1 << vertexIndex)) != 0; + } + + /** True if any vertex normal has been set. */ + public boolean hasVertexNormals() { + return normalFlags() != 0; + } + + /** True if all vertex normals have been set. */ + public boolean hasAllVertexNormals() { + return (normalFlags() & 0b1111) == 0b1111; + } + + protected final int normalIndex(int vertexIndex) { + return baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_NORMAL; + } + + @Override + public float normalX(int vertexIndex) { + return hasNormal(vertexIndex) ? NormalHelper.unpackNormalX(data[normalIndex(vertexIndex)]) : Float.NaN; + } + + @Override + public float normalY(int vertexIndex) { + return hasNormal(vertexIndex) ? NormalHelper.unpackNormalY(data[normalIndex(vertexIndex)]) : Float.NaN; + } + + @Override + public float normalZ(int vertexIndex) { + return hasNormal(vertexIndex) ? NormalHelper.unpackNormalZ(data[normalIndex(vertexIndex)]) : Float.NaN; + } + + @Override + @Nullable + public Vector3f copyNormal(int vertexIndex, @Nullable Vector3f target) { + if (hasNormal(vertexIndex)) { + if (target == null) { + target = new Vector3f(); + } + + final int normal = data[normalIndex(vertexIndex)]; + NormalHelper.unpackNormal(normal, target); + return target; + } else { + return null; + } + } + + @Override + @Nullable + public final Direction cullFace() { + return EncodingFormat.cullFace(data[baseIndex + HEADER_BITS]); + } + + @Override + @NotNull + public final Direction lightFace() { + computeGeometry(); + return EncodingFormat.lightFace(data[baseIndex + HEADER_BITS]); + } + + @Override + @Nullable + public final Direction nominalFace() { + return nominalFace; + } + + public final int packedFaceNormal() { + computeGeometry(); + return data[baseIndex + HEADER_FACE_NORMAL]; + } + + @Override + public final Vector3f faceNormal() { + computeGeometry(); + return faceNormal; + } + + @Override + public final RenderMaterialImpl material() { + return EncodingFormat.material(data[baseIndex + HEADER_BITS]); + } + + @Override + public final int colorIndex() { + return data[baseIndex + HEADER_COLOR_INDEX]; + } + + @Override + public final int tag() { + return data[baseIndex + HEADER_TAG]; + } + + @Override + public final void toVanilla(int[] target, int targetIndex) { + System.arraycopy(data, baseIndex + HEADER_STRIDE, target, targetIndex, QUAD_STRIDE); + + // The color is the fourth integer in each vertex. + // EncodingFormat.VERTEX_COLOR is not used because it also + // contains the header size; vanilla quads do not have a header. + int colorIndex = targetIndex + 3; + + for (int i = 0; i < 4; i++) { + target[colorIndex] = ColorHelper.toVanillaColor(target[colorIndex]); + colorIndex += VANILLA_VERTEX_STRIDE; + } + } + + @Override + public int getFlags() { + return geometryFlags(); + } + + @Override + public float getX(int idx) { + return this.x(idx); + } + + @Override + public float getY(int idx) { + return this.y(idx); + } + + @Override + public float getZ(int idx) { + return this.z(idx); + } + + @Override + public int getColor(int idx) { + return this.color(idx); + } + + @Override + public float getU(int idx) { + return this.u(idx); + } + + @Override + public float getV(int idx) { + return this.v(idx); + } + + @Override + public int getColorIndex() { + return this.colorIndex(); + } + + @Override + public Direction getFacingDirection() { + return this.lightFace(); + } + + @Override + public int getNormal() { + return packedFaceNormal(); + } + + @Override + public QuadFacing getQuadFacing() { + return this.facing; + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/AbstractBlockRenderContext.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/AbstractBlockRenderContext.java new file mode 100644 index 000000000..2d7f86520 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/AbstractBlockRenderContext.java @@ -0,0 +1,303 @@ +package net.vulkanmod.render.chunk.build.frapi.render; + +import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap; +import net.fabricmc.fabric.api.renderer.v1.Renderer; +import net.fabricmc.fabric.api.renderer.v1.RendererAccess; +import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.minecraft.client.Minecraft; +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.block.BlockColors; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.phys.shapes.BooleanOp; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import net.vulkanmod.interfaces.color.BlockColorsExtended; +import net.vulkanmod.render.chunk.build.color.BlockColorRegistry; +import net.vulkanmod.render.chunk.build.light.LightPipeline; +import net.vulkanmod.render.chunk.build.light.data.QuadLightData; +import org.jetbrains.annotations.Nullable; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.util.TriState; +import net.vulkanmod.render.chunk.build.frapi.helper.ColorHelper; +import net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat; +import net.vulkanmod.render.chunk.build.frapi.mesh.MutableQuadViewImpl; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.List; +import java.util.function.Supplier; + +public abstract class AbstractBlockRenderContext extends AbstractRenderContext { + private static final Renderer RENDERER = RendererAccess.INSTANCE.getRenderer(); + protected static final RenderMaterial STANDARD_MATERIAL = RENDERER.materialFinder().shadeMode(ShadeMode.VANILLA).find(); + protected static final RenderMaterial NO_AO_MATERIAL = RENDERER.materialFinder().shadeMode(ShadeMode.VANILLA).ambientOcclusion(TriState.FALSE).find(); + + protected final BlockColorRegistry blockColorRegistry; + + private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { + { + data = new int[EncodingFormat.TOTAL_STRIDE]; + clear(); + } + + @Override + public void emitDirectly() { + renderQuad(this); + } + }; + + protected BlockState blockState; + protected BlockPos blockPos; + protected BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos(); + + protected BlockAndTintGetter renderRegion; + + protected final Object2ByteLinkedOpenHashMap occlusionCache = new Object2ByteLinkedOpenHashMap<>(2048, 0.25F) { + protected void rehash(int i) { + } + }; + + protected final QuadLightData quadLightData = new QuadLightData(); + protected LightPipeline smoothLightPipeline; + protected LightPipeline flatLightPipeline; + + protected boolean useAO; + protected boolean defaultAO; + + protected long seed; + protected RandomSource random; + public final Supplier randomSupplier = () -> { + long seed = this.seed; + + random.setSeed(seed); + return random; + }; + + protected boolean enableCulling = true; + protected int cullCompletionFlags; + protected int cullResultFlags; + + protected AbstractBlockRenderContext() { + this.occlusionCache.defaultReturnValue((byte) 127); + + BlockColors blockColors = Minecraft.getInstance().getBlockColors(); + this.blockColorRegistry = BlockColorsExtended.from(blockColors).getColorResolverMap(); + } + + protected void setupLightPipelines(LightPipeline flatLightPipeline, LightPipeline smoothLightPipeline) { + this.flatLightPipeline = flatLightPipeline; + this.smoothLightPipeline = smoothLightPipeline; + } + + @Override + public QuadEmitter getEmitter() { + editorQuad.clear(); + return editorQuad; + } + + @Override + public ItemDisplayContext itemTransformationMode() { + throw new IllegalStateException("itemTransformationMode() can only be called on an item render context."); + } + + @SuppressWarnings("removal") + @Override + public BakedModelConsumer bakedModelConsumer() { + return null; + } + + public void prepareForWorld(BlockAndTintGetter blockView, boolean enableCulling) { + this.renderRegion = blockView; + this.enableCulling = enableCulling; + } + + public void prepareForBlock(BlockState blockState, BlockPos blockPos, boolean modelAo) { + this.blockPos = blockPos; + this.blockState = blockState; + + this.useAO = Minecraft.useAmbientOcclusion(); + this.defaultAO = this.useAO && modelAo && blockState.getLightEmission() == 0; + + this.cullCompletionFlags = 0; + this.cullResultFlags = 0; + } + + @Override + public boolean isFaceCulled(@Nullable Direction face) { + return !this.shouldRenderFace(face); + } + + public boolean shouldRenderFace(Direction face) { + if (face == null || !enableCulling) { + return true; + } + + final int mask = 1 << face.get3DDataValue(); + + if ((cullCompletionFlags & mask) == 0) { + cullCompletionFlags |= mask; + + if (this.faceNotOccluded(blockState, face)) { + cullResultFlags |= mask; + return true; + } else { + return false; + } + } else { + return (cullResultFlags & mask) != 0; + } + } + + public boolean faceNotOccluded(BlockState blockState, Direction face) { + BlockGetter blockGetter = this.renderRegion; + + BlockPos adjPos = tempPos.setWithOffset(blockPos, face); + BlockState adjBlockState = blockGetter.getBlockState(adjPos); + + if (blockState.skipRendering(adjBlockState, face)) { + return false; + } + + if (adjBlockState.canOcclude()) { + VoxelShape shape = blockState.getFaceOcclusionShape(blockGetter, blockPos, face); + + if (shape.isEmpty()) + return true; + + VoxelShape adjShape = adjBlockState.getFaceOcclusionShape(blockGetter, adjPos, face.getOpposite()); + + if (adjShape.isEmpty()) + return true; + + if (shape == Shapes.block() && adjShape == Shapes.block()) { + return false; + } + + Block.BlockStatePairKey blockStatePairKey = new Block.BlockStatePairKey(blockState, adjBlockState, face); + + byte b = occlusionCache.getAndMoveToFirst(blockStatePairKey); + if (b != 127) { + return b != 0; + } else { + boolean bl = Shapes.joinIsNotEmpty(shape, adjShape, BooleanOp.ONLY_FIRST); + + if (occlusionCache.size() == 2048) { + occlusionCache.removeLastByte(); + } + + occlusionCache.putAndMoveToFirst(blockStatePairKey, (byte) (bl ? 1 : 0)); + return bl; + } + } + + return true; + } + + private void renderQuad(MutableQuadViewImpl quad) { + if (!transform(quad)) { + return; + } + + if (isFaceCulled(quad.cullFace())) { + return; + } + + endRenderQuad(quad); + } + + protected void endRenderQuad(MutableQuadViewImpl quad) {} + + /** handles block color, common to all renders. */ + protected void colorizeQuad(MutableQuadViewImpl quad, int colorIndex) { + if (colorIndex != -1) { + final int blockColor = getBlockColor(this.renderRegion, colorIndex); + + for (int i = 0; i < 4; i++) { + quad.color(i, ColorHelper.multiplyColor(blockColor, quad.color(i))); + } + } + } + + private int getBlockColor(BlockAndTintGetter region, int colorIndex) { + BlockColor blockColor = this.blockColorRegistry.getBlockColor(this.blockState.getBlock()); + + int color = blockColor != null ? blockColor.getColor(blockState, region, blockPos, colorIndex) : -1; + return 0xFF000000 | color; + } + + protected void shadeQuad(MutableQuadViewImpl quad, LightPipeline lightPipeline, boolean emissive, boolean vanillaShade) { + QuadLightData data = this.quadLightData; + + // TODO: enhanced AO + lightPipeline.calculate(quad, this.blockPos, data, quad.cullFace(), quad.lightFace(), quad.hasShade()); + + if (emissive) { + for (int i = 0; i < 4; i++) { + quad.color(i, ColorHelper.multiplyRGB(quad.color(i), data.br[i])); + quad.lightmap(i, LightTexture.FULL_BRIGHT); + } + } else { + for (int i = 0; i < 4; i++) { + quad.color(i, ColorHelper.multiplyRGB(quad.color(i), data.br[i])); + quad.lightmap(i, ColorHelper.maxBrightness(quad.lightmap(i), data.lm[i])); + } + } + } + + public void emitBlockQuads(BakedModel model, @Nullable BlockState state, Supplier randomSupplier, RenderContext context) { + MutableQuadViewImpl quad = this.editorQuad; + final RenderMaterial defaultMaterial = model.useAmbientOcclusion() ? STANDARD_MATERIAL : NO_AO_MATERIAL; + + boolean noTransform = !this.hasTransform(); + + if (noTransform) { + for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) { + final Direction cullFace = ModelHelper.faceFromIndex(i); + + if (context.isFaceCulled(cullFace)) { + // Skip entire quad list if possible. + continue; + } + + final List quads = model.getQuads(state, cullFace, randomSupplier.get()); + final int count = quads.size(); + + //noinspection ForLoopReplaceableByForEach + for (int j = 0; j < count; j++) { + final BakedQuad q = quads.get(j); + quad.fromVanilla(q, defaultMaterial, cullFace); + + this.endRenderQuad(quad); + } + } + } else { + for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) { + final Direction cullFace = ModelHelper.faceFromIndex(i); + + final List quads = model.getQuads(state, cullFace, randomSupplier.get()); + final int count = quads.size(); + + //noinspection ForLoopReplaceableByForEach + for (int j = 0; j < count; j++) { + final BakedQuad q = quads.get(j); + quad.fromVanilla(q, defaultMaterial, cullFace); + + this.renderQuad(quad); + } + } + } + + } + +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/AbstractRenderContext.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/AbstractRenderContext.java new file mode 100644 index 000000000..5048e0874 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/AbstractRenderContext.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.render; + +import java.util.function.Consumer; +import com.mojang.blaze3d.vertex.VertexConsumer; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.joml.Vector4f; +import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.vulkanmod.render.chunk.build.frapi.mesh.MutableQuadViewImpl; + +abstract class AbstractRenderContext implements RenderContext { + private static final QuadTransform NO_TRANSFORM = q -> true; + + private QuadTransform activeTransform = NO_TRANSFORM; + private final ObjectArrayList transformStack = new ObjectArrayList<>(); + private final QuadTransform stackTransform = q -> { + int i = transformStack.size() - 1; + + while (i >= 0) { + if (!transformStack.get(i--).transform(q)) { + return false; + } + } + + return true; + }; + + @Deprecated + private final Consumer meshConsumer = mesh -> mesh.outputTo(getEmitter()); + + protected Matrix4f matrix; + protected Matrix3f normalMatrix; + protected int overlay; + private final Vector4f posVec = new Vector4f(); + private final Vector3f normalVec = new Vector3f(); + + protected final boolean transform(MutableQuadView q) { + return activeTransform.transform(q); + } + + @Override + public boolean hasTransform() { + return activeTransform != NO_TRANSFORM; + } + + @Override + public void pushTransform(QuadTransform transform) { + if (transform == null) { + throw new NullPointerException("Renderer received null QuadTransform."); + } + + transformStack.push(transform); + + if (transformStack.size() == 1) { + activeTransform = transform; + } else if (transformStack.size() == 2) { + activeTransform = stackTransform; + } + } + + @Override + public void popTransform() { + transformStack.pop(); + + if (transformStack.size() == 0) { + activeTransform = NO_TRANSFORM; + } else if (transformStack.size() == 1) { + activeTransform = transformStack.get(0); + } + } + + // Overridden to prevent allocating a lambda every time this method is called. + @Deprecated + @Override + public Consumer meshConsumer() { + return meshConsumer; + } + + /** final output step, common to all renders. */ + protected void bufferQuad(MutableQuadViewImpl quad, VertexConsumer vertexConsumer) { + final Vector4f posVec = this.posVec; + final Vector3f normalVec = this.normalVec; + final boolean useNormals = quad.hasVertexNormals(); + + if (useNormals) { + quad.populateMissingNormals(); + } else { + normalVec.set(quad.faceNormal()); + normalVec.mul(normalMatrix); + } + + for (int i = 0; i < 4; i++) { + posVec.set(quad.x(i), quad.y(i), quad.z(i), 1.0f); + posVec.mul(matrix); + vertexConsumer.addVertex(posVec.x(), posVec.y(), posVec.z()); + + final int color = quad.color(i); + vertexConsumer.setColor(color); + vertexConsumer.setUv(quad.u(i), quad.v(i)); + vertexConsumer.setOverlay(overlay); + vertexConsumer.setLight(quad.lightmap(i)); + + if (useNormals) { + quad.copyNormal(i, normalVec); + normalVec.mul(normalMatrix); + } + + vertexConsumer.setNormal(normalVec.x(), normalVec.y(), normalVec.z()); + } + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/BlockRenderContext.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/BlockRenderContext.java new file mode 100644 index 000000000..b00e6be85 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/BlockRenderContext.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode; +import net.fabricmc.fabric.api.util.TriState; +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; +import net.minecraft.ReportedException; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; +import net.vulkanmod.Initializer; +import net.vulkanmod.render.chunk.build.frapi.mesh.MutableQuadViewImpl; +import net.vulkanmod.render.chunk.build.light.LightMode; +import net.vulkanmod.render.chunk.build.light.LightPipeline; +import net.vulkanmod.render.chunk.build.light.data.ArrayLightDataCache; +import net.vulkanmod.render.chunk.build.light.flat.FlatLightPipeline; +import net.vulkanmod.render.chunk.build.light.smooth.NewSmoothLightPipeline; +import net.vulkanmod.render.chunk.build.light.smooth.SmoothLightPipeline; + +/** + * Context for non-terrain block rendering. + */ +public class BlockRenderContext extends AbstractBlockRenderContext { + private VertexConsumer vertexConsumer; + + private final ArrayLightDataCache lightDataCache = new ArrayLightDataCache(); + + public BlockRenderContext() { + LightPipeline flatLightPipeline = new FlatLightPipeline(this.lightDataCache); + + LightPipeline smoothLightPipeline; + if (Initializer.CONFIG.ambientOcclusion == LightMode.SUB_BLOCK) { + smoothLightPipeline = new NewSmoothLightPipeline(lightDataCache); + } + else { + smoothLightPipeline = new SmoothLightPipeline(lightDataCache); + } + + this.setupLightPipelines(flatLightPipeline, smoothLightPipeline); + } + + public void render(BlockAndTintGetter blockView, BakedModel model, BlockState state, BlockPos pos, PoseStack matrixStack, VertexConsumer buffer, boolean cull, RandomSource random, long seed, int overlay) { + try { + Vec3 offset = state.getOffset(blockView, pos); + matrixStack.translate(offset.x, offset.y, offset.z); + + this.blockPos = pos; + this.vertexConsumer = buffer; + this.matrix = matrixStack.last().pose(); + this.normalMatrix = matrixStack.last().normal(); + this.overlay = overlay; + + this.random = random; + this.seed = seed; + + this.lightDataCache.reset(blockView, pos); + + this.prepareForWorld(blockView, cull); + this.prepareForBlock(state, pos, model.useAmbientOcclusion()); + + model.emitBlockQuads(blockView, state, pos, this.randomSupplier, this); + } catch (Throwable throwable) { + CrashReport crashReport = CrashReport.forThrowable(throwable, "Tessellating block model - Indigo Renderer"); + CrashReportCategory crashReportSection = crashReport.addCategory("Block model being tessellated"); + CrashReportCategory.populateBlockDetails(crashReportSection, blockView, pos, state); + throw new ReportedException(crashReport); + } finally { + this.vertexConsumer = null; + } + } + + protected void endRenderQuad(MutableQuadViewImpl quad) { + final RenderMaterial mat = quad.material(); + final int colorIndex = mat.disableColorIndex() ? -1 : quad.colorIndex(); + final TriState aoMode = mat.ambientOcclusion(); + final boolean ao = this.useAO && (aoMode == TriState.TRUE || (aoMode == TriState.DEFAULT && this.defaultAO)); + final boolean emissive = mat.emissive(); + final boolean vanillaShade = mat.shadeMode() == ShadeMode.VANILLA; + + LightPipeline lightPipeline = ao ? this.smoothLightPipeline : this.flatLightPipeline; + + colorizeQuad(quad, colorIndex); + shadeQuad(quad, lightPipeline, emissive, vanillaShade); + bufferQuad(quad, vertexConsumer); + } + +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/ItemRenderContext.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/ItemRenderContext.java new file mode 100644 index 000000000..6ece16a2d --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/ItemRenderContext.java @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.vulkanmod.render.chunk.build.frapi.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.MatrixUtil; + +import java.util.List; +import java.util.function.Supplier; + +import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.vulkanmod.mixin.render.frapi.ItemRendererAccessor; +import org.jetbrains.annotations.Nullable; +import net.minecraft.client.Minecraft; +import net.minecraft.client.color.item.ItemColors; +import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.Sheets; +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; +import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.util.TriState; +import net.vulkanmod.render.chunk.build.frapi.helper.ColorHelper; +import net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat; +import net.vulkanmod.render.chunk.build.frapi.mesh.MutableQuadViewImpl; +import net.fabricmc.fabric.impl.renderer.VanillaModelEncoder; + +import static net.vulkanmod.render.chunk.build.frapi.render.AbstractBlockRenderContext.STANDARD_MATERIAL; + +/** + * The render context used for item rendering. + */ +@SuppressWarnings("removal") +public class ItemRenderContext extends AbstractRenderContext { + /** Value vanilla uses for item rendering. The only sensible choice, of course. */ + private static final long ITEM_RANDOM_SEED = 42L; + + private final ItemColors itemColors; + private final RandomSource random = RandomSource.create(); + private final Supplier randomSupplier = () -> { + random.setSeed(ITEM_RANDOM_SEED); + return random; + }; + + private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { + { + data = new int[EncodingFormat.TOTAL_STRIDE]; + clear(); + } + + @Override + public void emitDirectly() { + renderQuad(this); + } + }; + + private final BakedModelConsumerImpl vanillaModelConsumer = new BakedModelConsumerImpl(); + + private ItemStack itemStack; + private ItemDisplayContext transformMode; + private PoseStack matrixStack; + private MultiBufferSource vertexConsumerProvider; + private int lightmap; + + private boolean isDefaultTranslucent; + private boolean isTranslucentDirect; + private boolean isDefaultGlint; + private boolean isGlintDynamicDisplay; + + private PoseStack.Pose dynamicDisplayGlintEntry; + private VertexConsumer translucentVertexConsumer; + private VertexConsumer cutoutVertexConsumer; + private VertexConsumer translucentGlintVertexConsumer; + private VertexConsumer cutoutGlintVertexConsumer; + + public ItemRenderContext(ItemColors itemColors) { + this.itemColors = itemColors; + } + + @Override + public QuadEmitter getEmitter() { + editorQuad.clear(); + return editorQuad; + } + + @Override + public boolean isFaceCulled(@Nullable Direction face) { + throw new IllegalStateException("isFaceCulled can only be called on a block render context."); + } + + @Override + public ItemDisplayContext itemTransformationMode() { + return transformMode; + } + + @Override + public BakedModelConsumer bakedModelConsumer() { + return vanillaModelConsumer; + } + + public void renderModel(ItemStack itemStack, ItemDisplayContext transformMode, boolean invert, PoseStack matrixStack, MultiBufferSource vertexConsumerProvider, int lightmap, int overlay, BakedModel model) { + this.itemStack = itemStack; + this.transformMode = transformMode; + this.matrixStack = matrixStack; + this.vertexConsumerProvider = vertexConsumerProvider; + this.lightmap = lightmap; + this.overlay = overlay; + computeOutputInfo(); + + matrix = matrixStack.last().pose(); + normalMatrix = matrixStack.last().normal(); + + model.emitItemQuads(itemStack, randomSupplier, this); + + this.itemStack = null; + this.matrixStack = null; + this.vertexConsumerProvider = null; + + dynamicDisplayGlintEntry = null; + translucentVertexConsumer = null; + cutoutVertexConsumer = null; + translucentGlintVertexConsumer = null; + cutoutGlintVertexConsumer = null; + } + + public void emitItemQuads(BakedModel model, @Nullable BlockState state, Supplier randomSupplier) { + for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) { + final Direction cullFace = ModelHelper.faceFromIndex(i); + final List quads = model.getQuads(state, cullFace, randomSupplier.get()); + final int count = quads.size(); + + for (int j = 0; j < count; j++) { + final BakedQuad q = quads.get(j); + editorQuad.fromVanilla(q, STANDARD_MATERIAL, cullFace); + + endRenderQuad(editorQuad); + } + } + } + + private void computeOutputInfo() { + isDefaultTranslucent = true; + isTranslucentDirect = true; + + Item item = itemStack.getItem(); + + if (item instanceof BlockItem blockItem) { + BlockState state = blockItem.getBlock().defaultBlockState(); + RenderType renderLayer = ItemBlockRenderTypes.getChunkRenderType(state); + + if (renderLayer != RenderType.translucent()) { + isDefaultTranslucent = false; + } + + if (transformMode != ItemDisplayContext.GUI && !transformMode.firstPerson()) { + isTranslucentDirect = false; + } + } + + isDefaultGlint = itemStack.hasFoil(); + isGlintDynamicDisplay = ItemRendererAccessor.hasAnimatedTexture(itemStack); + } + + private void renderQuad(MutableQuadViewImpl quad) { + if (!transform(quad)) { + return; + } + + endRenderQuad(quad); + } + + private void endRenderQuad(MutableQuadViewImpl quad) { + final RenderMaterial mat = quad.material(); + final int colorIndex = mat.disableColorIndex() ? -1 : quad.colorIndex(); + final boolean emissive = mat.emissive(); + final VertexConsumer vertexConsumer = getVertexConsumer(mat.blendMode(), mat.glint()); + + colorizeQuad(quad, colorIndex); + shadeQuad(quad, emissive); + bufferQuad(quad, vertexConsumer); + } + + private void colorizeQuad(MutableQuadViewImpl quad, int colorIndex) { + if (colorIndex != -1) { + final int itemColor = itemColors.getColor(itemStack, colorIndex); + + for (int i = 0; i < 4; i++) { + quad.color(i, ColorHelper.multiplyColor(itemColor, quad.color(i))); + } + } + } + + private void shadeQuad(MutableQuadViewImpl quad, boolean emissive) { + if (emissive) { + for (int i = 0; i < 4; i++) { + quad.lightmap(i, LightTexture.FULL_BRIGHT); + } + } else { + final int lightmap = this.lightmap; + + for (int i = 0; i < 4; i++) { + quad.lightmap(i, ColorHelper.maxBrightness(quad.lightmap(i), lightmap)); + } + } + } + + /** + * Caches custom blend mode / vertex consumers and mimics the logic + * in {@code RenderLayers.getEntityBlockLayer}. Layers other than + * translucent are mapped to cutout. + */ + private VertexConsumer getVertexConsumer(BlendMode blendMode, TriState glintMode) { + boolean translucent; + boolean glint; + + if (blendMode == BlendMode.DEFAULT) { + translucent = isDefaultTranslucent; + } else { + translucent = blendMode == BlendMode.TRANSLUCENT; + } + + if (glintMode == TriState.DEFAULT) { + glint = isDefaultGlint; + } else { + glint = glintMode == TriState.TRUE; + } + + if (translucent) { + if (glint) { + if (translucentGlintVertexConsumer == null) { + translucentGlintVertexConsumer = createTranslucentVertexConsumer(true); + } + + return translucentGlintVertexConsumer; + } else { + if (translucentVertexConsumer == null) { + translucentVertexConsumer = createTranslucentVertexConsumer(false); + } + + return translucentVertexConsumer; + } + } else { + if (glint) { + if (cutoutGlintVertexConsumer == null) { + cutoutGlintVertexConsumer = createCutoutVertexConsumer(true); + } + + return cutoutGlintVertexConsumer; + } else { + if (cutoutVertexConsumer == null) { + cutoutVertexConsumer = createCutoutVertexConsumer(false); + } + + return cutoutVertexConsumer; + } + } + } + + private VertexConsumer createTranslucentVertexConsumer(boolean glint) { + if (glint && isGlintDynamicDisplay) { + return createDynamicDisplayGlintVertexConsumer(Minecraft.useShaderTransparency() && !isTranslucentDirect ? Sheets.translucentItemSheet() : Sheets.translucentCullBlockSheet()); + } + + if (isTranslucentDirect) { + return ItemRenderer.getFoilBufferDirect(vertexConsumerProvider, Sheets.translucentCullBlockSheet(), true, glint); + } else if (Minecraft.useShaderTransparency()) { + return ItemRenderer.getFoilBuffer(vertexConsumerProvider, Sheets.translucentItemSheet(), true, glint); + } else { + return ItemRenderer.getFoilBuffer(vertexConsumerProvider, Sheets.translucentCullBlockSheet(), true, glint); + } + } + + private VertexConsumer createCutoutVertexConsumer(boolean glint) { + if (glint && isGlintDynamicDisplay) { + return createDynamicDisplayGlintVertexConsumer(Sheets.cutoutBlockSheet()); + } + + return ItemRenderer.getFoilBufferDirect(vertexConsumerProvider, Sheets.cutoutBlockSheet(), true, glint); + } + + private VertexConsumer createDynamicDisplayGlintVertexConsumer(RenderType layer) { + if (dynamicDisplayGlintEntry == null) { + dynamicDisplayGlintEntry = matrixStack.last().copy(); + + if (transformMode == ItemDisplayContext.GUI) { + MatrixUtil.mulComponentWise(dynamicDisplayGlintEntry.pose(), 0.5F); + } else if (transformMode.firstPerson()) { + MatrixUtil.mulComponentWise(dynamicDisplayGlintEntry.pose(), 0.75F); + } + } + + return ItemRenderer.getCompassFoilBuffer(vertexConsumerProvider, layer, dynamicDisplayGlintEntry); + } + + private class BakedModelConsumerImpl implements BakedModelConsumer { + @Override + public void accept(BakedModel model) { + accept(model, null); + } + + @Override + public void accept(BakedModel model, @Nullable BlockState state) { + VanillaModelEncoder.emitItemQuads(model, state, randomSupplier, ItemRenderContext.this); + } + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/LightPipeline.java b/src/main/java/net/vulkanmod/render/chunk/build/light/LightPipeline.java index ba0fa8a7b..69d3c184e 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/LightPipeline.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/LightPipeline.java @@ -2,7 +2,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.vulkanmod.render.model.quad.QuadView; +import net.vulkanmod.render.model.quad.ModelQuadView; import net.vulkanmod.render.chunk.build.light.data.QuadLightData; /** @@ -19,5 +19,5 @@ public interface LightPipeline { * @param lightFace The light face of the quad * @param shade True if the block is shaded by ambient occlusion */ - void calculate(QuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFace, boolean shade); + void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFace, boolean shade); } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/data/ArrayLightDataCache.java b/src/main/java/net/vulkanmod/render/chunk/build/light/data/ArrayLightDataCache.java index 1fbde68f7..3e23dcc5c 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/data/ArrayLightDataCache.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/data/ArrayLightDataCache.java @@ -25,7 +25,7 @@ public ArrayLightDataCache() { } public void reset(BlockAndTintGetter blockAndTintGetter, int x, int y, int z) { - this.world = blockAndTintGetter; + this.region = blockAndTintGetter; this.xOffset = x - NEIGHBOR_BLOCK_RADIUS; this.yOffset = y - NEIGHBOR_BLOCK_RADIUS; @@ -34,6 +34,16 @@ public void reset(BlockAndTintGetter blockAndTintGetter, int x, int y, int z) { Arrays.fill(this.light, 0); } + public void reset(BlockAndTintGetter blockAndTintGetter, BlockPos origin) { + this.region = blockAndTintGetter; + + this.xOffset = origin.getX() - NEIGHBOR_BLOCK_RADIUS; + this.yOffset = origin.getY() - NEIGHBOR_BLOCK_RADIUS; + this.zOffset = origin.getZ() - NEIGHBOR_BLOCK_RADIUS; + + Arrays.fill(this.light, 0); + } + public void reset(SectionPos origin) { this.xOffset = origin.minBlockX() - NEIGHBOR_BLOCK_RADIUS; this.yOffset = origin.minBlockY() - NEIGHBOR_BLOCK_RADIUS; diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/data/LightDataAccess.java b/src/main/java/net/vulkanmod/render/chunk/build/light/data/LightDataAccess.java index ff0ad86d4..1312b4671 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/data/LightDataAccess.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/data/LightDataAccess.java @@ -5,7 +5,6 @@ import net.minecraft.core.BlockPos; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.LightLayer; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.shapes.VoxelShape; import net.vulkanmod.Initializer; @@ -16,10 +15,10 @@ /** * The light data cache is used to make accessing the light data and occlusion properties of blocks cheaper. The data * for each block is stored as an integer with packed fields in order to work around the lack of value types in Java. - * + *

* This code is not very pretty, but it does perform significantly faster than the vanilla implementation and has * good cache locality. - * + *

* Each integer contains the following fields: * - BL: World block light, encoded as a 4-bit unsigned integer * - SL: World sky light, encoded as a 4-bit unsigned integer @@ -29,7 +28,7 @@ * - OP: Block opacity test, true if opaque * - FO: Full cube opacity test, true if opaque full cube * - FC: Full cube test, true if full cube - * + *

* You can use the various static pack/unpack methods to extract these values in a usable format. */ public abstract class LightDataAccess { @@ -45,7 +44,7 @@ public abstract class LightDataAccess { private static final float AO_INV = 1.0f / 2048.0f; private final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); - protected BlockAndTintGetter world; + protected BlockAndTintGetter region; final boolean subBlockLighting; @@ -55,14 +54,14 @@ protected LightDataAccess() { public int get(int x, int y, int z, SimpleDirection d1, SimpleDirection d2) { return this.get(x + d1.getStepX() + d2.getStepX(), - y + d1.getStepY() + d2.getStepY(), - z + d1.getStepZ() + d2.getStepZ()); + y + d1.getStepY() + d2.getStepY(), + z + d1.getStepZ() + d2.getStepZ()); } public int get(int x, int y, int z, SimpleDirection dir) { return this.get(x + dir.getStepX(), - y + dir.getStepY(), - z + dir.getStepZ()); + y + dir.getStepY(), + z + dir.getStepZ()); } public int get(BlockPos pos, SimpleDirection dir) { @@ -81,19 +80,18 @@ public int get(BlockPos pos) { protected int compute(int x, int y, int z) { BlockPos pos = this.pos.set(x, y, z); + BlockState state = region.getBlockState(pos); - BlockState state = world.getBlockState(pos); - - boolean em = state.emissiveRendering(world, pos); + boolean em = state.emissiveRendering(region, pos); boolean op; - if(this.subBlockLighting) + if (this.subBlockLighting) op = state.canOcclude(); else - op = state.isViewBlocking(world, pos) && state.getLightBlock(world, pos) != 0; + op = state.isViewBlocking(region, pos) && state.getLightBlock(region, pos) != 0; - boolean fo = state.isSolidRender(world, pos); - boolean fc = state.isCollisionShapeFullBlock(world, pos); + boolean fo = state.isSolidRender(region, pos); + boolean fc = state.isCollisionShapeFullBlock(region, pos); int lu = state.getLightEmission(); @@ -103,16 +101,25 @@ protected int compute(int x, int y, int z) { if (fo && lu == 0) { bl = 0; sl = 0; - } else { - bl = world.getBrightness(LightLayer.BLOCK, pos); - sl = world.getBrightness(LightLayer.SKY, pos); + } + else { + if (em) { + bl = region.getBrightness(LightLayer.BLOCK, pos); + sl = region.getBrightness(LightLayer.SKY, pos); + } + else { + int light = LevelRenderer.getLightColor(region, state, pos); + bl = LightTexture.block(light); + sl = LightTexture.sky(light); + } } // FIX: Do not apply AO from blocks that emit light float ao; if (lu == 0) { - ao = state.getShadeBrightness(world, pos); - } else { + ao = state.getShadeBrightness(region, pos); + } + else { ao = 1.0f; } @@ -121,12 +128,12 @@ protected int compute(int x, int y, int z) { bl = Math.max(bl, lu); int crs = (fo || fc) && lu == 0 && useAo ? 0xFF : 0; - if(!fo && op) { - VoxelShape shape = state.getShape(world, pos); - crs = ((VoxelShapeExtended)(shape)).getCornerOcclusion(); + if (!fo && op) { + VoxelShape shape = state.getShape(region, pos); + crs = ((VoxelShapeExtended) (shape)).getCornerOcclusion(); } - return packFC(fc) | packFO(fo) | packOP(op) | packEM(em) | packCO(crs) | packAO(ao) | packSL(sl) | packBL(bl); + return packFC(fc) | packFO(fo) | packOP(op) | packEM(em) | packCO(crs) | packAO(ao) | packSL(sl) | packBL(bl); } public static int packBL(int blockLight) { @@ -210,12 +217,13 @@ public static int getLightmap(int word) { public static int getEmissiveLightmap(int word) { if (unpackEM(word)) { return LightTexture.FULL_BRIGHT; - } else { + } + else { return getLightmap(word); } } - public BlockAndTintGetter getWorld() { - return this.world; + public BlockAndTintGetter getRegion() { + return this.region; } } \ No newline at end of file diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/flat/FlatLightPipeline.java b/src/main/java/net/vulkanmod/render/chunk/build/light/flat/FlatLightPipeline.java index 2472ac4b8..b11f4e352 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/flat/FlatLightPipeline.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/flat/FlatLightPipeline.java @@ -4,7 +4,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.vulkanmod.render.chunk.util.SimpleDirection; -import net.vulkanmod.render.model.quad.QuadView; +import net.vulkanmod.render.model.quad.ModelQuadView; import net.vulkanmod.render.chunk.build.light.data.LightDataAccess; import net.vulkanmod.render.chunk.build.light.LightPipeline; import net.vulkanmod.render.chunk.build.light.data.QuadLightData; @@ -29,7 +29,7 @@ public FlatLightPipeline(LightDataAccess lightCache) { } @Override - public void calculate(QuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFace, boolean shade) { + public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFace, boolean shade) { int lightmap; // To match vanilla behavior, use the cull face if it exists/is available @@ -47,7 +47,7 @@ public void calculate(QuadView quad, BlockPos pos, QuadLightData out, Direction } Arrays.fill(out.lm, lightmap); - Arrays.fill(out.br, this.lightCache.getWorld().getShade(lightFace, shade)); + Arrays.fill(out.br, this.lightCache.getRegion().getShade(lightFace, shade)); } private int getLightmap(BlockPos pos, Direction face) { diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/NewSmoothLightPipeline.java b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/NewSmoothLightPipeline.java index 32cdabcb9..503d27ff9 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/NewSmoothLightPipeline.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/NewSmoothLightPipeline.java @@ -4,7 +4,7 @@ import net.minecraft.core.Direction; import net.minecraft.util.Mth; import net.vulkanmod.render.chunk.util.SimpleDirection; -import net.vulkanmod.render.model.quad.QuadView; +import net.vulkanmod.render.model.quad.ModelQuadView; import net.vulkanmod.render.chunk.build.light.data.LightDataAccess; import net.vulkanmod.render.chunk.build.light.LightPipeline; import net.vulkanmod.render.chunk.build.light.data.QuadLightData; @@ -42,7 +42,7 @@ public NewSmoothLightPipeline(LightDataAccess cache) { } @Override - public void calculate(QuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFaceO, boolean shade) { + public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFaceO, boolean shade) { this.updateCachedData(pos.asLong()); int flags = quad.getFlags(); @@ -85,7 +85,7 @@ private void applyAlignedFullFace(AoNeighborInfo neighborInfo, BlockPos pos, Sim * Calculates the light data for a grid-aligned quad that does not cover the entire block volume's face. * Flags: IS_ALIGNED, IS_PARTIAL */ - private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, QuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { + private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { // TODO stair lighting is inconsistent // A solution might be an interpolation grid // this.self.calculatePartialAlignedFace(this.lightCache, pos, dir); @@ -104,13 +104,13 @@ private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, QuadView quad, } /** - * This method is the same as {@link #applyNonParallelFace(AoNeighborInfo, QuadView, BlockPos, SimpleDirection, + * This method is the same as {@link #applyNonParallelFace(AoNeighborInfo, ModelQuadView, BlockPos, SimpleDirection, * QuadLightData)} but with the check for a depth of approximately 0 removed. If the quad is parallel but not * aligned, all of its vertices will have the same depth and this depth must be approximately greater than 0, * meaning the check for 0 will always return false. * Flags: !IS_ALIGNED, IS_PARALLEL */ - private void applyParallelFace(AoNeighborInfo neighborInfo, QuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { + private void applyParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { this.self.calculateSelfOcclusion(this.lightCache, pos, dir); for (int i = 0; i < 4; i++) { @@ -139,7 +139,7 @@ private void applyParallelFace(AoNeighborInfo neighborInfo, QuadView quad, Block /** * Flags: !IS_ALIGNED, !IS_PARALLEL */ - private void applyNonParallelFace(AoNeighborInfo neighborInfo, QuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { + private void applyNonParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { for (int i = 0; i < 4; i++) { // Clamp the vertex positions to the block's boundaries to prevent weird errors in lighting float cx = clamp(quad.getX(i)); @@ -229,7 +229,7 @@ private void applyInsetPartialFaceVertexSO(BlockPos pos, SimpleDirection dir, fl } private void applySidedBrightness(QuadLightData out, Direction face, boolean shade) { - float brightness = this.lightCache.getWorld().getShade(face, shade); + float brightness = this.lightCache.getRegion().getShade(face, shade); float[] br = out.br; for (int i = 0; i < br.length; i++) { diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SmoothLightPipeline.java b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SmoothLightPipeline.java index 62993e312..154eb0518 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SmoothLightPipeline.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SmoothLightPipeline.java @@ -4,7 +4,7 @@ import net.minecraft.core.Direction; import net.minecraft.util.Mth; import net.vulkanmod.render.chunk.util.SimpleDirection; -import net.vulkanmod.render.model.quad.QuadView; +import net.vulkanmod.render.model.quad.ModelQuadView; import net.vulkanmod.render.chunk.build.light.data.LightDataAccess; import net.vulkanmod.render.chunk.build.light.LightPipeline; import net.vulkanmod.render.chunk.build.light.data.QuadLightData; @@ -67,7 +67,7 @@ public SmoothLightPipeline(LightDataAccess cache) { } @Override - public void calculate(QuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFaceO, boolean shade) { + public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFaceO, boolean shade) { this.updateCachedData(pos.asLong()); int flags = quad.getFlags(); @@ -110,7 +110,7 @@ private void applyAlignedFullFace(AoNeighborInfo neighborInfo, BlockPos pos, Sim * Calculates the light data for a grid-aligned quad that does not cover the entire block volume's face. * Flags: IS_ALIGNED, IS_PARTIAL */ - private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, QuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { + private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { for (int i = 0; i < 4; i++) { // Clamp the vertex positions to the block's boundaries to prevent weird errors in lighting float cx = clamp(quad.getX(i)); @@ -124,13 +124,13 @@ private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, QuadView quad, } /** - * This method is the same as {@link #applyNonParallelFace(AoNeighborInfo, QuadView, BlockPos, SimpleDirection, + * This method is the same as {@link #applyNonParallelFace(AoNeighborInfo, ModelQuadView, BlockPos, SimpleDirection, * QuadLightData)} but with the check for a depth of approximately 0 removed. If the quad is parallel but not * aligned, all of its vertices will have the same depth and this depth must be approximately greater than 0, * meaning the check for 0 will always return false. * Flags: !IS_ALIGNED, IS_PARALLEL */ - private void applyParallelFace(AoNeighborInfo neighborInfo, QuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { + private void applyParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { for (int i = 0; i < 4; i++) { // Clamp the vertex positions to the block's boundaries to prevent weird errors in lighting float cx = clamp(quad.getX(i)); @@ -157,7 +157,7 @@ private void applyParallelFace(AoNeighborInfo neighborInfo, QuadView quad, Block /** * Flags: !IS_ALIGNED, !IS_PARALLEL */ - private void applyNonParallelFace(AoNeighborInfo neighborInfo, QuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { + private void applyNonParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, SimpleDirection dir, QuadLightData out) { for (int i = 0; i < 4; i++) { // Clamp the vertex positions to the block's boundaries to prevent weird errors in lighting float cx = clamp(quad.getX(i)); @@ -220,7 +220,7 @@ private void applyInsetPartialFaceVertex(BlockPos pos, SimpleDirection dir, floa } private void applySidedBrightness(QuadLightData out, Direction face, boolean shade) { - float brightness = this.lightCache.getWorld().getShade(face, shade); + float brightness = this.lightCache.getRegion().getShade(face, shade); float[] br = out.br; for (int i = 0; i < br.length; i++) { diff --git a/src/main/java/net/vulkanmod/render/chunk/build/renderer/BlockRenderer.java b/src/main/java/net/vulkanmod/render/chunk/build/renderer/BlockRenderer.java new file mode 100644 index 000000000..f04244f3f --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/renderer/BlockRenderer.java @@ -0,0 +1,147 @@ +package net.vulkanmod.render.chunk.build.renderer; + +import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode; +import net.fabricmc.fabric.api.util.TriState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.SingleThreadedRandomSource; +import net.minecraft.world.phys.Vec3; +import net.vulkanmod.Initializer; +import net.vulkanmod.render.chunk.build.frapi.mesh.MutableQuadViewImpl; +import net.vulkanmod.render.chunk.build.frapi.render.AbstractBlockRenderContext; +import net.vulkanmod.render.chunk.build.light.LightPipeline; +import net.vulkanmod.render.chunk.build.light.data.QuadLightData; +import net.vulkanmod.render.chunk.build.thread.BuilderResources; +import net.vulkanmod.render.chunk.cull.QuadFacing; +import net.vulkanmod.render.model.quad.QuadUtils; +import net.vulkanmod.render.model.quad.ModelQuadView; +import net.vulkanmod.render.vertex.TerrainBufferBuilder; +import net.vulkanmod.render.vertex.TerrainBuilder; +import net.vulkanmod.render.vertex.TerrainRenderType; +import net.vulkanmod.render.vertex.format.I32_SNorm; +import net.vulkanmod.vulkan.util.ColorUtil; +import org.joml.Vector3f; + +public class BlockRenderer extends AbstractBlockRenderContext { + private Vector3f pos; + + private BuilderResources resources; + private TerrainBuilder terrainBuilder; + + final boolean backFaceCulling = Initializer.CONFIG.backFaceCulling; + + private TerrainRenderType renderType; + + public void setResources(BuilderResources resources) { + this.resources = resources; + } + + public BlockRenderer(LightPipeline flatLightPipeline, LightPipeline smoothLightPipeline) { + super(); + this.setupLightPipelines(flatLightPipeline, smoothLightPipeline); + + this.random = new SingleThreadedRandomSource(42L); + } + + public void renderBlock(BlockState blockState, BlockPos blockPos, Vector3f pos) { + this.pos = pos; + this.blockPos = blockPos; + this.blockState = blockState; + this.seed = blockState.getSeed(blockPos); + + TerrainRenderType renderType = TerrainRenderType.get(ItemBlockRenderTypes.getChunkRenderType(blockState)); + renderType = TerrainRenderType.getRemapped(renderType); + this.renderType = renderType; + this.terrainBuilder = this.resources.builderPack.builder(renderType); + this.terrainBuilder.setBlockAttributes(blockState); + + BakedModel model = Minecraft.getInstance().getBlockRenderer().getBlockModel(blockState); + + BlockAndTintGetter renderRegion = this.renderRegion; + Vec3 offset = blockState.getOffset(renderRegion, blockPos); + pos.add((float) offset.x, (float) offset.y, (float) offset.z); + + this.prepareForBlock(blockState, blockPos, model.useAmbientOcclusion()); + + model.emitBlockQuads(renderRegion, blockState, blockPos, this.randomSupplier, this); + } + + protected void endRenderQuad(MutableQuadViewImpl quad) { + final RenderMaterial mat = quad.material(); + final int colorIndex = mat.disableColorIndex() ? -1 : quad.colorIndex(); + final TriState aoMode = mat.ambientOcclusion(); + final boolean ao = this.useAO && (aoMode == TriState.TRUE || (aoMode == TriState.DEFAULT && this.defaultAO)); + final boolean emissive = mat.emissive(); + final boolean vanillaShade = mat.shadeMode() == ShadeMode.VANILLA; + + TerrainBuilder terrainBuilder = getBufferBuilder(mat.blendMode()); + + LightPipeline lightPipeline = ao ? this.smoothLightPipeline : this.flatLightPipeline; + + colorizeQuad(quad, colorIndex); + shadeQuad(quad, lightPipeline, emissive, vanillaShade); + bufferQuad(terrainBuilder, this.pos, quad, this.quadLightData); + } + + private TerrainBuilder getBufferBuilder(BlendMode blendMode) { + if (blendMode == BlendMode.DEFAULT) { + return this.terrainBuilder; + } else { + TerrainRenderType renderType = TerrainRenderType.get(blendMode.blockRenderLayer); + renderType = TerrainRenderType.getRemapped(renderType); + TerrainBuilder bufferBuilder = this.resources.builderPack.builder(renderType); + bufferBuilder.setBlockAttributes(this.blockState); + + return bufferBuilder; + } + } + + public void bufferQuad(TerrainBuilder terrainBuilder, Vector3f pos, ModelQuadView quad, QuadLightData quadLightData) { + QuadFacing quadFacing = quad.getQuadFacing(); + + if (renderType == TerrainRenderType.TRANSLUCENT || !this.backFaceCulling) { + quadFacing = QuadFacing.UNDEFINED; + } + + TerrainBufferBuilder bufferBuilder = terrainBuilder.getBufferBuilder(quadFacing.ordinal()); + + Vec3i normal = quad.getFacingDirection().getNormal(); + int packedNormal = I32_SNorm.packNormal(normal.getX(), normal.getY(), normal.getZ()); + + float[] brightnessArr = quadLightData.br; + int[] lights = quadLightData.lm; + + // Rotate triangles if needed to fix AO anisotropy + int idx = QuadUtils.getIterationStartIdx(brightnessArr, lights); + + bufferBuilder.ensureCapacity(); + + for (byte i = 0; i < 4; ++i) { + final float x = pos.x() + quad.getX(idx); + final float y = pos.y() + quad.getY(idx); + final float z = pos.z() + quad.getZ(idx); + + final int quadColor = quad.getColor(idx); + + int color = ColorUtil.ARGB.toRGBA(quadColor); + + final int light = lights[idx]; + final float u = quad.getU(idx); + final float v = quad.getV(idx); + + bufferBuilder.vertex(x, y, z, color, u, v, light, packedNormal); + + idx = (idx + 1) & 0b11; + } + + } + +} + diff --git a/src/main/java/net/vulkanmod/render/chunk/build/renderer/DefaultFluidRenderers.java b/src/main/java/net/vulkanmod/render/chunk/build/renderer/DefaultFluidRenderers.java new file mode 100644 index 000000000..0fbbe5415 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/build/renderer/DefaultFluidRenderers.java @@ -0,0 +1,17 @@ +package net.vulkanmod.render.chunk.build.renderer; + +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; + +public abstract class DefaultFluidRenderers { + + private static final ReferenceOpenHashSet set = new ReferenceOpenHashSet<>(); + + public static void add(FluidRenderHandler handler) { + set.add(handler); + } + + public static boolean has(FluidRenderHandler handler) { + return set.contains(handler); + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/build/LiquidRenderer.java b/src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java similarity index 89% rename from src/main/java/net/vulkanmod/render/chunk/build/LiquidRenderer.java rename to src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java index 4ae8eca4a..b70970f41 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/LiquidRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java @@ -1,12 +1,12 @@ -package net.vulkanmod.render.chunk.build; +package net.vulkanmod.render.chunk.build.renderer; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.tags.FluidTags; import net.minecraft.util.Mth; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.BlockGetter; @@ -20,16 +20,18 @@ import net.vulkanmod.render.chunk.build.light.LightPipeline; import net.vulkanmod.render.chunk.build.light.data.QuadLightData; import net.vulkanmod.render.chunk.build.thread.BuilderResources; +import net.vulkanmod.render.chunk.cull.QuadFacing; import net.vulkanmod.render.chunk.util.Util; import net.vulkanmod.render.model.quad.ModelQuad; import net.vulkanmod.render.model.quad.ModelQuadFlags; import net.vulkanmod.render.model.quad.QuadUtils; import net.vulkanmod.render.vertex.TerrainBufferBuilder; -import net.vulkanmod.render.vertex.VertexUtil; +import net.vulkanmod.render.vertex.TerrainRenderType; +import net.vulkanmod.render.vertex.format.I32_SNorm; import net.vulkanmod.vulkan.util.ColorUtil; import org.joml.Vector3f; -public class LiquidRenderer { +public class FluidRenderer { private static final float MAX_FLUID_HEIGHT = 0.8888889F; private final BlockPos.MutableBlockPos mBlockPos = new BlockPos.MutableBlockPos(); @@ -38,14 +40,34 @@ public class LiquidRenderer { BuilderResources resources; + private final LightPipeline smoothLightPipeline; + private final LightPipeline flatLightPipeline; + private final int[] quadColors = new int[4]; + public FluidRenderer(LightPipeline flatLightPipeline, LightPipeline smoothLightPipeline) { + this.smoothLightPipeline = smoothLightPipeline; + this.flatLightPipeline = flatLightPipeline; + } + public void setResources(BuilderResources resources) { this.resources = resources; } - public void renderLiquid(BlockState blockState, FluidState fluidState, BlockPos blockPos, TerrainBufferBuilder vertexConsumer) { - tessellate(blockState, fluidState, blockPos, vertexConsumer); + public void renderLiquid(BlockState blockState, FluidState fluidState, BlockPos blockPos) { + FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(fluidState.getType()); + + TerrainRenderType renderType = TerrainRenderType.get(ItemBlockRenderTypes.getRenderLayer(fluidState)); + renderType = TerrainRenderType.getRemapped(renderType); + TerrainBufferBuilder bufferBuilder = this.resources.builderPack.builder(renderType).getBufferBuilder(QuadFacing.UNDEFINED.ordinal()); + + if (handler != null) { + handler.renderFluid(blockPos, this.resources.getRegion(), bufferBuilder, blockState, fluidState); + } + + if (DefaultFluidRenderers.has(handler)) { + tessellate(blockState, fluidState, blockPos, bufferBuilder); + } } private boolean isFaceOccludedByState(BlockGetter blockGetter, float h, Direction direction, BlockPos blockPos, BlockState blockState) { @@ -85,8 +107,8 @@ public BlockState getAdjBlockState(BlockAndTintGetter blockAndTintGetter, int x, return blockAndTintGetter.getBlockState(mBlockPos); } - public void tessellate(BlockState blockState, FluidState fluidState, BlockPos blockPos, TerrainBufferBuilder vertexConsumer) { - BlockAndTintGetter region = this.resources.region; + public void tessellate(BlockState blockState, FluidState fluidState, BlockPos blockPos, TerrainBufferBuilder bufferBuilder) { + BlockAndTintGetter region = this.resources.getRegion(); final FluidRenderHandler handler = getFluidRenderHandler(fluidState); int color = handler.getFluidColor(region, blockPos, fluidState); @@ -102,7 +124,7 @@ public void tessellate(BlockState blockState, FluidState fluidState, BlockPos bl final int posZ = blockPos.getZ(); boolean useAO = blockState.getLightEmission() == 0 && Minecraft.useAmbientOcclusion(); - LightPipeline lightPipeline = useAO ? this.resources.smoothLightPipeline : this.resources.flatLightPipeline; + LightPipeline lightPipeline = useAO ? this.smoothLightPipeline : this.flatLightPipeline; BlockState downState = getAdjBlockState(region, posX, posY, posZ, Direction.DOWN); BlockState upState = getAdjBlockState(region, posX, posY, posZ, Direction.UP); @@ -214,10 +236,10 @@ public void tessellate(BlockState blockState, FluidState fluidState, BlockPos bl updateQuad(this.modelQuad, blockPos, lightPipeline, Direction.UP); updateColor(r, g, b, brightness); - putQuad(modelQuad, vertexConsumer, x0, y0, z0, false); + putQuad(modelQuad, bufferBuilder, x0, y0, z0, false); if (fluidState.shouldRenderBackwardUpFace(region, blockPos.above())) { - putQuad(modelQuad, vertexConsumer, x0, y0, z0, true); + putQuad(modelQuad, bufferBuilder, x0, y0, z0, true); } } @@ -240,8 +262,7 @@ public void tessellate(BlockState blockState, FluidState fluidState, BlockPos bl updateQuad(this.modelQuad, blockPos, lightPipeline, Direction.DOWN); updateColor(r, g, b, brightness); - putQuad(modelQuad, vertexConsumer, x0, y0, z0, false); - + putQuad(modelQuad, bufferBuilder, x0, y0, z0, false); } modelQuad.setFlags(ModelQuadFlags.IS_PARALLEL | ModelQuadFlags.IS_ALIGNED); @@ -347,10 +368,10 @@ public void tessellate(BlockState blockState, FluidState fluidState, BlockPos bl updateQuad(this.modelQuad, blockPos, lightPipeline, direction); updateColor(r, g, b, brightness); - putQuad(modelQuad, vertexConsumer, x0, y0, z0, false); + putQuad(modelQuad, bufferBuilder, x0, y0, z0, false); if (!isOverlay) { - putQuad(modelQuad, vertexConsumer, x0, y0, z0, true); + putQuad(modelQuad, bufferBuilder, x0, y0, z0, true); } } @@ -420,7 +441,7 @@ private int calculateNormal(ModelQuad quad) { .cross(quad.getX(3), quad.getY(3), quad.getZ(3)); normal.normalize(); - return VertexUtil.packNormal(normal.x(), normal.y(), normal.z()); + return I32_SNorm.packNormal(normal.x(), normal.y(), normal.z()); } private void putQuad(ModelQuad quad, TerrainBufferBuilder bufferBuilder, float xOffset, float yOffset, float zOffset, boolean flip) { @@ -455,11 +476,8 @@ private void setVertex(ModelQuad quad, int i, float x, float y, float z, float u quad.setV(i, v); } - private void updateQuad(ModelQuad quad, BlockPos blockPos, - LightPipeline lightPipeline, Direction dir) { - + private void updateQuad(ModelQuad quad, BlockPos blockPos, LightPipeline lightPipeline, Direction dir) { lightPipeline.calculate(quad, blockPos, resources.quadLightData, null, dir, false); - } private void updateColor(float r, float g, float b, float brightness) { diff --git a/src/main/java/net/vulkanmod/render/chunk/build/task/BuildTask.java b/src/main/java/net/vulkanmod/render/chunk/build/task/BuildTask.java index 6c104faa9..068700b6d 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/task/BuildTask.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/task/BuildTask.java @@ -1,7 +1,6 @@ package net.vulkanmod.render.chunk.build.task; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.chunk.VisGraph; import net.minecraft.core.BlockPos; @@ -13,13 +12,14 @@ import net.vulkanmod.Initializer; import net.vulkanmod.render.chunk.RenderSection; import net.vulkanmod.render.chunk.WorldRenderer; -import net.vulkanmod.render.chunk.build.BlockRenderer; -import net.vulkanmod.render.chunk.build.LiquidRenderer; +import net.vulkanmod.render.chunk.build.renderer.BlockRenderer; +import net.vulkanmod.render.chunk.build.renderer.FluidRenderer; import net.vulkanmod.render.chunk.build.RenderRegion; import net.vulkanmod.render.chunk.build.UploadBuffer; import net.vulkanmod.render.chunk.build.thread.BuilderResources; import net.vulkanmod.render.chunk.build.thread.ThreadBuilderPack; -import net.vulkanmod.render.vertex.TerrainBufferBuilder; +import net.vulkanmod.render.chunk.cull.QuadFacing; +import net.vulkanmod.render.vertex.TerrainBuilder; import net.vulkanmod.render.vertex.TerrainRenderType; import org.jetbrains.annotations.Nullable; import org.joml.Vector3f; @@ -94,7 +94,7 @@ private CompileResult compile(float camX, float camY, float camZ, BuilderResourc BlockRenderer blockRenderer = builderResources.blockRenderer; - LiquidRenderer liquidRenderer = builderResources.liquidRenderer; + FluidRenderer fluidRenderer = builderResources.fluidRenderer; BlockPos.MutableBlockPos blockPos = new BlockPos.MutableBlockPos(); @@ -116,44 +116,34 @@ private CompileResult compile(float camX, float camY, float camZ, BuilderResourc } FluidState fluidState = blockState.getFluidState(); - TerrainRenderType renderType; - TerrainBufferBuilder bufferBuilder; if (!fluidState.isEmpty()) { - renderType = TerrainRenderType.get(ItemBlockRenderTypes.getRenderLayer(fluidState)); - - bufferBuilder = getBufferBuilder(bufferBuilders, renderType); - bufferBuilder.setBlockAttributes(blockState); - - liquidRenderer.renderLiquid(blockState, fluidState, blockPos, bufferBuilder); + fluidRenderer.renderLiquid(blockState, fluidState, blockPos); } if (blockState.getRenderShape() == RenderShape.MODEL) { - renderType = TerrainRenderType.get(ItemBlockRenderTypes.getChunkRenderType(blockState)); - - bufferBuilder = getBufferBuilder(bufferBuilders, renderType); - bufferBuilder.setBlockAttributes(blockState); - pos.set(blockPos.getX() & 15, blockPos.getY() & 15, blockPos.getZ() & 15); - blockRenderer.renderBlock(blockState, blockPos, pos, bufferBuilder); + blockRenderer.renderBlock(blockState, blockPos, pos); } } } } - TerrainBufferBuilder translucentBufferBuilder = bufferBuilders.builder(TerrainRenderType.TRANSLUCENT); - if (!translucentBufferBuilder.isCurrentBatchEmpty()) { - translucentBufferBuilder.setupQuadSortingPoints(); - translucentBufferBuilder.setupQuadSorting(camX - (float) startBlockPos.getX(), camY - (float) startBlockPos.getY(), camZ - (float) startBlockPos.getZ()); - compileResult.transparencyState = translucentBufferBuilder.getSortState(); + TerrainBuilder trasnlucentTerrainBuilder = bufferBuilders.builder(TerrainRenderType.TRANSLUCENT); + if (trasnlucentTerrainBuilder.getBufferBuilder(QuadFacing.UNDEFINED.ordinal()).getVertices() > 0) { + trasnlucentTerrainBuilder.setupQuadSortingPoints(); + trasnlucentTerrainBuilder.setupQuadSorting(camX - (float) startBlockPos.getX(), camY - (float) startBlockPos.getY(), camZ - (float) startBlockPos.getZ()); + compileResult.transparencyState = trasnlucentTerrainBuilder.getSortState(); } for (TerrainRenderType renderType : TerrainRenderType.VALUES) { - TerrainBufferBuilder.RenderedBuffer renderedBuffer = bufferBuilders.builder(renderType).end(); - if (renderedBuffer != null) { - UploadBuffer uploadBuffer = new UploadBuffer(renderedBuffer); - compileResult.renderedLayers.put(renderType, uploadBuffer); - renderedBuffer.release(); - } + TerrainBuilder builder = bufferBuilders.builder(renderType); + + TerrainBuilder.DrawState drawState = builder.endDrawing(); + + UploadBuffer uploadBuffer = new UploadBuffer(builder, drawState); + compileResult.renderedLayers.put(renderType, uploadBuffer); + + builder.clear(); } compileResult.visibilitySet = visGraph.resolve(); @@ -163,12 +153,12 @@ private CompileResult compile(float camX, float camY, float camZ, BuilderResourc private void setupBufferBuilders(ThreadBuilderPack builderPack) { for (TerrainRenderType renderType : TerrainRenderType.VALUES) { - TerrainBufferBuilder bufferBuilder = builderPack.builder(renderType); + TerrainBuilder bufferBuilder = builderPack.builder(renderType); bufferBuilder.begin(); } } - private TerrainBufferBuilder getBufferBuilder(ThreadBuilderPack bufferBuilders, TerrainRenderType renderType) { + private TerrainBuilder getTerrainBuilder(ThreadBuilderPack bufferBuilders, TerrainRenderType renderType) { renderType = compactRenderTypes(renderType); return bufferBuilders.builder(renderType); } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/task/ChunkTask.java b/src/main/java/net/vulkanmod/render/chunk/build/task/ChunkTask.java index 13d416da6..c1acc33df 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/task/ChunkTask.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/task/ChunkTask.java @@ -2,7 +2,6 @@ import net.vulkanmod.render.chunk.RenderSection; import net.vulkanmod.render.chunk.build.RenderRegion; -import net.vulkanmod.render.chunk.build.TaskDispatcher; import net.vulkanmod.render.chunk.build.thread.BuilderResources; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/src/main/java/net/vulkanmod/render/chunk/build/task/CompiledSection.java b/src/main/java/net/vulkanmod/render/chunk/build/task/CompiledSection.java index c93de3a3c..e233ab0a2 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/task/CompiledSection.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/task/CompiledSection.java @@ -3,7 +3,6 @@ import com.google.common.collect.Lists; import net.minecraft.world.level.block.entity.BlockEntity; import net.vulkanmod.render.vertex.QuadSorter; -import net.vulkanmod.render.vertex.TerrainBufferBuilder; import org.jetbrains.annotations.Nullable; import java.util.List; diff --git a/src/main/java/net/vulkanmod/render/chunk/build/task/SortTransparencyTask.java b/src/main/java/net/vulkanmod/render/chunk/build/task/SortTransparencyTask.java index 5f804c1a5..122ab3751 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/task/SortTransparencyTask.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/task/SortTransparencyTask.java @@ -7,7 +7,7 @@ import net.vulkanmod.render.chunk.build.thread.BuilderResources; import net.vulkanmod.render.chunk.build.thread.ThreadBuilderPack; import net.vulkanmod.render.vertex.QuadSorter; -import net.vulkanmod.render.vertex.TerrainBufferBuilder; +import net.vulkanmod.render.vertex.TerrainBuilder; import net.vulkanmod.render.vertex.TerrainRenderType; public class SortTransparencyTask extends ChunkTask { @@ -35,21 +35,23 @@ public Result runTask(BuilderResources context) { CompiledSection compiledSection = this.section.getCompiledSection(); QuadSorter.SortState transparencyState = compiledSection.transparencyState; - TerrainBufferBuilder bufferBuilder = builderPack.builder(TerrainRenderType.TRANSLUCENT); + TerrainBuilder bufferBuilder = builderPack.builder(TerrainRenderType.TRANSLUCENT); bufferBuilder.begin(); bufferBuilder.restoreSortState(transparencyState); bufferBuilder.setupQuadSorting(x - (float) this.section.xOffset(), y - (float) this.section.yOffset(), z - (float) this.section.zOffset()); - TerrainBufferBuilder.RenderedBuffer renderedBuffer = bufferBuilder.end(); + TerrainBuilder.DrawState drawState = bufferBuilder.endDrawing(); CompileResult compileResult = new CompileResult(this.section, false); - UploadBuffer uploadBuffer = new UploadBuffer(renderedBuffer); + UploadBuffer uploadBuffer = new UploadBuffer(bufferBuilder, drawState); compileResult.renderedLayers.put(TerrainRenderType.TRANSLUCENT, uploadBuffer); - renderedBuffer.release(); + + bufferBuilder.reset(); if (this.cancelled.get()) { return Result.CANCELLED; } + taskDispatcher.scheduleSectionUpdate(compileResult); return Result.SUCCESSFUL; } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/TaskDispatcher.java b/src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java similarity index 96% rename from src/main/java/net/vulkanmod/render/chunk/build/TaskDispatcher.java rename to src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java index ae43f3544..0a3cf4def 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/TaskDispatcher.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java @@ -1,4 +1,4 @@ -package net.vulkanmod.render.chunk.build; +package net.vulkanmod.render.chunk.build.task; import com.google.common.collect.Queues; import net.vulkanmod.render.chunk.ChunkArea; @@ -6,8 +6,7 @@ import net.vulkanmod.render.chunk.RenderSection; import net.vulkanmod.render.chunk.WorldRenderer; import net.vulkanmod.render.chunk.buffer.DrawBuffers; -import net.vulkanmod.render.chunk.build.task.ChunkTask; -import net.vulkanmod.render.chunk.build.task.CompileResult; +import net.vulkanmod.render.chunk.build.UploadBuffer; import net.vulkanmod.render.chunk.build.thread.ThreadBuilderPack; import net.vulkanmod.render.chunk.build.thread.BuilderResources; import net.vulkanmod.render.vertex.TerrainRenderType; @@ -166,7 +165,7 @@ private void doSectionUpdate(CompileResult compileResult) { if(uploadBuffer != null) { drawBuffers.upload(section, uploadBuffer, renderType); } else { - section.getDrawParameters(renderType).reset(renderArea, renderType); + section.resetDrawParameters(renderType); } } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/thread/BuilderResources.java b/src/main/java/net/vulkanmod/render/chunk/build/thread/BuilderResources.java index 41a05af95..fd6e69f11 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/thread/BuilderResources.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/thread/BuilderResources.java @@ -2,10 +2,10 @@ import net.vulkanmod.Initializer; import net.vulkanmod.render.chunk.RenderSection; -import net.vulkanmod.render.chunk.build.BlockRenderer; -import net.vulkanmod.render.chunk.build.LiquidRenderer; +import net.vulkanmod.render.chunk.build.renderer.BlockRenderer; +import net.vulkanmod.render.chunk.build.renderer.FluidRenderer; import net.vulkanmod.render.chunk.build.RenderRegion; -import net.vulkanmod.render.chunk.build.TintCache; +import net.vulkanmod.render.chunk.build.color.TintCache; import net.vulkanmod.render.chunk.build.light.LightMode; import net.vulkanmod.render.chunk.build.light.LightPipeline; import net.vulkanmod.render.chunk.build.light.data.ArrayLightDataCache; @@ -16,37 +16,41 @@ public class BuilderResources { public final ThreadBuilderPack builderPack = new ThreadBuilderPack(); - public final BlockRenderer blockRenderer = new BlockRenderer(); - public final LiquidRenderer liquidRenderer = new LiquidRenderer(); - public final TintCache tintCache = new TintCache(); - public RenderRegion region; + public final BlockRenderer blockRenderer; + public final FluidRenderer fluidRenderer; public final ArrayLightDataCache lightDataCache = new ArrayLightDataCache(); public final QuadLightData quadLightData = new QuadLightData(); - public final LightPipeline smoothLightPipeline; - public final LightPipeline flatLightPipeline; + private RenderRegion region; private int totalBuildTime = 0, buildCount = 0; public BuilderResources() { - this.flatLightPipeline = new FlatLightPipeline(lightDataCache); + LightPipeline flatLightPipeline = new FlatLightPipeline(this.lightDataCache); + + LightPipeline smoothLightPipeline; + if (Initializer.CONFIG.ambientOcclusion == LightMode.SUB_BLOCK) { + smoothLightPipeline = new NewSmoothLightPipeline(lightDataCache); + } + else { + smoothLightPipeline = new SmoothLightPipeline(lightDataCache); + } + + this.blockRenderer = new BlockRenderer(flatLightPipeline, smoothLightPipeline); + this.fluidRenderer = new FluidRenderer(flatLightPipeline, smoothLightPipeline); - if(Initializer.CONFIG.ambientOcclusion == LightMode.SUB_BLOCK) - this.smoothLightPipeline = new NewSmoothLightPipeline(lightDataCache); - else - this.smoothLightPipeline = new SmoothLightPipeline(lightDataCache); + this.blockRenderer.setResources(this); + this.fluidRenderer.setResources(this); } public void update(RenderRegion region, RenderSection renderSection) { this.region = region; + this.blockRenderer.prepareForWorld(region, true); - lightDataCache.reset(region, renderSection.xOffset(), renderSection.yOffset(), renderSection.zOffset()); - - blockRenderer.setResources(this); - liquidRenderer.setResources(this); + this.lightDataCache.reset(region, renderSection.xOffset(), renderSection.yOffset(), renderSection.zOffset()); } public void clear() { @@ -58,6 +62,10 @@ public void updateBuildStats(int buildTime) { this.totalBuildTime += buildTime; } + public RenderRegion getRegion() { + return region; + } + public int getTotalBuildTime() { return totalBuildTime; } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/thread/ThreadBuilderPack.java b/src/main/java/net/vulkanmod/render/chunk/build/thread/ThreadBuilderPack.java index 5517ce4ea..84102838f 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/thread/ThreadBuilderPack.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/thread/ThreadBuilderPack.java @@ -1,6 +1,6 @@ package net.vulkanmod.render.chunk.build.thread; -import net.vulkanmod.render.vertex.TerrainBufferBuilder; +import net.vulkanmod.render.vertex.TerrainBuilder; import net.vulkanmod.render.vertex.TerrainRenderType; import java.util.Arrays; @@ -9,20 +9,20 @@ import java.util.function.Function; public class ThreadBuilderPack { - private static Function terrainBuilderConstructor; + private static Function terrainBuilderConstructor; public static void defaultTerrainBuilderConstructor() { - terrainBuilderConstructor = renderType -> new TerrainBufferBuilder(TerrainRenderType.getRenderType(renderType).bufferSize()); + terrainBuilderConstructor = renderType -> new TerrainBuilder(TerrainRenderType.getRenderType(renderType).bufferSize()); } - public static void setTerrainBuilderConstructor(Function constructor) { + public static void setTerrainBuilderConstructor(Function constructor) { terrainBuilderConstructor = constructor; } - private final Map builders; + private final Map builders; public ThreadBuilderPack() { - var map = new EnumMap(TerrainRenderType.class); + var map = new EnumMap(TerrainRenderType.class); Arrays.stream(TerrainRenderType.values()).forEach( terrainRenderType -> map.put(terrainRenderType, terrainBuilderConstructor.apply(terrainRenderType)) @@ -30,12 +30,12 @@ public ThreadBuilderPack() { builders = map; } - public TerrainBufferBuilder builder(TerrainRenderType renderType) { + public TerrainBuilder builder(TerrainRenderType renderType) { return this.builders.get(renderType); } public void clearAll() { - this.builders.values().forEach(TerrainBufferBuilder::clear); + this.builders.values().forEach(TerrainBuilder::clear); } } diff --git a/src/main/java/net/vulkanmod/render/chunk/cull/QuadFacing.java b/src/main/java/net/vulkanmod/render/chunk/cull/QuadFacing.java new file mode 100644 index 000000000..642fd9bf4 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/chunk/cull/QuadFacing.java @@ -0,0 +1,66 @@ +package net.vulkanmod.render.chunk.cull; + +import net.minecraft.core.Direction; +import net.minecraft.util.Mth; +import net.vulkanmod.render.vertex.format.I32_SNorm; +import org.joml.Vector3f; + +public enum QuadFacing { + X_POS, + X_NEG, + Y_POS, + Y_NEG, + Z_POS, + Z_NEG, + UNDEFINED; + + public static final QuadFacing[] VALUES = QuadFacing.values(); + public static final int COUNT = VALUES.length; + + public static QuadFacing fromDirection(Direction direction) { + return switch (direction) { + case DOWN -> Y_NEG; + case UP -> Y_POS; + case NORTH -> Z_NEG; + case SOUTH -> Z_POS; + case WEST -> X_NEG; + case EAST -> X_POS; + }; + } + + public static QuadFacing fromNormal(int packedNormal) { + final float x = I32_SNorm.unpackX(packedNormal); + final float y = I32_SNorm.unpackY(packedNormal); + final float z = I32_SNorm.unpackZ(packedNormal); + + return fromNormal(x, y, z); + } + + public static QuadFacing fromNormal(Vector3f normal) { + return fromNormal(normal.x(), normal.y(), normal.z()); + } + + public static QuadFacing fromNormal(float x, float y, float z) { + final float absX = Math.abs(x); + final float absY = Math.abs(y); + final float absZ = Math.abs(z); + + float sum = absX + absY + absZ; + + if (Mth.equal(sum, 1.0f)) { + if (Mth.equal(absX, 1.0f)) { + return x > 0.0f ? QuadFacing.X_POS : QuadFacing.X_NEG; + } + + if (Mth.equal(absY, 1.0f)) { + return y > 0.0f ? QuadFacing.Y_POS : QuadFacing.Y_NEG; + } + + if (Mth.equal(absZ, 1.0f)) { + return z > 0.0f ? QuadFacing.Z_POS : QuadFacing.Z_NEG; + } + } + + return QuadFacing.UNDEFINED; + } +} diff --git a/src/main/java/net/vulkanmod/render/chunk/graph/SectionGraph.java b/src/main/java/net/vulkanmod/render/chunk/graph/SectionGraph.java index f3758feda..8a3d641be 100644 --- a/src/main/java/net/vulkanmod/render/chunk/graph/SectionGraph.java +++ b/src/main/java/net/vulkanmod/render/chunk/graph/SectionGraph.java @@ -13,7 +13,7 @@ import net.vulkanmod.interfaces.FrustumMixed; import net.vulkanmod.render.chunk.*; import net.vulkanmod.render.chunk.build.RenderRegionBuilder; -import net.vulkanmod.render.chunk.build.TaskDispatcher; +import net.vulkanmod.render.chunk.build.task.TaskDispatcher; import net.vulkanmod.render.chunk.frustum.VFrustum; import net.vulkanmod.render.chunk.util.AreaSetQueue; import net.vulkanmod.render.chunk.util.ResettableQueue; diff --git a/src/main/java/net/vulkanmod/render/chunk/util/CircularIntList.java b/src/main/java/net/vulkanmod/render/chunk/util/CircularIntList.java index e81145a91..d8964eaa9 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/CircularIntList.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/CircularIntList.java @@ -1,78 +1,67 @@ package net.vulkanmod.render.chunk.util; import org.apache.commons.lang3.Validate; -import org.jetbrains.annotations.NotNull; import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Spliterator; -import java.util.function.Consumer; public class CircularIntList { - private int[] list; - private final int startIndex; + private final int size; + private final int[] list; + private int startIndex; - private int[] previous; - private int[] next; + private final OwnIterator iterator; + private final RangeIterator rangeIterator; - private OwnIterator iterator; + public CircularIntList(int size) { + this.size = size; + this.list = new int[size + 2]; - public CircularIntList(int size, int startIndex) { - this.startIndex = startIndex; - - this.generateList(size); + this.iterator = new OwnIterator(); + this.rangeIterator = new RangeIterator(); } - private void generateList(int size) { - int[] list = new int[size]; + public void updateStartIdx(int startIndex) { + int[] list = this.list; + this.startIndex = startIndex; - this.previous = new int[size]; - this.next = new int[size]; + list[0] = -1; + list[size + 1] = -1; - int k = 0; + int k = 1; for(int i = startIndex; i < size; ++i) { list[k] = i; - ++k; } for(int i = 0; i < startIndex; ++i) { list[k] = i; ++k; } - - this.previous[0] = -1; - System.arraycopy(list, 0, this.previous, 1, size - 1); - - this.next[size - 1] = -1; - System.arraycopy(list, 1, this.next, 0, size - 1); - - this.list = list; } public int getNext(int i) { - return this.next[i]; + return this.list[i + 1]; } public int getPrevious(int i) { - return this.previous[i]; + return this.list[i - 1]; } public OwnIterator iterator() { - return new OwnIterator(); + return this.iterator; } - public RangeIterator rangeIterator(int startIndex, int endIndex) { - return new RangeIterator(startIndex, endIndex); + public RangeIterator getRangeIterator(int startIndex, int endIndex) { + this.rangeIterator.update(startIndex, endIndex); + return this.rangeIterator; } - public void restartIterator() { - this.iterator.restart(); + public RangeIterator createRangeIterator() { + return new RangeIterator(); } public class OwnIterator implements Iterator { - private int currentIndex = -1; - private final int maxIndex = list.length - 1; + private int currentIndex = 0; + private final int maxIndex = size; @Override public boolean hasNext() { @@ -90,38 +79,32 @@ public int getCurrentIndex() { } public void restart() { - this.currentIndex = -1; + this.currentIndex = 0; } } public class RangeIterator implements Iterator { private int currentIndex; - private final int startIndex; - private final int maxIndex; + private int startIndex; + private int endIndex; - public RangeIterator(int startIndex, int endIndex) { - this.startIndex = startIndex; - this.maxIndex = endIndex; - Validate.isTrue(this.maxIndex < list.length, "Beyond max size"); + public void update(int startIndex, int endIndex) { + Validate.isTrue(endIndex < list.length, "Beyond max size"); + this.startIndex = startIndex + 1; + this.endIndex = endIndex + 1; this.restart(); } @Override public boolean hasNext() { - return currentIndex < maxIndex; + return currentIndex < endIndex; } @Override public Integer next() { currentIndex++; - try { - return list[currentIndex]; - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(); - } - + return list[currentIndex]; } public int getCurrentIndex() { diff --git a/src/main/java/net/vulkanmod/render/chunk/util/Util.java b/src/main/java/net/vulkanmod/render/chunk/util/Util.java index c37ddd0ff..caa063410 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/Util.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/Util.java @@ -44,11 +44,11 @@ public static int flooredLog(int v) { return log; } - public static int align(int i, int alignment) { + public static long align(long l, int alignment) { if (alignment == 0) - return i; + return l; - int r = i % alignment; - return r != 0 ? i + alignment - r : i; + long r = l % alignment; + return r != 0 ? l + alignment - r : l; } } diff --git a/src/main/java/net/vulkanmod/render/model/quad/ModelQuad.java b/src/main/java/net/vulkanmod/render/model/quad/ModelQuad.java index efeebc0bd..d87df233d 100644 --- a/src/main/java/net/vulkanmod/render/model/quad/ModelQuad.java +++ b/src/main/java/net/vulkanmod/render/model/quad/ModelQuad.java @@ -2,10 +2,18 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.Direction; +import net.vulkanmod.render.chunk.cull.QuadFacing; -public class ModelQuad implements QuadView { +/** + * Only used by FluidRenderer + */ +public class ModelQuad implements ModelQuadView { public static final int VERTEX_SIZE = 8; + public static int vertexOffset(int vertexIndex) { + return vertexIndex * VERTEX_SIZE; + } + private final int[] data = new int[4 * VERTEX_SIZE]; Direction direction; @@ -58,6 +66,21 @@ public Direction getFacingDirection() { return this.direction; } + @Override + public Direction lightFace() { + return this.direction; + } + + @Override + public QuadFacing getQuadFacing() { + return QuadFacing.UNDEFINED; + } + + @Override + public int getNormal() { + return 0; + } + public float setX(int idx, float f) { return this.data[vertexOffset(idx)] = Float.floatToRawIntBits(f); } @@ -88,8 +111,4 @@ public void setFlags(int f) { public void setSprite(TextureAtlasSprite sprite) { this.sprite = sprite; } - - private static int vertexOffset(int vertexIndex) { - return vertexIndex * VERTEX_SIZE; - } } diff --git a/src/main/java/net/vulkanmod/render/model/quad/ModelQuadFlags.java b/src/main/java/net/vulkanmod/render/model/quad/ModelQuadFlags.java index 9016cb4aa..bb1dc0cca 100644 --- a/src/main/java/net/vulkanmod/render/model/quad/ModelQuadFlags.java +++ b/src/main/java/net/vulkanmod/render/model/quad/ModelQuadFlags.java @@ -2,8 +2,6 @@ import net.minecraft.core.Direction; -import static net.vulkanmod.render.model.quad.ModelQuad.VERTEX_SIZE; - public class ModelQuadFlags { /** * Indicates that the quad does not fully cover the given face for the model. @@ -25,7 +23,7 @@ public static boolean contains(int flags, int mask) { return (flags & mask) != 0; } - public static int getQuadFlags(int[] vertices, Direction face) { + public static int getQuadFlags(ModelQuadView quad, Direction face) { float minX = 32.0F; float minY = 32.0F; float minZ = 32.0F; @@ -35,9 +33,9 @@ public static int getQuadFlags(int[] vertices, Direction face) { float maxZ = -32.0F; for (int i = 0; i < 4; ++i) { - float x = Float.intBitsToFloat(vertices[i * VERTEX_SIZE]); - float y = Float.intBitsToFloat(vertices[i * VERTEX_SIZE + 1]); - float z = Float.intBitsToFloat(vertices[i * VERTEX_SIZE + 2]); + float x = quad.getX(i); + float y = quad.getY(i); + float z = quad.getZ(i); minX = Math.min(minX, x); minY = Math.min(minY, y); diff --git a/src/main/java/net/vulkanmod/render/model/quad/QuadView.java b/src/main/java/net/vulkanmod/render/model/quad/ModelQuadView.java similarity index 71% rename from src/main/java/net/vulkanmod/render/model/quad/QuadView.java rename to src/main/java/net/vulkanmod/render/model/quad/ModelQuadView.java index 883c4b315..ac791d9a5 100644 --- a/src/main/java/net/vulkanmod/render/model/quad/QuadView.java +++ b/src/main/java/net/vulkanmod/render/model/quad/ModelQuadView.java @@ -1,8 +1,9 @@ package net.vulkanmod.render.model.quad; import net.minecraft.core.Direction; +import net.vulkanmod.render.chunk.cull.QuadFacing; -public interface QuadView { +public interface ModelQuadView { int getFlags(); @@ -22,6 +23,12 @@ public interface QuadView { Direction getFacingDirection(); + Direction lightFace(); + + QuadFacing getQuadFacing(); + + int getNormal(); + default boolean isTinted() { return this.getColorIndex() != -1; } diff --git a/src/main/java/net/vulkanmod/render/profiling/Profiler.java b/src/main/java/net/vulkanmod/render/profiling/Profiler.java index a5a34318c..ccfe5cb59 100644 --- a/src/main/java/net/vulkanmod/render/profiling/Profiler.java +++ b/src/main/java/net/vulkanmod/render/profiling/Profiler.java @@ -37,6 +37,7 @@ public static void setActive(boolean b) { ObjectArrayList nodeStack = new ObjectArrayList<>(); ObjectArrayList nodes = new ObjectArrayList<>(); + ObjectArrayList currentFrameNodes = new ObjectArrayList<>(); Object2ReferenceOpenHashMap nodeMap = new Object2ReferenceOpenHashMap<>(); Node mainNode; @@ -67,7 +68,7 @@ public void push(String s) { node.children.clear(); if (node.parent == selectedNode) - nodes.add(node); + currentFrameNodes.add(node); currentNode = node; @@ -118,7 +119,10 @@ public void start() { pushNodeStack(mainNode); - nodes.clear(); + var t = nodes; + nodes = currentFrameNodes; + currentFrameNodes = t; + currentFrameNodes.clear(); } public void end() { diff --git a/src/main/java/net/vulkanmod/render/profiling/ProfilerOverlay.java b/src/main/java/net/vulkanmod/render/profiling/ProfilerOverlay.java index d75fcdbd4..8f0ffdd9f 100644 --- a/src/main/java/net/vulkanmod/render/profiling/ProfilerOverlay.java +++ b/src/main/java/net/vulkanmod/render/profiling/ProfilerOverlay.java @@ -68,7 +68,7 @@ public void render(GuiGraphics guiGraphics) { Objects.requireNonNull(this.font); RenderSystem.enableBlend(); - GuiRenderer.beginBatch(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + GuiRenderer.beginBatch(); for (int i = 0; i < infoList.size(); ++i) { String line = infoList.get(i); @@ -104,13 +104,22 @@ private List buildInfo() { this.updateResults(); - if (lastResults == null) + if (lastResults == null) { return list; + } + + var partialResults = lastResults.getPartialResults(); + if (partialResults.size() < 2) { + return list; + } int fps = Math.round(1000.0f / frametime); list.add(String.format("FPS: %d Frametime: %.3f", fps, frametime)); list.add(""); + list.add(String.format("CPU fence wait time: %.3f", partialResults.get(1).value)); + list.add(""); + for (Profiler.Result result : lastResults.getPartialResults()) { list.add(String.format("%s: %.3f", result.name, result.value)); } @@ -123,8 +132,9 @@ private List buildInfo() { list.add(""); list.add(String.format("Build time: %.0fms", BuildTimeProfiler.getDeltaTime())); - if (ChunkTask.BENCH) + if (ChunkTask.BENCH) { list.add(buildStats); + } return list; } diff --git a/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java b/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java new file mode 100644 index 000000000..b7b036307 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java @@ -0,0 +1,180 @@ +package net.vulkanmod.render.shader; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import net.minecraft.resources.ResourceLocation; +import net.vulkanmod.vulkan.shader.Pipeline; +import net.vulkanmod.vulkan.shader.SPIRVUtils; +import org.apache.commons.io.IOUtils; + +import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public abstract class ShaderLoadUtil { + + private static final String RESOURCES_PATH = SPIRVUtils.class.getResource("/assets/vulkanmod").toExternalForm(); + + public static void loadShaders(Pipeline.Builder pipelineBuilder, JsonObject config, String configName, String path) { + String vertexShader = config.has("vertex") ? config.get("vertex").getAsString() : configName; + String fragmentShader = config.has("fragment") ? config.get("fragment").getAsString() : configName; + + vertexShader = removeNameSpace(vertexShader); + fragmentShader = removeNameSpace(fragmentShader); + + vertexShader = getFileName(vertexShader); + fragmentShader = getFileName(fragmentShader); + + loadShader(pipelineBuilder, configName, path, vertexShader, SPIRVUtils.ShaderKind.VERTEX_SHADER); + loadShader(pipelineBuilder, configName, path, fragmentShader, SPIRVUtils.ShaderKind.FRAGMENT_SHADER); + } + + public static void loadShader(Pipeline.Builder pipelineBuilder, String configName, String path, SPIRVUtils.ShaderKind type) { + String[] splitPath = splitPath(path); + String shaderName = splitPath[1]; + String subPath = splitPath[0]; + + loadShader(pipelineBuilder, configName, subPath, shaderName, type); + } + + public static void loadShader(Pipeline.Builder pipelineBuilder, String configName, String path, String shaderName, SPIRVUtils.ShaderKind type) { + String basePath = "%s/shaders/%s".formatted(RESOURCES_PATH, path); + + String source = getShaderSource(basePath, configName, shaderName, type); + + SPIRVUtils.SPIRV spirv = SPIRVUtils.compileShader(shaderName, source, type); + + switch (type) { + case VERTEX_SHADER -> pipelineBuilder.setVertShaderSPIRV(spirv); + case FRAGMENT_SHADER -> pipelineBuilder.setFragShaderSPIRV(spirv); + } + } + + public static String getConfigFilePath(String path, String rendertype) { + String basePath = "%s/shaders/%s".formatted(RESOURCES_PATH, path); + String configPath = "%s/%s/%s.json".formatted(basePath, rendertype, rendertype); + + Path filePath; + try { + filePath = FileSystems.getDefault().getPath(configPath); + + if (!Files.exists(filePath)) { + configPath = "%s/%s.json".formatted(basePath, rendertype); + filePath = FileSystems.getDefault().getPath(configPath); + } + + if (!Files.exists(filePath)) { + return null; + } + } catch (Throwable e) { + throw new RuntimeException(e); + } + + return filePath.toString(); + } + + public static JsonObject getJsonConfig(String path, String rendertype) { + // Check for external shader + if (rendertype.contains(String.valueOf(ResourceLocation.NAMESPACE_SEPARATOR))) { + return null; + } + + String basePath = "%s/shaders/%s".formatted(RESOURCES_PATH, path); + String configPath = "%s/%s/%s.json".formatted(basePath, rendertype, rendertype); + + InputStream stream; + try { + stream = getInputStream(configPath); + + if (stream == null) { + configPath = "%s/%s.json".formatted(basePath, rendertype); + stream = getInputStream(configPath); + } + + if (stream == null) { + return null; + } + + JsonElement jsonElement = JsonParser.parseReader(new BufferedReader(new InputStreamReader(stream))); + stream.close(); + + return (JsonObject) jsonElement; + } catch (Throwable e) { + throw new RuntimeException(e); + } + + } + + public static String getShaderSource(String basePath, String rendertype, String shaderName, SPIRVUtils.ShaderKind type) { + String shaderExtension = switch (type) { + case VERTEX_SHADER -> ".vsh"; + case FRAGMENT_SHADER -> ".fsh"; + default -> throw new UnsupportedOperationException("shader type %s unsupported"); + }; + + String shaderPath = "/%s/%s".formatted(rendertype, rendertype); + String shaderFile = "%s%s%s".formatted(basePath, shaderPath, shaderExtension); + + InputStream stream; + try { + stream = getInputStream(shaderFile); + + if (stream == null) { + shaderPath = "/%s/%s".formatted(rendertype, shaderName); + shaderFile = "%s%s%s".formatted(basePath, shaderPath, shaderExtension); + stream = getInputStream(shaderFile); + } + + if (stream == null) { + shaderPath = "/%s/%s".formatted(shaderName, shaderName); + shaderFile = "%s%s%s".formatted(basePath, shaderPath, shaderExtension); + stream = getInputStream(shaderFile); + } + + if (stream == null) { + return null; + } + + String source = IOUtils.toString(new BufferedReader(new InputStreamReader(stream))); + stream.close(); + + return source; + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + public static String getFileName(String path) { + int idx = path.lastIndexOf('/'); + return idx > -1 ? path.substring(idx + 1) : path; + } + + public static String removeNameSpace(String path) { + int idx = path.indexOf(':'); + return idx > -1 ? path.substring(idx + 1) : path; + } + + public static String[] splitPath(String path) { + int idx = path.lastIndexOf('/'); + + return new String[] {path.substring(0, idx), path.substring(idx + 1)}; + } + + public static InputStream getInputStream(String path) { + try { + var path1 = Paths.get(new URI(path)); + + if (!Files.exists(path1)) + return null; + + return Files.newInputStream(path1); + } catch (URISyntaxException | IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java b/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java new file mode 100644 index 000000000..c7e3d3b4d --- /dev/null +++ b/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java @@ -0,0 +1,378 @@ +package net.vulkanmod.render.sky; + +import com.mojang.blaze3d.platform.NativeImage; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.*; +import net.minecraft.client.CloudStatus; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.FogRenderer; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.world.phys.Vec3; +import net.vulkanmod.render.PipelineManager; +import net.vulkanmod.render.VBO; +import net.vulkanmod.vulkan.VRenderSystem; +import net.vulkanmod.vulkan.shader.GraphicsPipeline; +import net.vulkanmod.vulkan.util.ColorUtil; +import org.apache.commons.lang3.Validate; +import org.joml.Matrix4f; + +import java.io.IOException; + +public class CloudRenderer { + private static final ResourceLocation TEXTURE_LOCATION = ResourceLocation.withDefaultNamespace("textures/environment/clouds.png"); + + private static final int DIR_NEG_Y_BIT = 1 << 0; + private static final int DIR_POS_Y_BIT = 1 << 1; + private static final int DIR_NEG_X_BIT = 1 << 2; + private static final int DIR_POS_X_BIT = 1 << 3; + private static final int DIR_NEG_Z_BIT = 1 << 4; + private static final int DIR_POS_Z_BIT = 1 << 5; + + private static final byte Y_BELOW_CLOUDS = 0; + private static final byte Y_ABOVE_CLOUDS = 1; + private static final byte Y_INSIDE_CLOUDS = 2; + + private static final int CELL_WIDTH = 12; + private static final int CELL_HEIGHT = 4; + + private CloudGrid cloudGrid; + + private int prevCloudX; + private int prevCloudZ; + private byte prevCloudY; + + private CloudStatus prevCloudsType; + + private boolean generateClouds; + private VBO cloudBuffer; + + public CloudRenderer() { + loadTexture(); + } + + public void loadTexture() { + this.cloudGrid = createCloudGrid(TEXTURE_LOCATION); + } + + public void renderClouds(ClientLevel level, PoseStack poseStack, Matrix4f modelView, Matrix4f projection, float ticks, float partialTicks, double camX, double camY, double camZ) { + float cloudHeight = level.effects().getCloudHeight(); + + if (Float.isNaN(cloudHeight)) { + return; + } + + Minecraft minecraft = Minecraft.getInstance(); + + double timeOffset = (ticks + partialTicks) * 0.03F; + double centerX = (camX + timeOffset); + double centerZ = camZ + 0.33F * CELL_WIDTH; + double centerY = cloudHeight - (float) camY + 0.33F; + + int centerCellX = (int) Math.floor(centerX / CELL_WIDTH); + int centerCellZ = (int) Math.floor(centerZ / CELL_WIDTH); + + byte yState; + if (centerY < -4.0f) { + yState = Y_BELOW_CLOUDS; + } + else if (centerY > 0.0f) { + yState = Y_ABOVE_CLOUDS; + } + else { + yState = Y_INSIDE_CLOUDS; + } + + if (centerCellX != this.prevCloudX || centerCellZ != this.prevCloudZ + || (minecraft.options.getCloudsType() != this.prevCloudsType) + || (this.prevCloudY != yState) + || this.cloudBuffer == null) { + this.prevCloudX = centerCellX; + this.prevCloudZ = centerCellZ; + this.prevCloudsType = minecraft.options.getCloudsType(); + this.prevCloudY = yState; + this.generateClouds = true; + } + + if (this.generateClouds) { + this.generateClouds = false; + if (this.cloudBuffer != null) { + this.cloudBuffer.close(); + } + + this.resetBuffer(); + + MeshData cloudsMesh = this.buildClouds(Tesselator.getInstance(), centerCellX, centerCellZ, centerY); + + if (cloudsMesh == null) { + return; + } + + this.cloudBuffer = new VBO(VertexBuffer.Usage.STATIC); + this.cloudBuffer.upload(cloudsMesh); + } + + if (this.cloudBuffer == null) { + return; + } + + FogRenderer.levelFogColor(); + + float xTranslation = (float) (centerX - (centerCellX * CELL_WIDTH)); + float yTranslation = (float) (centerY); + float zTranslation = (float) (centerZ - (centerCellZ * CELL_WIDTH)); + + poseStack.pushPose(); + poseStack.mulPose(modelView); + poseStack.translate(-xTranslation, yTranslation, -zTranslation); + + VRenderSystem.setModelOffset(-xTranslation, 0, -zTranslation); + + Vec3 cloudColor = level.getCloudColor(partialTicks); + RenderSystem.setShaderColor((float) cloudColor.x, (float) cloudColor.y, (float) cloudColor.z, 0.8f); + + GraphicsPipeline pipeline = PipelineManager.getCloudsPipeline(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.enableDepthTest(); + + boolean fastClouds = this.prevCloudsType == CloudStatus.FAST; + boolean insideClouds = yState == Y_INSIDE_CLOUDS; + boolean disableCull = insideClouds || (fastClouds && centerY <= 0.0f); + + if (disableCull) { + RenderSystem.disableCull(); + } + + if (!fastClouds) { + RenderSystem.colorMask(false, false, false, false); + this.cloudBuffer.drawWithShader(poseStack.last().pose(), projection, pipeline); + + RenderSystem.colorMask(true, true, true, true); + } + + this.cloudBuffer.drawWithShader(poseStack.last().pose(), projection, pipeline); + + RenderSystem.enableCull(); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + VRenderSystem.setModelOffset(0.0f, 0.0f, 0.0f); + + poseStack.popPose(); + } + + public void resetBuffer() { + if (this.cloudBuffer != null) { + this.cloudBuffer.close(); + this.cloudBuffer = null; + } + } + + private MeshData buildClouds(Tesselator tesselator, int centerCellX, int centerCellZ, double cloudY) { + final int upFaceColor = ColorUtil.RGBA.pack(1.0f, 1.0f, 1.0f, 1.0f); + final int xDirColor = ColorUtil.RGBA.pack(0.9f, 0.9f, 0.9f, 1.0f); + final int downFaceColor = ColorUtil.RGBA.pack(0.7f, 0.7f, 0.7f, 1.0f); + final int zDirColor = ColorUtil.RGBA.pack(0.8f, 0.8f, 0.8f, 1.0f); + + BufferBuilder bufferBuilder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + + int renderDistance = 32; + boolean insideClouds = this.prevCloudY == Y_INSIDE_CLOUDS; + + if (this.prevCloudsType == CloudStatus.FANCY) { + + for (int cellX = -renderDistance; cellX < renderDistance; ++cellX) { + for (int cellZ = -renderDistance; cellZ < renderDistance; ++cellZ) { + int cellIdx = this.cloudGrid.getWrappedIdx(centerCellX + cellX, centerCellZ + cellZ); + byte renderFaces = this.cloudGrid.renderFaces[cellIdx]; + + float x = cellX * CELL_WIDTH; + float z = cellZ * CELL_WIDTH; + + if ((renderFaces & DIR_POS_Y_BIT) != 0 && cloudY <= 0.0f) { + putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + CELL_WIDTH, upFaceColor); + putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, upFaceColor); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, upFaceColor); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, upFaceColor); + } + + if ((renderFaces & DIR_NEG_Y_BIT) != 0 && cloudY >= -CELL_HEIGHT) { + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, downFaceColor); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, downFaceColor); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, downFaceColor); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, downFaceColor); + } + + if ((renderFaces & DIR_POS_X_BIT) != 0 && (x < 1.0f || insideClouds)) { + putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + CELL_WIDTH, xDirColor); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, xDirColor); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, xDirColor); + putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, xDirColor); + } + + if ((renderFaces & DIR_NEG_X_BIT) != 0 && (x > -1.0f || insideClouds)) { + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, xDirColor); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, xDirColor); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, xDirColor); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, xDirColor); + } + + if ((renderFaces & DIR_POS_Z_BIT) != 0 && (z < 1.0f || insideClouds)) { + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, zDirColor); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, zDirColor); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, zDirColor); + putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + CELL_WIDTH, zDirColor); + } + + if ((renderFaces & DIR_NEG_Z_BIT) != 0 && (z > -1.0f || insideClouds)) { + putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, zDirColor); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, zDirColor); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, zDirColor); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, zDirColor); + } + + } + } + } + else { + + for (int cellX = -renderDistance; cellX < renderDistance; ++cellX) { + for (int cellZ = -renderDistance; cellZ < renderDistance; ++cellZ) { + int cellIdx = this.cloudGrid.getWrappedIdx(centerCellX + cellX, centerCellZ + cellZ); + byte renderFaces = this.cloudGrid.renderFaces[cellIdx]; + + float x = cellX * CELL_WIDTH; + float z = cellZ * CELL_WIDTH; + + if ((renderFaces & DIR_NEG_Y_BIT) != 0) { + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, upFaceColor); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, upFaceColor); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, upFaceColor); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, upFaceColor); + } + + } + } + } + + return bufferBuilder.build(); + } + + private static void putVertex(BufferBuilder bufferBuilder, float x, float y, float z, int color) { + bufferBuilder.addVertex(x, y, z).setColor(color); + } + + private static CloudGrid createCloudGrid(ResourceLocation textureLocation) { + ResourceManager resourceManager = Minecraft.getInstance().getResourceManager(); + + try { + Resource resource = resourceManager.getResourceOrThrow(textureLocation); + + try (var inputStream = resource.open()) { + NativeImage image = NativeImage.read(inputStream); + + int width = image.getWidth(); + int height = image.getHeight(); + Validate.isTrue(width == height, "Image width and height must be the same"); + + int[] pixels = image.getPixelsRGBA(); + + return new CloudGrid(pixels, width); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + static class CloudGrid { + final int width; + final int[] pixels; + final byte[] renderFaces; + + CloudGrid(int[] pixels, int width) { + this.pixels = pixels; + this.width = width; + + this.renderFaces = computeRenderFaces(); + } + + byte[] computeRenderFaces() { + byte[] renderFaces = new byte[pixels.length]; + + for (int z = 0; z < this.width; z++) { + for (int x = 0; x < this.width; x++) { + int idx = this.getIdx(x, z); + int pixel = this.pixels[idx]; + + if (!hasColor(pixel)) { + continue; + } + + byte faces = DIR_NEG_Y_BIT | DIR_POS_Y_BIT; + + int adjPixel; + + adjPixel = getTexelWrapped(x - 1, z); + if (pixel != adjPixel) { + faces |= DIR_NEG_X_BIT; + } + + adjPixel = getTexelWrapped(x + 1, z); + if (pixel != adjPixel) { + faces |= DIR_POS_X_BIT; + } + + adjPixel = getTexelWrapped(x, z - 1); + if (pixel != adjPixel) { + faces |= DIR_NEG_Z_BIT; + } + + adjPixel = getTexelWrapped(x, z + 1); + if (pixel != adjPixel) { + faces |= DIR_POS_Z_BIT; + } + + renderFaces[idx] = faces; + } + } + + return renderFaces; + } + + int getTexelWrapped(int x, int z) { + if (x < 0) { + x = this.width - 1; + } + + if (x > this.width - 1) { + x = 0; + } + + if (z < 0) { + z = this.width - 1; + } + + if (z > this.width - 1) { + z = 0; + } + + return this.pixels[getIdx(x, z)]; + } + + int getWrappedIdx(int x, int z) { + x = Math.floorMod(x, this.width); + z = Math.floorMod(z, this.width); + + return this.getIdx(x, z); + } + + int getIdx(int x, int z) { + return z * this.width + x; + } + + private static boolean hasColor(int pixel) { + return ((pixel >> 24) & 0xFF) > 1; + } + } +} diff --git a/src/main/java/net/vulkanmod/render/texture/ImageUploadHelper.java b/src/main/java/net/vulkanmod/render/texture/ImageUploadHelper.java new file mode 100644 index 000000000..9e5f80493 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/texture/ImageUploadHelper.java @@ -0,0 +1,41 @@ +package net.vulkanmod.render.texture; + +import net.vulkanmod.vulkan.Synchronization; +import net.vulkanmod.vulkan.device.DeviceManager; +import net.vulkanmod.vulkan.queue.CommandPool; +import net.vulkanmod.vulkan.queue.Queue; + +public class ImageUploadHelper { + + public static final ImageUploadHelper INSTANCE = new ImageUploadHelper(); + + final Queue queue; + private CommandPool.CommandBuffer currentCmdBuffer; + + public ImageUploadHelper() { + queue = DeviceManager.getGraphicsQueue(); + } + + public void submitCommands() { + if (this.currentCmdBuffer == null) { + return; + } + + long fence = queue.submitCommands(this.currentCmdBuffer); + Synchronization.INSTANCE.addCommandBuffer(this.currentCmdBuffer); + + this.currentCmdBuffer = null; + } + + public CommandPool.CommandBuffer getOrStartCommandBuffer() { + if (this.currentCmdBuffer == null) { + this.currentCmdBuffer = this.queue.beginCommands(); + } + + return this.currentCmdBuffer; + } + + public CommandPool.CommandBuffer getCommandBuffer() { + return this.currentCmdBuffer; + } +} diff --git a/src/main/java/net/vulkanmod/render/texture/SpriteUtil.java b/src/main/java/net/vulkanmod/render/texture/SpriteUpdateUtil.java similarity index 54% rename from src/main/java/net/vulkanmod/render/texture/SpriteUtil.java rename to src/main/java/net/vulkanmod/render/texture/SpriteUpdateUtil.java index 6b5df13ff..82f0ceab2 100644 --- a/src/main/java/net/vulkanmod/render/texture/SpriteUtil.java +++ b/src/main/java/net/vulkanmod/render/texture/SpriteUpdateUtil.java @@ -7,17 +7,16 @@ import java.util.HashSet; import java.util.Set; -public abstract class SpriteUtil { +public abstract class SpriteUpdateUtil { - private static boolean doUpload = false; - - private static Set transitionedLayouts = new HashSet<>(); + private static boolean doUpload = true; + private static final Set transitionedLayouts = new HashSet<>(); public static void setDoUpload(boolean b) { doUpload = b; } - public static boolean shouldUpload() { + public static boolean doUploadFrame() { return doUpload; } @@ -25,10 +24,15 @@ public static void addTransitionedLayout(VulkanImage image) { transitionedLayouts.add(image); } - public static void transitionLayouts(VkCommandBuffer commandBuffer) { - try(MemoryStack stack = MemoryStack.stackPush()) { - transitionedLayouts.forEach(image -> image.readOnlyLayout(stack, commandBuffer)); + public static void transitionLayouts() { + if (!doUpload || transitionedLayouts.isEmpty()) { + return; + } + VkCommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer().handle; + + try (MemoryStack stack = MemoryStack.stackPush()) { + transitionedLayouts.forEach(image -> image.readOnlyLayout(stack, commandBuffer)); transitionedLayouts.clear(); } } diff --git a/src/main/java/net/vulkanmod/render/util/MathUtil.java b/src/main/java/net/vulkanmod/render/util/MathUtil.java index 99f26cbcb..0d8e42fe8 100644 --- a/src/main/java/net/vulkanmod/render/util/MathUtil.java +++ b/src/main/java/net/vulkanmod/render/util/MathUtil.java @@ -1,5 +1,10 @@ package net.vulkanmod.render.util; +import net.vulkanmod.render.vertex.format.I32_SNorm; +import org.joml.Math; +import org.joml.Matrix3f; +import org.joml.Matrix4f; + public class MathUtil { public static float clamp(float min, float max, float x) { @@ -17,4 +22,46 @@ public static float saturate(float x) { public static float lerp(float v0, float v1, float t) { return v0 + t * (v1 - v0); } + + // JOML Math util + + public static float transformX(Matrix4f mat, float x, float y, float z) { + return Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30()))); + } + + public static float transformY(Matrix4f mat, float x, float y, float z) { + return Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31()))); + } + + public static float transformZ(Matrix4f mat, float x, float y, float z) { + return Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32()))); + } + + public static int packTransformedNorm(Matrix3f mat, boolean trustedNormals, float x, float y, float z) { + float nx = transformNormX(mat, x, y, z); + float ny = transformNormY(mat, x, y, z); + float nz = transformNormZ(mat, x, y, z); + + if (!trustedNormals) { + float scalar = Math.invsqrt(Math.fma(nx, nx, Math.fma(ny, ny, nz * nz))); + nx = nx * scalar; + ny = ny * scalar; + nz = nz * scalar; + } + + int packedNormal = I32_SNorm.packNormal(nx, ny, nz); + return packedNormal; + } + + public static float transformNormX(Matrix3f mat, float x, float y, float z) { + return Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, mat.m20() * z)); + } + + public static float transformNormY(Matrix3f mat, float x, float y, float z) { + return Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, mat.m21() * z)); + } + + public static float transformNormZ(Matrix3f mat, float x, float y, float z) { + return Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, mat.m22() * z)); + } } diff --git a/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java b/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java index 78e798735..e26bd0892 100644 --- a/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java +++ b/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java @@ -2,19 +2,18 @@ import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormatElement; +import net.vulkanmod.vulkan.Vulkan; public class CustomVertexFormat { public static final VertexFormatElement ELEMENT_POSITION = new VertexFormatElement(0, 0,VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.POSITION, 4); public static final VertexFormatElement ELEMENT_COLOR = new VertexFormatElement(1, 0, VertexFormatElement.Type.UBYTE, VertexFormatElement.Usage.COLOR, 4); - public static final VertexFormatElement ELEMENT_UV0 = new VertexFormatElement(2, 0, VertexFormatElement.Type.USHORT, VertexFormatElement.Usage.UV, 2); - public static final VertexFormatElement ELEMENT_UV2 = new VertexFormatElement(3, 2, VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.UV, 2); + public static final VertexFormatElement ELEMENT_UV0 = Vulkan.getDevice().isShaderFloat16Supported() ? new VertexFormatElement(2, 0, VertexFormatElement.Type.USHORT, VertexFormatElement.Usage.UV, 2) : new VertexFormatElement(2, 0, VertexFormatElement.Type.UINT, VertexFormatElement.Usage.UV, 1); public static final VertexFormat COMPRESSED_TERRAIN = VertexFormat.builder() .add("Position", ELEMENT_POSITION) .add("Color", ELEMENT_COLOR) .add("UV0", ELEMENT_UV0) - .add("UV2", ELEMENT_UV2) .build(); public static final VertexFormat NONE = VertexFormat.builder().build(); diff --git a/src/main/java/net/vulkanmod/render/vertex/QuadSorter.java b/src/main/java/net/vulkanmod/render/vertex/QuadSorter.java index fa6dd03da..91c26a129 100644 --- a/src/main/java/net/vulkanmod/render/vertex/QuadSorter.java +++ b/src/main/java/net/vulkanmod/render/vertex/QuadSorter.java @@ -15,6 +15,10 @@ public class QuadSorter { private VertexFormat format; private int vertexCount; + private int indexCount; + + private float[] distances; + private int[] sortingPointsIndices; public void setQuadSortOrigin(float x, float y, float z) { this.sortX = x; @@ -23,12 +27,14 @@ public void setQuadSortOrigin(float x, float y, float z) { } public SortState getSortState() { - return new SortState(this.vertexCount, this.sortingPoints); + return new SortState(this.vertexCount, this.sortingPoints, this.distances, this.sortingPointsIndices); } public void restoreSortState(QuadSorter.SortState sortState) { this.vertexCount = sortState.vertexCount; this.sortingPoints = sortState.sortingPoints; + this.distances = sortState.distances; + this.sortingPointsIndices = sortState.sortingPointsIndices; this.indexOnly = true; } @@ -80,9 +86,43 @@ public void setupQuadSortingPoints(long bufferPtr, int vertexCount, VertexFormat } this.sortingPoints = sortingPoints; + this.distances = new float[pointCount]; + this.sortingPointsIndices = new int[pointCount]; } public void putSortedQuadIndices(TerrainBufferBuilder bufferBuilder, VertexFormat.IndexType indexType) { + float[] distances = this.distances; + int[] sortingPointsIndices = this.sortingPointsIndices; + + for (int i = 0; i < this.sortingPoints.length; sortingPointsIndices[i] = i++) { + float dx = this.sortingPoints[i].x() - this.sortX; + float dy = this.sortingPoints[i].y() - this.sortY; + float dz = this.sortingPoints[i].z() - this.sortZ; + distances[i] = dx * dx + dy * dy + dz * dz; + } + + SortUtil.mergeSort(sortingPointsIndices, distances); + + long ptr = bufferBuilder.getPtr(); + + final int size = indexType.bytes; + final int stride = 4; // 4 vertices in a quad + for (int i = 0; i < sortingPointsIndices.length; ++i) { + final int quadIndex = sortingPointsIndices[i]; + final int baseVertex = quadIndex * stride; + + MemoryUtil.memPutInt(ptr + (size * 0L), baseVertex + 0); + MemoryUtil.memPutInt(ptr + (size * 1L), baseVertex + 1); + MemoryUtil.memPutInt(ptr + (size * 2L), baseVertex + 2); + MemoryUtil.memPutInt(ptr + (size * 3L), baseVertex + 2); + MemoryUtil.memPutInt(ptr + (size * 4L), baseVertex + 3); + MemoryUtil.memPutInt(ptr + (size * 5L), baseVertex + 0); + + ptr += size * 6L; + } + } + + public void putSortedQuadIndices(TerrainBuilder bufferBuilder, VertexFormat.IndexType indexType) { float[] distances = new float[this.sortingPoints.length]; int[] sortingPoints = new int[this.sortingPoints.length]; @@ -95,7 +135,7 @@ public void putSortedQuadIndices(TerrainBufferBuilder bufferBuilder, VertexForma SortUtil.mergeSort(sortingPoints, distances); - long ptr = bufferBuilder.getPtr(); + long ptr = bufferBuilder.indexBufferPtr; final int size = indexType.bytes; final int stride = 4; // 4 vertices in a quad @@ -114,14 +154,29 @@ public void putSortedQuadIndices(TerrainBufferBuilder bufferBuilder, VertexForma } } + public void reset() { + this.vertexCount = 0; + } + + public int getVertexCount() { + return vertexCount; + } + + public int getIndexCount() { + return indexCount; + } + public static class SortState { final int vertexCount; final Vector3f[] sortingPoints; + final float[] distances; + final int[] sortingPointsIndices; - SortState(int vertexCount, Vector3f[] sortingPoints) { + SortState(int vertexCount, Vector3f[] sortingPoints, float[] distances, int[] sortingPointsIndices) { this.vertexCount = vertexCount; this.sortingPoints = sortingPoints; - + this.distances = distances; + this.sortingPointsIndices = sortingPointsIndices; } } } diff --git a/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java b/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java index ca116035e..9e8651dae 100644 --- a/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java @@ -1,51 +1,38 @@ package net.vulkanmod.render.vertex; -import com.mojang.blaze3d.vertex.VertexFormat; -import net.minecraft.world.level.block.state.BlockState; +import com.mojang.blaze3d.vertex.VertexConsumer; import net.vulkanmod.Initializer; -import net.vulkanmod.render.PipelineManager; -import net.vulkanmod.render.util.SortUtil; +import net.vulkanmod.render.vertex.format.I32_SNorm; import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.Nullable; -import org.joml.Vector3f; import org.lwjgl.system.MemoryUtil; import java.nio.ByteBuffer; -public class TerrainBufferBuilder { +public class TerrainBufferBuilder implements VertexConsumer { private static final Logger LOGGER = Initializer.LOGGER; private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false); private int capacity; - protected long bufferPtr; - protected int nextElementByte; - private int vertexCount; - - private int renderedBufferCount; - private int renderedBufferPointer; + private int vertexSize; - private final VertexFormat format; - - private boolean building; + protected long bufferPtr; - private final QuadSorter quadSorter = new QuadSorter(); + protected int nextElementByte; + int vertices; - private boolean needsSorting; - private boolean indexOnly; + private long elementPtr; - protected VertexBuilder vertexBuilder; + private VertexBuilder vertexBuilder; - public TerrainBufferBuilder(int size) { + public TerrainBufferBuilder(int size, int vertexSize, VertexBuilder vertexBuilder) { this.bufferPtr = ALLOCATOR.malloc(size); this.capacity = size; - - this.format = PipelineManager.TERRAIN_VERTEX_FORMAT; - this.vertexBuilder = PipelineManager.TERRAIN_VERTEX_FORMAT == CustomVertexFormat.COMPRESSED_TERRAIN - ? new VertexBuilder.CompressedVertexBuilder() : new VertexBuilder.DefaultVertexBuilder(); + this.vertexSize = vertexSize; + this.vertexBuilder = vertexBuilder; } public void ensureCapacity() { - this.ensureCapacity(this.format.getVertexSize() * 4); + this.ensureCapacity(this.vertexSize * 4); } private void ensureCapacity(int size) { @@ -66,129 +53,9 @@ private void resize(int i) { } } - public void setupQuadSorting(float x, float y, float z) { - this.quadSorter.setQuadSortOrigin(x, y, z); - this.needsSorting = true; - } - - public QuadSorter.SortState getSortState() { - return this.quadSorter.getSortState(); - } - - public void restoreSortState(QuadSorter.SortState sortState) { - this.vertexCount = sortState.vertexCount; - this.nextElementByte = this.renderedBufferPointer; - - this.quadSorter.restoreSortState(sortState); - - this.indexOnly = true; - } - - public void setIndexOnly() { - this.indexOnly = true; - } - - public void begin() { - if (this.building) { - throw new IllegalStateException("Already building!"); - } else { - this.building = true; - } - } - - public void setupQuadSortingPoints() { - this.quadSorter.setupQuadSortingPoints(this.bufferPtr + this.renderedBufferPointer, this.vertexCount, this.format); - } - - public boolean isCurrentBatchEmpty() { - return this.vertexCount == 0; - } - - @Nullable - public RenderedBuffer end() { - this.ensureDrawing(); - if (this.isCurrentBatchEmpty()) { - this.reset(); - return null; - } else { - RenderedBuffer renderedBuffer = this.storeRenderedBuffer(); - this.reset(); - return renderedBuffer; - } - } - - private void ensureDrawing() { - if (!this.building) { - throw new IllegalStateException("Not building!"); - } - } - - private RenderedBuffer storeRenderedBuffer() { - int indexCount = this.vertexCount / 4 * 6; - int vertexBufferSize = !this.indexOnly ? this.vertexCount * this.format.getVertexSize() : 0; - VertexFormat.IndexType indexType = VertexFormat.IndexType.least(indexCount); - - boolean sequentialIndexing; - int size; - - if (this.needsSorting) { - int indexBufferSize = indexCount * indexType.bytes; - this.ensureCapacity(indexBufferSize); - - this.quadSorter.putSortedQuadIndices(this, indexType); - - sequentialIndexing = false; - this.nextElementByte += indexBufferSize; - size = vertexBufferSize + indexBufferSize; - } else { - sequentialIndexing = true; - size = vertexBufferSize; - } - - int ptr = this.renderedBufferPointer; - this.renderedBufferPointer += size; - ++this.renderedBufferCount; - - DrawState drawState = new DrawState(this.format.getVertexSize(), this.vertexCount, indexCount, indexType, this.indexOnly, sequentialIndexing); - return new RenderedBuffer(ptr, drawState); - } - - public void reset() { - this.building = false; - this.vertexCount = 0; - - this.indexOnly = false; - this.needsSorting = false; - } - - void releaseRenderedBuffer() { - if (this.renderedBufferCount > 0 && --this.renderedBufferCount == 0) { - this.clear(); - } - - } - - public void clear() { - if (this.renderedBufferCount > 0) { - LOGGER.warn("Clearing BufferBuilder with unused batches"); - } - - this.discard(); - } - - public void discard() { - this.renderedBufferCount = 0; - this.renderedBufferPointer = 0; - this.nextElementByte = 0; - } - - public boolean building() { - return this.building; - } - public void endVertex() { - this.nextElementByte += this.vertexBuilder.getStride(); - ++this.vertexCount; + this.nextElementByte += this.vertexSize; + ++this.vertices; } public void vertex(float x, float y, float z, int color, float u, float v, int light, int packedNormal) { @@ -197,106 +64,78 @@ public void vertex(float x, float y, float z, int color, float u, float v, int l this.endVertex(); } - public void setBlockAttributes(BlockState blockState) { + public void end() { } - public long getPtr() { - return this.bufferPtr + this.nextElementByte; + public void clear() { + this.nextElementByte = 0; + this.vertices = 0; } - public int getVertexCount() { - return vertexCount; + public ByteBuffer getBuffer() { + return MemoryUtil.memByteBuffer(this.bufferPtr, this.vertices * this.vertexSize); } - public class RenderedBuffer { - private final int pointer; - private final DrawState drawState; - private boolean released; - - RenderedBuffer(int pointer, DrawState drawState) { - this.pointer = pointer; - this.drawState = drawState; - } - - public ByteBuffer vertexBuffer() { - int start = this.pointer + this.drawState.vertexBufferStart(); - int end = this.pointer + this.drawState.vertexBufferEnd(); - return MemoryUtil.memByteBuffer(TerrainBufferBuilder.this.bufferPtr + start, end - start); - } + public long getPtr() { + return bufferPtr; + } - public ByteBuffer indexBuffer() { - int start = this.pointer + this.drawState.indexBufferStart(); - int end = this.pointer + this.drawState.indexBufferEnd(); - return MemoryUtil.memByteBuffer(TerrainBufferBuilder.this.bufferPtr + start, end - start); - } + public int getVertices() { + return vertices; + } - public DrawState drawState() { - return this.drawState; - } + public int getNextElementByte() { + return nextElementByte; + } - public boolean isEmpty() { - return this.drawState.vertexCount == 0; - } + @Override + public VertexConsumer addVertex(float x, float y, float z) { + this.elementPtr = this.bufferPtr + this.nextElementByte; + this.endVertex(); - public void release() { - if (this.released) { - throw new IllegalStateException("Buffer has already been released!"); - } else { - TerrainBufferBuilder.this.releaseRenderedBuffer(); - this.released = true; - } - } - } + this.vertexBuilder.position(this.elementPtr, x, y, z); - public record DrawState(int vertexSize, int vertexCount, int indexCount, VertexFormat.IndexType indexType, - boolean indexOnly, boolean sequentialIndex) { + return this; + } - public int vertexBufferSize() { - return this.vertexCount * this.vertexSize; - } + @Override + public VertexConsumer setColor(int r, int g, int b, int a) { + int color = (a & 0xFF) << 24 | (b & 0xFF) << 16 | (g & 0xFF) << 8 | (r & 0xFF); - public int vertexBufferStart() { - return 0; - } + this.vertexBuilder.color(this.elementPtr, color); - public int vertexBufferEnd() { - return this.vertexBufferSize(); - } + return this; + } - public int indexBufferStart() { - return this.indexOnly ? 0 : this.vertexBufferEnd(); - } + @Override + public VertexConsumer setUv(float u, float v) { + this.vertexBuilder.uv(this.elementPtr, u, v); - public int indexBufferEnd() { - return this.indexBufferStart() + this.indexBufferSize(); - } + return this; + } - private int indexBufferSize() { - return this.sequentialIndex ? 0 : this.indexCount * this.indexType.bytes; - } + public VertexConsumer setLight(int i) { + this.vertexBuilder.light(this.elementPtr, i); - public int bufferSize() { - return this.indexBufferEnd(); - } + return this; + } - public int vertexCount() { - return this.vertexCount; - } + @Override + public VertexConsumer setNormal(float f, float g, float h) { + int packedNormal = I32_SNorm.packNormal(f, g, h); - public int indexCount() { - return this.indexCount; - } + this.vertexBuilder.normal(this.elementPtr, packedNormal); - public VertexFormat.IndexType indexType() { - return this.indexType; - } + return this; + } - public boolean indexOnly() { - return this.indexOnly; - } + @Override + public VertexConsumer setUv1(int i, int j) { + return this; + } - public boolean sequentialIndex() { - return this.sequentialIndex; - } - } + @Override + public VertexConsumer setUv2(int i, int j) { + return this; + } } diff --git a/src/main/java/net/vulkanmod/render/vertex/TerrainBuilder.java b/src/main/java/net/vulkanmod/render/vertex/TerrainBuilder.java new file mode 100644 index 000000000..f12c69a17 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainBuilder.java @@ -0,0 +1,190 @@ +package net.vulkanmod.render.vertex; + +import com.mojang.blaze3d.vertex.VertexFormat; +import net.minecraft.world.level.block.state.BlockState; +import net.vulkanmod.Initializer; +import net.vulkanmod.render.PipelineManager; +import net.vulkanmod.render.chunk.cull.QuadFacing; +import org.apache.logging.log4j.Logger; +import org.lwjgl.system.MemoryUtil; + +import java.nio.ByteBuffer; + +public class TerrainBuilder { + private static final Logger LOGGER = Initializer.LOGGER; + private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false); + + protected long indexBufferPtr; + + private int indexBufferCapacity; + protected long bufferPtr; + + private final VertexFormat format; + + private boolean building; + + private final QuadSorter quadSorter = new QuadSorter(); + + private boolean needsSorting; + private boolean indexOnly; + + protected VertexBuilder vertexBuilder; + + private final TerrainBufferBuilder[] bufferBuilders; + + public TerrainBuilder(int size) { + // TODO index buffer + this.indexBufferPtr = ALLOCATOR.malloc(size); + this.indexBufferCapacity = size; + + this.format = PipelineManager.terrainVertexFormat; + this.vertexBuilder = PipelineManager.terrainVertexFormat == CustomVertexFormat.COMPRESSED_TERRAIN + ? new VertexBuilder.CompressedVertexBuilder() : new VertexBuilder.DefaultVertexBuilder(); + + var bufferBuilders = new TerrainBufferBuilder[QuadFacing.COUNT]; + for (int i = 0; i < QuadFacing.COUNT; i++) { + bufferBuilders[i] = new TerrainBufferBuilder(size, this.format.getVertexSize(), this.vertexBuilder); + } + + this.bufferBuilders = bufferBuilders; + } + + public TerrainBufferBuilder getBufferBuilder(int i) { + return this.bufferBuilders[i]; + } + + private void ensureIndexCapacity(int size) { + if (size > this.indexBufferCapacity) { + int capacity = this.indexBufferCapacity; + int newSize = (capacity + size) * 2; + this.resizeIndexBuffer(newSize); + } + } + + private void resizeIndexBuffer(int i) { + this.bufferPtr = ALLOCATOR.realloc(this.bufferPtr, i); + LOGGER.debug("Needed to grow index buffer: Old size {} bytes, new size {} bytes.", this.indexBufferCapacity, i); + if (this.bufferPtr == 0L) { + throw new OutOfMemoryError("Failed to resize buffer from " + this.indexBufferCapacity + " bytes to " + i + " bytes"); + } else { + this.indexBufferCapacity = i; + } + } + + public void setupQuadSorting(float x, float y, float z) { + this.quadSorter.setQuadSortOrigin(x, y, z); + this.needsSorting = true; + } + + public QuadSorter.SortState getSortState() { + return this.quadSorter.getSortState(); + } + + public void restoreSortState(QuadSorter.SortState sortState) { + this.quadSorter.restoreSortState(sortState); + + this.indexOnly = true; + } + + public void setIndexOnly() { + this.indexOnly = true; + } + + public void begin() { + if (this.building) { + throw new IllegalStateException("Already building!"); + } else { + this.building = true; + } + } + + public void setupQuadSortingPoints() { + TerrainBufferBuilder bufferBuilder = bufferBuilders[QuadFacing.UNDEFINED.ordinal()]; + long bufferPtr = bufferBuilder.getPtr(); + int vertexCount = bufferBuilder.getVertices(); + + this.quadSorter.setupQuadSortingPoints(bufferPtr, vertexCount, this.format); + } + + public DrawState endDrawing() { + for (TerrainBufferBuilder bufferBuilder : this.bufferBuilders) { + bufferBuilder.end(); + } + + int vertexCount = this.quadSorter.getVertexCount(); + + int indexCount = vertexCount / 4 * 6; + + VertexFormat.IndexType indexType = VertexFormat.IndexType.least(indexCount); + boolean sequentialIndexing; + + // TODO sorting + if (this.needsSorting) { + int indexBufferSize = indexCount * indexType.bytes; + this.ensureIndexCapacity(indexBufferSize); + + this.quadSorter.putSortedQuadIndices(this, indexType); + + sequentialIndexing = false; + } else { + sequentialIndexing = true; + } + + return new DrawState(this.format.getVertexSize(), indexCount, indexType, this.indexOnly, sequentialIndexing); + } + + // TODO hardcoded index type size + public ByteBuffer getIndexBuffer() { + int indexCount = this.quadSorter.getVertexCount() * 6 / 4; + + return MemoryUtil.memByteBuffer(this.indexBufferPtr, indexCount * 2); + } + + private void ensureDrawing() { + if (!this.building) { + throw new IllegalStateException("Not building!"); + } + } + + public void reset() { + this.building = false; + + this.indexOnly = false; + this.needsSorting = false; + } + + public void clear() { + this.reset(); + + for (TerrainBufferBuilder bufferBuilder : this.bufferBuilders) { + bufferBuilder.clear(); + } + } + + public void setBlockAttributes(BlockState blockState) { + } + + public record DrawState(int vertexSize, int indexCount, VertexFormat.IndexType indexType, + boolean indexOnly, boolean sequentialIndex) { + + private int indexBufferSize() { + return this.sequentialIndex ? 0 : this.indexCount * this.indexType.bytes; + } + + public int indexCount() { + return this.indexCount; + } + + public VertexFormat.IndexType indexType() { + return this.indexType; + } + + public boolean indexOnly() { + return this.indexOnly; + } + + public boolean sequentialIndex() { + return this.sequentialIndex; + } + } +} diff --git a/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java b/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java index bd42c0752..2eb1a14d0 100644 --- a/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java @@ -1,10 +1,12 @@ package net.vulkanmod.render.vertex; import net.minecraft.client.renderer.RenderType; +import net.vulkanmod.Initializer; import net.vulkanmod.interfaces.ExtendedRenderType; import net.vulkanmod.vulkan.VRenderSystem; import java.util.EnumSet; +import java.util.function.Function; public enum TerrainRenderType { SOLID(0.0f), @@ -18,6 +20,8 @@ public enum TerrainRenderType { public static final EnumSet COMPACT_RENDER_TYPES = EnumSet.of(CUTOUT_MIPPED, TRANSLUCENT); public static final EnumSet SEMI_COMPACT_RENDER_TYPES = EnumSet.of(CUTOUT_MIPPED, CUTOUT, TRANSLUCENT); + private static Function remapper; + static { SEMI_COMPACT_RENDER_TYPES.add(CUTOUT); SEMI_COMPACT_RENDER_TYPES.add(CUTOUT_MIPPED); @@ -61,4 +65,23 @@ public static RenderType getRenderType(TerrainRenderType renderType) { case TRIPWIRE -> RenderType.tripwire(); }; } + + public static void updateMapping() { + if (Initializer.CONFIG.uniqueOpaqueLayer) { + remapper = (renderType) -> switch (renderType) { + case SOLID, CUTOUT, CUTOUT_MIPPED -> TerrainRenderType.CUTOUT_MIPPED; + case TRANSLUCENT, TRIPWIRE -> TerrainRenderType.TRANSLUCENT; + }; + } else { + remapper = (renderType) -> switch (renderType) { + case SOLID, CUTOUT_MIPPED -> TerrainRenderType.CUTOUT_MIPPED; + case CUTOUT -> TerrainRenderType.CUTOUT; + case TRANSLUCENT, TRIPWIRE -> TerrainRenderType.TRANSLUCENT; + }; + } + } + + public static TerrainRenderType getRemapped(TerrainRenderType renderType) { + return remapper.apply(renderType); + } } diff --git a/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java b/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java index 511845515..3deaf6dfd 100644 --- a/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java +++ b/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java @@ -5,6 +5,16 @@ public interface VertexBuilder { void vertex(long ptr, float x, float y, float z, int color, float u, float v, int light, int packedNormal); + void position(long ptr, float x, float y, float z); + + void color(long ptr, int color); + + void uv(long ptr, float u, float v); + + void light(long ptr, int light); + + void normal(long ptr, int normal); + int getStride(); class DefaultVertexBuilder implements VertexBuilder { @@ -26,6 +36,32 @@ public void vertex(long ptr, float x, float y, float z, int color, float u, floa MemoryUtil.memPutInt(ptr + 28, packedNormal); } + // TODO + @Override + public void position(long ptr, float x, float y, float z) { + + } + + @Override + public void color(long ptr, int color) { + + } + + @Override + public void uv(long ptr, float u, float v) { + + } + + @Override + public void light(long ptr, int light) { + + } + + @Override + public void normal(long ptr, int normal) { + + } + @Override public int getStride() { return VERTEX_SIZE; @@ -33,13 +69,13 @@ public int getStride() { } class CompressedVertexBuilder implements VertexBuilder { - private static final int VERTEX_SIZE = 20; + private static final int VERTEX_SIZE = 16; public static final float POS_CONV_MUL = 2048.0f; public static final float POS_OFFSET = -4.0f; public static final float POS_OFFSET_CONV = POS_OFFSET * POS_CONV_MUL; - public static final float UV_CONV_MUL = 32768.0f; + public static final float UV_CONV_MUL = 65536.f; public void vertex(long ptr, float x, float y, float z, int color, float u, float v, int light, int packedNormal) { final short sX = (short) (x * POS_CONV_MUL + POS_OFFSET_CONV); @@ -59,6 +95,39 @@ public void vertex(long ptr, float x, float y, float z, int color, float u, floa MemoryUtil.memPutShort(ptr + 14, (short) (v * UV_CONV_MUL)); } + @Override + public void position(long ptr, float x, float y, float z) { + final short sX = (short) (x * POS_CONV_MUL + POS_OFFSET_CONV); + final short sY = (short) (y * POS_CONV_MUL + POS_OFFSET_CONV); + final short sZ = (short) (z * POS_CONV_MUL + POS_OFFSET_CONV); + + MemoryUtil.memPutShort(ptr + 0, sX); + MemoryUtil.memPutShort(ptr + 2, sY); + MemoryUtil.memPutShort(ptr + 4, sZ); + } + + @Override + public void color(long ptr, int color) { + MemoryUtil.memPutInt(ptr + 8, color); + } + + @Override + public void uv(long ptr, float u, float v) { + MemoryUtil.memPutShort(ptr + 12, (short) (u * UV_CONV_MUL)); + MemoryUtil.memPutShort(ptr + 14, (short) (v * UV_CONV_MUL)); + } + + @Override + public void light(long ptr, int light) { + final short l = (short) (((light >>> 8) & 0xFF00) | (light & 0xFF)); + MemoryUtil.memPutShort(ptr + 6, l); + } + + @Override + public void normal(long ptr, int normal) { + + } + @Override public int getStride() { return VERTEX_SIZE; diff --git a/src/main/java/net/vulkanmod/render/vertex/VertexUtil.java b/src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java similarity index 73% rename from src/main/java/net/vulkanmod/render/vertex/VertexUtil.java rename to src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java index 00777f51c..fb8366991 100644 --- a/src/main/java/net/vulkanmod/render/vertex/VertexUtil.java +++ b/src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java @@ -1,7 +1,6 @@ -package net.vulkanmod.render.vertex; - -public class VertexUtil { +package net.vulkanmod.render.vertex.format; +public abstract class I32_SNorm { private static final float NORM_INV = 1.0f / 127.0f; public static int packNormal(float x, float y, float z) { @@ -16,16 +15,15 @@ public static int packNormal(int x, int y, int z) { return (x & 0xFF) | (y & 0xFF) << 8| (z & 0xFF) << 16; } - public static float unpackN1(int i) { + public static float unpackX(int i) { return (byte)(i & 0xFF) * NORM_INV; } - public static float unpackN2(int i) { + public static float unpackY(int i) { return (byte)((i >> 8) & 0xFF) * NORM_INV; } - public static float unpackN3(int i) { + public static float unpackZ(int i) { return (byte)((i >> 16) & 0xFF) * NORM_INV; } - } diff --git a/src/main/java/net/vulkanmod/vulkan/Drawer.java b/src/main/java/net/vulkanmod/vulkan/Drawer.java index 40b88274b..1881c0974 100644 --- a/src/main/java/net/vulkanmod/vulkan/Drawer.java +++ b/src/main/java/net/vulkanmod/vulkan/Drawer.java @@ -2,6 +2,11 @@ import com.mojang.blaze3d.vertex.VertexFormat; import net.vulkanmod.vulkan.memory.*; +import net.vulkanmod.vulkan.memory.buffer.Buffer; +import net.vulkanmod.vulkan.memory.buffer.IndexBuffer; +import net.vulkanmod.vulkan.memory.buffer.UniformBuffer; +import net.vulkanmod.vulkan.memory.buffer.VertexBuffer; +import net.vulkanmod.vulkan.memory.buffer.index.AutoIndexBuffer; import net.vulkanmod.vulkan.util.VUtil; import org.lwjgl.system.MemoryUtil; import org.lwjgl.vulkan.VkCommandBuffer; @@ -13,7 +18,8 @@ import static org.lwjgl.vulkan.VK10.*; public class Drawer { - private static final int INITIAL_VB_SIZE = 2000000; + private static final int INITIAL_VB_SIZE = 4000000; + private static final int INITIAL_IB_SIZE = 1000000; private static final int INITIAL_UB_SIZE = 200000; private static final LongBuffer buffers = MemoryUtil.memAllocLong(1); @@ -23,19 +29,22 @@ public class Drawer { private int framesNum; private VertexBuffer[] vertexBuffers; + private IndexBuffer[] indexBuffers; + private final AutoIndexBuffer quadsIndexBuffer; private final AutoIndexBuffer quadsIntIndexBuffer; private final AutoIndexBuffer linesIndexBuffer; private final AutoIndexBuffer debugLineStripIndexBuffer; private final AutoIndexBuffer triangleFanIndexBuffer; private final AutoIndexBuffer triangleStripIndexBuffer; + private UniformBuffer[] uniformBuffers; private int currentFrame; public Drawer() { // Index buffers - this.quadsIndexBuffer = new AutoIndexBuffer(AutoIndexBuffer.QUAD_U16_MAX_VERTEX_COUNT, AutoIndexBuffer.DrawType.QUADS); + this.quadsIndexBuffer = new AutoIndexBuffer(AutoIndexBuffer.U16_MAX_VERTEX_COUNT, AutoIndexBuffer.DrawType.QUADS); this.quadsIntIndexBuffer = new AutoIndexBuffer(100000, AutoIndexBuffer.DrawType.QUADS); this.linesIndexBuffer = new AutoIndexBuffer(10000, AutoIndexBuffer.DrawType.LINES); this.debugLineStripIndexBuffer = new AutoIndexBuffer(10000, AutoIndexBuffer.DrawType.DEBUG_LINE_STRIP); @@ -52,15 +61,23 @@ public void createResources(int framesNum) { if (this.vertexBuffers != null) { Arrays.stream(this.vertexBuffers).iterator().forEachRemaining( - Buffer::freeBuffer + Buffer::scheduleFree ); } this.vertexBuffers = new VertexBuffer[framesNum]; Arrays.setAll(this.vertexBuffers, i -> new VertexBuffer(INITIAL_VB_SIZE, MemoryTypes.HOST_MEM)); + if (this.indexBuffers != null) { + Arrays.stream(this.indexBuffers).iterator().forEachRemaining( + Buffer::scheduleFree + ); + } + this.indexBuffers = new IndexBuffer[framesNum]; + Arrays.setAll(this.indexBuffers, i -> new IndexBuffer(INITIAL_IB_SIZE, MemoryTypes.HOST_MEM)); + if (this.uniformBuffers != null) { Arrays.stream(this.uniformBuffers).iterator().forEachRemaining( - Buffer::freeBuffer + Buffer::scheduleFree ); } this.uniformBuffers = new UniformBuffer[framesNum]; @@ -69,54 +86,39 @@ public void createResources(int framesNum) { public void resetBuffers(int currentFrame) { this.vertexBuffers[currentFrame].reset(); + this.indexBuffers[currentFrame].reset(); this.uniformBuffers[currentFrame].reset(); } - public void draw(ByteBuffer buffer, VertexFormat.Mode mode, VertexFormat vertexFormat, int vertexCount) { - AutoIndexBuffer autoIndexBuffer; - int indexCount; + public void draw(ByteBuffer vertexData, VertexFormat.Mode mode, VertexFormat vertexFormat, int vertexCount) { + draw(vertexData, null, mode, vertexFormat, vertexCount); + } + public void draw(ByteBuffer vertexData, ByteBuffer indexData, VertexFormat.Mode mode, VertexFormat vertexFormat, int vertexCount) { VertexBuffer vertexBuffer = this.vertexBuffers[this.currentFrame]; - vertexBuffer.copyToVertexBuffer(vertexFormat.getVertexSize(), vertexCount, buffer); + vertexBuffer.copyToVertexBuffer(vertexFormat.getVertexSize(), vertexCount, vertexData); - switch (mode) { - case QUADS -> { - indexCount = vertexCount * 3 / 2; + if (indexData != null) { + IndexBuffer indexBuffer = this.indexBuffers[this.currentFrame]; + indexBuffer.copyBuffer(indexData); - autoIndexBuffer = indexCount > AutoIndexBuffer.U16_MAX_INDEX_COUNT - ? this.quadsIntIndexBuffer : this.quadsIndexBuffer; - } - case LINES -> { - autoIndexBuffer = this.linesIndexBuffer; - indexCount = vertexCount * 3 / 2; - } - case TRIANGLE_FAN -> { - autoIndexBuffer = this.triangleFanIndexBuffer; - indexCount = (vertexCount - 2) * 3; - } - case TRIANGLE_STRIP, LINE_STRIP -> { - autoIndexBuffer = this.triangleStripIndexBuffer; - indexCount = (vertexCount - 2) * 3; - } - case DEBUG_LINE_STRIP -> { - autoIndexBuffer = this.debugLineStripIndexBuffer; - indexCount = (vertexCount - 1) * 2; - } - case TRIANGLES, DEBUG_LINES -> { - indexCount = 0; - autoIndexBuffer = null; - } - default -> throw new RuntimeException(String.format("unknown drawMode: %s", mode)); + int indexCount = vertexCount * 3 / 2; + + drawIndexed(vertexBuffer, indexBuffer, indexCount); } + else { + AutoIndexBuffer autoIndexBuffer = getAutoIndexBuffer(mode, vertexCount); - if (indexCount > 0) { - autoIndexBuffer.checkCapacity(vertexCount); + if (autoIndexBuffer != null) { + int indexCount = autoIndexBuffer.getIndexCount(vertexCount); + autoIndexBuffer.checkCapacity(indexCount); - drawIndexed(vertexBuffer, autoIndexBuffer.getIndexBuffer(), indexCount); - } else { - draw(vertexBuffer, vertexCount); + drawIndexed(vertexBuffer, autoIndexBuffer.getIndexBuffer(), indexCount); + } + else { + draw(vertexBuffer, vertexCount); + } } - } public void drawIndexed(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, int indexCount) { @@ -150,14 +152,18 @@ public void cleanUpResources() { buffer = this.vertexBuffers[i]; MemoryManager.freeBuffer(buffer.getId(), buffer.getAllocation()); - buffer = this.uniformBuffers[i]; + buffer = this.indexBuffers[i]; MemoryManager.freeBuffer(buffer.getId(), buffer.getAllocation()); + buffer = this.uniformBuffers[i]; + MemoryManager.freeBuffer(buffer.getId(), buffer.getAllocation()); } this.quadsIndexBuffer.freeBuffer(); + this.quadsIntIndexBuffer.freeBuffer(); this.linesIndexBuffer.freeBuffer(); this.triangleFanIndexBuffer.freeBuffer(); + this.triangleStripIndexBuffer.freeBuffer(); this.debugLineStripIndexBuffer.freeBuffer(); } @@ -185,4 +191,19 @@ public UniformBuffer getUniformBuffer() { return this.uniformBuffers[this.currentFrame]; } + private AutoIndexBuffer getAutoIndexBuffer(VertexFormat.Mode mode, int vertexCount) { + return switch (mode) { + case QUADS -> { + int indexCount = vertexCount * 3 / 2; + + yield indexCount > AutoIndexBuffer.U16_MAX_VERTEX_COUNT + ? this.quadsIntIndexBuffer : this.quadsIndexBuffer; + } + case LINES -> this.linesIndexBuffer; + case TRIANGLE_FAN -> this.triangleFanIndexBuffer; + case TRIANGLE_STRIP, LINE_STRIP -> this.triangleStripIndexBuffer; + case DEBUG_LINE_STRIP -> this.debugLineStripIndexBuffer; + case TRIANGLES, DEBUG_LINES -> null; + }; + } } diff --git a/src/main/java/net/vulkanmod/vulkan/Renderer.java b/src/main/java/net/vulkanmod/vulkan/Renderer.java index d06831374..fc21d3a8e 100644 --- a/src/main/java/net/vulkanmod/vulkan/Renderer.java +++ b/src/main/java/net/vulkanmod/vulkan/Renderer.java @@ -1,5 +1,6 @@ package net.vulkanmod.vulkan; +import com.mojang.blaze3d.platform.GlStateManager; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import net.minecraft.client.Minecraft; @@ -10,9 +11,11 @@ import net.vulkanmod.render.chunk.WorldRenderer; import net.vulkanmod.render.chunk.buffer.UploadManager; import net.vulkanmod.render.profiling.Profiler; +import net.vulkanmod.render.texture.ImageUploadHelper; import net.vulkanmod.vulkan.device.DeviceManager; import net.vulkanmod.vulkan.framebuffer.Framebuffer; import net.vulkanmod.vulkan.framebuffer.RenderPass; +import net.vulkanmod.vulkan.framebuffer.SwapChain; import net.vulkanmod.vulkan.memory.MemoryManager; import net.vulkanmod.vulkan.pass.DefaultMainPass; import net.vulkanmod.vulkan.pass.MainPass; @@ -79,8 +82,9 @@ public static int getCurrentImage() { private Drawer drawer; + private SwapChain swapChain; + private int framesNum; - private int imagesNum; private List commandBuffers; private ArrayList imageAvailableSemaphores; private ArrayList renderFinishedSemaphores; @@ -95,14 +99,13 @@ public static int getCurrentImage() { private VkCommandBuffer currentCmdBuffer; private boolean recordingCmds = false; - MainPass mainPass = DefaultMainPass.create(); + MainPass mainPass; private final List onResizeCallbacks = new ObjectArrayList<>(); public Renderer() { device = Vulkan.getVkDevice(); framesNum = Initializer.CONFIG.frameQueueSize; - imagesNum = getSwapChain().getImagesNum(); } public static void setLineWidth(float width) { @@ -116,6 +119,9 @@ private void init() { MemoryManager.createInstance(Renderer.getFramesNum()); Vulkan.createStagingBuffers(); + swapChain = new SwapChain(); + mainPass = DefaultMainPass.create(); + drawer = new Drawer(); drawer.createResources(framesNum); @@ -176,8 +182,8 @@ private void createSyncObjects() { for (int i = 0; i < framesNum; i++) { if (vkCreateSemaphore(device, semaphoreInfo, null, pImageAvailableSemaphore) != VK_SUCCESS - || vkCreateSemaphore(device, semaphoreInfo, null, pRenderFinishedSemaphore) != VK_SUCCESS - || vkCreateFence(device, fenceInfo, null, pFence) != VK_SUCCESS) { + || vkCreateSemaphore(device, semaphoreInfo, null, pRenderFinishedSemaphore) != VK_SUCCESS + || vkCreateFence(device, fenceInfo, null, pFence) != VK_SUCCESS) { throw new RuntimeException("Failed to create synchronization objects for the frame: " + i); } @@ -191,6 +197,25 @@ private void createSyncObjects() { } } + public void preInitFrame() { + Profiler p = Profiler.getMainProfiler(); + p.pop(); + p.round(); + p.push("Frame_ops"); + + // runTick might be called recursively, + // this check forces sync to avoid upload corruption + if (lastReset == currentFrame) { + waitFences(); + } + lastReset = currentFrame; + + drawer.resetBuffers(currentFrame); + + WorldRenderer.getInstance().uploadSections(); + UploadManager.INSTANCE.submitUploads(); + } + public void beginFrame() { Profiler p = Profiler.getMainProfiler(); p.pop(); @@ -230,8 +255,8 @@ public void beginFrame() { IntBuffer pImageIndex = stack.mallocInt(1); - int vkResult = vkAcquireNextImageKHR(device, Vulkan.getSwapChain().getId(), VUtil.UINT64_MAX, - imageAvailableSemaphores.get(currentFrame), VK_NULL_HANDLE, pImageIndex); + int vkResult = vkAcquireNextImageKHR(device, swapChain.getId(), VUtil.UINT64_MAX, + imageAvailableSemaphores.get(currentFrame), VK_NULL_HANDLE, pImageIndex); if (vkResult == VK_SUBOPTIMAL_KHR || vkResult == VK_ERROR_OUT_OF_DATE_KHR || swapChainUpdate) { swapChainUpdate = true; @@ -278,6 +303,8 @@ public void endFrame() { mainPass.end(currentCmdBuffer); + waitFences(); + submitFrame(); recordingCmds = false; @@ -298,15 +325,11 @@ private void submitFrame() { submitInfo.waitSemaphoreCount(1); submitInfo.pWaitSemaphores(stack.longs(imageAvailableSemaphores.get(currentFrame))); submitInfo.pWaitDstStageMask(stack.ints(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)); - submitInfo.pSignalSemaphores(stack.longs(renderFinishedSemaphores.get(currentFrame))); - submitInfo.pCommandBuffers(stack.pointers(currentCmdBuffer)); vkResetFences(device, inFlightFences.get(currentFrame)); - Synchronization.INSTANCE.waitFences(); - if ((vkResult = vkQueueSubmit(DeviceManager.getGraphicsQueue().queue(), submitInfo, inFlightFences.get(currentFrame))) != VK_SUCCESS) { vkResetFences(device, inFlightFences.get(currentFrame)); throw new RuntimeException("Failed to submit draw command buffer: %s".formatted(VkResult.decode(vkResult))); @@ -318,7 +341,7 @@ private void submitFrame() { presentInfo.pWaitSemaphores(stack.longs(renderFinishedSemaphores.get(currentFrame))); presentInfo.swapchainCount(1); - presentInfo.pSwapchains(stack.longs(Vulkan.getSwapChain().getId())); + presentInfo.pSwapchains(stack.longs(swapChain.getId())); presentInfo.pImageIndices(stack.ints(imageIndex)); @@ -336,7 +359,7 @@ private void submitFrame() { } /** - * Called in case draw results are needed before the of the frame + * Called in case draw results are needed before the of the frame */ public void flushCmds() { if (!this.recordingCmds) @@ -355,7 +378,7 @@ public void flushCmds() { vkResetFences(device, inFlightFences.get(currentFrame)); - Synchronization.INSTANCE.waitFences(); + waitFences(); if ((vkResult = vkQueueSubmit(DeviceManager.getGraphicsQueue().queue(), submitInfo, inFlightFences.get(currentFrame))) != VK_SUCCESS) { vkResetFences(device, inFlightFences.get(currentFrame)); @@ -373,7 +396,7 @@ public void endRenderPass() { } public void endRenderPass(VkCommandBuffer commandBuffer) { - if (skipRendering || this.boundFramebuffer == null) + if (skipRendering || !recordingCmds || this.boundFramebuffer == null) return; if (!DYNAMIC_RENDERING) @@ -403,27 +426,6 @@ public boolean beginRendering(RenderPass renderPass, Framebuffer framebuffer) { return true; } - public void preInitFrame() { - Profiler p = Profiler.getMainProfiler(); - p.pop(); - p.round(); - p.push("Frame_ops"); - - // runTick might be called recursively, - // this check forces sync to avoid upload corruption - if (lastReset == currentFrame) { - Synchronization.INSTANCE.waitFences(); - } - lastReset = currentFrame; - - drawer.resetBuffers(currentFrame); - - Vulkan.getStagingBuffer().reset(); - - WorldRenderer.getInstance().uploadSections(); - UploadManager.INSTANCE.submitUploads(); - } - public void addUsedPipeline(Pipeline pipeline) { usedPipelines.add(pipeline); } @@ -432,6 +434,13 @@ public void removeUsedPipeline(Pipeline pipeline) { usedPipelines.remove(pipeline); } + private void waitFences() { + // Make sure there are no uploads/transitions scheduled + ImageUploadHelper.INSTANCE.submitCommands(); + Synchronization.INSTANCE.waitFences(); + Vulkan.getStagingBuffer().reset(); + } + private void resetDescriptors() { for (Pipeline pipeline : usedPipelines) { pipeline.resetDescriptorPool(currentFrame); @@ -449,9 +458,9 @@ void waitForSwapChain() { try (MemoryStack stack = MemoryStack.stackPush()) { //Empty Submit VkSubmitInfo info = VkSubmitInfo.calloc(stack) - .sType$Default() - .pWaitSemaphores(stack.longs(imageAvailableSemaphores.get(currentFrame))) - .pWaitDstStageMask(stack.ints(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)); + .sType$Default() + .pWaitSemaphores(stack.longs(imageAvailableSemaphores.get(currentFrame))) + .pWaitDstStageMask(stack.ints(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)); vkQueueSubmit(DeviceManager.getGraphicsQueue().queue(), info, inFlightFences.get(currentFrame)); vkWaitForFences(device, inFlightFences.get(currentFrame), true, -1); @@ -460,23 +469,24 @@ void waitForSwapChain() { @SuppressWarnings("UnreachableCode") private void recreateSwapChain() { - Synchronization.INSTANCE.waitFences(); + waitFences(); Vulkan.waitIdle(); commandBuffers.forEach(commandBuffer -> vkResetCommandBuffer(commandBuffer, 0)); + recordingCmds = false; - Vulkan.getSwapChain().recreate(); + swapChain.recreate(); //Semaphores need to be recreated in order to make them unsignaled destroySyncObjects(); int newFramesNum = Initializer.CONFIG.frameQueueSize; - imagesNum = getSwapChain().getImagesNum(); if (framesNum != newFramesNum) { UploadManager.INSTANCE.submitUploads(); framesNum = newFramesNum; + MemoryManager.getInstance().freeAllBuffers(); MemoryManager.createInstance(newFramesNum); createStagingBuffers(); allocateCommandBuffers(); @@ -495,9 +505,12 @@ private void recreateSwapChain() { } public void cleanUpResources() { + WorldRenderer.getInstance().cleanUp(); destroySyncObjects(); drawer.cleanUpResources(); + mainPass.cleanUp(); + swapChain.cleanUp(); PipelineManager.destroyPipelines(); VTextureSelector.getWhiteTexture().free(); @@ -511,26 +524,6 @@ private void destroySyncObjects() { } } - public void setBoundFramebuffer(Framebuffer framebuffer) { - this.boundFramebuffer = framebuffer; - } - - public void setBoundRenderPass(RenderPass boundRenderPass) { - this.boundRenderPass = boundRenderPass; - } - - public RenderPass getBoundRenderPass() { - return boundRenderPass; - } - - public void setMainPass(MainPass mainPass) { - this.mainPass = mainPass; - } - - public MainPass getMainPass() { - return this.mainPass; - } - public void addOnResizeCallback(Runnable runnable) { this.onResizeCallbacks.add(runnable); } @@ -575,6 +568,30 @@ public Pipeline getBoundPipeline() { return boundPipeline; } + public void setBoundFramebuffer(Framebuffer framebuffer) { + this.boundFramebuffer = framebuffer; + } + + public void setBoundRenderPass(RenderPass boundRenderPass) { + this.boundRenderPass = boundRenderPass; + } + + public RenderPass getBoundRenderPass() { + return boundRenderPass; + } + + public void setMainPass(MainPass mainPass) { + this.mainPass = mainPass; + } + + public MainPass getMainPass() { + return this.mainPass; + } + + public SwapChain getSwapChain() { + return swapChain; + } + private static void resetDynamicState(VkCommandBuffer commandBuffer) { vkCmdSetDepthBias(commandBuffer, 0.0F, 0.0F, 0.0F); @@ -655,7 +672,18 @@ public static void clearAttachments(int v, int width, int height) { } public static void setInvertedViewport(int x, int y, int width, int height) { - setViewport(x, y + height, width, -height); + setViewportState(x, y + height, width, -height); + } + + public static void resetViewport() { + int width = INSTANCE.getSwapChain().getWidth(); + int height = INSTANCE.getSwapChain().getHeight(); + + setViewportState(0, 0, width, height); + } + + public static void setViewportState(int x, int y, int width, int height) { + GlStateManager._viewport(x, y, width, height); } public static void setViewport(int x, int y, int width, int height) { @@ -679,23 +707,6 @@ public static void setViewport(int x, int y, int width, int height, MemoryStack vkCmdSetViewport(INSTANCE.currentCmdBuffer, 0, viewport); } - public static void resetViewport() { - try (MemoryStack stack = stackPush()) { - int width = getSwapChain().getWidth(); - int height = getSwapChain().getHeight(); - - VkViewport.Buffer viewport = VkViewport.malloc(1, stack); - viewport.x(0.0f); - viewport.y(height); - viewport.width(width); - viewport.height(-height); - viewport.minDepth(0.0f); - viewport.maxDepth(1.0f); - - vkCmdSetViewport(INSTANCE.currentCmdBuffer, 0, viewport); - } - } - public static void setScissor(int x, int y, int width, int height) { if (INSTANCE.boundFramebuffer == null) return; diff --git a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java index 08bd5bdc6..7f647f9d5 100644 --- a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java +++ b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java @@ -3,7 +3,6 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; import net.vulkanmod.vulkan.device.DeviceManager; import net.vulkanmod.vulkan.shader.PipelineState; @@ -46,7 +45,7 @@ public abstract class VRenderSystem { public static MappedBuffer TextureMatrix = new MappedBuffer(16 * 4); public static MappedBuffer MVP = new MappedBuffer(16 * 4); - public static MappedBuffer ChunkOffset = new MappedBuffer(3 * 4); + public static MappedBuffer modelOffset = new MappedBuffer(3 * 4); public static MappedBuffer lightDirection0 = new MappedBuffer(3 * 4); public static MappedBuffer lightDirection1 = new MappedBuffer(3 * 4); @@ -79,8 +78,8 @@ public static void setWindow(long window) { VRenderSystem.window = window; } - public static ByteBuffer getChunkOffset() { - return ChunkOffset.buffer; + public static ByteBuffer getModelOffset() { + return modelOffset.buffer; } public static int maxSupportedTextureSize() { @@ -95,7 +94,6 @@ public static void applyMVP(Matrix4f MV, Matrix4f P) { public static void applyModelViewMatrix(Matrix4f mat) { mat.get(modelViewMatrix.buffer.asFloatBuffer()); - //MemoryUtil.memPutFloat(MemoryUtil.memAddress(modelViewMatrix), 1); } public static void applyProjectionMatrix(Matrix4f mat) { @@ -129,11 +127,11 @@ public static MappedBuffer getMVP() { return MVP; } - public static void setChunkOffset(float f1, float f2, float f3) { - long ptr = ChunkOffset.ptr; - VUtil.UNSAFE.putFloat(ptr, f1); - VUtil.UNSAFE.putFloat(ptr + 4, f2); - VUtil.UNSAFE.putFloat(ptr + 8, f3); + public static void setModelOffset(float x, float y, float z) { + long ptr = modelOffset.ptr; + VUtil.UNSAFE.putFloat(ptr, x); + VUtil.UNSAFE.putFloat(ptr + 4, y); + VUtil.UNSAFE.putFloat(ptr + 8, z); } public static void setShaderColor(float f1, float f2, float f3, float f4) { diff --git a/src/main/java/net/vulkanmod/vulkan/Vulkan.java b/src/main/java/net/vulkanmod/vulkan/Vulkan.java index 33c75fcea..9c99cc24d 100644 --- a/src/main/java/net/vulkanmod/vulkan/Vulkan.java +++ b/src/main/java/net/vulkanmod/vulkan/Vulkan.java @@ -3,13 +3,13 @@ import net.vulkanmod.vulkan.device.Device; import net.vulkanmod.vulkan.device.DeviceManager; import net.vulkanmod.vulkan.framebuffer.SwapChain; -import net.vulkanmod.vulkan.memory.Buffer; +import net.vulkanmod.vulkan.memory.buffer.Buffer; import net.vulkanmod.vulkan.memory.MemoryManager; import net.vulkanmod.vulkan.memory.MemoryTypes; -import net.vulkanmod.vulkan.memory.StagingBuffer; +import net.vulkanmod.vulkan.memory.buffer.StagingBuffer; import net.vulkanmod.vulkan.queue.Queue; import net.vulkanmod.vulkan.shader.Pipeline; -import net.vulkanmod.vulkan.util.VUtil; +import net.vulkanmod.vulkan.texture.SamplerManager; import net.vulkanmod.vulkan.util.VkResult; import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; @@ -125,8 +125,6 @@ public static long getAllocator() { private static long debugMessenger; private static long surface; - private static SwapChain swapChain; - private static long commandPool; private static VkCommandBuffer immediateCmdBuffer; private static long immediateFence; @@ -149,12 +147,9 @@ public static void initVulkan(long window) { MemoryTypes.createMemoryTypes(); createCommandPool(); - allocateImmediateCmdBuffer(); setupDepthFormat(); - createSwapChain(); Renderer.initRenderer(); - } static void createStagingBuffers() { @@ -165,7 +160,7 @@ static void createStagingBuffers() { stagingBuffers = new StagingBuffer[Renderer.getFramesNum()]; for (int i = 0; i < stagingBuffers.length; ++i) { - stagingBuffers[i] = new StagingBuffer(30 * 1024 * 1024); + stagingBuffers[i] = new StagingBuffer(); } } @@ -173,10 +168,6 @@ static void setupDepthFormat() { DEFAULT_DEPTH_FORMAT = DeviceManager.findDepthFormat(use24BitsDepthFormat); } - private static void createSwapChain() { - swapChain = new SwapChain(); - } - public static void waitIdle() { vkDeviceWaitIdle(DeviceManager.vkDevice); } @@ -189,7 +180,6 @@ public static void cleanUp() { Pipeline.destroyPipelineCache(); Renderer.getInstance().cleanUpResources(); - swapChain.cleanUp(); freeStagingBuffers(); @@ -201,6 +191,7 @@ public static void cleanUp() { vmaDestroyAllocator(allocator); + SamplerManager.cleanUp(); DeviceManager.destroy(); destroyDebugUtilsMessengerEXT(instance, debugMessenger, null); KHRSurface.vkDestroySurfaceKHR(instance, surface, null); @@ -208,7 +199,7 @@ public static void cleanUp() { } private static void freeStagingBuffers() { - Arrays.stream(stagingBuffers).forEach(Buffer::freeBuffer); + Arrays.stream(stagingBuffers).forEach(Buffer::scheduleFree); } private static void createInstance() { @@ -361,58 +352,6 @@ private static void createCommandPool() { } } - private static void allocateImmediateCmdBuffer() { - try (MemoryStack stack = stackPush()) { - - VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo.calloc(stack); - allocInfo.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO); - allocInfo.level(VK_COMMAND_BUFFER_LEVEL_PRIMARY); - allocInfo.commandPool(commandPool); - allocInfo.commandBufferCount(1); - - PointerBuffer pCommandBuffer = stack.mallocPointer(1); - vkAllocateCommandBuffers(DeviceManager.vkDevice, allocInfo, pCommandBuffer); - immediateCmdBuffer = new VkCommandBuffer(pCommandBuffer.get(0), DeviceManager.vkDevice); - - VkFenceCreateInfo fenceInfo = VkFenceCreateInfo.calloc(stack); - fenceInfo.sType(VK_STRUCTURE_TYPE_FENCE_CREATE_INFO); - fenceInfo.flags(VK_FENCE_CREATE_SIGNALED_BIT); - - LongBuffer pFence = stack.mallocLong(1); - vkCreateFence(DeviceManager.vkDevice, fenceInfo, null, pFence); - vkResetFences(DeviceManager.vkDevice, pFence.get(0)); - - immediateFence = pFence.get(0); - } - } - - public static VkCommandBuffer beginImmediateCmd() { - try (MemoryStack stack = stackPush()) { - VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.calloc(stack); - beginInfo.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO); - - vkBeginCommandBuffer(immediateCmdBuffer, beginInfo); - } - return immediateCmdBuffer; - } - - public static void endImmediateCmd() { - try (MemoryStack stack = stackPush()) { - vkEndCommandBuffer(immediateCmdBuffer); - - VkSubmitInfo submitInfo = VkSubmitInfo.calloc(stack); - submitInfo.sType(VK_STRUCTURE_TYPE_SUBMIT_INFO); - submitInfo.pCommandBuffers(stack.pointers(immediateCmdBuffer)); - - vkQueueSubmit(DeviceManager.getGraphicsQueue().queue(), submitInfo, immediateFence); - - vkWaitForFences(DeviceManager.vkDevice, immediateFence, true, VUtil.UINT64_MAX); - vkResetFences(DeviceManager.vkDevice, immediateFence); - vkResetCommandBuffer(immediateCmdBuffer, 0); - } - - } - private static PointerBuffer getRequiredInstanceExtensions() { PointerBuffer glfwExtensions = glfwGetRequiredInstanceExtensions(); @@ -440,6 +379,7 @@ public static void checkResult(int result, String errorMessage) { } public static void setVsync(boolean b) { + SwapChain swapChain = Renderer.getInstance().getSwapChain(); if (swapChain.isVsync() != b) { Renderer.scheduleSwapChainUpdate(); swapChain.setVsync(b); @@ -454,10 +394,6 @@ public static long getSurface() { return surface; } - public static SwapChain getSwapChain() { - return swapChain; - } - public static long getCommandPool() { return commandPool; } diff --git a/src/main/java/net/vulkanmod/vulkan/device/Device.java b/src/main/java/net/vulkanmod/vulkan/device/Device.java index da850d3b9..6ce71eae4 100644 --- a/src/main/java/net/vulkanmod/vulkan/device/Device.java +++ b/src/main/java/net/vulkanmod/vulkan/device/Device.java @@ -29,12 +29,11 @@ public class Device { public final String vkVersion; public final VkPhysicalDeviceFeatures2 availableFeatures; - public final VkPhysicalDeviceVulkan11Features availableFeatures11; // public final VkPhysicalDeviceVulkan13Features availableFeatures13; // public final boolean vulkan13Support; - private boolean drawIndirectSupported; + final private boolean drawIndirectSupported, shaderFloat16; public Device(VkPhysicalDevice device) { this.physicalDevice = device; @@ -42,30 +41,30 @@ public Device(VkPhysicalDevice device) { properties = VkPhysicalDeviceProperties.malloc(); vkGetPhysicalDeviceProperties(physicalDevice, properties); - this.vendorId = properties.vendorID(); - this.vendorIdString = decodeVendor(properties.vendorID()); - this.deviceName = properties.deviceNameString(); - this.driverVersion = decodeDvrVersion(properties.driverVersion(), properties.vendorID()); - this.vkVersion = decDefVersion(getVkVer()); + try (MemoryStack stack = MemoryStack.stackPush()) { + //Using memoryStack to avoid polluting the Off-heap with unused allocations + + this.vendorId = properties.vendorID(); + this.vendorIdString = decodeVendor(properties.vendorID()); + this.deviceName = properties.deviceNameString(); + this.driverVersion = decodeDvrVersion(properties.driverVersion(), properties.vendorID()); + this.vkVersion = decDefVersion(getVkVer()); - this.availableFeatures = VkPhysicalDeviceFeatures2.calloc(); - this.availableFeatures.sType$Default(); + this.availableFeatures = VkPhysicalDeviceFeatures2.calloc(stack); + this.availableFeatures.sType$Default(); - this.availableFeatures11 = VkPhysicalDeviceVulkan11Features.malloc(); - this.availableFeatures11.sType$Default(); - this.availableFeatures.pNext(this.availableFeatures11); + VkPhysicalDeviceVulkan11Features availableFeatures11 = VkPhysicalDeviceVulkan11Features.malloc(stack); + availableFeatures11.sType$Default(); - //Vulkan 1.3 -// this.availableFeatures13 = VkPhysicalDeviceVulkan13Features.malloc(); -// this.availableFeatures13.sType$Default(); -// this.availableFeatures11.pNext(this.availableFeatures13.address()); -// -// this.vulkan13Support = this.device.getCapabilities().apiVersion == VK_API_VERSION_1_3; + VkPhysicalDeviceVulkan12Features availableFeatures12 = VkPhysicalDeviceVulkan12Features.malloc(stack); + availableFeatures12.sType$Default(); + this.availableFeatures.pNext(availableFeatures11).pNext(availableFeatures12); - vkGetPhysicalDeviceFeatures2(this.physicalDevice, this.availableFeatures); + vkGetPhysicalDeviceFeatures2(this.physicalDevice, this.availableFeatures); - if (this.availableFeatures.features().multiDrawIndirect() && this.availableFeatures11.shaderDrawParameters()) - this.drawIndirectSupported = true; + this.drawIndirectSupported = this.availableFeatures.features().multiDrawIndirect() & availableFeatures11.shaderDrawParameters(); + this.shaderFloat16 = availableFeatures12.shaderFloat16(); + } } @@ -146,6 +145,10 @@ public boolean isDrawIndirectSupported() { return drawIndirectSupported; } + public boolean isShaderFloat16Supported() { + return shaderFloat16; + } + // Added these to allow detecting GPU vendor, to allow handling vendor specific circumstances: // (e.g. such as in case we encounter a vendor specific driver bug) public boolean isAMD() { diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java index b5eb00b10..8a2d5ad09 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java @@ -1,6 +1,5 @@ package net.vulkanmod.vulkan.framebuffer; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.Reference2LongArrayMap; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.Vulkan; @@ -34,9 +33,7 @@ public class Framebuffer { private VulkanImage colorAttachment; protected VulkanImage depthAttachment; - private final ObjectArrayList renderPasses = new ObjectArrayList<>(); - - private final Reference2LongArrayMap framebufferIds = new Reference2LongArrayMap<>(); + private final Reference2LongArrayMap renderpassToFramebufferMap = new Reference2LongArrayMap<>(); //SwapChain protected Framebuffer() {} @@ -59,10 +56,6 @@ public Framebuffer(Builder builder) { } } - public void addRenderPass(RenderPass renderPass) { - this.renderPasses.add(renderPass); - } - public void createImages() { if (this.hasColorAttachment) { this.colorAttachment = VulkanImage.builder(this.width, this.height) @@ -133,12 +126,12 @@ public void beginRenderPass(VkCommandBuffer commandBuffer, RenderPass renderPass Renderer.getInstance().setBoundRenderPass(renderPass); Renderer.getInstance().setBoundFramebuffer(this); - Renderer.setViewport(0, 0, this.width, this.height); + Renderer.setViewportState(0, 0, this.width, this.height); Renderer.setScissor(0, 0, this.width, this.height); } protected long getFramebufferId(RenderPass renderPass) { - return this.framebufferIds.computeIfAbsent(renderPass, renderPass1 -> createFramebuffer(renderPass)); + return this.renderpassToFramebufferMap.computeIfAbsent(renderPass, renderPass1 -> createFramebuffer(renderPass)); } public VkViewport.Buffer viewport(MemoryStack stack) { @@ -175,7 +168,7 @@ public void cleanUp(boolean cleanImages) { } final VkDevice device = Vulkan.getVkDevice(); - final var ids = framebufferIds.values().toLongArray(); + final var ids = renderpassToFramebufferMap.values().toLongArray(); MemoryManager.getInstance().addFrameOp( () -> Arrays.stream(ids).forEach(id -> @@ -183,7 +176,7 @@ public void cleanUp(boolean cleanImages) { ); - framebufferIds.clear(); + renderpassToFramebufferMap.clear(); } public long getDepthImageView() { diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java index 24cc8c031..589f00c21 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java @@ -34,8 +34,6 @@ public RenderPass(Framebuffer framebuffer, AttachmentInfo colorAttachmentInfo, A this.attachmentCount = count; if (!Vulkan.DYNAMIC_RENDERING) { - framebuffer.addRenderPass(this); - createRenderPass(); } diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java index 44b8bf7e5..9b68ec2d7 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java @@ -29,8 +29,6 @@ import static org.lwjgl.vulkan.VK10.*; public class SwapChain extends Framebuffer { - private static final int DEFAULT_IMAGE_COUNT = 3; - // Necessary until tearing-control-unstable-v1 is fully implemented on all GPU Drivers for Wayland // (As Immediate Mode (and by extension Screen tearing) doesn't exist on some Wayland installations currently) private static final int defUncappedMode = checkPresentMode(VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR); @@ -90,9 +88,10 @@ private void createSwapChain() { return; } - // minImageCount depends on driver: Mesa/RADV needs a min of 4, but most other drivers are at least 2 or 3 - // TODO using FIFO present mode with image num > 2 introduces (unnecessary) input lag - int requestedImages = Math.max(DEFAULT_IMAGE_COUNT, surfaceProperties.capabilities.minImageCount()); + int requestedImages = surfaceProperties.capabilities.minImageCount() + 1; + if (surfaceProperties.capabilities.maxImageCount() > 0 && requestedImages > surfaceProperties.capabilities.maxImageCount()) { + requestedImages = surfaceProperties.capabilities.maxImageCount(); + } IntBuffer imageCount = stack.ints(requestedImages); @@ -291,7 +290,7 @@ private int getPresentMode(IntBuffer availablePresentModes) { } } - Initializer.LOGGER.warn("Requested mode not supported: " + getDisplayModeString(requestedMode) + ": using VSync"); + Initializer.LOGGER.warn("Requested mode not supported: " + getDisplayModeString(requestedMode) + ": using FIFO present mode"); return VK_PRESENT_MODE_FIFO_KHR; } diff --git a/src/main/java/net/vulkanmod/vulkan/memory/Buffer.java b/src/main/java/net/vulkanmod/vulkan/memory/Buffer.java deleted file mode 100644 index b0a558f41..000000000 --- a/src/main/java/net/vulkanmod/vulkan/memory/Buffer.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.vulkanmod.vulkan.memory; - -import org.lwjgl.PointerBuffer; - -public abstract class Buffer { - protected long id; - protected long allocation; - - protected int bufferSize; - protected int usedBytes; - protected int offset; - - protected MemoryType type; - protected int usage; - protected PointerBuffer data; - - protected Buffer(int usage, MemoryType type) { - //TODO: check usage - this.usage = usage; - this.type = type; - - } - - protected void createBuffer(int bufferSize) { - this.type.createBuffer(this, bufferSize); - - if(this.type.mappable()) { - this.data = MemoryManager.getInstance().Map(this.allocation); - } - } - - public void freeBuffer() { - MemoryManager.getInstance().addToFreeable(this); - } - - public void reset() { usedBytes = 0; } - - public long getAllocation() { return allocation; } - - public long getUsedBytes() { return usedBytes; } - - public long getOffset() { return offset; } - - public long getId() { return id; } - - public int getBufferSize() { return bufferSize; } - - protected void setBufferSize(int size) { this.bufferSize = size; } - - protected void setId(long id) { this.id = id; } - - protected void setAllocation(long allocation) {this.allocation = allocation; } - - public BufferInfo getBufferInfo() { return new BufferInfo(this.id, this.allocation, this.bufferSize, this.type.getType()); } - - public record BufferInfo(long id, long allocation, long bufferSize, MemoryType.Type type) { - - } -} diff --git a/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java b/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java index a007bb189..9e9ea353a 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java @@ -6,6 +6,8 @@ import net.vulkanmod.render.chunk.buffer.AreaBuffer; import net.vulkanmod.vulkan.Vulkan; import net.vulkanmod.vulkan.device.DeviceManager; +import net.vulkanmod.vulkan.memory.buffer.Buffer; +import net.vulkanmod.vulkan.queue.Queue; import net.vulkanmod.vulkan.texture.VulkanImage; import net.vulkanmod.vulkan.util.Pair; import net.vulkanmod.vulkan.util.VkResult; @@ -43,11 +45,11 @@ public class MemoryManager { private int currentFrame = 0; - private ObjectArrayList[] freeableBuffers = new ObjectArrayList[Frames]; - private ObjectArrayList[] freeableImages = new ObjectArrayList[Frames]; + private final ObjectArrayList[] freeableBuffers = new ObjectArrayList[Frames]; + private final ObjectArrayList[] freeableImages = new ObjectArrayList[Frames]; - private ObjectArrayList[] frameOps = new ObjectArrayList[Frames]; - private ObjectArrayList>[] segmentsToFree = new ObjectArrayList[Frames]; + private final ObjectArrayList[] frameOps = new ObjectArrayList[Frames]; + private final ObjectArrayList>[] segmentsToFree = new ObjectArrayList[Frames]; //debug private ObjectArrayList[] stackTraces; @@ -82,6 +84,7 @@ public static void createInstance(int frames) { public synchronized void initFrame(int frame) { this.setCurrentFrame(frame); this.freeBuffers(frame); + this.freeImages(frame); this.doFrameOps(frame); this.freeSegments(frame); } @@ -94,6 +97,7 @@ public void setCurrentFrame(int frame) { public void freeAllBuffers() { for (int frame = 0; frame < Frames; ++frame) { this.freeBuffers(frame); + this.freeImages(frame); this.doFrameOps(frame); } @@ -124,11 +128,8 @@ public void createBuffer(long size, int usage, int properties, LongBuffer pBuffe } } - public synchronized void createBuffer(Buffer buffer, int size, int usage, int properties) { - + public synchronized void createBuffer(Buffer buffer, long size, int usage, int properties) { try (MemoryStack stack = stackPush()) { - buffer.setBufferSize(size); - LongBuffer pBuffer = stack.mallocLong(1); PointerBuffer pAllocation = stack.pointers(VK_NULL_HANDLE); @@ -136,10 +137,12 @@ public synchronized void createBuffer(Buffer buffer, int size, int usage, int pr buffer.setId(pBuffer.get(0)); buffer.setAllocation(pAllocation.get(0)); + buffer.setBufferSize(size); - if ((properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) > 0) { + if ((properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0) { deviceMemory += size; - } else { + } + else { nativeMemory += size; } @@ -147,11 +150,11 @@ public synchronized void createBuffer(Buffer buffer, int size, int usage, int pr } } - public static synchronized void createImage(int width, int height, int mipLevels, int format, int tiling, int usage, int memProperties, - LongBuffer pTextureImage, PointerBuffer pTextureImageMemory) { + public void createImage(int width, int height, int mipLevels, int format, int tiling, int usage, + int memProperties, + LongBuffer pTextureImage, PointerBuffer pTextureImageMemory) { try (MemoryStack stack = stackPush()) { - VkImageCreateInfo imageInfo = VkImageCreateInfo.calloc(stack); imageInfo.sType(VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); imageInfo.imageType(VK_IMAGE_TYPE_2D); @@ -166,19 +169,26 @@ public static synchronized void createImage(int width, int height, int mipLevels imageInfo.usage(usage); imageInfo.samples(VK_SAMPLE_COUNT_1_BIT); // imageInfo.sharingMode(VK_SHARING_MODE_CONCURRENT); - // TODO hardcoded queue family indices - imageInfo.pQueueFamilyIndices(stack.ints(0, 1)); + imageInfo.pQueueFamilyIndices( + stack.ints(Queue.getQueueFamilies().graphicsFamily, Queue.getQueueFamilies().computeFamily)); VmaAllocationCreateInfo allocationInfo = VmaAllocationCreateInfo.calloc(stack); allocationInfo.requiredFlags(memProperties); - vmaCreateImage(ALLOCATOR, imageInfo, allocationInfo, pTextureImage, pTextureImageMemory, null); + int result = vmaCreateImage(ALLOCATOR, imageInfo, allocationInfo, pTextureImage, pTextureImageMemory, null); + if (result != VK_SUCCESS) { + Initializer.LOGGER.info(String.format("Failed to create image with size: %dx%d", width, height)); + + throw new RuntimeException("Failed to create image: %s".formatted(VkResult.decode(result))); + } } } public static void addImage(VulkanImage image) { images.putIfAbsent(image.getId(), image); + + deviceMemory += image.size; } public static void MapAndCopy(long allocation, Consumer consumer) { @@ -210,17 +220,19 @@ private static void freeBuffer(Buffer.BufferInfo bufferInfo) { if (bufferInfo.type() == MemoryType.Type.DEVICE_LOCAL) { deviceMemory -= bufferInfo.bufferSize(); - } else { + } + else { nativeMemory -= bufferInfo.bufferSize(); } buffers.remove(bufferInfo.id()); } - public static void freeImage(long image, long allocation) { - vmaDestroyImage(ALLOCATOR, image, allocation); + public static void freeImage(long imageId, long allocation) { + vmaDestroyImage(ALLOCATOR, imageId, allocation); - images.remove(image); + VulkanImage image = images.remove(imageId); + deviceMemory -= image.size; } public synchronized void addToFreeable(Buffer buffer) { @@ -261,12 +273,10 @@ private void freeBuffers(int frame) { if (DEBUG) stackTraces[frame].clear(); - - this.freeImages(); } - private void freeImages() { - List bufferList = freeableImages[currentFrame]; + private void freeImages(int frame) { + List bufferList = freeableImages[frame]; for (VulkanImage image : bufferList) { image.doFree(); diff --git a/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java b/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java index 91380c0d6..3d20c94b2 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java @@ -1,5 +1,6 @@ package net.vulkanmod.vulkan.memory; +import net.vulkanmod.vulkan.memory.buffer.Buffer; import org.lwjgl.vulkan.VkMemoryHeap; import org.lwjgl.vulkan.VkMemoryType; @@ -16,13 +17,13 @@ public abstract class MemoryType { this.vkMemoryHeap = vkMemoryHeap; } - abstract void createBuffer(Buffer buffer, int size); + public abstract void createBuffer(Buffer buffer, long size); - abstract void copyToBuffer(Buffer buffer, long bufferSize, ByteBuffer byteBuffer); + public abstract void copyToBuffer(Buffer buffer, long bufferSize, ByteBuffer byteBuffer); - abstract void copyFromBuffer(Buffer buffer, long bufferSize, ByteBuffer byteBuffer); + public abstract void copyFromBuffer(Buffer buffer, long bufferSize, ByteBuffer byteBuffer); - abstract boolean mappable(); + public abstract boolean mappable(); public Type getType() { return this.type; diff --git a/src/main/java/net/vulkanmod/vulkan/memory/MemoryTypes.java b/src/main/java/net/vulkanmod/vulkan/memory/MemoryTypes.java index 300a813b5..020670220 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/MemoryTypes.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/MemoryTypes.java @@ -2,7 +2,10 @@ import net.vulkanmod.vulkan.Vulkan; import net.vulkanmod.vulkan.device.DeviceManager; +import net.vulkanmod.vulkan.memory.buffer.Buffer; +import net.vulkanmod.vulkan.memory.buffer.StagingBuffer; import net.vulkanmod.vulkan.util.VUtil; +import org.lwjgl.system.MemoryUtil; import org.lwjgl.vulkan.VkMemoryHeap; import org.lwjgl.vulkan.VkMemoryType; @@ -19,15 +22,14 @@ public static void createMemoryTypes() { for (int i = 0; i < DeviceManager.memoryProperties.memoryTypeCount(); ++i) { VkMemoryType memoryType = DeviceManager.memoryProperties.memoryTypes(i); VkMemoryHeap heap = DeviceManager.memoryProperties.memoryHeaps(memoryType.heapIndex()); + int propertyFlags = memoryType.propertyFlags(); - //GPU only Memory - if (memoryType.propertyFlags() == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { + if (propertyFlags == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { GPU_MEM = new DeviceLocalMemory(memoryType, heap); - } - if (memoryType.propertyFlags() == (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT)) { - HOST_MEM = new HostLocalCachedMemory(memoryType, heap); + if (propertyFlags == (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { + HOST_MEM = new HostCoherentMemory(memoryType, heap); } } @@ -63,35 +65,35 @@ public static class DeviceLocalMemory extends MemoryType { } @Override - void createBuffer(Buffer buffer, int size) { + public void createBuffer(Buffer buffer, long size) { MemoryManager.getInstance().createBuffer(buffer, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | buffer.usage, VK_MEMORY_HEAP_DEVICE_LOCAL_BIT); } @Override - void copyToBuffer(Buffer buffer, long bufferSize, ByteBuffer byteBuffer) { + public void copyToBuffer(Buffer buffer, long bufferSize, ByteBuffer byteBuffer) { StagingBuffer stagingBuffer = Vulkan.getStagingBuffer(); stagingBuffer.copyBuffer((int) bufferSize, byteBuffer); - DeviceManager.getTransferQueue().copyBufferCmd(stagingBuffer.id, stagingBuffer.offset, buffer.getId(), buffer.getUsedBytes(), bufferSize); + DeviceManager.getTransferQueue().copyBufferCmd(stagingBuffer.getId(), stagingBuffer.getOffset(), buffer.getId(), buffer.getUsedBytes(), bufferSize); } @Override - void copyFromBuffer(Buffer buffer, long bufferSize, ByteBuffer byteBuffer) { + public void copyFromBuffer(Buffer buffer, long bufferSize, ByteBuffer byteBuffer) { // TODO } public long copyBuffer(Buffer src, Buffer dst) { - if (dst.bufferSize < src.bufferSize) { + if (dst.getBufferSize() < src.getBufferSize()) { throw new IllegalArgumentException("dst size is less than src size."); } - return DeviceManager.getTransferQueue().copyBufferCmd(src.getId(), 0, dst.getId(), 0, src.bufferSize); + return DeviceManager.getTransferQueue().copyBufferCmd(src.getId(), 0, dst.getId(), 0, src.getBufferSize()); } @Override - boolean mappable() { + public boolean mappable() { return false; } } @@ -103,45 +105,35 @@ static abstract class MappableMemory extends MemoryType { } @Override - void copyToBuffer(Buffer buffer, long bufferSize, ByteBuffer byteBuffer) { - VUtil.memcpy(byteBuffer, buffer.data.getByteBuffer(0, (int) buffer.bufferSize), (int) bufferSize, buffer.getUsedBytes()); + public void copyToBuffer(Buffer buffer, long size, ByteBuffer byteBuffer) { + VUtil.memcpy(byteBuffer, buffer, size); } @Override - void copyFromBuffer(Buffer buffer, long bufferSize, ByteBuffer byteBuffer) { - VUtil.memcpy(buffer.data.getByteBuffer(0, (int) buffer.bufferSize), byteBuffer, 0); + public void copyFromBuffer(Buffer buffer, long size, ByteBuffer byteBuffer) { + MemoryUtil.memCopy(buffer.getDataPtr(), MemoryUtil.memAddress(byteBuffer), size); + VUtil.memcpy(buffer, byteBuffer, size); } @Override - boolean mappable() { + public boolean mappable() { return true; } } - static class HostLocalCachedMemory extends MappableMemory { + static class HostCoherentMemory extends MappableMemory { - HostLocalCachedMemory(VkMemoryType vkMemoryType, VkMemoryHeap vkMemoryHeap) { + HostCoherentMemory(VkMemoryType vkMemoryType, VkMemoryHeap vkMemoryHeap) { super(Type.HOST_LOCAL, vkMemoryType, vkMemoryHeap); } @Override - void createBuffer(Buffer buffer, int size) { - + public void createBuffer(Buffer buffer, long size) { MemoryManager.getInstance().createBuffer(buffer, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | buffer.usage, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT); - } - - void copyToBuffer(Buffer buffer, long dstOffset, long bufferSize, ByteBuffer byteBuffer) { - VUtil.memcpy(byteBuffer, buffer.data.getByteBuffer((int) 0, (int) buffer.bufferSize), (int) bufferSize, dstOffset); + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); } - void copyBuffer(Buffer src, Buffer dst) { - VUtil.memcpy(src.data.getByteBuffer(0, src.bufferSize), - dst.data.getByteBuffer(0, dst.bufferSize), src.bufferSize, 0); - -// copyBufferCmd(src.getId(), 0, dst.getId(), 0, src.bufferSize); - } } static class HostLocalFallbackMemory extends MappableMemory { @@ -151,7 +143,7 @@ static class HostLocalFallbackMemory extends MappableMemory { } @Override - void createBuffer(Buffer buffer, int size) { + public void createBuffer(Buffer buffer, long size) { MemoryManager.getInstance().createBuffer(buffer, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | buffer.usage, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); @@ -165,7 +157,7 @@ static class DeviceMappableMemory extends MappableMemory { } @Override - void createBuffer(Buffer buffer, int size) { + public void createBuffer(Buffer buffer, long size) { MemoryManager.getInstance().createBuffer(buffer, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | buffer.usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); diff --git a/src/main/java/net/vulkanmod/vulkan/memory/StagingBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/StagingBuffer.java deleted file mode 100644 index f90331087..000000000 --- a/src/main/java/net/vulkanmod/vulkan/memory/StagingBuffer.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.vulkanmod.vulkan.memory; - -import net.vulkanmod.render.chunk.util.Util; -import net.vulkanmod.vulkan.util.VUtil; -import org.lwjgl.system.MemoryUtil; - -import java.nio.ByteBuffer; - -import static org.lwjgl.system.libc.LibCString.nmemcpy; -import static org.lwjgl.vulkan.VK10.*; - -public class StagingBuffer extends Buffer { - - public StagingBuffer(int bufferSize) { - super(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, MemoryTypes.HOST_MEM); - this.usedBytes = 0; - this.offset = 0; - - this.createBuffer(bufferSize); - } - - public void copyBuffer(int size, ByteBuffer byteBuffer) { - - if(size > this.bufferSize - this.usedBytes) { - resizeBuffer((this.bufferSize + size) * 2); - } - -// VUtil.memcpy(byteBuffer, this.data.getByteBuffer(0, this.bufferSize), this.usedBytes); - nmemcpy(this.data.get(0) + this.usedBytes, MemoryUtil.memAddress(byteBuffer), size); - - offset = usedBytes; - usedBytes += size; - - //createVertexBuffer(vertexSize, vertexCount, byteBuffer); - } - - public void align(int alignment) { - int alignedValue = Util.align(usedBytes, alignment); - - if(alignedValue > this.bufferSize) { - resizeBuffer((this.bufferSize) * 2); - } - - usedBytes = alignedValue; - } - - private void resizeBuffer(int newSize) { - MemoryManager.getInstance().addToFreeable(this); - this.createBuffer(newSize); - - System.out.println("resized staging buffer to: " + newSize); - } -} diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java new file mode 100644 index 000000000..56e9b1341 --- /dev/null +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java @@ -0,0 +1,85 @@ +package net.vulkanmod.vulkan.memory.buffer; + +import net.vulkanmod.vulkan.memory.MemoryManager; +import net.vulkanmod.vulkan.memory.MemoryType; + +public abstract class Buffer { + public final MemoryType type; + public final int usage; + + protected long id; + protected long allocation; + + protected long bufferSize; + protected long usedBytes; + protected long offset; + + protected long dataPtr; + + protected Buffer(int usage, MemoryType type) { + //TODO: check usage + this.usage = usage; + this.type = type; + + } + + protected void createBuffer(long bufferSize) { + this.type.createBuffer(this, bufferSize); + + if (this.type.mappable()) { + this.dataPtr = MemoryManager.getInstance().Map(this.allocation).get(0); + } + } + + public void scheduleFree() { + MemoryManager.getInstance().addToFreeable(this); + } + + public void reset() { + usedBytes = 0; + } + + public long getAllocation() { + return allocation; + } + + public long getUsedBytes() { + return usedBytes; + } + + public long getOffset() { + return offset; + } + + public long getId() { + return id; + } + + public long getBufferSize() { + return bufferSize; + } + + public long getDataPtr() { + return dataPtr; + } + + public void setBufferSize(long size) { + this.bufferSize = size; + } + + public void setId(long id) { + this.id = id; + } + + public void setAllocation(long allocation) { + this.allocation = allocation; + } + + public BufferInfo getBufferInfo() { + return new BufferInfo(this.id, this.allocation, this.bufferSize, this.type.getType()); + } + + public record BufferInfo(long id, long allocation, long bufferSize, MemoryType.Type type) { + + } +} diff --git a/src/main/java/net/vulkanmod/vulkan/memory/IndexBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndexBuffer.java similarity index 50% rename from src/main/java/net/vulkanmod/vulkan/memory/IndexBuffer.java rename to src/main/java/net/vulkanmod/vulkan/memory/buffer/IndexBuffer.java index 311f71720..694740229 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/IndexBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndexBuffer.java @@ -1,4 +1,7 @@ -package net.vulkanmod.vulkan.memory; +package net.vulkanmod.vulkan.memory.buffer; + +import net.vulkanmod.vulkan.memory.MemoryManager; +import net.vulkanmod.vulkan.memory.MemoryType; import java.nio.ByteBuffer; @@ -9,7 +12,7 @@ public class IndexBuffer extends Buffer { public IndexType indexType; public IndexBuffer(int size, MemoryType type) { - this(size, type, IndexType.SHORT); + this(size, type, IndexType.UINT16); } public IndexBuffer(int size, MemoryType type, IndexType indexType) { @@ -19,22 +22,26 @@ public IndexBuffer(int size, MemoryType type, IndexType indexType) { this.createBuffer(size); } - public void copyBuffer(ByteBuffer buffer) { - int size = buffer.remaining(); + public void copyBuffer(ByteBuffer byteBuffer) { + int size = byteBuffer.remaining(); if(size > this.bufferSize - this.usedBytes) { - throw new RuntimeException("Trying to write buffer beyond max size."); - } - else { - this.type.copyToBuffer(this, size, buffer); - offset = usedBytes; - usedBytes += size; + resizeBuffer((this.bufferSize + size) * 2); } + + this.type.copyToBuffer(this, size, byteBuffer); + offset = usedBytes; + usedBytes += size; + } + + private void resizeBuffer(long newSize) { + MemoryManager.getInstance().addToFreeable(this); + this.createBuffer(newSize); } public enum IndexType { - SHORT(2, VK_INDEX_TYPE_UINT16), - INT(4, VK_INDEX_TYPE_UINT32); + UINT16(2, VK_INDEX_TYPE_UINT16), + UINT32(4, VK_INDEX_TYPE_UINT32); public final int size; public final int type; diff --git a/src/main/java/net/vulkanmod/vulkan/memory/IndirectBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java similarity index 89% rename from src/main/java/net/vulkanmod/vulkan/memory/IndirectBuffer.java rename to src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java index 811bddfb1..ddcbc31ed 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/IndirectBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java @@ -1,8 +1,10 @@ -package net.vulkanmod.vulkan.memory; +package net.vulkanmod.vulkan.memory.buffer; import net.vulkanmod.vulkan.Synchronization; import net.vulkanmod.vulkan.Vulkan; import net.vulkanmod.vulkan.device.DeviceManager; +import net.vulkanmod.vulkan.memory.MemoryManager; +import net.vulkanmod.vulkan.memory.MemoryType; import net.vulkanmod.vulkan.queue.CommandPool; import net.vulkanmod.vulkan.queue.TransferQueue; @@ -43,7 +45,7 @@ public void recordCopyCmd(ByteBuffer byteBuffer) { private void resizeBuffer() { MemoryManager.getInstance().addToFreeable(this); - int newSize = this.bufferSize + (this.bufferSize >> 1); + long newSize = this.bufferSize + (this.bufferSize >> 1); this.createBuffer(newSize); this.usedBytes = 0; } @@ -57,8 +59,4 @@ public void submitUploads() { commandBuffer = null; } - //debug - public ByteBuffer getByteBuffer() { - return this.data.getByteBuffer(0, this.bufferSize); - } } diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java new file mode 100644 index 000000000..d45835fff --- /dev/null +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java @@ -0,0 +1,64 @@ +package net.vulkanmod.vulkan.memory.buffer; + +import net.vulkanmod.render.chunk.buffer.UploadManager; +import net.vulkanmod.render.chunk.util.Util; +import net.vulkanmod.render.texture.ImageUploadHelper; +import net.vulkanmod.vulkan.Synchronization; +import net.vulkanmod.vulkan.memory.MemoryTypes; +import org.lwjgl.system.MemoryUtil; + +import java.nio.ByteBuffer; + +import static org.lwjgl.system.libc.LibCString.nmemcpy; +import static org.lwjgl.vulkan.VK10.*; + +public class StagingBuffer extends Buffer { + private static final long DEFAULT_SIZE = 64 * 1024 * 1024; + + public StagingBuffer() { + this(DEFAULT_SIZE); + } + + public StagingBuffer(long size) { + super(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, MemoryTypes.HOST_MEM); + this.usedBytes = 0; + this.offset = 0; + + this.createBuffer(size); + } + + public void copyBuffer(int size, ByteBuffer byteBuffer) { + if (size > this.bufferSize) { + throw new IllegalArgumentException("Upload size is greater than staging buffer size."); + } + + if (size > this.bufferSize - this.usedBytes) { + submitUploads(); + } + + nmemcpy(this.dataPtr + this.usedBytes, MemoryUtil.memAddress(byteBuffer), size); + + this.offset = this.usedBytes; + this.usedBytes += size; + } + + public void align(int alignment) { + long alignedOffset = Util.align(usedBytes, alignment); + + if (alignedOffset > this.bufferSize) { + submitUploads(); + alignedOffset = 0; + } + + this.usedBytes = alignedOffset; + } + + private void submitUploads() { + // Submit and wait all recorded uploads before resetting the buffer + UploadManager.INSTANCE.submitUploads(); + ImageUploadHelper.INSTANCE.submitCommands(); + Synchronization.INSTANCE.waitFences(); + + this.reset(); + } +} diff --git a/src/main/java/net/vulkanmod/vulkan/memory/UniformBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java similarity index 81% rename from src/main/java/net/vulkanmod/vulkan/memory/UniformBuffer.java rename to src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java index fd6f80fe3..5f056644a 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/UniformBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java @@ -1,6 +1,8 @@ -package net.vulkanmod.vulkan.memory; +package net.vulkanmod.vulkan.memory.buffer; import net.vulkanmod.vulkan.device.DeviceManager; +import net.vulkanmod.vulkan.memory.MemoryManager; +import net.vulkanmod.vulkan.memory.MemoryType; import static net.vulkanmod.vulkan.util.VUtil.align; import static org.lwjgl.vulkan.VK10.VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; @@ -28,12 +30,12 @@ public void updateOffset(int alignedSize) { usedBytes += alignedSize; } - private void resizeBuffer(int newSize) { + private void resizeBuffer(long newSize) { MemoryManager.getInstance().addToFreeable(this); createBuffer(newSize); } public long getPointer() { - return this.data.get(0) + usedBytes; + return this.dataPtr + usedBytes; } } diff --git a/src/main/java/net/vulkanmod/vulkan/memory/VertexBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/VertexBuffer.java similarity index 81% rename from src/main/java/net/vulkanmod/vulkan/memory/VertexBuffer.java rename to src/main/java/net/vulkanmod/vulkan/memory/buffer/VertexBuffer.java index 37f3ffc7f..7551696b2 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/VertexBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/VertexBuffer.java @@ -1,4 +1,8 @@ -package net.vulkanmod.vulkan.memory; +package net.vulkanmod.vulkan.memory.buffer; + +import net.vulkanmod.vulkan.memory.MemoryManager; +import net.vulkanmod.vulkan.memory.MemoryType; +import net.vulkanmod.vulkan.memory.MemoryTypes; import java.nio.ByteBuffer; @@ -30,7 +34,7 @@ public void copyToVertexBuffer(long vertexSize, long vertexCount, ByteBuffer byt } - private void resizeBuffer(int newSize) { + private void resizeBuffer(long newSize) { MemoryManager.getInstance().addToFreeable(this); this.createBuffer(newSize); diff --git a/src/main/java/net/vulkanmod/vulkan/memory/AutoIndexBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java similarity index 80% rename from src/main/java/net/vulkanmod/vulkan/memory/AutoIndexBuffer.java rename to src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java index 98795ff19..d5140bdce 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/AutoIndexBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java @@ -1,6 +1,8 @@ -package net.vulkanmod.vulkan.memory; +package net.vulkanmod.vulkan.memory.buffer.index; import net.vulkanmod.Initializer; +import net.vulkanmod.vulkan.memory.buffer.IndexBuffer; +import net.vulkanmod.vulkan.memory.MemoryTypes; import org.lwjgl.system.MemoryUtil; import java.nio.ByteBuffer; @@ -8,8 +10,8 @@ import java.nio.ShortBuffer; public class AutoIndexBuffer { - public static final int U16_MAX_INDEX_COUNT = 65536; - public static final int QUAD_U16_MAX_VERTEX_COUNT = U16_MAX_INDEX_COUNT * 3 / 2; + public static final int U16_MAX_VERTEX_COUNT = 65536; + public static final int QUAD_U16_MAX_INDEX_COUNT = U16_MAX_VERTEX_COUNT * 3 / 2; int vertexCount; DrawType drawType; @@ -25,14 +27,19 @@ private void createIndexBuffer(int vertexCount) { this.vertexCount = vertexCount; ByteBuffer buffer; - IndexBuffer.IndexType indexType = IndexBuffer.IndexType.SHORT; + IndexBuffer.IndexType indexType = IndexBuffer.IndexType.UINT16; + + if (vertexCount > U16_MAX_VERTEX_COUNT && + (this.drawType == DrawType.QUADS || this.drawType == DrawType.LINES)) + { + indexType = IndexBuffer.IndexType.UINT32; + } switch (this.drawType) { case QUADS -> { - if (vertexCount <= QUAD_U16_MAX_VERTEX_COUNT) + if (indexType == IndexBuffer.IndexType.UINT16) buffer = genQuadIndices(vertexCount); else { - indexType = IndexBuffer.IndexType.INT; buffer = genIntQuadIndices(vertexCount); } } @@ -55,11 +62,43 @@ public void checkCapacity(int vertexCount) { int newVertexCount = this.vertexCount * 2; Initializer.LOGGER.info("Reallocating AutoIndexBuffer from {} to {}", this.vertexCount, newVertexCount); - this.indexBuffer.freeBuffer(); + this.indexBuffer.scheduleFree(); createIndexBuffer(newVertexCount); } } + public IndexBuffer getIndexBuffer() { return this.indexBuffer; } + + public void freeBuffer() { + this.indexBuffer.scheduleFree(); + } + public int getIndexCount(int vertexCount) { + return getIndexCount(this.drawType, vertexCount); + } + + public static int getIndexCount(DrawType drawType, int vertexCount) { + switch (drawType) { + case QUADS, LINES -> { + return vertexCount * 3 / 2; + } + case TRIANGLE_FAN, TRIANGLE_STRIP -> { + return (vertexCount - 2) * 3; + } + case DEBUG_LINE_STRIP -> { + return (vertexCount - 1) * 2; + } + default -> throw new RuntimeException(String.format("unknown drawMode: %s", drawType)); + } + } + + public static int maxVertexCount(DrawType drawType, int maxIndexCount) { + return switch (drawType) { + case QUADS, LINES -> maxIndexCount * 3 / 2; + + default -> maxIndexCount; + }; + } + public static ByteBuffer genQuadIndices(int vertexCount) { int indexCount = vertexCount * 3 / 2; indexCount = roundUpToDivisible(indexCount, 6); @@ -182,12 +221,6 @@ public static int roundUpToDivisible(int n, int d) { return ((n + d - 1) / d) * d; } - public IndexBuffer getIndexBuffer() { return this.indexBuffer; } - - public void freeBuffer() { - this.indexBuffer.freeBuffer(); - } - public enum DrawType { QUADS(7), TRIANGLE_FAN(6), @@ -202,14 +235,6 @@ public enum DrawType { this.n = n; } - public static int getIndexCount(DrawType drawType, int vertexCount) { - return switch (drawType) { - case QUADS, LINES -> vertexCount * 3 / 2; - case TRIANGLE_FAN, TRIANGLE_STRIP -> (vertexCount - 2) * 3; - default -> 0; - }; - } - public static int getQuadIndexCount(int vertexCount) { return vertexCount * 3 / 2; } diff --git a/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java b/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java index 59b1c2afe..f6c2e07a4 100644 --- a/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java +++ b/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java @@ -31,7 +31,7 @@ public static DefaultMainPass create() { DefaultMainPass() { this.mainTarget = Minecraft.getInstance().getMainRenderTarget(); - this.mainFramebuffer = Vulkan.getSwapChain(); + this.mainFramebuffer = Renderer.getInstance().getSwapChain(); createRenderPasses(); } @@ -55,7 +55,7 @@ private void createRenderPasses() { @Override public void begin(VkCommandBuffer commandBuffer, MemoryStack stack) { - SwapChain framebuffer = Vulkan.getSwapChain(); + SwapChain framebuffer = Renderer.getInstance().getSwapChain(); VulkanImage colorAttachment = framebuffer.getColorAttachment(); colorAttachment.transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); @@ -74,7 +74,7 @@ public void end(VkCommandBuffer commandBuffer) { Renderer.getInstance().endRenderPass(commandBuffer); try(MemoryStack stack = MemoryStack.stackPush()) { - SwapChain framebuffer = Vulkan.getSwapChain(); + SwapChain framebuffer = Renderer.getInstance().getSwapChain(); framebuffer.getColorAttachment().transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); } @@ -84,8 +84,14 @@ public void end(VkCommandBuffer commandBuffer) { } } + @Override + public void cleanUp() { + this.mainRenderPass.cleanUp(); + this.auxRenderPass.cleanUp(); + } + public void rebindMainTarget() { - SwapChain swapChain = Vulkan.getSwapChain(); + SwapChain swapChain = Renderer.getInstance().getSwapChain(); VkCommandBuffer commandBuffer = Renderer.getCommandBuffer(); // Do not rebind if the framebuffer is already bound @@ -103,7 +109,7 @@ public void rebindMainTarget() { @Override public void bindAsTexture() { - SwapChain swapChain = Vulkan.getSwapChain(); + SwapChain swapChain = Renderer.getInstance().getSwapChain(); VkCommandBuffer commandBuffer = Renderer.getCommandBuffer(); // Check if render pass is using the framebuffer @@ -119,7 +125,7 @@ public void bindAsTexture() { } public int getColorAttachmentGlId() { - SwapChain swapChain = Vulkan.getSwapChain(); + SwapChain swapChain = Renderer.getInstance().getSwapChain(); return swapChain.getColorAttachmentGlId(); } } diff --git a/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java b/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java index d62476f0b..f84b52daf 100644 --- a/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java +++ b/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java @@ -11,6 +11,8 @@ public interface MainPass { void end(VkCommandBuffer commandBuffer); + void cleanUp(); + default void mainTargetBindWrite() {} default void mainTargetUnbindWrite() {} diff --git a/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java b/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java index eff323b7f..d6de2982e 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java @@ -23,13 +23,12 @@ public class CommandPool { this.createCommandPool(queueFamilyIndex); } - public void createCommandPool(int familyIndex) { - + public void createCommandPool(int queueFamily) { try (MemoryStack stack = stackPush()) { VkCommandPoolCreateInfo poolInfo = VkCommandPoolCreateInfo.calloc(stack); poolInfo.sType(VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO); - poolInfo.queueFamilyIndex(familyIndex); + poolInfo.queueFamilyIndex(queueFamily); poolInfo.flags(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); LongBuffer pCommandPool = stack.mallocLong(1); @@ -42,68 +41,45 @@ public void createCommandPool(int familyIndex) { } } - public CommandBuffer beginCommands() { - - try (MemoryStack stack = stackPush()) { - final int size = 10; - - if (availableCmdBuffers.isEmpty()) { - - VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo.calloc(stack); - allocInfo.sType$Default(); - allocInfo.level(VK_COMMAND_BUFFER_LEVEL_PRIMARY); - allocInfo.commandPool(id); - allocInfo.commandBufferCount(size); - - PointerBuffer pCommandBuffer = stack.mallocPointer(size); - vkAllocateCommandBuffers(Vulkan.getVkDevice(), allocInfo, pCommandBuffer); - - VkFenceCreateInfo fenceInfo = VkFenceCreateInfo.calloc(stack); - fenceInfo.sType$Default(); - fenceInfo.flags(VK_FENCE_CREATE_SIGNALED_BIT); - - for (int i = 0; i < size; ++i) { - LongBuffer pFence = stack.mallocLong(size); - vkCreateFence(Vulkan.getVkDevice(), fenceInfo, null, pFence); - - CommandBuffer commandBuffer = new CommandBuffer(new VkCommandBuffer(pCommandBuffer.get(i), Vulkan.getVkDevice()), pFence.get(0)); - commandBuffer.handle = new VkCommandBuffer(pCommandBuffer.get(i), Vulkan.getVkDevice()); - commandBuffers.add(commandBuffer); - availableCmdBuffers.add(commandBuffer); - } - - } - - CommandBuffer commandBuffer = availableCmdBuffers.poll(); - - VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.calloc(stack); - beginInfo.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO); - beginInfo.flags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - - vkBeginCommandBuffer(commandBuffer.handle, beginInfo); - -// current++; - - return commandBuffer; + public CommandBuffer getCommandBuffer(MemoryStack stack) { + if (availableCmdBuffers.isEmpty()) { + allocateCommandBuffers(stack); } + + CommandBuffer commandBuffer = availableCmdBuffers.poll(); + return commandBuffer; } - public long submitCommands(CommandBuffer commandBuffer, VkQueue queue) { + private void allocateCommandBuffers(MemoryStack stack) { + final int size = 10; - try (MemoryStack stack = stackPush()) { - long fence = commandBuffer.fence; + VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo.calloc(stack); + allocInfo.sType$Default(); + allocInfo.level(VK_COMMAND_BUFFER_LEVEL_PRIMARY); + allocInfo.commandPool(id); + allocInfo.commandBufferCount(size); - vkEndCommandBuffer(commandBuffer.handle); + PointerBuffer pCommandBuffer = stack.mallocPointer(size); + vkAllocateCommandBuffers(Vulkan.getVkDevice(), allocInfo, pCommandBuffer); - vkResetFences(Vulkan.getVkDevice(), commandBuffer.fence); + VkFenceCreateInfo fenceInfo = VkFenceCreateInfo.calloc(stack); + fenceInfo.sType$Default(); + fenceInfo.flags(VK_FENCE_CREATE_SIGNALED_BIT); - VkSubmitInfo submitInfo = VkSubmitInfo.calloc(stack); - submitInfo.sType(VK_STRUCTURE_TYPE_SUBMIT_INFO); - submitInfo.pCommandBuffers(stack.pointers(commandBuffer.handle)); + VkSemaphoreCreateInfo semaphoreCreateInfo = VkSemaphoreCreateInfo.calloc(stack); + semaphoreCreateInfo.sType$Default(); - vkQueueSubmit(queue, submitInfo, fence); + for (int i = 0; i < size; ++i) { + LongBuffer pFence = stack.mallocLong(1); + vkCreateFence(Vulkan.getVkDevice(), fenceInfo, null, pFence); - return fence; + LongBuffer pSemaphore = stack.mallocLong(1); + vkCreateSemaphore(Vulkan.getVkDevice(), semaphoreCreateInfo, null, pSemaphore); + + VkCommandBuffer vkCommandBuffer = new VkCommandBuffer(pCommandBuffer.get(i), Vulkan.getVkDevice()); + CommandBuffer commandBuffer = new CommandBuffer(this, vkCommandBuffer, pFence.get(0), pSemaphore.get(0)); + commandBuffers.add(commandBuffer); + availableCmdBuffers.add(commandBuffer); } } @@ -114,20 +90,30 @@ public void addToAvailable(CommandBuffer commandBuffer) { public void cleanUp() { for (CommandBuffer commandBuffer : commandBuffers) { vkDestroyFence(Vulkan.getVkDevice(), commandBuffer.fence, null); + vkDestroySemaphore(Vulkan.getVkDevice(), commandBuffer.semaphore, null); } vkResetCommandPool(Vulkan.getVkDevice(), id, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT); vkDestroyCommandPool(Vulkan.getVkDevice(), id, null); } - public class CommandBuffer { - VkCommandBuffer handle; - long fence; + public long getId() { + return id; + } + + public static class CommandBuffer { + public final CommandPool commandPool; + public final VkCommandBuffer handle; + public final long fence; + public final long semaphore; + boolean submitted; boolean recording; - public CommandBuffer(VkCommandBuffer handle, long fence) { + public CommandBuffer(CommandPool commandPool, VkCommandBuffer handle, long fence, long semaphore) { + this.commandPool = commandPool; this.handle = handle; this.fence = fence; + this.semaphore = semaphore; } public VkCommandBuffer getHandle() { @@ -146,10 +132,42 @@ public boolean isRecording() { return recording; } + public void begin(MemoryStack stack) { + VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.calloc(stack); + beginInfo.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO); + beginInfo.flags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + + vkBeginCommandBuffer(this.handle, beginInfo); + + this.recording = true; + } + + public long submitCommands(MemoryStack stack, VkQueue queue, boolean useSemaphore) { + long fence = this.fence; + + vkEndCommandBuffer(this.handle); + + vkResetFences(Vulkan.getVkDevice(), this.fence); + + VkSubmitInfo submitInfo = VkSubmitInfo.calloc(stack); + submitInfo.sType(VK_STRUCTURE_TYPE_SUBMIT_INFO); + submitInfo.pCommandBuffers(stack.pointers(this.handle)); + + if (useSemaphore) { + submitInfo.pSignalSemaphores(stack.longs(this.semaphore)); + } + + vkQueueSubmit(queue, submitInfo, fence); + + this.recording = false; + this.submitted = true; + return fence; + } + public void reset() { this.submitted = false; this.recording = false; - addToAvailable(this); + this.commandPool.addToAvailable(this); } } } diff --git a/src/main/java/net/vulkanmod/vulkan/queue/Queue.java b/src/main/java/net/vulkanmod/vulkan/queue/Queue.java index 4f68e0778..c2775d05e 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/Queue.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/Queue.java @@ -18,15 +18,20 @@ import static org.lwjgl.vulkan.VK10.*; public abstract class Queue { - private static VkDevice DEVICE; - + private static VkDevice device; private static QueueFamilyIndices queueFamilyIndices; - protected CommandPool commandPool; private final VkQueue queue; + protected CommandPool commandPool; + public synchronized CommandPool.CommandBuffer beginCommands() { - return this.commandPool.beginCommands(); + try (MemoryStack stack = stackPush()) { + CommandPool.CommandBuffer commandBuffer = this.commandPool.getCommandBuffer(stack); + commandBuffer.begin(stack); + + return commandBuffer; + } } Queue(MemoryStack stack, int familyIndex) { @@ -43,7 +48,9 @@ public synchronized CommandPool.CommandBuffer beginCommands() { } public synchronized long submitCommands(CommandPool.CommandBuffer commandBuffer) { - return this.commandPool.submitCommands(commandBuffer, queue); + try (MemoryStack stack = stackPush()) { + return commandBuffer.submitCommands(stack, queue, false); + } } public VkQueue queue() { @@ -59,6 +66,10 @@ public void waitIdle() { vkQueueWaitIdle(queue); } + public CommandPool getCommandPool() { + return commandPool; + } + public enum Family { Graphics, Transfer, @@ -66,17 +77,16 @@ public enum Family { } public static QueueFamilyIndices getQueueFamilies() { - if (DEVICE == null) - DEVICE = Vulkan.getVkDevice(); + if (device == null) + device = Vulkan.getVkDevice(); if (queueFamilyIndices == null) { - queueFamilyIndices = findQueueFamilies(DEVICE.getPhysicalDevice()); + queueFamilyIndices = findQueueFamilies(device.getPhysicalDevice()); } return queueFamilyIndices; } public static QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) { - QueueFamilyIndices indices = new QueueFamilyIndices(); try (MemoryStack stack = stackPush()) { diff --git a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java index 179ce47b3..109ec24bf 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java @@ -164,10 +164,15 @@ private long createGraphicsPipeline(PipelineState state) { VkPipelineDynamicStateCreateInfo dynamicStates = VkPipelineDynamicStateCreateInfo.calloc(stack); dynamicStates.sType(VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO); - if (topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST || polygonMode == VK_POLYGON_MODE_LINE) - dynamicStates.pDynamicStates(stack.ints(VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH)); - else - dynamicStates.pDynamicStates(stack.ints(VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR)); + if (topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST || polygonMode == VK_POLYGON_MODE_LINE) { + dynamicStates.pDynamicStates( + stack.ints(VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_LINE_WIDTH)); + } + else { + dynamicStates.pDynamicStates( + stack.ints(VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR)); + } VkGraphicsPipelineCreateInfo.Buffer pipelineInfo = VkGraphicsPipelineCreateInfo.calloc(1, stack); pipelineInfo.sType(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO); @@ -199,9 +204,8 @@ private long createGraphicsPipeline(PipelineState state) { LongBuffer pGraphicsPipeline = stack.mallocLong(1); - if (vkCreateGraphicsPipelines(DeviceManager.vkDevice, PIPELINE_CACHE, pipelineInfo, null, pGraphicsPipeline) != VK_SUCCESS) { - throw new RuntimeException("Failed to create graphics pipeline"); - } + Vulkan.checkResult(vkCreateGraphicsPipelines(DeviceManager.vkDevice, PIPELINE_CACHE, pipelineInfo, null, pGraphicsPipeline), + "Failed to create graphics pipeline " + this.name); return pGraphicsPipeline.get(0); } @@ -316,6 +320,12 @@ private static VkVertexInputAttributeDescription.Buffer getAttributeDescriptions offset += 8; } + case UINT -> { + posDescription.format(VK_FORMAT_R32_UINT); + posDescription.offset(offset); + + offset += 4; + } case SHORT -> { posDescription.format(VK_FORMAT_R16G16_SINT); posDescription.offset(offset); diff --git a/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java index f3f8bf326..49d146cf2 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java @@ -10,7 +10,7 @@ import net.vulkanmod.vulkan.device.DeviceManager; import net.vulkanmod.vulkan.framebuffer.RenderPass; import net.vulkanmod.vulkan.memory.MemoryManager; -import net.vulkanmod.vulkan.memory.UniformBuffer; +import net.vulkanmod.vulkan.memory.buffer.UniformBuffer; import net.vulkanmod.vulkan.shader.SPIRVUtils.SPIRV; import net.vulkanmod.vulkan.shader.SPIRVUtils.ShaderKind; import net.vulkanmod.vulkan.shader.descriptor.ImageDescriptor; @@ -18,26 +18,25 @@ import net.vulkanmod.vulkan.shader.descriptor.UBO; import net.vulkanmod.vulkan.shader.layout.AlignedStruct; import net.vulkanmod.vulkan.shader.layout.PushConstants; +import net.vulkanmod.vulkan.shader.layout.Uniform; import net.vulkanmod.vulkan.texture.VTextureSelector; import net.vulkanmod.vulkan.texture.VulkanImage; +import net.vulkanmod.vulkan.util.MappedBuffer; import org.apache.commons.lang3.Validate; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; import org.lwjgl.vulkan.*; -import java.io.InputStream; -import java.io.InputStreamReader; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.LongBuffer; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import java.util.function.Function; +import java.util.function.Supplier; -import static net.vulkanmod.vulkan.shader.SPIRVUtils.compileShader; -import static net.vulkanmod.vulkan.shader.SPIRVUtils.compileShaderAbsoluteFile; import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.vulkan.VK10.*; @@ -481,14 +480,6 @@ private void cleanUp() { } public static class Builder { - - public static GraphicsPipeline createGraphicsPipeline(VertexFormat format, String path) { - Pipeline.Builder pipelineBuilder = new Pipeline.Builder(format, path); - pipelineBuilder.parseBindingsJSON(); - pipelineBuilder.compileShaders(); - return pipelineBuilder.createGraphicsPipeline(); - } - final VertexFormat vertexFormat; final String shaderPath; List UBOs; @@ -502,6 +493,8 @@ public static GraphicsPipeline createGraphicsPipeline(VertexFormat format, Strin RenderPass renderPass; + Function> uniformSupplierGetter; + public Builder(VertexFormat vertexFormat, String path) { this.vertexFormat = vertexFormat; this.shaderPath = path; @@ -511,6 +504,10 @@ public Builder(VertexFormat vertexFormat) { this(vertexFormat, null); } + public Builder() { + this(null, null); + } + public GraphicsPipeline createGraphicsPipeline() { Validate.isTrue(this.imageDescriptors != null && this.UBOs != null && this.vertShaderSPIRV != null && this.fragShaderSPIRV != null, @@ -532,34 +529,23 @@ public void setSPIRVs(SPIRV vertShaderSPIRV, SPIRV fragShaderSPIRV) { this.fragShaderSPIRV = fragShaderSPIRV; } - public void compileShaders() { - String resourcePath = SPIRVUtils.class.getResource("/assets/vulkanmod/shaders/").toExternalForm(); - - this.vertShaderSPIRV = compileShaderAbsoluteFile(String.format("%s%s.vsh", resourcePath, this.shaderPath), ShaderKind.VERTEX_SHADER); - this.fragShaderSPIRV = compileShaderAbsoluteFile(String.format("%s%s.fsh", resourcePath, this.shaderPath), ShaderKind.FRAGMENT_SHADER); + public void compileShaders(String name, String vsh, String fsh) { + this.vertShaderSPIRV = SPIRVUtils.compileShader(String.format("%s.vsh", name), vsh, ShaderKind.VERTEX_SHADER); + this.fragShaderSPIRV = SPIRVUtils.compileShader(String.format("%s.fsh", name), fsh, ShaderKind.FRAGMENT_SHADER); } - public void compileShaders(String name, String vsh, String fsh) { - this.vertShaderSPIRV = compileShader(String.format("%s.vsh", name), vsh, ShaderKind.VERTEX_SHADER); - this.fragShaderSPIRV = compileShader(String.format("%s.fsh", name), fsh, ShaderKind.FRAGMENT_SHADER); + public void setVertShaderSPIRV(SPIRV vertShaderSPIRV) { + this.vertShaderSPIRV = vertShaderSPIRV; } - public void parseBindingsJSON() { - Validate.notNull(this.shaderPath, "Cannot parse bindings: shaderPath is null"); + public void setFragShaderSPIRV(SPIRV fragShaderSPIRV) { + this.fragShaderSPIRV = fragShaderSPIRV; + } + public void parseBindings(JsonObject jsonObject) { this.UBOs = new ArrayList<>(); this.imageDescriptors = new ArrayList<>(); - JsonObject jsonObject; - - String resourcePath = String.format("/assets/vulkanmod/shaders/%s.json", this.shaderPath); - InputStream stream = Pipeline.class.getResourceAsStream(resourcePath); - - if (stream == null) - throw new NullPointerException(String.format("Failed to load: %s", resourcePath)); - - jsonObject = GsonHelper.parse(new InputStreamReader(stream, StandardCharsets.UTF_8)); - JsonArray jsonUbos = GsonHelper.getAsJsonArray(jsonObject, "UBOs", null); JsonArray jsonManualUbos = GsonHelper.getAsJsonArray(jsonObject, "ManualUBOs", null); JsonArray jsonSamplers = GsonHelper.getAsJsonArray(jsonObject, "samplers", null); @@ -586,6 +572,10 @@ public void parseBindingsJSON() { } } + public void setUniformSupplierGetter(Function> uniformSupplierGetter) { + this.uniformSupplierGetter = uniformSupplierGetter; + } + private void parseUboNode(JsonElement jsonelement) { JsonObject jsonobject = GsonHelper.convertToJsonObject(jsonelement, "UBO"); int binding = GsonHelper.getAsInt(jsonobject, "binding"); @@ -599,11 +589,29 @@ private void parseUboNode(JsonElement jsonelement) { //need to store some infos String name = GsonHelper.getAsString(jsonobject2, "name"); String type2 = GsonHelper.getAsString(jsonobject2, "type"); - int j = GsonHelper.getAsInt(jsonobject2, "count"); + int count = GsonHelper.getAsInt(jsonobject2, "count"); - builder.addUniformInfo(type2, name, j); + Uniform.Info uniformInfo = Uniform.createUniformInfo(type2, name, count); + uniformInfo.setupSupplier(); + if (!uniformInfo.hasSupplier()) { + if (this.uniformSupplierGetter != null) { + var uniformSupplier = this.uniformSupplierGetter.apply(uniformInfo); + + if (uniformSupplier == null) { + throw new IllegalStateException("No uniform supplier found for uniform: (%s:%s)".formatted(type2, name)); + } + + uniformInfo.setBufferSupplier(uniformSupplier); + } + else { + throw new IllegalStateException("No uniform supplier found for uniform: (%s:%s)".formatted(type2, name)); + } + } + + builder.addUniformInfo(uniformInfo); } + UBO ubo = builder.buildUBO(binding, type); if (binding >= this.nextBinding) @@ -637,13 +645,16 @@ private void parsePushConstantNode(JsonArray jsonArray) { AlignedStruct.Builder builder = new AlignedStruct.Builder(); for (JsonElement jsonelement : jsonArray) { - JsonObject jsonobject2 = GsonHelper.convertToJsonObject(jsonelement, "PC"); + JsonObject jsonobject2 = GsonHelper.convertToJsonObject(jsonelement, "PushConstants"); String name = GsonHelper.getAsString(jsonobject2, "name"); String type2 = GsonHelper.getAsString(jsonobject2, "type"); - int j = GsonHelper.getAsInt(jsonobject2, "count"); + int count = GsonHelper.getAsInt(jsonobject2, "count"); + + Uniform.Info uniformInfo = Uniform.createUniformInfo(type2, name, count); + uniformInfo.setupSupplier(); - builder.addUniformInfo(type2, name, j); + builder.addUniformInfo(uniformInfo); } this.pushConstants = builder.buildPushConstant(); diff --git a/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java b/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java index f1d8001e6..7ce07c043 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java @@ -1,8 +1,8 @@ package net.vulkanmod.vulkan.shader; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.vulkanmod.vulkan.Vulkan; import org.lwjgl.system.MemoryStack; -import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.NativeResource; import org.lwjgl.util.shaderc.ShadercIncludeResolveI; import org.lwjgl.util.shaderc.ShadercIncludeResult; @@ -10,7 +10,6 @@ import org.lwjgl.vulkan.VK12; import java.io.IOException; -import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; @@ -22,8 +21,10 @@ import static org.lwjgl.system.MemoryUtil.NULL; import static org.lwjgl.system.MemoryUtil.memASCII; import static org.lwjgl.util.shaderc.Shaderc.*; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_compile_options_set_optimization_level; public class SPIRVUtils { + private static final boolean use4ByteAlignFormat = !Vulkan.getDevice().isShaderFloat16Supported(); private static final boolean DEBUG = false; private static final boolean OPTIMIZATIONS = true; @@ -37,8 +38,6 @@ public class SPIRVUtils { private static ObjectArrayList includePaths; - private static float time = 0.0f; - static { initCompiler(); } @@ -46,20 +45,26 @@ public class SPIRVUtils { private static void initCompiler() { compiler = shaderc_compiler_initialize(); - if(compiler == NULL) { + if (compiler == NULL) { throw new RuntimeException("Failed to create shader compiler"); } options = shaderc_compile_options_initialize(); - if(options == NULL) { + if (options == NULL) { throw new RuntimeException("Failed to create compiler options"); } - - if(OPTIMIZATIONS) + //Using the wrong alignment can cause performance problems on some architectures + // Force Alignment to 4 bytes for AMD GCN and Old Nvidia (Pascal or Older) + // Otherwise defaults to 2 Bytes for AMD RDNA and Nvidia Turing+ + // (using shaderFloat16 avoids forcing the override on RDNA cards: which are unaffected by the GCN issue) + if(use4ByteAlignFormat) + shaderc_compile_options_add_macro_definition(options, "GCN_FIX", null); + + if (OPTIMIZATIONS) shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_performance); - if(DEBUG) + if (DEBUG) shaderc_compile_options_set_generate_debug_info(options); shaderc_compile_options_set_target_env(options, shaderc_env_version_vulkan_1_2, VK12.VK_API_VERSION_1_2); @@ -72,52 +77,30 @@ private static void initCompiler() { public static void addIncludePath(String path) { URL url = SPIRVUtils.class.getResource(path); - if(url != null) + if (url != null) includePaths.add(url.toExternalForm()); } - public static SPIRV compileShaderAbsoluteFile(String shaderFile, ShaderKind shaderKind) { - try { - String source = new String(Files.readAllBytes(Paths.get(new URI(shaderFile)))); - return compileShader(shaderFile, source, shaderKind); - } catch (IOException | URISyntaxException e) { - e.printStackTrace(); - } - return null; - } - public static SPIRV compileShader(String filename, String source, ShaderKind shaderKind) { - long startTime = System.nanoTime(); + if (source == null) { + throw new NullPointerException("source for %s.%s is null".formatted(filename, shaderKind)); + } long result = shaderc_compile_into_spv(compiler, source, shaderKind.kind, filename, "main", options); - if(result == NULL) { + if (result == NULL) { throw new RuntimeException("Failed to compile shader " + filename + " into SPIR-V"); } - if(shaderc_result_get_compilation_status(result) != shaderc_compilation_status_success) { - throw new RuntimeException("Failed to compile shader " + filename + " into SPIR-V:\n" + shaderc_result_get_error_message(result)); + if (shaderc_result_get_compilation_status(result) != shaderc_compilation_status_success) { + throw new RuntimeException( + "Failed to compile shader " + filename + " into SPIR-V:\n" + shaderc_result_get_error_message( + result)); } - time += (System.nanoTime() - startTime) / 1000000.0f; - return new SPIRV(result, shaderc_result_get_bytes(result)); } - private static SPIRV readFromStream(InputStream inputStream) { - try { - byte[] bytes = inputStream.readAllBytes(); - ByteBuffer buffer = MemoryUtil.memAlloc(bytes.length); - buffer.put(bytes); - buffer.position(0); - - return new SPIRV(MemoryUtil.memAddress(buffer), buffer); - } catch (Exception e) { - e.printStackTrace(); - } - throw new RuntimeException("unable to read inputStream"); - } - public enum ShaderKind { VERTEX_SHADER(shaderc_glsl_vertex_shader), GEOMETRY_SHADER(shaderc_glsl_geometry_shader), @@ -140,19 +123,19 @@ public long invoke(long user_data, long requested_source, int type, long request var requesting = memASCII(requesting_source); var requested = memASCII(requested_source); - try(MemoryStack stack = MemoryStack.stackPush()) { + try (MemoryStack stack = MemoryStack.stackPush()) { Path path; - for(String includePath : includePaths) { + for (String includePath : includePaths) { path = Paths.get(new URI(String.format("%s%s", includePath, requested))); - if(Files.exists(path)) { + if (Files.exists(path)) { byte[] bytes = Files.readAllBytes(path); return ShadercIncludeResult.malloc(stack) - .source_name(stack.ASCII(requested)) - .content(stack.bytes(bytes)) - .user_data(user_data).address(); + .source_name(stack.ASCII(requested)) + .content(stack.bytes(bytes)) + .user_data(user_data).address(); } } } catch (IOException | URISyntaxException e) { diff --git a/src/main/java/net/vulkanmod/vulkan/shader/Uniforms.java b/src/main/java/net/vulkanmod/vulkan/shader/Uniforms.java index e233046d7..7ca193a65 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/Uniforms.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/Uniforms.java @@ -44,11 +44,22 @@ public static void setupDefaultUniforms() { //Vec3 vec3f_uniformMap.put("Light0_Direction", () -> VRenderSystem.lightDirection0); vec3f_uniformMap.put("Light1_Direction", () -> VRenderSystem.lightDirection1); - vec3f_uniformMap.put("ChunkOffset", () -> VRenderSystem.ChunkOffset); + vec3f_uniformMap.put("ModelOffset", () -> VRenderSystem.modelOffset); //Vec4 vec4f_uniformMap.put("ColorModulator", VRenderSystem::getShaderColor); vec4f_uniformMap.put("FogColor", VRenderSystem::getShaderFogColor); } + + public static Supplier getUniformSupplier(String type, String name) { + return switch (type) { + case "mat4" -> Uniforms.mat4f_uniformMap.get(name); + case "vec4" -> Uniforms.vec4f_uniformMap.get(name); + case "vec3" -> Uniforms.vec3f_uniformMap.get(name); + case "vec2" -> Uniforms.vec2f_uniformMap.get(name); + + default -> null; + }; + } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/parser/CodeParser.java b/src/main/java/net/vulkanmod/vulkan/shader/converter/CodeParser.java similarity index 97% rename from src/main/java/net/vulkanmod/vulkan/shader/parser/CodeParser.java rename to src/main/java/net/vulkanmod/vulkan/shader/converter/CodeParser.java index b6f95f752..7ed82e3fb 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/parser/CodeParser.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/converter/CodeParser.java @@ -1,4 +1,4 @@ -package net.vulkanmod.vulkan.shader.parser; +package net.vulkanmod.vulkan.shader.converter; import it.unimi.dsi.fastutil.objects.ObjectArrayList; diff --git a/src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java b/src/main/java/net/vulkanmod/vulkan/shader/converter/GlslConverter.java similarity index 60% rename from src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java rename to src/main/java/net/vulkanmod/vulkan/shader/converter/GlslConverter.java index f934a5def..50d2302a7 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/converter/GlslConverter.java @@ -1,4 +1,4 @@ -package net.vulkanmod.vulkan.shader.parser; +package net.vulkanmod.vulkan.shader.converter; import net.vulkanmod.vulkan.shader.descriptor.ImageDescriptor; import net.vulkanmod.vulkan.shader.descriptor.UBO; @@ -20,66 +20,106 @@ public void process(String vertShader, String fragShader) { this.uniformParser = new UniformParser(this); this.inOutParser = new InputOutputParser(this); - StringBuilder vshOut = new StringBuilder(); - StringBuilder fshOut = new StringBuilder(); + StringBuilder vshOut = this.processShaderFile(ShaderStage.Vertex, vertShader); + vshOut.insert(0, this.inOutParser.createInOutCode()); - this.setShaderStage(ShaderStage.Vertex); + StringBuilder fshOut = this.processShaderFile(ShaderStage.Fragment, fragShader); + fshOut.insert(0, this.inOutParser.createInOutCode()); - String[] lines = vertShader.split("\n"); + String uniformBlock = this.uniformParser.createUniformsCode(); + vshOut.insert(0, uniformBlock); + fshOut.insert(0, uniformBlock); + + String samplersVertCode = this.uniformParser.createSamplersCode(ShaderStage.Vertex); + String samplersFragCode = this.uniformParser.createSamplersCode(ShaderStage.Fragment); + + vshOut.insert(0, samplersVertCode); + fshOut.insert(0, samplersFragCode); + + vshOut.insert(0, "#version 450\n\n"); + fshOut.insert(0, "#define sample sample1\n"); + fshOut.insert(0, "#version 450\n\n"); + + this.vshConverted = vshOut.toString(); + this.fshConverted = fshOut.toString(); + + } + + private StringBuilder processShaderFile(ShaderStage stage, String shader) { + this.setShaderStage(stage); + + String[] lines = shader.split("\n"); + var out = new StringBuilder(); var iterator = Arrays.stream(lines).iterator(); while (iterator.hasNext()) { String line = iterator.next(); - String parsedLine = this.parseLine(line); - if (parsedLine != null) { - vshOut.append(parsedLine); - vshOut.append("\n"); - } + int semicolons = charOccurences(line, ';'); - } + if (semicolons > 1) { + var lines2 = line.splitWithDelimiters(";", 0); - vshOut.insert(0, this.inOutParser.createInOutCode()); + int matchingFor = 0; + for (int i = 0; i < lines2.length;) { + StringBuilder line2 = new StringBuilder(lines2[i]); + i++; - this.setShaderStage(ShaderStage.Fragment); + matchingFor += charOccurences(line2.toString(), '('); + matchingFor -= charOccurences(line2.toString(), ')'); - lines = fragShader.split("\n"); + while (matchingFor > 0) { + String next = lines2[i]; + i++; - iterator = Arrays.stream(lines).iterator(); + matchingFor += charOccurences(next, '('); + matchingFor -= charOccurences(next, ')'); - while (iterator.hasNext()) { - String line = iterator.next(); + line2.append(next); + } - String parsedLine = this.parseLine(line); - if (parsedLine != null) { - fshOut.append(parsedLine); - fshOut.append("\n"); - } - } + if (i < lines2.length) { + line2.append(lines2[i]); + i++; + } - fshOut.insert(0, this.inOutParser.createInOutCode()); - String uniformBlock = this.uniformParser.createUniformsCode(); - vshOut.insert(0, uniformBlock); - fshOut.insert(0, uniformBlock); + if (matchingFor == 0) { + String parsedLine = this.parseLine(line2.toString()); + if (parsedLine != null) { + out.append(parsedLine); + out.append("\n"); + } + } - String samplersVertCode = this.uniformParser.createSamplersCode(ShaderStage.Vertex); - String samplersFragCode = this.uniformParser.createSamplersCode(ShaderStage.Fragment); + } + } + else { + String parsedLine = this.parseLine(line); + if (parsedLine != null) { + out.append(parsedLine); + out.append("\n"); + } + } - vshOut.insert(0, samplersVertCode); - fshOut.insert(0, samplersFragCode); + } - vshOut.insert(0, "#version 450\n\n"); - fshOut.insert(0, "#version 450\n\n"); + return out; + } - this.vshConverted = vshOut.toString(); - this.fshConverted = fshOut.toString(); + private int charOccurences(String s, char c) { + int count = 0; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == c) { + count++; + } + } + return count; } private String parseLine(String line) { - StringTokenizer tokenizer = new StringTokenizer(line); // empty line @@ -135,8 +175,8 @@ private void setShaderStage(ShaderStage shaderStage) { this.inOutParser.setShaderStage(this.shaderStage); } - public UBO getUBO() { - return this.uniformParser.getUbo(); + public UBO createUBO() { + return this.uniformParser.createUBO(); } public List getSamplerList() { diff --git a/src/main/java/net/vulkanmod/vulkan/shader/parser/InputOutputParser.java b/src/main/java/net/vulkanmod/vulkan/shader/converter/InputOutputParser.java similarity index 96% rename from src/main/java/net/vulkanmod/vulkan/shader/parser/InputOutputParser.java rename to src/main/java/net/vulkanmod/vulkan/shader/converter/InputOutputParser.java index aa8c5c0fe..cde9e5eff 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/parser/InputOutputParser.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/converter/InputOutputParser.java @@ -1,4 +1,4 @@ -package net.vulkanmod.vulkan.shader.parser; +package net.vulkanmod.vulkan.shader.converter; import com.mojang.blaze3d.vertex.VertexFormat; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -6,7 +6,7 @@ import java.util.List; import java.util.Objects; -import static net.vulkanmod.vulkan.shader.parser.UniformParser.removeSemicolon; +import static net.vulkanmod.vulkan.shader.converter.UniformParser.removeSemicolon; public class InputOutputParser { private final GlslConverter converterInstance; diff --git a/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java b/src/main/java/net/vulkanmod/vulkan/shader/converter/UniformParser.java similarity index 74% rename from src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java rename to src/main/java/net/vulkanmod/vulkan/shader/converter/UniformParser.java index cc5087ce0..0fe03111e 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/converter/UniformParser.java @@ -1,10 +1,10 @@ -package net.vulkanmod.vulkan.shader.parser; +package net.vulkanmod.vulkan.shader.converter; import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import net.vulkanmod.vulkan.shader.Pipeline; import net.vulkanmod.vulkan.shader.descriptor.ImageDescriptor; -import net.vulkanmod.vulkan.shader.layout.AlignedStruct; import net.vulkanmod.vulkan.shader.descriptor.UBO; +import net.vulkanmod.vulkan.shader.layout.AlignedStruct; +import org.lwjgl.vulkan.VK11; import java.util.ArrayList; import java.util.List; @@ -19,19 +19,18 @@ public class UniformParser { private String type; private String name; - private UBO ubo; private List imageDescriptors; public UniformParser(GlslConverter converterInstance) { this.converterInstance = converterInstance; - for(int i = 0; i < this.stageUniforms.length; ++i) { + for (int i = 0; i < this.stageUniforms.length; ++i) { this.stageUniforms[i] = new StageUniforms(); } } public boolean parseToken(String token) { - if(token.matches("uniform")) return false; + if (token.matches("uniform")) return false; if (this.type == null) { this.type = token; @@ -47,7 +46,8 @@ else if (this.name == null) { if ("sampler2D".equals(this.type)) { if (!this.currentUniforms.samplers.contains(uniform)) this.currentUniforms.samplers.add(uniform); - } else { + } + else { if (!this.globalUniforms.contains(uniform)) this.globalUniforms.add(uniform); } @@ -72,11 +72,9 @@ private void resetSate() { public String createUniformsCode() { StringBuilder builder = new StringBuilder(); - this.ubo = this.createUBO(); - //hardcoded 0 binding as it should always be 0 in this case builder.append(String.format("layout(binding = %d) uniform UniformBufferObject {\n", 0)); - for(Uniform uniform : this.globalUniforms) { + for (Uniform uniform : this.globalUniforms) { builder.append(String.format("%s %s;\n", uniform.type, uniform.name)); } builder.append("};\n\n"); @@ -89,23 +87,29 @@ public String createSamplersCode(GlslConverter.ShaderStage shaderStage) { this.imageDescriptors = createSamplerList(); - for(ImageDescriptor imageDescriptor : this.imageDescriptors) { - builder.append(String.format("layout(binding = %d) uniform %s %s;\n", imageDescriptor.getBinding(), imageDescriptor.qualifier, imageDescriptor.name)); + for (ImageDescriptor imageDescriptor : this.imageDescriptors) { + builder.append(String.format("layout(binding = %d) uniform %s %s;\n", imageDescriptor.getBinding(), + imageDescriptor.qualifier, imageDescriptor.name)); } builder.append("\n"); return builder.toString(); } - private UBO createUBO() { + public UBO createUBO() { AlignedStruct.Builder builder = new AlignedStruct.Builder(); - for(Uniform uniform : this.globalUniforms) { - builder.addUniformInfo(uniform.type, uniform.name); + for (UniformParser.Uniform uniform : this.globalUniforms) { + String name = uniform.name(); + String type = uniform.type(); + + net.vulkanmod.vulkan.shader.layout.Uniform.Info uniformInfo = net.vulkanmod.vulkan.shader.layout.Uniform.createUniformInfo(type, name); + + builder.addUniformInfo(uniformInfo); } - //hardcoded 0 binding as it should always be 0 in this case - return builder.buildUBO(0, Pipeline.Builder.getStageFromString("all")); + // Use binding 0 for global uniforms + return builder.buildUBO(0, VK11.VK_SHADER_STAGE_ALL); } private List createSamplerList() { @@ -113,8 +117,8 @@ private List createSamplerList() { List imageDescriptors = new ObjectArrayList<>(); - for(StageUniforms stageUniforms : this.stageUniforms) { - for(Uniform uniform : stageUniforms.samplers) { + for (StageUniforms stageUniforms : this.stageUniforms) { + for (Uniform uniform : stageUniforms.samplers) { int imageIdx = currentLocation - 1; imageDescriptors.add(new ImageDescriptor(currentLocation, uniform.type, uniform.name, imageIdx)); currentLocation++; @@ -126,20 +130,21 @@ private List createSamplerList() { public static String removeSemicolon(String s) { int last = s.length() - 1; - if((s.charAt(last)) != ';' ) + if ((s.charAt(last)) != ';') throw new IllegalArgumentException("last char is not ;"); return s.substring(0, last); } - public UBO getUbo() { - return this.ubo; + public List getGlobalUniforms() { + return globalUniforms; } public List getSamplers() { return this.imageDescriptors; } - public record Uniform(String type, String name) {} + public record Uniform(String type, String name) { + } private static class StageUniforms { List samplers = new ArrayList<>(); diff --git a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java index 4614285fe..1d0a76daa 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java @@ -1,6 +1,6 @@ package net.vulkanmod.vulkan.shader.descriptor; -import net.vulkanmod.vulkan.memory.UniformBuffer; +import net.vulkanmod.vulkan.memory.buffer.UniformBuffer; import net.vulkanmod.vulkan.shader.layout.AlignedStruct; import net.vulkanmod.vulkan.shader.layout.Uniform; diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/AlignedStruct.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/AlignedStruct.java index 89c015da5..11560c621 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/AlignedStruct.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/AlignedStruct.java @@ -13,18 +13,17 @@ public abstract class AlignedStruct { protected AlignedStruct(List infoList, int size) { this.size = size; - if(infoList == null) + if (infoList == null) return; - for(Uniform.Info info : infoList) { - + for (Uniform.Info info : infoList) { Uniform uniform = Uniform.createField(info); this.uniforms.add(uniform); } } public void update(long ptr) { - for(Uniform uniform : this.uniforms) { + for (Uniform uniform : this.uniforms) { uniform.update(ptr); } } @@ -39,33 +38,36 @@ public int getSize() { public static class Builder { - final List uniformsInfo = new ArrayList<>(); + final List uniforms = new ArrayList<>(); protected int currentOffset = 0; public void addUniformInfo(String type, String name, int count) { Uniform.Info info = Uniform.createUniformInfo(type, name, count); - - this.currentOffset = info.computeAlignmentOffset(this.currentOffset); - this.currentOffset += info.size; - this.uniformsInfo.add(info); + addUniformInfo(info); } public void addUniformInfo(String type, String name) { Uniform.Info info = Uniform.createUniformInfo(type, name); + addUniformInfo(info); + } - this.currentOffset = info.computeAlignmentOffset(this.currentOffset); - this.currentOffset += info.size; - this.uniformsInfo.add(info); + public void addUniformInfo(Uniform.Info uniformInfo) { + this.currentOffset = uniformInfo.computeAlignmentOffset(this.currentOffset); + this.currentOffset += uniformInfo.size; + this.uniforms.add(uniformInfo); } public UBO buildUBO(int binding, int stages) { //offset is expressed in floats/ints - return new UBO(binding, stages, this.currentOffset * 4, this.uniformsInfo); + return new UBO(binding, stages, this.currentOffset * 4, this.uniforms); } public PushConstants buildPushConstant() { - if(this.uniformsInfo.isEmpty()) return null; - return new PushConstants(this.uniformsInfo, this.currentOffset * 4); + if (this.uniforms.isEmpty()) { + return null; + } + + return new PushConstants(this.uniforms, this.currentOffset * 4); } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java index c0f07797c..8c1509df1 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java @@ -17,18 +17,12 @@ public class Uniform { this.info = info; this.offset = info.offset * 4L; this.size = info.size * 4; - this.setSupplier(); - } - void setSupplier() { - this.values = switch (info.type) { - case "mat4" -> Uniforms.mat4f_uniformMap.get(info.name); - case "vec4" -> Uniforms.vec4f_uniformMap.get(info.name); - case "vec3" -> Uniforms.vec3f_uniformMap.get(info.name); - case "vec2" -> Uniforms.vec2f_uniformMap.get(info.name); + this.setupSupplier(); + } - default -> null; - }; + protected void setupSupplier() { + this.values = this.info.bufferSupplier; } public void setSupplier(Supplier supplier) { @@ -61,6 +55,10 @@ public int getOffset() { public int getSize() { return info.size; } + public Info getInfo() { + return info; + } + public String toString() { return String.format("%s: %s offset: %d", info.type, info.name, info.offset); } @@ -98,12 +96,16 @@ public static Info createUniformInfo(String type, String name) { } public static class Info { - final String type; - final String name; - final int align; - final int size; + public final String type; + public final String name; + public final int align; + public final int size; int offset; + Supplier bufferSupplier; + Supplier intSupplier; + Supplier floatSupplier; + Info(String type, String name, int align, int size) { this.type = type; this.name = name; @@ -116,5 +118,26 @@ public static class Info { int computeAlignmentOffset(int builderOffset) { return this.offset = builderOffset + ((align - (builderOffset % align)) % align); } + + public void setupSupplier() { + switch (this.type) { + case "float" -> this.floatSupplier = Uniforms.vec1f_uniformMap.get(this.name); + case "int" -> this.intSupplier = Uniforms.vec1i_uniformMap.get(this.name); + default -> this.bufferSupplier = Uniforms.getUniformSupplier(this.type, this.name); + } + } + + public boolean hasSupplier() { + return switch (this.type) { + case "float" -> this.floatSupplier != null || this.bufferSupplier != null; + case "int" -> this.intSupplier != null || this.bufferSupplier != null; + default -> this.bufferSupplier != null; + }; + } + + public void setBufferSupplier(Supplier supplier) { + this.bufferSupplier = supplier; + } + } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1f.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1f.java index 4e9a2084c..484861490 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1f.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1f.java @@ -1,8 +1,6 @@ package net.vulkanmod.vulkan.shader.layout; -import net.vulkanmod.vulkan.shader.Uniforms; import net.vulkanmod.vulkan.util.MappedBuffer; -import org.apache.commons.lang3.Validate; import org.lwjgl.system.MemoryUtil; import java.util.function.Supplier; @@ -14,8 +12,12 @@ public Vec1f(Info info) { super(info); } - void setSupplier() { - this.floatSupplier = Uniforms.vec1f_uniformMap.get(this.info.name); + protected void setupSupplier() { + if (this.info.floatSupplier != null) { + this.floatSupplier = this.info.floatSupplier; + } else { + this.setSupplier(this.info.bufferSupplier); + } } @Override diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java index 995076cb2..700fd00bf 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java @@ -14,8 +14,12 @@ public Vec1i(Info info) { super(info); } - void setSupplier() { - this.intSupplier = Uniforms.vec1i_uniformMap.get(this.info.name); + protected void setupSupplier() { + if (this.info.intSupplier != null) { + this.intSupplier = this.info.intSupplier; + } else { + this.setSupplier(this.info.bufferSupplier); + } } @Override diff --git a/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java b/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java index 151969d06..6ec57980f 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java @@ -1,5 +1,6 @@ package net.vulkanmod.vulkan.texture; +import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.device.DeviceManager; import net.vulkanmod.vulkan.memory.MemoryManager; import net.vulkanmod.vulkan.queue.CommandPool; @@ -15,23 +16,21 @@ public abstract class ImageUtil { - public static void copyBufferToImageCmd(VkCommandBuffer commandBuffer, long buffer, long image, int mipLevel, int width, int height, int xOffset, int yOffset, int bufferOffset, int bufferRowLenght, int bufferImageHeight) { - - try (MemoryStack stack = stackPush()) { - - VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack); - region.bufferOffset(bufferOffset); - region.bufferRowLength(bufferRowLenght); // Tightly packed - region.bufferImageHeight(bufferImageHeight); // Tightly packed - region.imageSubresource().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); - region.imageSubresource().mipLevel(mipLevel); - region.imageSubresource().baseArrayLayer(0); - region.imageSubresource().layerCount(1); - region.imageOffset().set(xOffset, yOffset, 0); - region.imageExtent(VkExtent3D.calloc(stack).set(width, height, 1)); - - vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, region); - } + public static void copyBufferToImageCmd(MemoryStack stack, VkCommandBuffer commandBuffer, long buffer, long image, + int mipLevel, int width, int height, int xOffset, int yOffset, + int bufferOffset, int bufferRowLenght, int bufferImageHeight) { + VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack); + region.bufferOffset(bufferOffset); + region.bufferRowLength(bufferRowLenght); // Tightly packed + region.bufferImageHeight(bufferImageHeight); // Tightly packed + region.imageSubresource().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); + region.imageSubresource().mipLevel(mipLevel); + region.imageSubresource().baseArrayLayer(0); + region.imageSubresource().layerCount(1); + region.imageOffset().set(xOffset, yOffset, 0); + region.imageExtent(VkExtent3D.calloc(stack).set(width, height, 1)); + + vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, region); } public static void downloadTexture(VulkanImage image, long ptr) { @@ -44,27 +43,27 @@ public static void downloadTexture(VulkanImage image, long ptr) { LongBuffer pStagingBuffer = stack.mallocLong(1); PointerBuffer pStagingAllocation = stack.pointers(0L); - MemoryManager.getInstance().createBuffer(imageSize, - VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - pStagingBuffer, - pStagingAllocation); + MemoryManager.getInstance().createBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + pStagingBuffer, pStagingAllocation); - copyImageToBuffer(commandBuffer.getHandle(), pStagingBuffer.get(0), image.getId(), 0, image.width, image.height, 0, 0, 0, 0, 0); + copyImageToBuffer(commandBuffer.getHandle(), pStagingBuffer.get(0), image.getId(), 0, image.width, + image.height, 0, 0, 0, 0, 0); image.transitionImageLayout(stack, commandBuffer.getHandle(), prevLayout); long fence = DeviceManager.getGraphicsQueue().submitCommands(commandBuffer); vkWaitForFences(DeviceManager.vkDevice, fence, true, VUtil.UINT64_MAX); MemoryManager.MapAndCopy(pStagingAllocation.get(0), - (data) -> VUtil.memcpy(data.getByteBuffer(0, (int) imageSize), ptr) - ); + (data) -> VUtil.memcpy(data.getByteBuffer(0, (int) imageSize), ptr)); MemoryManager.freeBuffer(pStagingBuffer.get(0), pStagingAllocation.get(0)); } } - public static void copyImageToBuffer(VkCommandBuffer commandBuffer, long buffer, long image, int mipLevel, int width, int height, int xOffset, int yOffset, int bufferOffset, int bufferRowLenght, int bufferImageHeight) { + public static void copyImageToBuffer(VkCommandBuffer commandBuffer, long buffer, long image, int mipLevel, + int width, int height, int xOffset, int yOffset, int bufferOffset, + int bufferRowLenght, int bufferImageHeight) { try (MemoryStack stack = stackPush()) { VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack); @@ -82,6 +81,44 @@ public static void copyImageToBuffer(VkCommandBuffer commandBuffer, long buffer, } } + public static void blitFramebuffer(VulkanImage dstImage, int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1) { + try (MemoryStack stack = stackPush()) { + + VkCommandBuffer commandBuffer = Renderer.getCommandBuffer(); + + Renderer.getInstance().endRenderPass(commandBuffer); + + dstImage.transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + // TODO: hardcoded srcImage + VulkanImage srcImage = Renderer.getInstance().getSwapChain().getColorAttachment(); + + srcImage.transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + VkImageBlit.Buffer blit = VkImageBlit.calloc(1, stack); + blit.srcOffsets(0, VkOffset3D.calloc(stack).set(0, 0, 0)); + blit.srcOffsets(1, VkOffset3D.calloc(stack).set(srcImage.width, srcImage.height, 1)); + blit.srcSubresource() + .aspectMask(VK_IMAGE_ASPECT_COLOR_BIT) + .mipLevel(0) + .baseArrayLayer(0) + .layerCount(1); + + blit.dstOffsets(0, VkOffset3D.calloc(stack).set(0, 0, 0)); + blit.dstOffsets(1, VkOffset3D.calloc(stack).set(dstImage.width, dstImage.height, 1)); + blit.dstSubresource().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT).mipLevel(0).baseArrayLayer(0) + .layerCount(1); + + vkCmdBlitImage(commandBuffer, srcImage.getId(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + dstImage.getId(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, blit, VK_FILTER_LINEAR); + + dstImage.transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + Renderer.getInstance().getMainPass().rebindMainTarget(); + + } + } + public static void generateMipmaps(VulkanImage image) { try (MemoryStack stack = stackPush()) { @@ -112,12 +149,8 @@ public static void generateMipmaps(VulkanImage image) { barrier.srcAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT); barrier.dstAccessMask(VK_ACCESS_TRANSFER_READ_BIT); - vkCmdPipelineBarrier(commandBuffer.getHandle(), - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, - null, - null, - barrier); + vkCmdPipelineBarrier(commandBuffer.getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, null, null, barrier); prevLevel = level - 1; @@ -125,24 +158,18 @@ public static void generateMipmaps(VulkanImage image) { blit.srcOffsets(0, VkOffset3D.calloc(stack).set(0, 0, 0)); blit.srcOffsets(1, VkOffset3D.calloc(stack).set(image.width >> prevLevel, image.height >> prevLevel, 1)); blit.srcSubresource() - .aspectMask(VK_IMAGE_ASPECT_COLOR_BIT) - .mipLevel(prevLevel) - .baseArrayLayer(0) - .layerCount(1); + .aspectMask(VK_IMAGE_ASPECT_COLOR_BIT) + .mipLevel(prevLevel) + .baseArrayLayer(0) + .layerCount(1); blit.dstOffsets(0, VkOffset3D.calloc(stack).set(0, 0, 0)); blit.dstOffsets(1, VkOffset3D.calloc(stack).set(image.width >> level, image.height >> level, 1)); - blit.dstSubresource() - .aspectMask(VK_IMAGE_ASPECT_COLOR_BIT) - .mipLevel(level) - .baseArrayLayer(0) - .layerCount(1); - - vkCmdBlitImage(commandBuffer.getHandle(), - image.getId(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - image.getId(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - blit, - VK_FILTER_LINEAR); + blit.dstSubresource().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT).mipLevel(level).baseArrayLayer(0) + .layerCount(1); + + vkCmdBlitImage(commandBuffer.getHandle(), image.getId(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + image.getId(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, blit, VK_FILTER_LINEAR); } @@ -165,22 +192,20 @@ public static void generateMipmaps(VulkanImage image) { barrier.dstAccessMask(VK_ACCESS_SHADER_READ_BIT); vkCmdPipelineBarrier(commandBuffer.getHandle(), - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - 0, - null, - null, - barrier); + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, + null, null, + barrier); barrier.oldLayout(VK_IMAGE_USAGE_TRANSFER_DST_BIT); barrier.subresourceRange().baseMipLevel(image.mipLevels - 1); barrier.subresourceRange().levelCount(1); vkCmdPipelineBarrier(commandBuffer.getHandle(), - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - 0, - null, - null, - barrier); + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, + null, null, + barrier); image.setCurrentLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); diff --git a/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java b/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java index 0b3903d7f..b8b9fee58 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java @@ -105,6 +105,8 @@ public static void setActiveTexture(int activeTexture) { VTextureSelector.activeTexture = activeTexture; } + public static VulkanImage getBoundTexture() { return boundTextures[activeTexture]; } + public static VulkanImage getBoundTexture(int i) { return boundTextures[i]; } public static VulkanImage getWhiteTexture() { return whiteTexture; } diff --git a/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java b/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java index 440f1ec56..e447a0b71 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java @@ -1,11 +1,11 @@ package net.vulkanmod.vulkan.texture; import com.mojang.blaze3d.platform.NativeImage; -import net.vulkanmod.vulkan.Synchronization; +import net.vulkanmod.render.texture.ImageUploadHelper; +import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.Vulkan; -import net.vulkanmod.vulkan.device.DeviceManager; import net.vulkanmod.vulkan.memory.MemoryManager; -import net.vulkanmod.vulkan.memory.StagingBuffer; +import net.vulkanmod.vulkan.memory.buffer.StagingBuffer; import net.vulkanmod.vulkan.queue.CommandPool; import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; @@ -28,6 +28,15 @@ public class VulkanImage { private static final VkDevice DEVICE = Vulkan.getVkDevice(); + public final int format; + public final int aspect; + public final int mipLevels; + public final int width; + public final int height; + public final int formatSize; + public final int usage; + public final int size; + private long id; private long allocation; private long mainImageView; @@ -36,14 +45,6 @@ public class VulkanImage { private long sampler; - public final int format; - public final int aspect; - public final int mipLevels; - public final int width; - public final int height; - public final int formatSize; - private final int usage; - private int currentLayout; //Used for swap chain images @@ -59,6 +60,8 @@ public VulkanImage(long id, int format, int mipLevels, int width, int height, in this.usage = usage; this.aspect = getAspect(this.format); + this.size = width * height * formatSize; + this.sampler = SamplerManager.getTextureSampler((byte) this.mipLevels, (byte) 0); } @@ -70,12 +73,14 @@ private VulkanImage(Builder builder) { this.format = builder.format; this.usage = builder.usage; this.aspect = getAspect(this.format); + + this.size = width * height * formatSize; } public static VulkanImage createTextureImage(Builder builder) { VulkanImage image = new VulkanImage(builder); - image.createImage(builder.mipLevels, builder.width, builder.height, builder.format, builder.usage); + image.createImage(); image.mainImageView = createImageView(image.id, builder.format, image.aspect, builder.mipLevels); image.sampler = SamplerManager.getTextureSampler(builder.mipLevels, builder.samplerFlags); @@ -120,14 +125,12 @@ public static VulkanImage createWhiteTexture() { } } - private void createImage(int mipLevels, int width, int height, int format, int usage) { - + private void createImage() { try (MemoryStack stack = stackPush()) { - LongBuffer pTextureImage = stack.mallocLong(1); PointerBuffer pAllocation = stack.pointers(0L); - MemoryManager.createImage(width, height, mipLevels, + MemoryManager.getInstance().createImage(width, height, mipLevels, format, VK_IMAGE_TILING_OPTIMAL, usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, @@ -192,25 +195,31 @@ public static long createImageView(long image, int format, int aspectFlags, int } public void uploadSubTextureAsync(int mipLevel, int width, int height, int xOffset, int yOffset, int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, ByteBuffer buffer) { - long imageSize = buffer.limit(); + long uploadSize = buffer.limit(); - CommandPool.CommandBuffer commandBuffer = DeviceManager.getGraphicsQueue().getCommandBuffer(); - try (MemoryStack stack = stackPush()) { - transferDstLayout(stack, commandBuffer.getHandle()); + StagingBuffer stagingBuffer = Vulkan.getStagingBuffer(); + + // Use a temporary staging buffer if the upload size is greater than + // the default staging buffer + if (uploadSize > stagingBuffer.getBufferSize()) { + stagingBuffer = new StagingBuffer(uploadSize); + stagingBuffer.scheduleFree(); } - StagingBuffer stagingBuffer = Vulkan.getStagingBuffer(); stagingBuffer.align(this.formatSize); + stagingBuffer.copyBuffer((int) uploadSize, buffer); - stagingBuffer.copyBuffer((int) imageSize, buffer); + long bufferId = stagingBuffer.getId(); - ImageUtil.copyBufferToImageCmd(commandBuffer.getHandle(), stagingBuffer.getId(), id, mipLevel, width, height, xOffset, yOffset, - (int) (stagingBuffer.getOffset() + (unpackRowLength * unpackSkipRows + unpackSkipPixels) * this.formatSize), unpackRowLength, height); + VkCommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer().getHandle(); + try (MemoryStack stack = stackPush()) { + transferDstLayout(stack, commandBuffer); + + final int srcOffset = (int) (stagingBuffer.getOffset() + (unpackRowLength * unpackSkipRows + unpackSkipPixels) * this.formatSize); - long fence = DeviceManager.getGraphicsQueue().endIfNeeded(commandBuffer); - if (fence != VK_NULL_HANDLE) -// Synchronization.INSTANCE.addFence(fence); - Synchronization.INSTANCE.addCommandBuffer(commandBuffer); + ImageUtil.copyBufferToImageCmd(stack, commandBuffer, bufferId, this.id, mipLevel, width, height, xOffset, yOffset, + srcOffset, unpackRowLength, height); + } } private void transferDstLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { @@ -221,12 +230,17 @@ public void readOnlyLayout() { if (this.currentLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) return; - CommandPool.CommandBuffer commandBuffer = DeviceManager.getGraphicsQueue().getCommandBuffer(); try (MemoryStack stack = MemoryStack.stackPush()) { - readOnlyLayout(stack, commandBuffer.getHandle()); + if (Renderer.getInstance().getBoundRenderPass() != null) { + CommandPool.CommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer(); + VkCommandBuffer vkCommandBuffer = commandBuffer.getHandle(); + + readOnlyLayout(stack, vkCommandBuffer); + } + else { + readOnlyLayout(stack, Renderer.getCommandBuffer()); + } } - DeviceManager.getGraphicsQueue().submitCommands(commandBuffer); - Synchronization.INSTANCE.addCommandBuffer(commandBuffer); } public void readOnlyLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { @@ -504,8 +518,8 @@ private static int formatSize(int format) { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_SINT -> 4; case VK_FORMAT_R8_UNORM -> 1; -// default -> throw new IllegalArgumentException(String.format("Unxepcted format: %s", format)); - default -> 0; + default -> throw new IllegalArgumentException(String.format("Unxepcted format: %s", format)); +// default -> 0; }; } } diff --git a/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java b/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java index 7dc60c03c..145935a85 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java @@ -47,11 +47,14 @@ public static int multiplyAlpha(int color, float m) { int newA = floatToInt(unpackA(color) * m); return (color & 0x00FFFFFF) | newA << 24; } + + public static int toRGBA(int color) { + return (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000); + } } public static class RGBA { public static int pack(float r, float g, float b, float a) { -// int color = floatToInt(r) << 24 | floatToInt(g) << 16 | floatToInt(b) << 8 | floatToInt(a); int color = floatToInt(a) << 24 | floatToInt(b) << 16 | floatToInt(g) << 8 | floatToInt(r); return color; diff --git a/src/main/java/net/vulkanmod/vulkan/util/VUtil.java b/src/main/java/net/vulkanmod/vulkan/util/VUtil.java index 46ffadeb3..37a9671f0 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/VUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/util/VUtil.java @@ -1,5 +1,6 @@ package net.vulkanmod.vulkan.util; +import net.vulkanmod.vulkan.memory.buffer.Buffer; import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; @@ -7,12 +8,13 @@ import java.lang.reflect.Field; import java.nio.ByteBuffer; -import java.nio.FloatBuffer; import java.util.Collection; import static org.lwjgl.system.MemoryStack.stackGet; public class VUtil { + public static final boolean CHECKS = true; + public static final int UINT32_MAX = 0xFFFFFFFF; public static final long UINT64_MAX = 0xFFFFFFFFFFFFFFFFL; @@ -43,74 +45,34 @@ public static PointerBuffer asPointerBuffer(Collection collection) { return buffer.rewind(); } - public static void memcpy(ByteBuffer buffer, short[] indices) { - - for(short index : indices) { - buffer.putShort(index); - } - - buffer.rewind(); - } - - public static void memcpy(ByteBuffer buffer, short[] indices, long offset) { - buffer.position((int) offset); - - for(short index : indices) { - buffer.putShort(index); - } - - buffer.rewind(); - } - - public static void memcpy(ByteBuffer src, ByteBuffer dst) { - MemoryUtil.memCopy(src, dst); - src.limit(src.capacity()).rewind(); - } - public static void memcpy(ByteBuffer src, long dstPtr) { MemoryUtil.memCopy(MemoryUtil.memAddress0(src), dstPtr, src.capacity()); } - public static void memcpy(ByteBuffer src, ByteBuffer dst, long offset) { - dst.position((int)offset); - - MemoryUtil.memCopy(src, dst); - src.limit(src.capacity()).rewind(); - } + public static void memcpy(ByteBuffer src, Buffer dst, long size) { + if (CHECKS) { + if (size > dst.getBufferSize() - dst.getUsedBytes()) { + throw new IllegalArgumentException("Upload size is greater than available dst buffer size"); + } + } - public static void memcpy(ByteBuffer src, ByteBuffer dst, int size, long offset) { - dst.position((int)offset); - src.limit(size); + final long srcPtr = MemoryUtil.memAddress(src); + final long dstPtr = dst.getDataPtr() + dst.getUsedBytes(); - MemoryUtil.memCopy(src, dst); - src.limit(src.capacity()).rewind(); + MemoryUtil.memCopy(srcPtr, dstPtr, size); } - public static void memcpyImage(ByteBuffer dst, ByteBuffer src, int width, int height, int channels, int unpackSkipRows, int unpackSkipPixels, int unpackRowLenght) { - int offset = (unpackSkipRows * unpackRowLenght + unpackSkipPixels) * channels; - for (int i = 0; i < height; ++i) { - src.limit(offset + width * channels); - src.position(offset); - dst.put(src); - offset += unpackRowLenght * channels; + public static void memcpy(Buffer src, ByteBuffer dst, long size) { + if (CHECKS) { + if (size > dst.remaining()) { + throw new IllegalArgumentException("Upload size is greater than available dst buffer size"); + } } - } - public static void memcpy(ByteBuffer buffer, FloatBuffer floatBuffer) { - while(floatBuffer.hasRemaining()) { - float f = floatBuffer.get(); - buffer.putFloat(f); - } - floatBuffer.position(0); - } + final long srcPtr = src.getDataPtr(); + final long dstPtr = MemoryUtil.memAddress(dst); - public static void memcpy(ByteBuffer buffer, FloatBuffer floatBuffer, long offset) { - buffer.position((int) offset); - while(floatBuffer.hasRemaining()) { - float f = floatBuffer.get(); - buffer.putFloat(f); - } - floatBuffer.position(0); + MemoryUtil.memCopy(srcPtr, dstPtr, size); } public static int align(int x, int align) { diff --git a/src/main/resources/assets/vulkanmod/lang/en_us.json b/src/main/resources/assets/vulkanmod/lang/en_us.json index 28f7ba3db..5880f84fc 100644 --- a/src/main/resources/assets/vulkanmod/lang/en_us.json +++ b/src/main/resources/assets/vulkanmod/lang/en_us.json @@ -28,13 +28,18 @@ "vulkanmod.options.frameQueue": "Render queue size", "vulkanmod.options.frameQueue.tooltip": "Higher values might help stabilize frametime but will increase input lag.", + "vulkanmod.options.backfaceCulling": "Backface Culling", + "vulkanmod.options.backfaceCulling.tooltip": "Culls not visible block faces on the CPU improving GPU performance. To prevent increased CPU overhead enable Indirect Draw.", + "vulkanmod.options.indirectDraw": "Indirect Draw", - "vulkanmod.options.indirectDraw.tooltip": "Reduces CPU overhead but increases GPU overhead. Enabling it might help in CPU limited systems.", + "vulkanmod.options.indirectDraw.tooltip": "Reduces CPU overhead but might increases GPU overhead.", "vulkanmod.options.refreshRate": "Refresh Rate", "vulkanmod.options.uniqueOpaqueLayer": "Unique opaque layer", "vulkanmod.options.uniqueOpaqueLayer.tooltip": "Use a unique render layer for opaque terrain to improve performance.", - "vulkanmod.options.windowedFullscreen": "Windowed Fullscreen" + "vulkanmod.options.windowMode": "Window Mode", + "vulkanmod.options.windowMode.windowed": "Windowed", + "vulkanmod.options.windowMode.windowedFullscreen": "Windowed Fullscreen" } \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/clouds/clouds.fsh b/src/main/resources/assets/vulkanmod/shaders/basic/clouds/clouds.fsh new file mode 100644 index 000000000..738d242d1 --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/basic/clouds/clouds.fsh @@ -0,0 +1,20 @@ +#version 450 + +layout(binding = 1) uniform UBO{ + vec4 ColorModulator; + vec4 FogColor; + float FogStart; + float FogEnd; +}; + +layout(location = 0) in vec4 vertexColor; +layout(location = 1) in float vertexDistance; + +layout(location = 0) out vec4 fragColor; + +void main() { + vec4 color = vertexColor * ColorModulator; + + float alpha = smoothstep(FogEnd, FogStart, vertexDistance); + fragColor = vec4(color.rgb, color.a * alpha); +} diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/clouds/clouds.json b/src/main/resources/assets/vulkanmod/shaders/basic/clouds/clouds.json new file mode 100644 index 000000000..ccfee165a --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/basic/clouds/clouds.json @@ -0,0 +1,17 @@ +{ + "vertex": "clouds", + "fragment": "clouds", + "samplers": [], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ModelOffset", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, + { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, + { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/clouds/clouds.vsh b/src/main/resources/assets/vulkanmod/shaders/basic/clouds/clouds.vsh new file mode 100644 index 000000000..203842a4e --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/basic/clouds/clouds.vsh @@ -0,0 +1,20 @@ +#version 450 + +layout(binding = 0) uniform UniformBufferObject { + mat4 MVP; + vec3 ModelOffset; +}; + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec4 Color; + +layout(location = 0) out vec4 vertexColor; +layout(location = 1) out float vertexDistance; + +void main() { + gl_Position = MVP * vec4(Position, 1.0); + vec3 viewPos = Position + ModelOffset; + vertexDistance = length(viewPos.xyz); + + vertexColor = Color; +} diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.fsh b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.fsh index 84146fa24..9da3f09ff 100644 --- a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.fsh @@ -12,9 +12,9 @@ layout(binding = 1) uniform UBO { float AlphaCutout; }; -layout(location = 0) in float vertexDistance; -layout(location = 1) in vec4 vertexColor; -layout(location = 2) in vec2 texCoord0; +layout(location = 0) in vec4 vertexColor; +layout(location = 1) in vec2 texCoord0; +layout(location = 2) in float vertexDistance; layout(location = 0) out vec4 fragColor; diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.json b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.json index bf010c54b..b527c5169 100644 --- a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.json +++ b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.json @@ -1,26 +1,10 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "rendertype_solid", - "fragment": "rendertype_solid", - "attributes": [ - "Position", - "Color", - "UV0" - ], + "vertex": "terrain", + "fragment": "terrain", "samplers": [ { "name": "Sampler0" }, { "name": "Sampler2" } ], - "uniforms": [ - { "name": "ChunkOffset", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } @@ -33,6 +17,6 @@ ] } ], "PushConstants": [ - { "name": "ChunkOffset", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] } + { "name": "ModelOffset", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] } ] } diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh index 87a3531d5..6c1c4bd86 100644 --- a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh @@ -8,50 +8,62 @@ layout (binding = 0) uniform UniformBufferObject { }; layout (push_constant) uniform pushConstant { - vec3 ChunkOffset; + vec3 ModelOffset; }; layout (binding = 3) uniform sampler2D Sampler2; -layout (location = 0) out float vertexDistance; -layout (location = 1) out vec4 vertexColor; -layout (location = 2) out vec2 texCoord0; +layout (location = 0) out vec4 vertexColor; +layout (location = 1) out vec2 texCoord0; +layout (location = 2) out float vertexDistance; +#define COMPRESSED_VERTEX + +#ifdef COMPRESSED_VERTEX //Compressed Vertex -layout (location = 0) in ivec4 Position; -layout (location = 1) in vec4 Color; -layout (location = 2) in uvec2 UV0; +#ifndef GCN_FIX + layout (location = 0) in ivec4 Position; + layout (location = 1) in vec4 Color; + layout (location = 2) in uvec2 UV0; +#else + layout (location = 0) in ivec4 Position; + layout (location = 1) in vec4 Color; + layout (location = 2) in uint UV0; +#endif + +#else + layout (location = 0) in vec3 Position; + layout (location = 1) in vec4 Color; + layout (location = 2) in vec2 UV0; + layout (location = 3) in ivec2 UV2; + layout (location = 4) in vec3 Normal; +#endif -const float UV_INV = 1.0 / 32768.0; -//const vec3 POSITION_INV = vec3(1.0 / 1024.0); +const float UV_INV = 1.0 / 65536.0; const vec3 POSITION_INV = vec3(1.0 / 2048.0); const vec3 POSITION_OFFSET = vec3(4.0); -void main() { +vec4 getVertexPosition() { const vec3 baseOffset = bitfieldExtract(ivec3(gl_InstanceIndex) >> ivec3(0, 16, 8), 0, 8); - const vec4 pos = vec4(fma(Position.xyz, POSITION_INV, ChunkOffset + baseOffset), 1.0); + + #ifdef COMPRESSED_VERTEX + return vec4(fma(Position.xyz, POSITION_INV, ModelOffset + baseOffset), 1.0); + #else + return vec4(Position.xyz + baseOffset, 1.0); + #endif +} + +void main() { + const vec4 pos = getVertexPosition(); gl_Position = MVP * pos; vertexDistance = fog_distance(pos.xyz, 0); vertexColor = Color * sample_lightmap2(Sampler2, Position.a); - texCoord0 = UV0 * UV_INV; -} -////Default Vertex -//layout(location = 0) in vec3 Position; -//layout(location = 1) in vec4 Color; -//layout(location = 2) in vec2 UV0; -//layout(location = 3) in ivec2 UV2; -//layout(location = 4) in vec3 Normal; -// -//void main() { -// const vec3 baseOffset = bitfieldExtract(ivec3(gl_InstanceIndex) >> ivec3(0, 16, 8), 0, 8); -// const vec4 pos = vec4(Position.xyz + baseOffset, 1.0); -// gl_Position = MVP * pos; -// -// vertexDistance = length((ModelViewMat * pos).xyz); -// vertexColor = Color * minecraft_sample_lightmap(Sampler2, UV2); -// texCoord0 = UV0; -// // normal = MVP * vec4(Normal, 0.0); -//} \ No newline at end of file + #ifndef GCN_FIX + texCoord0 = UV0 * UV_INV; + #else + texCoord0 = unpackUnorm2x16(UV0); + #endif +} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain_Z.fsh b/src/main/resources/assets/vulkanmod/shaders/basic/terrain_earlyZ/terrain_earlyZ.fsh similarity index 77% rename from src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain_Z.fsh rename to src/main/resources/assets/vulkanmod/shaders/basic/terrain_earlyZ/terrain_earlyZ.fsh index b3d4faf58..6ee8d3e74 100644 --- a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain_Z.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/basic/terrain_earlyZ/terrain_earlyZ.fsh @@ -1,5 +1,7 @@ #version 450 + layout(early_fragment_tests) in; + #include "light.glsl" #include "fog.glsl" @@ -11,10 +13,9 @@ layout(binding = 1) uniform UBO { float FogEnd; }; - -layout(location = 0) in float vertexDistance; -layout(location = 1) in vec4 vertexColor; -layout(location = 2) in vec2 texCoord0; +layout(location = 0) in vec4 vertexColor; +layout(location = 1) in vec2 texCoord0; +layout(location = 2) in float vertexDistance; layout(location = 0) out vec4 fragColor; diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/terrain_earlyZ/terrain_earlyZ.json b/src/main/resources/assets/vulkanmod/shaders/basic/terrain_earlyZ/terrain_earlyZ.json new file mode 100644 index 000000000..13062973c --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/basic/terrain_earlyZ/terrain_earlyZ.json @@ -0,0 +1,22 @@ +{ + "vertex": "terrain", + "fragment": "terrain_earlyZ", + "samplers": [ + { "name": "Sampler0" }, + { "name": "Sampler2" } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, + { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, + { "name": "AlphaCutout", "type": "float", "count": 1, "values": [ 1.0 ] } + ] } + ], + "PushConstants": [ + { "name": "ModelOffset", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.fsh b/src/main/resources/assets/vulkanmod/shaders/core/blit_screen/blit_screen.fsh similarity index 60% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/blit_screen/blit_screen.fsh index be1711e59..471982cdd 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/core/blit_screen/blit_screen.fsh @@ -1,6 +1,6 @@ #version 450 -layout(binding = 1) uniform sampler2D DiffuseSampler; +layout(binding = 0) uniform sampler2D DiffuseSampler; layout(location = 0) in vec2 texCoord; @@ -8,7 +8,5 @@ layout(location = 0) out vec4 fragColor; void main() { vec4 color = texture(DiffuseSampler, texCoord); - - // blit final output of compositor into displayed back buffer fragColor = color; } diff --git a/src/main/resources/assets/vulkanmod/shaders/core/blit_screen/blit_screen.json b/src/main/resources/assets/vulkanmod/shaders/core/blit_screen/blit_screen.json new file mode 100644 index 000000000..6405ec09d --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/blit_screen/blit_screen.json @@ -0,0 +1,9 @@ +{ + "vertex": "blit_screen", + "fragment": "blit_screen", + "samplers": [ + { "name": "Sampler0" } + ], + "uniforms": [ + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/core/blit_screen/blit_screen.vsh b/src/main/resources/assets/vulkanmod/shaders/core/blit_screen/blit_screen.vsh new file mode 100644 index 000000000..8cedf7251 --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/blit_screen/blit_screen.vsh @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) in vec3 Position; + +layout(location = 0) out vec2 texCoord; + +void main() { + vec2 screenPos = Position.xy * 2.0 - 1.0; + gl_Position = vec4(screenPos.x, screenPos.y, 1.0, 1.0); + texCoord = Position.xy; +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout/rendertype_entity_cutout.fsh b/src/main/resources/assets/vulkanmod/shaders/core/entity/entity.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout/rendertype_entity_cutout.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/entity/entity.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.vsh b/src/main/resources/assets/vulkanmod/shaders/core/entity/entity.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/entity/entity.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.fsh b/src/main/resources/assets/vulkanmod/shaders/core/glint/glint.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/glint/glint.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.vsh b/src/main/resources/assets/vulkanmod/shaders/core/glint/glint.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/glint/glint.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color/position_color.fsh b/src/main/resources/assets/vulkanmod/shaders/core/gui/gui.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color/position_color.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/gui/gui.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/core/gui/gui.vsh b/src/main/resources/assets/vulkanmod/shaders/core/gui/gui.vsh new file mode 100644 index 000000000..5fd8ccf2b --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/gui/gui.vsh @@ -0,0 +1,16 @@ +#version 450 + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec4 Color; + +layout(binding = 0) uniform UniformBufferObject { + mat4 MVP; +}; + +layout(location = 0) out vec4 vertexColor; + +void main() { + gl_Position = MVP * vec4(Position, 1.0); + + vertexColor = Color; +} diff --git a/src/main/resources/assets/vulkanmod/shaders/core/lightmap/lightmap.fsh b/src/main/resources/assets/vulkanmod/shaders/core/lightmap/lightmap.fsh new file mode 100644 index 000000000..8465e6034 --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/lightmap/lightmap.fsh @@ -0,0 +1,70 @@ +#version 450 + +layout(binding = 0) uniform UniformBufferObject { + float AmbientLightFactor; + float SkyFactor; + float BlockFactor; + int UseBrightLightmap; + vec3 SkyLightColor; + float NightVisionFactor; + float DarknessScale; + float DarkenWorldFactor; + float BrightnessFactor; +}; + +layout(location = 0) in vec2 texCoord; + +layout(location = 0) out vec4 fragColor; + +float get_brightness(float level) { + float curved_level = level / (4.0 - 3.0 * level); + return mix(curved_level, 1.0, AmbientLightFactor); +} + +vec3 notGamma(vec3 x) { + vec3 nx = 1.0 - x; + return 1.0 - nx * nx * nx * nx; +} + +void main() { + float block_brightness = get_brightness(floor(texCoord.x * 16) / 15) * BlockFactor; + float sky_brightness = get_brightness(floor(texCoord.y * 16) / 15) * SkyFactor; + + // cubic nonsense, dips to yellowish in the middle, white when fully saturated + vec3 color = vec3( + block_brightness, + block_brightness * ((block_brightness * 0.6 + 0.4) * 0.6 + 0.4), + block_brightness * (block_brightness * block_brightness * 0.6 + 0.4) + ); + + if (UseBrightLightmap != 0) { + color = mix(color, vec3(0.99, 1.12, 1.0), 0.25); + color = clamp(color, 0.0, 1.0); + } else { + color += SkyLightColor * sky_brightness; + color = mix(color, vec3(0.75), 0.04); + + vec3 darkened_color = color * vec3(0.7, 0.6, 0.6); + color = mix(color, darkened_color, DarkenWorldFactor); + } + + if (NightVisionFactor > 0.0) { + // scale up uniformly until 1.0 is hit by one of the colors + float max_component = max(color.r, max(color.g, color.b)); + if (max_component < 1.0) { + vec3 bright_color = color / max_component; + color = mix(color, bright_color, NightVisionFactor); + } + } + + if (UseBrightLightmap == 0) { + color = clamp(color - vec3(DarknessScale), 0.0, 1.0); + } + + vec3 notGamma = notGamma(color); + color = mix(color, notGamma, BrightnessFactor); + color = mix(color, vec3(0.75), 0.04); + color = clamp(color, 0.0, 1.0); + + fragColor = vec4(color, 1.0); +} diff --git a/src/main/resources/assets/vulkanmod/shaders/core/lightmap/lightmap.json b/src/main/resources/assets/vulkanmod/shaders/core/lightmap/lightmap.json new file mode 100644 index 000000000..5efc51dac --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/lightmap/lightmap.json @@ -0,0 +1,30 @@ +{ + "vertex": "blit_screen", + "fragment": "lightmap", + "samplers": [ + ], + "uniforms": [ + { "name": "AmbientLightFactor", "type": "float", "count": 1, "values": [1.0] }, + { "name": "SkyFactor", "type": "float", "count": 1, "values": [1.0] }, + { "name": "BlockFactor", "type": "float", "count": 1, "values": [1.0] }, + { "name": "UseBrightLightmap", "type": "int", "count": 1, "values": [0] }, + { "name": "SkyLightColor", "type": "float", "count": 3, "values": [1.0] }, + { "name": "NightVisionFactor", "type": "float", "count": 1, "values": [0.0] }, + { "name": "DarknessScale", "type": "float", "count": 1, "values": [0.0] }, + { "name": "DarkenWorldFactor", "type": "float", "count": 1, "values": [0.0] }, + { "name": "BrightnessFactor", "type": "float", "count": 1, "values": [1.0] } + ], + "UBOs": [ + { "type": "fragment", "binding": 0, "fields": [ + { "name": "AmbientLightFactor", "type": "float", "count": 1, "values": [1.0] }, + { "name": "SkyFactor", "type": "float", "count": 1, "values": [1.0] }, + { "name": "BlockFactor", "type": "float", "count": 1, "values": [1.0] }, + { "name": "UseBrightLightmap", "type": "int", "count": 1, "values": [0] }, + { "name": "SkyLightColor", "type": "float", "count": 3, "values": [1.0] }, + { "name": "NightVisionFactor", "type": "float", "count": 1, "values": [0.0] }, + { "name": "DarknessScale", "type": "float", "count": 1, "values": [0.0] }, + { "name": "DarkenWorldFactor", "type": "float", "count": 1, "values": [0.0] }, + { "name": "BrightnessFactor", "type": "float", "count": 1, "values": [1.0] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/particle/particle.fsh b/src/main/resources/assets/vulkanmod/shaders/core/particle/particle.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/particle/particle.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/particle/particle.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/particle/particle.json b/src/main/resources/assets/vulkanmod/shaders/core/particle/particle.json similarity index 58% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/particle/particle.json rename to src/main/resources/assets/vulkanmod/shaders/core/particle/particle.json index 6dddf404d..f43398ce0 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/particle/particle.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/particle/particle.json @@ -1,27 +1,10 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, "vertex": "particle", "fragment": "particle", - "attributes": [ - "Position", - "UV0", - "Color", - "UV2" - ], "samplers": [ { "name": "Sampler0" }, { "name": "Sampler2" } ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/particle/particle.vsh b/src/main/resources/assets/vulkanmod/shaders/core/particle/particle.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/particle/particle.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/particle/particle.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position/position.fsh b/src/main/resources/assets/vulkanmod/shaders/core/position/position.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position/position.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/position/position.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position/position.json b/src/main/resources/assets/vulkanmod/shaders/core/position/position.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position/position.json rename to src/main/resources/assets/vulkanmod/shaders/core/position/position.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position/position.vsh b/src/main/resources/assets/vulkanmod/shaders/core/position/position.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position/position.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/position/position.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/core/position_color/position_color.fsh b/src/main/resources/assets/vulkanmod/shaders/core/position_color/position_color.fsh new file mode 100644 index 000000000..fce9fa7c6 --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/position_color/position_color.fsh @@ -0,0 +1,17 @@ +#version 450 + +layout(location = 0) in vec4 vertexColor; + +layout(binding = 1) uniform UBO{ + vec4 ColorModulator; +}; + +layout(location = 0) out vec4 fragColor; + +void main() { + vec4 color = vertexColor; + if (color.a == 0.0) { + discard; + } + fragColor = color * ColorModulator; +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color/position_color.json b/src/main/resources/assets/vulkanmod/shaders/core/position_color/position_color.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color/position_color.json rename to src/main/resources/assets/vulkanmod/shaders/core/position_color/position_color.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color/position_color.vsh b/src/main/resources/assets/vulkanmod/shaders/core/position_color/position_color.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color/position_color.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_color/position_color.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.fsh b/src/main/resources/assets/vulkanmod/shaders/core/position_color_lightmap/position_color_lightmap.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_lightmap/position_color_lightmap.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.json b/src/main/resources/assets/vulkanmod/shaders/core/position_color_lightmap/position_color_lightmap.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.json rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_lightmap/position_color_lightmap.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.vsh b/src/main/resources/assets/vulkanmod/shaders/core/position_color_lightmap/position_color_lightmap.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_lightmap/position_color_lightmap.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.fsh b/src/main/resources/assets/vulkanmod/shaders/core/position_color_normal/position_color_normal.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_normal/position_color_normal.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.json b/src/main/resources/assets/vulkanmod/shaders/core/position_color_normal/position_color_normal.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.json rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_normal/position_color_normal.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.vsh b/src/main/resources/assets/vulkanmod/shaders/core/position_color_normal/position_color_normal.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_normal/position_color_normal.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex/position_color_tex.fsh b/src/main/resources/assets/vulkanmod/shaders/core/position_color_tex/position_color_tex.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex/position_color_tex.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_tex/position_color_tex.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex/position_color_tex.json b/src/main/resources/assets/vulkanmod/shaders/core/position_color_tex/position_color_tex.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex/position_color_tex.json rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_tex/position_color_tex.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex/position_color_tex.vsh b/src/main/resources/assets/vulkanmod/shaders/core/position_color_tex/position_color_tex.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex/position_color_tex.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_tex/position_color_tex.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.fsh b/src/main/resources/assets/vulkanmod/shaders/core/position_color_tex_lightmap/position_color_tex_lightmap.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_tex_lightmap/position_color_tex_lightmap.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.json b/src/main/resources/assets/vulkanmod/shaders/core/position_color_tex_lightmap/position_color_tex_lightmap.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.json rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_tex_lightmap/position_color_tex_lightmap.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.vsh b/src/main/resources/assets/vulkanmod/shaders/core/position_color_tex_lightmap/position_color_tex_lightmap.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_color_tex_lightmap/position_color_tex_lightmap.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex/position_tex.fsh b/src/main/resources/assets/vulkanmod/shaders/core/position_tex/position_tex.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex/position_tex.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_tex/position_tex.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex/position_tex.json b/src/main/resources/assets/vulkanmod/shaders/core/position_tex/position_tex.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex/position_tex.json rename to src/main/resources/assets/vulkanmod/shaders/core/position_tex/position_tex.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex/position_tex.vsh b/src/main/resources/assets/vulkanmod/shaders/core/position_tex/position_tex.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex/position_tex.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_tex/position_tex.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color/position_tex_color.fsh b/src/main/resources/assets/vulkanmod/shaders/core/position_tex_color/position_tex_color.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color/position_tex_color.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_tex_color/position_tex_color.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/core/position_tex_color/position_tex_color.json b/src/main/resources/assets/vulkanmod/shaders/core/position_tex_color/position_tex_color.json new file mode 100644 index 000000000..c3bbf9faf --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/position_tex_color/position_tex_color.json @@ -0,0 +1,20 @@ +{ + "vertex": "minecraft:core/position_tex_color", + "fragment": "minecraft:core/position_tex_color", + "samplers": [ + { "name": "Sampler0" } + ], + "uniforms": [ + { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color/position_tex_color.vsh b/src/main/resources/assets/vulkanmod/shaders/core/position_tex_color/position_tex_color.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color/position_tex_color.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_tex_color/position_tex_color.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.fsh b/src/main/resources/assets/vulkanmod/shaders/core/position_tex_color_normal/position_tex_color_normal.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_tex_color_normal/position_tex_color_normal.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.json b/src/main/resources/assets/vulkanmod/shaders/core/position_tex_color_normal/position_tex_color_normal.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.json rename to src/main/resources/assets/vulkanmod/shaders/core/position_tex_color_normal/position_tex_color_normal.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.vsh b/src/main/resources/assets/vulkanmod/shaders/core/position_tex_color_normal/position_tex_color_normal.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/position_tex_color_normal/position_tex_color_normal.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_cutout_no_cull/rendertype_armor_cutout_no_cull.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_glint/rendertype_armor_glint.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_glint/rendertype_armor_glint.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_glint/rendertype_armor_glint.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_glint/rendertype_armor_glint.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_entity_glint/rendertype_armor_entity_glint.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_glint/rendertype_armor_glint.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_glint/rendertype_armor_glint.json similarity index 56% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_glint/rendertype_armor_glint.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_glint/rendertype_armor_glint.json index 33c472d39..04bbe696c 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_armor_glint/rendertype_armor_glint.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_glint/rendertype_armor_glint.json @@ -1,24 +1,9 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "rendertype_armor_glint", - "fragment": "rendertype_armor_glint", - "attributes": [ - "Position", - "UV0" - ], + "vertex": "glint", + "fragment": "glint", "samplers": [ { "name": "Sampler0" } ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "TextureMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, diff --git a/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_translucent/rendertype_armor_translucent.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_translucent/rendertype_armor_translucent.json new file mode 100644 index 000000000..f393b88b0 --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_armor_translucent/rendertype_armor_translucent.json @@ -0,0 +1,29 @@ +{ + "vertex": "entity", + "fragment": "entity", + "defines": { + "values": { + "ALPHA_CUTOUT": "0.1" + }, + "flags": [ + "NO_OVERLAY" + ] + }, + "samplers": [ + { "name": "Sampler0" }, + { "name": "Sampler2" } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, + { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, + { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, + { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_beacon_beam/rendertype_beacon_beam.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_beacon_beam/rendertype_beacon_beam.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_beacon_beam/rendertype_beacon_beam.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_beacon_beam/rendertype_beacon_beam.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_beacon_beam/rendertype_beacon_beam.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_beacon_beam/rendertype_beacon_beam.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_beacon_beam/rendertype_beacon_beam.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_beacon_beam/rendertype_beacon_beam.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_beacon_beam/rendertype_beacon_beam.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_beacon_beam/rendertype_beacon_beam.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_beacon_beam/rendertype_beacon_beam.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_beacon_beam/rendertype_beacon_beam.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_breeze_wind/rendertype_breeze_wind.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_breeze_wind/rendertype_breeze_wind.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_breeze_wind/rendertype_breeze_wind.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_breeze_wind/rendertype_breeze_wind.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_breeze_wind/rendertype_breeze_wind.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_breeze_wind/rendertype_breeze_wind.json similarity index 57% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_breeze_wind/rendertype_breeze_wind.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_breeze_wind/rendertype_breeze_wind.json index 17a3bd328..5f2a6453e 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_breeze_wind/rendertype_breeze_wind.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_breeze_wind/rendertype_breeze_wind.json @@ -1,29 +1,10 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, "vertex": "rendertype_breeze_wind", "fragment": "rendertype_breeze_wind", - "attributes": [ - "Position", - "Color", - "UV0", - "UV2" - ], "samplers": [ { "name": "Sampler0" }, { "name": "Sampler2" } ], - "uniforms": [ - { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, - { "name": "TextureMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "FogShape", "type": "int", "count": 1, "values": [ 0 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_breeze_wind/rendertype_breeze_wind.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_breeze_wind/rendertype_breeze_wind.vsh similarity index 82% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_breeze_wind/rendertype_breeze_wind.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_breeze_wind/rendertype_breeze_wind.vsh index 714c6e1a7..94a186ffd 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_breeze_wind/rendertype_breeze_wind.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_breeze_wind/rendertype_breeze_wind.vsh @@ -14,7 +14,7 @@ layout(binding = 0) uniform UniformBufferObject { int FogShape; }; -layout(binding = 4) uniform sampler2D Sampler2; +layout(binding = 3) uniform sampler2D Sampler2; layout(location = 0) out float vertexDistance; layout(location = 1) out vec4 vertexColor; @@ -24,8 +24,7 @@ layout(location = 3) out vec2 texCoord0; void main() { gl_Position = MVP * vec4(Position, 1.0); - vec4 pos = ModelViewMat * (Position, 1.0); - vertexDistance = fog_distance(pos.xyz, FogShape); + vertexDistance = fog_distance(Position, FogShape); lightMapColor = texelFetch(Sampler2, UV2 / 16, 0); vertexColor = Color * lightMapColor; diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_clouds/rendertype_clouds.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_clouds/rendertype_clouds.fsh similarity index 67% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_clouds/rendertype_clouds.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_clouds/rendertype_clouds.fsh index db89144f5..2a3e1b369 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_clouds/rendertype_clouds.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_clouds/rendertype_clouds.fsh @@ -2,27 +2,19 @@ #include "fog.glsl" -layout(binding = 2) uniform sampler2D Sampler0; - layout(binding = 1) uniform UBO{ - vec4 ColorModulator; vec4 FogColor; float FogStart; float FogEnd; }; layout(location = 0) in vec4 vertexColor; -layout(location = 1) in vec2 texCoord0; -layout(location = 2) in float vertexDistance; +layout(location = 1) in float vertexDistance; layout(location = 0) out vec4 fragColor; void main() { - vec4 color = texture(Sampler0, texCoord0) * vertexColor * ColorModulator; - if (color.a < 0.1) { - discard; - } - fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); + fragColor = linear_fog(vertexColor, vertexDistance, FogStart, FogEnd, FogColor); } //#version 150 diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_clouds/rendertype_clouds.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_clouds/rendertype_clouds.json similarity index 84% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_clouds/rendertype_clouds.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_clouds/rendertype_clouds.json index 7798d39af..d36098bcf 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_clouds/rendertype_clouds.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_clouds/rendertype_clouds.json @@ -1,17 +1,12 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "rendertype_clouds", - "fragment": "rendertype_clouds", + "vertex": "minecraft:core/rendertype_clouds", + "fragment": "minecraft:core/rendertype_clouds", "samplers": [ - { "name": "Sampler0" } ], "uniforms": [ { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ModelOffset", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] }, { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, @@ -25,7 +20,6 @@ { "name": "FogShape", "type": "int", "count": 1, "values": [ 0 ] } ] }, { "type": "fragment", "binding": 1, "fields": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_clouds/rendertype_clouds.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_clouds/rendertype_clouds.vsh similarity index 57% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_clouds/rendertype_clouds.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_clouds/rendertype_clouds.vsh index 289748aef..7b65d9058 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_clouds/rendertype_clouds.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_clouds/rendertype_clouds.vsh @@ -26,29 +26,3 @@ void main() { vertexDistance = fog_distance(pos.xyz, FogShape); vertexColor = Color; } - -//#version 150 -// -//#moj_import -// -//in vec3 Position; -//in vec2 UV0; -//in vec4 Color; -//in vec3 Normal; -// -//uniform mat4 ModelViewMat; -//uniform mat4 ProjMat; -//uniform int FogShape; -// -//out vec2 texCoord0; -//out float vertexDistance; -//out vec4 vertexColor; -// -//void main() { -// vec4 pos = ModelViewMat * vec4(Position, 1.0); -// gl_Position = ProjMat * pos; -// -// texCoord0 = UV0; -// vertexDistance = fog_distance(pos.xyz, FogShape); -// vertexColor = Color; -//} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_crumbling/rendertype_crumbling.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_crumbling/rendertype_crumbling.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_crumbling/rendertype_crumbling.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_crumbling/rendertype_crumbling.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_crumbling/rendertype_crumbling.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_crumbling/rendertype_crumbling.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_crumbling/rendertype_crumbling.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_crumbling/rendertype_crumbling.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_crumbling/rendertype_crumbling.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_crumbling/rendertype_crumbling.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_crumbling/rendertype_crumbling.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_crumbling/rendertype_crumbling.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout/rendertype_cutout.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout/rendertype_cutout.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout/rendertype_cutout.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout/rendertype_cutout.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout/rendertype_cutout.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout/rendertype_cutout.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout/rendertype_cutout.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout/rendertype_cutout.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout/rendertype_cutout.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout/rendertype_cutout.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout/rendertype_cutout.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout/rendertype_cutout.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout_mipped/rendertype_cutout_mipped.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout_mipped/rendertype_cutout_mipped.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout_mipped/rendertype_cutout_mipped.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout_mipped/rendertype_cutout_mipped.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout_mipped/rendertype_cutout_mipped.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout_mipped/rendertype_cutout_mipped.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout_mipped/rendertype_cutout_mipped.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout_mipped/rendertype_cutout_mipped.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout_mipped/rendertype_cutout_mipped.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout_mipped/rendertype_cutout_mipped.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_cutout_mipped/rendertype_cutout_mipped.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_cutout_mipped/rendertype_cutout_mipped.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/core/rendertype_end_gateway/rendertype_end_gateway.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_end_gateway/rendertype_end_gateway.json new file mode 100644 index 000000000..8e6cb7d0b --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_end_gateway/rendertype_end_gateway.json @@ -0,0 +1,17 @@ +{ + "vertex": "rendertype_end_portal", + "fragment": "rendertype_end_portal", + "samplers": [ + { "name": "Sampler0" }, + { "name": "Sampler1" } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "GameTime", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "EndPortalLayers", "type": "int", "count": 1, "values": [ 15 ] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_end_portal/rendertype_end_portal.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_end_portal/rendertype_end_portal.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_end_portal/rendertype_end_portal.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_end_portal/rendertype_end_portal.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_end_portal/rendertype_end_portal.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_end_portal/rendertype_end_portal.json similarity index 67% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_end_portal/rendertype_end_portal.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_end_portal/rendertype_end_portal.json index 8854d96e4..8e6cb7d0b 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_end_portal/rendertype_end_portal.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_end_portal/rendertype_end_portal.json @@ -1,20 +1,10 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, "vertex": "rendertype_end_portal", "fragment": "rendertype_end_portal", - "attributes": [], "samplers": [ { "name": "Sampler0" }, { "name": "Sampler1" } ], - "uniforms": [ - { "name": "GameTime", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "EndPortalLayers", "type": "int", "count": 1, "values": [ 15 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_end_portal/rendertype_end_portal.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_end_portal/rendertype_end_portal.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_end_portal/rendertype_end_portal.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_end_portal/rendertype_end_portal.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_energy_swirl/rendertype_energy_swirl.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_energy_swirl/rendertype_energy_swirl.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_energy_swirl/rendertype_energy_swirl.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_energy_swirl/rendertype_energy_swirl.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_energy_swirl/rendertype_energy_swirl.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_energy_swirl/rendertype_energy_swirl.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_energy_swirl/rendertype_energy_swirl.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_energy_swirl/rendertype_energy_swirl.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_energy_swirl/rendertype_energy_swirl.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_energy_swirl/rendertype_energy_swirl.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_energy_swirl/rendertype_energy_swirl.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_energy_swirl/rendertype_energy_swirl.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_alpha/rendertype_entity_alpha.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_alpha/rendertype_entity_alpha.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_alpha/rendertype_entity_alpha.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_alpha/rendertype_entity_alpha.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_alpha/rendertype_entity_alpha.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_alpha/rendertype_entity_alpha.json similarity index 64% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_alpha/rendertype_entity_alpha.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_alpha/rendertype_entity_alpha.json index 4caff8079..edbd117d5 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_alpha/rendertype_entity_alpha.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_alpha/rendertype_entity_alpha.json @@ -1,21 +1,9 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, "vertex": "rendertype_entity_alpha", "fragment": "rendertype_entity_alpha", - "attributes": [ - "Position", - "Color", - "UV0", - "Normal" - ], "samplers": [ { "name": "Sampler0" } ], - "uniforms": [], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_alpha/rendertype_entity_alpha.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_alpha/rendertype_entity_alpha.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_alpha/rendertype_entity_alpha.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_alpha/rendertype_entity_alpha.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout/rendertype_entity_cutout.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_cutout/rendertype_entity_cutout.json similarity index 53% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout/rendertype_entity_cutout.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_cutout/rendertype_entity_cutout.json index 51ae16d55..ea44c9e1e 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout/rendertype_entity_cutout.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_cutout/rendertype_entity_cutout.json @@ -1,32 +1,16 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" + "vertex": "entity", + "fragment": "entity", + "defines": { + "values": { + "ALPHA_CUTOUT": "0.1" + } }, - "vertex": "rendertype_entity_cutout", - "fragment": "rendertype_entity_cutout", - "attributes": [ - "Position", - "Color", - "UV0", - "UV1", - "UV2", - "Normal" - ], "samplers": [ { "name": "Sampler0" }, { "name": "Sampler1" }, { "name": "Sampler2" } ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, diff --git a/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.json new file mode 100644 index 000000000..ea44c9e1e --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.json @@ -0,0 +1,27 @@ +{ + "vertex": "entity", + "fragment": "entity", + "defines": { + "values": { + "ALPHA_CUTOUT": "0.1" + } + }, + "samplers": [ + { "name": "Sampler0" }, + { "name": "Sampler1" }, + { "name": "Sampler2" } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, + { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, + { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, + { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.json new file mode 100644 index 000000000..ea44c9e1e --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.json @@ -0,0 +1,27 @@ +{ + "vertex": "entity", + "fragment": "entity", + "defines": { + "values": { + "ALPHA_CUTOUT": "0.1" + } + }, + "samplers": [ + { "name": "Sampler0" }, + { "name": "Sampler1" }, + { "name": "Sampler2" } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, + { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, + { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, + { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_decal/rendertype_entity_decal.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_decal/rendertype_entity_decal.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_decal/rendertype_entity_decal.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_decal/rendertype_entity_decal.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_decal/rendertype_entity_decal.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_decal/rendertype_entity_decal.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_decal/rendertype_entity_decal.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_decal/rendertype_entity_decal.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_decal/rendertype_entity_decal.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_decal/rendertype_entity_decal.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_decal/rendertype_entity_decal.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_decal/rendertype_entity_decal.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint/rendertype_entity_glint.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint/rendertype_entity_glint.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint/rendertype_entity_glint.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint/rendertype_entity_glint.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint/rendertype_entity_glint.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint/rendertype_entity_glint.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint/rendertype_entity_glint.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint/rendertype_entity_glint.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint/rendertype_entity_glint.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint/rendertype_entity_glint.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint/rendertype_entity_glint.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint/rendertype_entity_glint.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_glint_direct/rendertype_entity_glint_direct.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_no_outline/rendertype_entity_no_outline.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_no_outline/rendertype_entity_no_outline.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_no_outline/rendertype_entity_no_outline.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_no_outline/rendertype_entity_no_outline.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_no_outline/rendertype_entity_no_outline.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_no_outline/rendertype_entity_no_outline.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_no_outline/rendertype_entity_no_outline.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_no_outline/rendertype_entity_no_outline.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_no_outline/rendertype_entity_no_outline.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_no_outline/rendertype_entity_no_outline.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_no_outline/rendertype_entity_no_outline.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_no_outline/rendertype_entity_no_outline.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_shadow/rendertype_entity_shadow.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_shadow/rendertype_entity_shadow.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_shadow/rendertype_entity_shadow.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_shadow/rendertype_entity_shadow.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_shadow/rendertype_entity_shadow.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_shadow/rendertype_entity_shadow.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_shadow/rendertype_entity_shadow.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_shadow/rendertype_entity_shadow.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_shadow/rendertype_entity_shadow.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_shadow/rendertype_entity_shadow.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_shadow/rendertype_entity_shadow.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_shadow/rendertype_entity_shadow.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.json new file mode 100644 index 000000000..ea44c9e1e --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.json @@ -0,0 +1,27 @@ +{ + "vertex": "entity", + "fragment": "entity", + "defines": { + "values": { + "ALPHA_CUTOUT": "0.1" + } + }, + "samplers": [ + { "name": "Sampler0" }, + { "name": "Sampler1" }, + { "name": "Sampler2" } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, + { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, + { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, + { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_solid/rendertype_entity_solid.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_solid/rendertype_entity_solid.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_solid/rendertype_entity_solid.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_solid/rendertype_entity_solid.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_solid/rendertype_entity_solid.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_solid/rendertype_entity_solid.json similarity index 57% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_solid/rendertype_entity_solid.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_solid/rendertype_entity_solid.json index e3d0c8b9d..0e4e0177b 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_solid/rendertype_entity_solid.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_solid/rendertype_entity_solid.json @@ -1,32 +1,11 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, "vertex": "rendertype_entity_solid", "fragment": "rendertype_entity_solid", - "attributes": [ - "Position", - "Color", - "UV0", - "UV1", - "UV2", - "Normal" - ], "samplers": [ { "name": "Sampler0" }, { "name": "Sampler1" }, { "name": "Sampler2" } ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_solid/rendertype_entity_solid.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_solid/rendertype_entity_solid.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_solid/rendertype_entity_solid.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_solid/rendertype_entity_solid.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent/rendertype_entity_translucent.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent/rendertype_entity_translucent.json similarity index 53% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent/rendertype_entity_translucent.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent/rendertype_entity_translucent.json index a3f707107..ea44c9e1e 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent/rendertype_entity_translucent.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent/rendertype_entity_translucent.json @@ -1,32 +1,16 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" + "vertex": "entity", + "fragment": "entity", + "defines": { + "values": { + "ALPHA_CUTOUT": "0.1" + } }, - "vertex": "rendertype_entity_translucent", - "fragment": "rendertype_entity_translucent", - "attributes": [ - "Position", - "Color", - "UV0", - "UV1", - "UV2", - "Normal" - ], "samplers": [ { "name": "Sampler0" }, { "name": "Sampler1" }, { "name": "Sampler2" } ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.json similarity index 94% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.json index 3f5cf9af4..3586e725a 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.json @@ -1,9 +1,4 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, "vertex": "rendertype_entity_translucent_cull", "fragment": "rendertype_entity_translucent_cull", "attributes": [ diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_cull/rendertype_entity_translucent_cull.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_entity_translucent_emissive/rendertype_entity_translucent_emissive.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_eyes/rendertype_eyes.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_eyes/rendertype_eyes.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_eyes/rendertype_eyes.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_eyes/rendertype_eyes.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_eyes/rendertype_eyes.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_eyes/rendertype_eyes.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_eyes/rendertype_eyes.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_eyes/rendertype_eyes.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_eyes/rendertype_eyes.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_eyes/rendertype_eyes.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_eyes/rendertype_eyes.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_eyes/rendertype_eyes.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint/rendertype_glint.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_glint/rendertype_glint.json similarity index 56% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint/rendertype_glint.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_glint/rendertype_glint.json index 83e0056a2..04bbe696c 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint/rendertype_glint.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_glint/rendertype_glint.json @@ -1,24 +1,9 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "rendertype_glint", - "fragment": "rendertype_glint", - "attributes": [ - "Position", - "UV0" - ], + "vertex": "glint", + "fragment": "glint", "samplers": [ { "name": "Sampler0" } ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "TextureMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_direct/rendertype_glint_direct.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_glint_direct/rendertype_glint_direct.json similarity index 55% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_direct/rendertype_glint_direct.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_glint_direct/rendertype_glint_direct.json index d016ddf12..aadaa01d4 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_direct/rendertype_glint_direct.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_glint_direct/rendertype_glint_direct.json @@ -1,29 +1,14 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "rendertype_glint_direct", - "fragment": "rendertype_glint_direct", - "attributes": [ - "Position", - "UV0" - ], + "vertex": "glint", + "fragment": "glint", "samplers": [ { "name": "Sampler0" } ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "TextureMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, { "name": "TextureMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } - ] }, + ] }, { "type": "fragment", "binding": 1, "fields": [ { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_translucent/rendertype_glint_translucent.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_glint_translucent/rendertype_glint_translucent.json similarity index 55% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_translucent/rendertype_glint_translucent.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_glint_translucent/rendertype_glint_translucent.json index 4fbd62b86..aadaa01d4 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_translucent/rendertype_glint_translucent.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_glint_translucent/rendertype_glint_translucent.json @@ -1,29 +1,14 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "rendertype_glint_translucent", - "fragment": "rendertype_glint_translucent", - "attributes": [ - "Position", - "UV0" - ], + "vertex": "glint", + "fragment": "glint", "samplers": [ { "name": "Sampler0" } ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "TextureMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } - ], "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, { "name": "TextureMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } - ] }, + ] }, { "type": "fragment", "binding": 1, "fields": [ { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color/position_tex_color.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui/rendertype_gui.json similarity index 59% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color/position_tex_color.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui/rendertype_gui.json index e65c24526..904c1badf 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color/position_tex_color.json +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui/rendertype_gui.json @@ -1,20 +1,11 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "position_tex_color", - "fragment": "position_tex_color", - "attributes": [ - "Position", - "UV0", - "Color" - ], + "vertex": "minecraft:core/gui", + "fragment": "minecraft:core/gui", "samplers": [ - { "name": "Sampler0" } ], "uniforms": [ + { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } ], "UBOs": [ diff --git a/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui_ghost_recipe_overlay.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui_ghost_recipe_overlay.json new file mode 100644 index 000000000..904c1badf --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui_ghost_recipe_overlay.json @@ -0,0 +1,19 @@ +{ + "vertex": "minecraft:core/gui", + "fragment": "minecraft:core/gui", + "samplers": [ + ], + "uniforms": [ + { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui_overlay/rendertype_gui_overlay.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui_overlay/rendertype_gui_overlay.json new file mode 100644 index 000000000..904c1badf --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui_overlay/rendertype_gui_overlay.json @@ -0,0 +1,19 @@ +{ + "vertex": "minecraft:core/gui", + "fragment": "minecraft:core/gui", + "samplers": [ + ], + "uniforms": [ + { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui_text_highlight.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui_text_highlight.json new file mode 100644 index 000000000..904c1badf --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_gui_text_highlight.json @@ -0,0 +1,19 @@ +{ + "vertex": "minecraft:core/gui", + "fragment": "minecraft:core/gui", + "samplers": [ + ], + "uniforms": [ + { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] } + ] +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_item_entity_translucent_cull/rendertype_item_entity_translucent_cull.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_leash/rendertype_leash.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_leash/rendertype_leash.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_leash/rendertype_leash.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_leash/rendertype_leash.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_leash/rendertype_leash.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_leash/rendertype_leash.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_leash/rendertype_leash.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_leash/rendertype_leash.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_leash/rendertype_leash.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_leash/rendertype_leash.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_leash/rendertype_leash.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_leash/rendertype_leash.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lightning/rendertype_lightning.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_lightning/rendertype_lightning.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lightning/rendertype_lightning.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_lightning/rendertype_lightning.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lightning/rendertype_lightning.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_lightning/rendertype_lightning.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lightning/rendertype_lightning.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_lightning/rendertype_lightning.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lightning/rendertype_lightning.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_lightning/rendertype_lightning.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lightning/rendertype_lightning.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_lightning/rendertype_lightning.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lines/rendertype_lines.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_lines/rendertype_lines.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lines/rendertype_lines.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_lines/rendertype_lines.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lines/rendertype_lines.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_lines/rendertype_lines.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lines/rendertype_lines.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_lines/rendertype_lines.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lines/rendertype_lines.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_lines/rendertype_lines.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_lines/rendertype_lines.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_lines/rendertype_lines.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_outline/rendertype_outline.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_outline/rendertype_outline.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_outline/rendertype_outline.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_outline/rendertype_outline.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_outline/rendertype_outline.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_outline/rendertype_outline.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_outline/rendertype_outline.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_outline/rendertype_outline.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_outline/rendertype_outline.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_outline/rendertype_outline.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_outline/rendertype_outline.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_outline/rendertype_outline.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_solid/rendertype_solid.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_solid/rendertype_solid.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_solid/rendertype_solid.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_solid/rendertype_solid.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_solid/rendertype_solid.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_solid/rendertype_solid.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_solid/rendertype_solid.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_solid/rendertype_solid.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_solid/rendertype_solid.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_solid/rendertype_solid.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_solid/rendertype_solid.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_solid/rendertype_solid.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text/rendertype_text.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text/rendertype_text.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text/rendertype_text.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text/rendertype_text.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text/rendertype_text.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text/rendertype_text.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text/rendertype_text.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text/rendertype_text.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text/rendertype_text.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text/rendertype_text.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text/rendertype_text.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text/rendertype_text.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background/rendertype_text_background.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background/rendertype_text_background.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background/rendertype_text_background.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background/rendertype_text_background.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background/rendertype_text_background.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background/rendertype_text_background.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background/rendertype_text_background.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background/rendertype_text_background.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background/rendertype_text_background.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background/rendertype_text_background.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background/rendertype_text_background.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background/rendertype_text_background.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background_see_through/rendertype_text_background_see_through.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background_see_through/rendertype_text_background_see_through.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background_see_through/rendertype_text_background_see_through.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background_see_through/rendertype_text_background_see_through.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background_see_through/rendertype_text_background_see_through.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_background_see_through/rendertype_text_background_see_through.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity/rendertype_text_intensity.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity/rendertype_text_intensity.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity/rendertype_text_intensity.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity/rendertype_text_intensity.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity/rendertype_text_intensity.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity/rendertype_text_intensity.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity/rendertype_text_intensity.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity/rendertype_text_intensity.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity/rendertype_text_intensity.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity/rendertype_text_intensity.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity/rendertype_text_intensity.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity/rendertype_text_intensity.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_intensity_see_through/rendertype_text_intensity_see_through.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_see_through/rendertype_text_see_through.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_see_through/rendertype_text_see_through.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_see_through/rendertype_text_see_through.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_see_through/rendertype_text_see_through.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_see_through/rendertype_text_see_through.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_text_see_through/rendertype_text_see_through.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent/rendertype_translucent.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent/rendertype_translucent.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent/rendertype_translucent.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent/rendertype_translucent.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent/rendertype_translucent.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent/rendertype_translucent.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent/rendertype_translucent.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent/rendertype_translucent.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent/rendertype_translucent.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent/rendertype_translucent.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent/rendertype_translucent.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent/rendertype_translucent.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_moving_block/rendertype_translucent_moving_block.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_translucent_no_crumbling/rendertype_translucent_no_crumbling.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_tripwire/rendertype_tripwire.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_tripwire/rendertype_tripwire.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_tripwire/rendertype_tripwire.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_tripwire/rendertype_tripwire.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_tripwire/rendertype_tripwire.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_tripwire/rendertype_tripwire.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_tripwire/rendertype_tripwire.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_tripwire/rendertype_tripwire.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_tripwire/rendertype_tripwire.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_tripwire/rendertype_tripwire.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_tripwire/rendertype_tripwire.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_tripwire/rendertype_tripwire.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_water_mask/rendertype_water_mask.fsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_water_mask/rendertype_water_mask.fsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_water_mask/rendertype_water_mask.fsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_water_mask/rendertype_water_mask.fsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_water_mask/rendertype_water_mask.json b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_water_mask/rendertype_water_mask.json similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_water_mask/rendertype_water_mask.json rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_water_mask/rendertype_water_mask.json diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_water_mask/rendertype_water_mask.vsh b/src/main/resources/assets/vulkanmod/shaders/core/rendertype_water_mask/rendertype_water_mask.vsh similarity index 100% rename from src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_water_mask/rendertype_water_mask.vsh rename to src/main/resources/assets/vulkanmod/shaders/core/rendertype_water_mask/rendertype_water_mask.vsh diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.json b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.json deleted file mode 100644 index bd9707c0e..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "blit_screen", - "fragment": "blit_screen", - "attributes": [ - "Position", - "UV", - "Color" - ], - "samplers": [], - "uniforms": [], - "UBOs": [] -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.vsh deleted file mode 100644 index e3dd01d3c..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.vsh +++ /dev/null @@ -1,12 +0,0 @@ -#version 450 - -layout(location = 0) in vec3 Position; -layout(location = 1) in vec2 UV; - -layout(location = 0) out vec2 texCoord; - -void main() { - gl_Position = vec4(Position, 1.0); - - texCoord = UV; -} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout/rendertype_entity_cutout.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout/rendertype_entity_cutout.vsh deleted file mode 100644 index 46038952c..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout/rendertype_entity_cutout.vsh +++ /dev/null @@ -1,36 +0,0 @@ -#version 450 - -#include "light.glsl" -#include "fog.glsl" - -layout(location = 0) in vec3 Position; -layout(location = 1) in vec4 Color; -layout(location = 2) in vec2 UV0; -layout(location = 3) in ivec2 UV1; -layout(location = 4) in ivec2 UV2; -layout(location = 5) in vec3 Normal; - -layout(binding = 0) uniform UniformBufferObject { - mat4 MVP; - vec3 Light0_Direction; - vec3 Light1_Direction; -}; - -layout(binding = 3) uniform sampler2D Sampler1; -layout(binding = 4) uniform sampler2D Sampler2; - -layout(location = 0) out vec4 vertexColor; -layout(location = 1) out vec4 lightMapColor; -layout(location = 2) out vec4 overlayColor; -layout(location = 3) out vec2 texCoord0; -layout(location = 4) out float vertexDistance; - -void main() { - gl_Position = MVP * vec4(Position, 1.0); - - vertexDistance = fog_distance(Position.xyz, 0); - vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color); - lightMapColor = texelFetch(Sampler2, UV2 / 16, 0); - overlayColor = texelFetch(Sampler1, UV1, 0); - texCoord0 = UV0; -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.fsh deleted file mode 100644 index fe257648a..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.fsh +++ /dev/null @@ -1,30 +0,0 @@ -#version 450 -#include "fog.glsl" - -layout(binding = 2) uniform sampler2D Sampler0; - -layout(binding = 1) uniform UBO{ - vec4 ColorModulator; - vec4 FogColor; - float FogStart; - float FogEnd; -}; - -layout(location = 0) in vec4 vertexColor; -layout(location = 1) in vec4 lightMapColor; -layout(location = 2) in vec4 overlayColor; -layout(location = 3) in vec2 texCoord0; -layout(location = 4) in float vertexDistance; - -layout(location = 0) out vec4 fragColor; - -void main() { - vec4 color = texture(Sampler0, texCoord0); - if (color.a < 0.1) { - discard; - } - color *= vertexColor * ColorModulator; - color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a); - color *= lightMapColor; - fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); -} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.json b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.json deleted file mode 100644 index d04943b44..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "rendertype_entity_cutout_no_cull", - "fragment": "rendertype_entity_cutout_no_cull", - "attributes": [ - "Position", - "Color", - "UV0", - "UV1", - "UV2", - "Normal" - ], - "samplers": [ - { "name": "Sampler0" }, - { "name": "Sampler1" }, - { "name": "Sampler2" } - ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] } - ], - "UBOs": [ - { "type": "vertex", "binding": 0, "fields": [ - { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, - { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] } - ] }, - { "type": "fragment", "binding": 1, "fields": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } - ] } - ] -} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.vsh deleted file mode 100644 index 46038952c..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.vsh +++ /dev/null @@ -1,36 +0,0 @@ -#version 450 - -#include "light.glsl" -#include "fog.glsl" - -layout(location = 0) in vec3 Position; -layout(location = 1) in vec4 Color; -layout(location = 2) in vec2 UV0; -layout(location = 3) in ivec2 UV1; -layout(location = 4) in ivec2 UV2; -layout(location = 5) in vec3 Normal; - -layout(binding = 0) uniform UniformBufferObject { - mat4 MVP; - vec3 Light0_Direction; - vec3 Light1_Direction; -}; - -layout(binding = 3) uniform sampler2D Sampler1; -layout(binding = 4) uniform sampler2D Sampler2; - -layout(location = 0) out vec4 vertexColor; -layout(location = 1) out vec4 lightMapColor; -layout(location = 2) out vec4 overlayColor; -layout(location = 3) out vec2 texCoord0; -layout(location = 4) out float vertexDistance; - -void main() { - gl_Position = MVP * vec4(Position, 1.0); - - vertexDistance = fog_distance(Position.xyz, 0); - vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color); - lightMapColor = texelFetch(Sampler2, UV2 / 16, 0); - overlayColor = texelFetch(Sampler1, UV1, 0); - texCoord0 = UV0; -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.fsh deleted file mode 100644 index fe257648a..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.fsh +++ /dev/null @@ -1,30 +0,0 @@ -#version 450 -#include "fog.glsl" - -layout(binding = 2) uniform sampler2D Sampler0; - -layout(binding = 1) uniform UBO{ - vec4 ColorModulator; - vec4 FogColor; - float FogStart; - float FogEnd; -}; - -layout(location = 0) in vec4 vertexColor; -layout(location = 1) in vec4 lightMapColor; -layout(location = 2) in vec4 overlayColor; -layout(location = 3) in vec2 texCoord0; -layout(location = 4) in float vertexDistance; - -layout(location = 0) out vec4 fragColor; - -void main() { - vec4 color = texture(Sampler0, texCoord0); - if (color.a < 0.1) { - discard; - } - color *= vertexColor * ColorModulator; - color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a); - color *= lightMapColor; - fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); -} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.json b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.json deleted file mode 100644 index 45caf5fb9..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "rendertype_entity_cutout_no_cull_z_offset", - "fragment": "rendertype_entity_cutout_no_cull_z_offset", - "attributes": [ - "Position", - "Color", - "UV0", - "UV1", - "UV2", - "Normal" - ], - "samplers": [ - { "name": "Sampler0" }, - { "name": "Sampler1" }, - { "name": "Sampler2" } - ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] } - ], - "UBOs": [ - { "type": "vertex", "binding": 0, "fields": [ - { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, - { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] } - ] }, - { "type": "fragment", "binding": 1, "fields": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } - ] } - ] -} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.fsh deleted file mode 100644 index fe257648a..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.fsh +++ /dev/null @@ -1,30 +0,0 @@ -#version 450 -#include "fog.glsl" - -layout(binding = 2) uniform sampler2D Sampler0; - -layout(binding = 1) uniform UBO{ - vec4 ColorModulator; - vec4 FogColor; - float FogStart; - float FogEnd; -}; - -layout(location = 0) in vec4 vertexColor; -layout(location = 1) in vec4 lightMapColor; -layout(location = 2) in vec4 overlayColor; -layout(location = 3) in vec2 texCoord0; -layout(location = 4) in float vertexDistance; - -layout(location = 0) out vec4 fragColor; - -void main() { - vec4 color = texture(Sampler0, texCoord0); - if (color.a < 0.1) { - discard; - } - color *= vertexColor * ColorModulator; - color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a); - color *= lightMapColor; - fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); -} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.json b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.json deleted file mode 100644 index c3f9d7219..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" - }, - "vertex": "rendertype_entity_smooth_cutout", - "fragment": "rendertype_entity_smooth_cutout", - "attributes": [ - "Position", - "Color", - "UV0", - "UV1", - "UV2", - "Normal" - ], - "samplers": [ - { "name": "Sampler0" }, - { "name": "Sampler1" }, - { "name": "Sampler2" } - ], - "uniforms": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] } - ], - "UBOs": [ - { "type": "vertex", "binding": 0, "fields": [ - { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, - { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, - { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] } - ] }, - { "type": "fragment", "binding": 1, "fields": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } - ] } - ] -} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.vsh deleted file mode 100644 index 46038952c..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_smooth_cutout/rendertype_entity_smooth_cutout.vsh +++ /dev/null @@ -1,36 +0,0 @@ -#version 450 - -#include "light.glsl" -#include "fog.glsl" - -layout(location = 0) in vec3 Position; -layout(location = 1) in vec4 Color; -layout(location = 2) in vec2 UV0; -layout(location = 3) in ivec2 UV1; -layout(location = 4) in ivec2 UV2; -layout(location = 5) in vec3 Normal; - -layout(binding = 0) uniform UniformBufferObject { - mat4 MVP; - vec3 Light0_Direction; - vec3 Light1_Direction; -}; - -layout(binding = 3) uniform sampler2D Sampler1; -layout(binding = 4) uniform sampler2D Sampler2; - -layout(location = 0) out vec4 vertexColor; -layout(location = 1) out vec4 lightMapColor; -layout(location = 2) out vec4 overlayColor; -layout(location = 3) out vec2 texCoord0; -layout(location = 4) out float vertexDistance; - -void main() { - gl_Position = MVP * vec4(Position, 1.0); - - vertexDistance = fog_distance(Position.xyz, 0); - vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color); - lightMapColor = texelFetch(Sampler2, UV2 / 16, 0); - overlayColor = texelFetch(Sampler1, UV1, 0); - texCoord0 = UV0; -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent/rendertype_entity_translucent.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent/rendertype_entity_translucent.fsh deleted file mode 100644 index 29fd0268f..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent/rendertype_entity_translucent.fsh +++ /dev/null @@ -1,30 +0,0 @@ -#version 450 -#include "fog.glsl" - -layout(binding = 2) uniform sampler2D Sampler0; - -layout(binding = 1) uniform UBO{ - vec4 ColorModulator; - vec4 FogColor; - float FogStart; - float FogEnd; -}; - -layout(location = 0) in vec4 vertexColor; -layout(location = 1) in vec4 lightMapColor; -layout(location = 2) in vec4 overlayColor; -layout(location = 3) in vec2 texCoord0; -layout(location = 4) in float vertexDistance; - -layout(location = 0) out vec4 fragColor; - -void main() { - vec4 color = texture(Sampler0, texCoord0); - if (color.a < 0.1) { - discard; - } - color *= vertexColor * ColorModulator; - color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a); - color *= lightMapColor; - fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent/rendertype_entity_translucent.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent/rendertype_entity_translucent.vsh deleted file mode 100644 index 46038952c..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_translucent/rendertype_entity_translucent.vsh +++ /dev/null @@ -1,36 +0,0 @@ -#version 450 - -#include "light.glsl" -#include "fog.glsl" - -layout(location = 0) in vec3 Position; -layout(location = 1) in vec4 Color; -layout(location = 2) in vec2 UV0; -layout(location = 3) in ivec2 UV1; -layout(location = 4) in ivec2 UV2; -layout(location = 5) in vec3 Normal; - -layout(binding = 0) uniform UniformBufferObject { - mat4 MVP; - vec3 Light0_Direction; - vec3 Light1_Direction; -}; - -layout(binding = 3) uniform sampler2D Sampler1; -layout(binding = 4) uniform sampler2D Sampler2; - -layout(location = 0) out vec4 vertexColor; -layout(location = 1) out vec4 lightMapColor; -layout(location = 2) out vec4 overlayColor; -layout(location = 3) out vec2 texCoord0; -layout(location = 4) out float vertexDistance; - -void main() { - gl_Position = MVP * vec4(Position, 1.0); - - vertexDistance = fog_distance(Position.xyz, 0); - vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color); - lightMapColor = texelFetch(Sampler2, UV2 / 16, 0); - overlayColor = texelFetch(Sampler1, UV1, 0); - texCoord0 = UV0; -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint/rendertype_glint.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint/rendertype_glint.fsh deleted file mode 100644 index 8ffd06755..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint/rendertype_glint.fsh +++ /dev/null @@ -1,25 +0,0 @@ -#version 450 -#include "fog.glsl" - -layout(binding = 2) uniform sampler2D Sampler0; - -layout(binding = 1) uniform UBO{ - vec4 ColorModulator; - float FogStart; - float FogEnd; - float GlintAlpha; -}; - -layout(location = 0) in float vertexDistance; -layout(location = 1) in vec2 texCoord0; - -layout(location = 0) out vec4 fragColor; - -void main() { - vec4 color = texture(Sampler0, texCoord0) * ColorModulator; - if (color.a < 0.1) { - discard; - } - float fade = linear_fog_fade(vertexDistance, FogStart, FogEnd) * GlintAlpha; - fragColor = vec4(color.rgb * fade, color.a); -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint/rendertype_glint.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint/rendertype_glint.vsh deleted file mode 100644 index 71aa44c51..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint/rendertype_glint.vsh +++ /dev/null @@ -1,21 +0,0 @@ -#version 450 - -#include "fog.glsl" - -layout(location = 0) in vec3 Position; -layout(location = 1) in vec2 UV0; - -layout(binding = 0) uniform UniformBufferObject { - mat4 MVP; - mat4 TextureMat; -}; - -layout(location = 0) out float vertexDistance; -layout(location = 1) out vec2 texCoord0; - -void main() { - gl_Position = MVP * vec4(Position, 1.0); - - vertexDistance = fog_distance(Position.xyz, 0); - texCoord0 = (TextureMat * vec4(UV0, 0.0, 1.0)).xy; -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_direct/rendertype_glint_direct.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_direct/rendertype_glint_direct.fsh deleted file mode 100644 index 8ffd06755..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_direct/rendertype_glint_direct.fsh +++ /dev/null @@ -1,25 +0,0 @@ -#version 450 -#include "fog.glsl" - -layout(binding = 2) uniform sampler2D Sampler0; - -layout(binding = 1) uniform UBO{ - vec4 ColorModulator; - float FogStart; - float FogEnd; - float GlintAlpha; -}; - -layout(location = 0) in float vertexDistance; -layout(location = 1) in vec2 texCoord0; - -layout(location = 0) out vec4 fragColor; - -void main() { - vec4 color = texture(Sampler0, texCoord0) * ColorModulator; - if (color.a < 0.1) { - discard; - } - float fade = linear_fog_fade(vertexDistance, FogStart, FogEnd) * GlintAlpha; - fragColor = vec4(color.rgb * fade, color.a); -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_direct/rendertype_glint_direct.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_direct/rendertype_glint_direct.vsh deleted file mode 100644 index 71aa44c51..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_direct/rendertype_glint_direct.vsh +++ /dev/null @@ -1,21 +0,0 @@ -#version 450 - -#include "fog.glsl" - -layout(location = 0) in vec3 Position; -layout(location = 1) in vec2 UV0; - -layout(binding = 0) uniform UniformBufferObject { - mat4 MVP; - mat4 TextureMat; -}; - -layout(location = 0) out float vertexDistance; -layout(location = 1) out vec2 texCoord0; - -void main() { - gl_Position = MVP * vec4(Position, 1.0); - - vertexDistance = fog_distance(Position.xyz, 0); - texCoord0 = (TextureMat * vec4(UV0, 0.0, 1.0)).xy; -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_translucent/rendertype_glint_translucent.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_translucent/rendertype_glint_translucent.fsh deleted file mode 100644 index 8ffd06755..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_translucent/rendertype_glint_translucent.fsh +++ /dev/null @@ -1,25 +0,0 @@ -#version 450 -#include "fog.glsl" - -layout(binding = 2) uniform sampler2D Sampler0; - -layout(binding = 1) uniform UBO{ - vec4 ColorModulator; - float FogStart; - float FogEnd; - float GlintAlpha; -}; - -layout(location = 0) in float vertexDistance; -layout(location = 1) in vec2 texCoord0; - -layout(location = 0) out vec4 fragColor; - -void main() { - vec4 color = texture(Sampler0, texCoord0) * ColorModulator; - if (color.a < 0.1) { - discard; - } - float fade = linear_fog_fade(vertexDistance, FogStart, FogEnd) * GlintAlpha; - fragColor = vec4(color.rgb * fade, color.a); -} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_translucent/rendertype_glint_translucent.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_translucent/rendertype_glint_translucent.vsh deleted file mode 100644 index 71aa44c51..000000000 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_glint_translucent/rendertype_glint_translucent.vsh +++ /dev/null @@ -1,21 +0,0 @@ -#version 450 - -#include "fog.glsl" - -layout(location = 0) in vec3 Position; -layout(location = 1) in vec2 UV0; - -layout(binding = 0) uniform UniformBufferObject { - mat4 MVP; - mat4 TextureMat; -}; - -layout(location = 0) out float vertexDistance; -layout(location = 1) out vec2 texCoord0; - -void main() { - gl_Position = MVP * vec4(Position, 1.0); - - vertexDistance = fog_distance(Position.xyz, 0); - texCoord0 = (TextureMat * vec4(UV0, 0.0, 1.0)).xy; -} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 37218f426..b70e87d78 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -28,7 +28,9 @@ "depends": { "fabricloader": ">=0.14.14", - "minecraft": ">=1.21", - "java": ">=17" + "minecraft": ["1.21", "1.21.1"] + }, + "custom": { + "fabric-renderer-api-v1:contains_renderer": true } } diff --git a/src/main/resources/vulkanmod.accesswidener b/src/main/resources/vulkanmod.accesswidener index 459ba601d..2dd84a08c 100644 --- a/src/main/resources/vulkanmod.accesswidener +++ b/src/main/resources/vulkanmod.accesswidener @@ -6,6 +6,12 @@ accessible class net/minecraft/client/gui/Gui$HeartType accessible class net/minecraft/client/renderer/OutlineBufferSource$EntityOutlineGenerator +accessible class net/minecraft/client/renderer/texture/SpriteContents$Ticker +accessible class net/minecraft/client/renderer/texture/SpriteContents$FrameInfo +accessible class net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture +accessible field net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture frames Ljava/util/List; +accessible field net/minecraft/client/renderer/texture/SpriteContents$FrameInfo time I + #1.20 accessible field com/mojang/blaze3d/systems/RenderSystem vertexSorting Lcom/mojang/blaze3d/vertex/VertexSorting; accessible field net/minecraft/client/renderer/RenderStateShard name Ljava/lang/String; diff --git a/src/main/resources/vulkanmod.mixins.json b/src/main/resources/vulkanmod.mixins.json index 674e07398..996c8973a 100644 --- a/src/main/resources/vulkanmod.mixins.json +++ b/src/main/resources/vulkanmod.mixins.json @@ -15,7 +15,7 @@ "chunk.DirectionMixin", "chunk.FrustumMixin", "chunk.LevelRendererMixin", - "chunk.RenderBuffersM", + "chunk.SectionBufferBuilderPoolM", "chunk.SectionRenderDispatcherM", "chunk.ViewAreaM", "chunk.VisibilitySetMixin", @@ -33,6 +33,7 @@ "debug.KeyboardHandlerM", "matrix.Matrix4fM", + "matrix.PoseAccessor", "profiling.GuiMixin", "profiling.KeyboardHandlerM", @@ -42,15 +43,25 @@ "render.GameRendererMixin", "render.GlProgramManagerMixin", "render.GlStateManagerM", - "render.LevelRendererMixin", "render.MinecraftMixin", "render.RenderSystemMixin", "render.RenderTypeM", "render.ShaderInstanceM", + "render.biome.BiomeManagerM", + "render.block.BakedQuadM", + "render.clouds.LevelRendererM", + "render.color.BlockColorsM", "render.entity.EntityRendererM", "render.entity.LevelRendererM", "render.entity.model.ModelPartCubeM", "render.entity.model.ModelPartM", + "render.frame.MinecraftMixin", + "render.frame.RenderSystemMixin", + "render.frapi.fluid.FluidRenderingImplMixin", + "render.frapi.BakedModelM", + "render.frapi.ItemRendererAccessor", + "render.frapi.ItemRendererMixin", + "render.frapi.ModelBlockRendererM", "render.particle.SingleQuadParticleM", "render.target.MainTargetMixin", "render.target.RenderTargetMixin", @@ -58,7 +69,6 @@ "render.vertex.FaceBakeryM", "render.vertex.IndexTypeMixin", "render.vertex.VertexBufferM", - "render.vertex.VertexConsumerM", "render.vertex.VertexFormatMixin", "screen.ScreenM", @@ -67,9 +77,11 @@ "texture.mip.MipmapGeneratorM", "texture.image.MNativeImage", "texture.image.NativeImageAccessor", + "texture.update.GameRendererM", + "texture.update.MLightTexture", + "texture.update.MSpriteContents", + "texture.update.MTextureManager", "texture.MAbstractTexture", - "texture.MSpriteContents", - "texture.MTextureManager", "texture.MTextureUtil", "util.ScreenshotRecorderM", @@ -88,8 +100,6 @@ "compatibility.PostChainM", "compatibility.PostPassM", - "render.block.BakedQuadM", - "voxel.VoxelShapeMixin" ], "injectors": {