From 00a3690c007aa81ffc902c8e89553bd2d14f9923 Mon Sep 17 00:00:00 2001 From: Temo Tskipuri Date: Wed, 26 Nov 2025 17:56:52 +0400 Subject: [PATCH 1/5] chore: update gradle tooling --- build.gradle | 2 +- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 5bcdbd291..c5b707464 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.12-SNAPSHOT' + id 'fabric-loom' version '1.13.4' id 'maven-publish' } diff --git a/gradle.properties b/gradle.properties index ba55088d9..3d093b893 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ yarn_mappings = 1.21.10+build.2 loader_version = 0.17.3 # Fabric API -fabric_version = 0.138.0+1.21.10 +fabric_version = 0.138.3+1.21.10 # Mod Properties mod_version = 0.5.7-dev diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d4081da47..23449a2b5 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.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 3452a7f4f807219c10f5e1cc58b4c4f3c571f502 Mon Sep 17 00:00:00 2001 From: Temo Tskipuri Date: Wed, 26 Nov 2025 19:14:26 +0400 Subject: [PATCH 2/5] chore: add layered parchment mappings --- build.gradle | 5 ++++- gradle.properties | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c5b707464..405984d7c 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,10 @@ loom { dependencies { // To change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings loom.officialMojangMappings() + mappings loom.layered { + officialMojangMappings() + parchment("org.parchmentmc.data:parchment-${project.minecraft_version}:${project.parchment_version}@zip") + } modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" // Fabric API. diff --git a/gradle.properties b/gradle.properties index 3d093b893..374890e6d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,8 @@ org.gradle.parallel=true minecraft_version = 1.21.10 yarn_mappings = 1.21.10+build.2 loader_version = 0.17.3 +# Mapping enhancements +parchment_version = 2025.10.12 # Fabric API fabric_version = 0.138.3+1.21.10 From 76bca7030a0c65e0502d9ab8f31a0f03178ec3f2 Mon Sep 17 00:00:00 2001 From: Temo Tskipuri Date: Wed, 26 Nov 2025 19:28:06 +0400 Subject: [PATCH 3/5] Add Parchment support --- build.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build.gradle b/build.gradle index 405984d7c..c8cfc4409 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,13 @@ loom { accessWidenerPath = file("src/main/resources/vulkanmod.accesswidener") } +repositories { + maven { + name = 'ParchmentMC' + url = 'https://maven.parchmentmc.org' + } +} + dependencies { // To change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" From 8025e79827a0b4b48b6cf54f8f0660c26296c810 Mon Sep 17 00:00:00 2001 From: Temo Tskipuri Date: Wed, 26 Nov 2025 19:48:58 +0400 Subject: [PATCH 4/5] Refactor code using IntelliJ --- src/main/java/net/vulkanmod/Initializer.java | 61 +- .../java/net/vulkanmod/config/Config.java | 54 +- .../net/vulkanmod/config/gui/GuiElement.java | 17 +- .../vulkanmod/config/gui/VOptionScreen.java | 9 +- .../config/gui/render/GuiRenderer.java | 3 +- .../config/gui/render/PolygonRenderState.java | 24 +- .../gui/widget/CyclingOptionWidget.java | 24 +- .../config/gui/widget/OptionWidget.java | 14 +- .../config/gui/widget/RangeOptionWidget.java | 9 +- .../config/gui/widget/SwitchOptionWidget.java | 10 +- .../config/gui/widget/VAbstractWidget.java | 8 +- .../config/gui/widget/VButtonWidget.java | 5 +- .../config/option/CyclingOption.java | 16 +- .../net/vulkanmod/config/option/Option.java | 24 +- .../net/vulkanmod/config/option/Options.java | 274 ++++---- .../config/video/VideoModeManager.java | 9 +- .../vulkanmod/config/video/VideoModeSet.java | 14 +- src/main/java/net/vulkanmod/gl/GlUtil.java | 53 +- .../java/net/vulkanmod/gl/VkGlBuffer.java | 18 +- .../net/vulkanmod/gl/VkGlFramebuffer.java | 34 +- .../java/net/vulkanmod/gl/VkGlProgram.java | 15 +- .../net/vulkanmod/gl/VkGlRenderbuffer.java | 32 +- .../java/net/vulkanmod/gl/VkGlShader.java | 22 +- .../java/net/vulkanmod/gl/VkGlTexture.java | 60 +- .../interfaces/ExtendedVertexBuilder.java | 3 +- .../shader/ExtendedRenderPipeline.java | 8 +- .../mixin/chunk/ClientChunkCacheM.java | 2 - .../vulkanmod/mixin/chunk/DirectionMixin.java | 8 +- .../vulkanmod/mixin/chunk/FrustumMixin.java | 20 +- .../mixin/chunk/LevelRendererMixin.java | 26 +- .../chunk/SectionBufferBuilderPoolM.java | 8 +- .../mixin/chunk/SectionRenderDispatcherM.java | 4 +- .../net/vulkanmod/mixin/chunk/ViewAreaM.java | 16 +- .../mixin/chunk/VisibilitySetMixin.java | 4 +- .../mixin/compatibility/PostPassM.java | 31 +- .../mixin/compatibility/gl/GL11M.java | 3 +- .../mixin/compatibility/gl/GL14M.java | 1 - .../mixin/debug/DebugEntryMemoryM.java | 4 +- .../mixin/debug/DebugScreenEntriesM.java | 2 +- .../mixin/debug/KeyboardHandlerM.java | 6 +- .../debug/crash_report/SystemReportM.java | 10 +- .../net/vulkanmod/mixin/matrix/Matrix4fM.java | 19 +- .../mixin/profiling/GameLoadTimeEventM.java | 18 +- .../vulkanmod/mixin/profiling/GuiMixin.java | 5 +- .../mixin/profiling/KeyboardHandlerM.java | 3 +- .../mixin/profiling/LevelRendererMixin.java | 4 +- .../mixin/render/CompositeRenderTypeM.java | 41 +- .../mixin/render/GlStateManagerM.java | 18 +- .../mixin/render/GuiRendererMixin.java | 14 +- .../mixin/render/MinecraftMixin.java | 17 +- .../mixin/render/RenderSystemMixin.java | 21 +- .../mixin/render/biome/BiomeManagerM.java | 4 +- .../mixin/render/block/BakedQuadM.java | 24 +- .../mixin/render/clouds/LevelRendererM.java | 23 +- .../mixin/render/color/BlockColorsM.java | 20 +- .../mixin/render/entity/EntityRendererM.java | 8 +- .../mixin/render/entity/LevelRendererM.java | 28 +- .../render/entity/model/ModelPartCubeM.java | 3 +- .../mixin/render/entity/model/ModelPartM.java | 34 +- .../mixin/render/frame/MinecraftMixin.java | 3 +- .../frapi/BatchingRenderCommandQueueM.java | 7 +- .../frapi/BlockRenderDispatcherAccessor.java | 5 +- .../render/frapi/ItemFeatureRendererM.java | 8 +- .../render/frapi/ItemRendererAccessor.java | 8 +- .../frapi/OrderedRenderCommandQueueImplM.java | 2 - .../render/particle/QuadParticleGroupM.java | 10 +- .../particle/QuadParticleRenderStateM.java | 8 +- .../mixin/render/shader/RenderPipelineM.java | 18 +- .../mixin/render/shader/ShaderManagerM.java | 1 - .../render/target/RenderTargetMixin.java | 26 +- .../mixin/render/vertex/BufferBuilderM.java | 39 +- .../render/vertex/VertexFormatMixin.java | 3 - .../mixin/screen/OptionsScreenM.java | 8 +- .../mixin/texture/mip/MipmapGeneratorM.java | 40 +- .../mixin/texture/update/MLightTexture.java | 87 ++- .../mixin/texture/update/MSpriteContents.java | 13 +- .../mixin/texture/update/MTextureManager.java | 4 +- .../vulkanmod/mixin/util/ScreenshotMixin.java | 6 +- .../vertex/SpriteCoordinateExpanderM.java | 4 +- .../mixin/vertex/VertexMultiConsumersM.java | 34 +- .../mixin/voxel/VoxelShapeMixin.java | 12 +- .../mixin/wayland/InputConstantsM.java | 2 +- .../mixin/wayland/MinecraftMixin.java | 19 +- .../vulkanmod/mixin/window/WindowMixin.java | 85 ++- .../net/vulkanmod/render/PipelineManager.java | 10 +- src/main/java/net/vulkanmod/render/VBO.java | 11 +- .../net/vulkanmod/render/chunk/ChunkArea.java | 19 +- .../render/chunk/ChunkAreaManager.java | 14 +- .../render/chunk/ChunkStatusMap.java | 12 +- .../vulkanmod/render/chunk/RenderSection.java | 71 +- .../vulkanmod/render/chunk/SectionGrid.java | 18 +- .../vulkanmod/render/chunk/WorldRenderer.java | 135 ++-- .../render/chunk/buffer/AreaBuffer.java | 33 +- .../render/chunk/buffer/DrawBuffers.java | 24 +- .../chunk/buffer/DrawParametersBuffer.java | 6 +- .../render/chunk/buffer/UploadManager.java | 8 +- .../render/chunk/build/RenderRegion.java | 12 +- .../render/chunk/build/UploadBuffer.java | 7 +- .../render/chunk/build/biome/BiomeData.java | 77 +-- .../chunk/build/color/BlockColorRegistry.java | 18 +- .../render/chunk/build/color/BoxBlur.java | 2 +- .../render/chunk/build/color/TintCache.java | 3 +- .../chunk/build/frapi/VulkanModRenderer.java | 76 +-- .../AccessBatchingRenderCommandQueue.java | 2 +- .../accessor/AccessChunkRendererRegion.java | 4 +- .../accessor/AccessLayerRenderState.java | 2 +- .../accessor/AccessRenderCommandQueue.java | 3 +- .../chunk/build/frapi/helper/ColorHelper.java | 169 ++--- .../build/frapi/helper/GeometryHelper.java | 418 ++++++------ .../build/frapi/helper/NormalHelper.java | 330 ++++----- .../build/frapi/helper/TextureHelper.java | 161 +++-- .../build/frapi/mesh/EncodingFormat.java | 371 +++++----- .../chunk/build/frapi/mesh/MeshImpl.java | 155 ++--- .../build/frapi/mesh/MutableMeshImpl.java | 26 +- .../build/frapi/mesh/MutableQuadViewImpl.java | 598 ++++++++-------- .../chunk/build/frapi/mesh/QuadViewImpl.java | 645 +++++++++--------- .../render/AbstractBlockRenderContext.java | 392 ++++++----- .../frapi/render/AbstractRenderContext.java | 85 +-- .../frapi/render/BlockRenderContext.java | 95 ++- .../build/frapi/render/ItemRenderContext.java | 162 +++-- .../build/frapi/render/MeshItemCommand.java | 7 +- .../render/SimpleBlockRenderContext.java | 2 - .../chunk/build/light/LightPipeline.java | 15 +- .../build/light/data/LightDataAccess.java | 169 +++-- .../build/light/flat/FlatLightPipeline.java | 6 +- .../chunk/build/light/smooth/AoFaceData.java | 120 ++-- .../build/light/smooth/AoNeighborInfo.java | 136 ++-- .../light/smooth/NewSmoothLightPipeline.java | 50 +- .../light/smooth/SmoothLightPipeline.java | 66 +- .../build/light/smooth/SubBlockAoFace.java | 30 +- .../chunk/build/renderer/BlockRenderer.java | 17 +- .../build/renderer/DefaultFluidRenderers.java | 14 +- .../chunk/build/renderer/FluidRenderer.java | 33 +- .../render/chunk/build/task/BuildTask.java | 4 +- .../render/chunk/build/task/ChunkTask.java | 18 +- .../chunk/build/task/CompileResult.java | 6 +- .../chunk/build/task/CompiledSection.java | 5 +- .../chunk/build/task/TaskDispatcher.java | 45 +- .../chunk/build/thread/BuilderResources.java | 7 +- .../chunk/build/thread/ThreadBuilderPack.java | 17 +- .../render/chunk/frustum/VFrustum.java | 5 +- .../render/chunk/graph/SectionGraph.java | 59 +- .../render/chunk/util/CircularIntList.java | 9 +- .../render/chunk/util/ResettableQueue.java | 4 +- .../render/chunk/util/SimpleDirection.java | 12 +- .../render/chunk/util/StaticQueue.java | 6 +- .../net/vulkanmod/render/chunk/util/Util.java | 3 - .../vulkanmod/render/engine/EGlProgram.java | 6 +- .../render/engine/VkCommandEncoder.java | 211 +++--- .../vulkanmod/render/engine/VkDebugLabel.java | 16 +- .../net/vulkanmod/render/engine/VkFbo.java | 4 - .../vulkanmod/render/engine/VkGpuBuffer.java | 44 +- .../vulkanmod/render/engine/VkGpuDevice.java | 61 +- .../vulkanmod/render/engine/VkGpuTexture.java | 86 ++- .../vulkanmod/render/engine/VkRenderPass.java | 60 +- .../net/vulkanmod/render/model/CubeModel.java | 35 +- .../render/model/quad/ModelQuad.java | 19 +- .../render/model/quad/ModelQuadFlags.java | 2 +- .../render/model/quad/QuadUtils.java | 8 +- .../render/profiling/BuildTimeProfiler.java | 4 +- .../vulkanmod/render/profiling/Profiler.java | 30 +- .../render/shader/CustomRenderPipelines.java | 12 +- .../render/shader/ShaderLoadUtil.java | 12 +- .../vulkanmod/render/sky/CloudRenderer.java | 105 ++- .../render/texture/SpriteUpdateUtil.java | 2 +- .../net/vulkanmod/render/util/DrawUtil.java | 2 - .../net/vulkanmod/render/util/SortUtil.java | 33 +- .../render/vertex/CustomVertexFormat.java | 10 +- .../vulkanmod/render/vertex/QuadSorter.java | 20 +- .../render/vertex/TerrainBufferBuilder.java | 84 ++- .../render/vertex/TerrainBuilder.java | 18 +- .../render/vertex/TerrainRenderType.java | 10 +- .../render/vertex/VertexBuilder.java | 10 +- .../render/vertex/format/I32_SNorm.java | 10 +- .../java/net/vulkanmod/vulkan/Drawer.java | 22 +- .../java/net/vulkanmod/vulkan/Renderer.java | 484 +++++++------ .../net/vulkanmod/vulkan/Synchronization.java | 24 +- .../net/vulkanmod/vulkan/VRenderSystem.java | 29 +- .../java/net/vulkanmod/vulkan/Vulkan.java | 33 +- .../net/vulkanmod/vulkan/device/Device.java | 12 +- .../vulkan/framebuffer/Framebuffer.java | 29 +- .../vulkan/framebuffer/RenderPass.java | 14 +- .../vulkan/framebuffer/SwapChain.java | 77 ++- .../vulkan/memory/MemoryManager.java | 120 ++-- .../vulkanmod/vulkan/memory/MemoryType.java | 4 +- .../vulkan/memory/buffer/Buffer.java | 20 +- .../vulkan/memory/buffer/IndirectBuffer.java | 1 - .../vulkan/memory/buffer/StagingBuffer.java | 2 +- .../vulkan/memory/buffer/UniformBuffer.java | 8 +- .../memory/buffer/index/AutoIndexBuffer.java | 122 ++-- .../vulkan/pass/DefaultMainPass.java | 14 +- .../net/vulkanmod/vulkan/pass/MainPass.java | 12 +- .../vulkanmod/vulkan/queue/CommandPool.java | 3 +- .../vulkanmod/vulkan/queue/GraphicsQueue.java | 6 +- .../net/vulkanmod/vulkan/queue/Queue.java | 76 +-- .../vulkanmod/vulkan/queue/TransferQueue.java | 26 +- .../vulkan/shader/DescriptorSets.java | 13 +- .../vulkan/shader/GraphicsPipeline.java | 282 ++++---- .../net/vulkanmod/vulkan/shader/Pipeline.java | 81 ++- .../vulkan/shader/PipelineState.java | 109 ++- .../vulkanmod/vulkan/shader/SPIRVUtils.java | 13 +- .../net/vulkanmod/vulkan/shader/Uniforms.java | 1 - .../vulkan/shader/converter/Attribute.java | 3 +- .../vulkan/shader/converter/GLSLParser.java | 42 +- .../vulkan/shader/converter/Token.java | 31 +- .../vulkan/shader/descriptor/Descriptor.java | 6 +- .../shader/descriptor/ImageDescriptor.java | 17 +- .../vulkan/shader/descriptor/UBO.java | 8 +- .../vulkanmod/vulkan/shader/layout/Mat3.java | 2 +- .../vulkan/shader/layout/Uniform.java | 73 +- .../vulkanmod/vulkan/shader/layout/Vec1i.java | 2 - .../vulkanmod/vulkan/texture/ImageUtil.java | 52 +- .../vulkan/texture/SamplerManager.java | 14 +- .../vulkan/texture/VTextureSelector.java | 4 +- .../vulkanmod/vulkan/texture/VulkanImage.java | 294 ++++---- .../net/vulkanmod/vulkan/util/ColorUtil.java | 96 +-- .../net/vulkanmod/vulkan/util/DrawUtil.java | 1 - .../vulkanmod/vulkan/util/MappedBuffer.java | 7 +- .../java/net/vulkanmod/vulkan/util/Pair.java | 2 +- 219 files changed, 4885 insertions(+), 5080 deletions(-) diff --git a/src/main/java/net/vulkanmod/Initializer.java b/src/main/java/net/vulkanmod/Initializer.java index 198d7153a..ba64d44a0 100644 --- a/src/main/java/net/vulkanmod/Initializer.java +++ b/src/main/java/net/vulkanmod/Initializer.java @@ -13,46 +13,45 @@ import java.nio.file.Path; public class Initializer implements ClientModInitializer { - public static final Logger LOGGER = LogManager.getLogger("VulkanMod"); + public static final Logger LOGGER = LogManager.getLogger("VulkanMod"); + public static Config CONFIG; + private static String VERSION; - private static String VERSION; - public static Config CONFIG; + private static Config loadConfig(Path path) { + Config config = Config.load(path); - @Override - public void onInitializeClient() { + if (config == null) { + config = new Config(); + config.write(); + } - VERSION = FabricLoader.getInstance() - .getModContainer("vulkanmod") - .get() - .getMetadata() - .getVersion().getFriendlyString(); + return config; + } - LOGGER.info("== VulkanMod =="); + public static String getVersion() { + return VERSION; + } - Platform.init(); - VideoModeManager.init(); + @Override + public void onInitializeClient() { - var configPath = FabricLoader.getInstance() - .getConfigDir() - .resolve("vulkanmod_settings.json"); + VERSION = FabricLoader.getInstance() + .getModContainer("vulkanmod") + .get() + .getMetadata() + .getVersion().getFriendlyString(); - CONFIG = loadConfig(configPath); + LOGGER.info("== VulkanMod =="); - Renderer.register(VulkanModRenderer.INSTANCE); - } + Platform.init(); + VideoModeManager.init(); - private static Config loadConfig(Path path) { - Config config = Config.load(path); + var configPath = FabricLoader.getInstance() + .getConfigDir() + .resolve("vulkanmod_settings.json"); - if(config == null) { - config = new Config(); - config.write(); - } + CONFIG = loadConfig(configPath); - return config; - } - - public static String getVersion() { - return VERSION; - } + Renderer.register(VulkanModRenderer.INSTANCE); + } } diff --git a/src/main/java/net/vulkanmod/config/Config.java b/src/main/java/net/vulkanmod/config/Config.java index e2bebdb7f..89598c07f 100644 --- a/src/main/java/net/vulkanmod/config/Config.java +++ b/src/main/java/net/vulkanmod/config/Config.java @@ -13,26 +13,44 @@ import java.util.Collections; public class Config { + private static final Gson GSON = new GsonBuilder() + .setPrettyPrinting() + .excludeFieldsWithModifiers(Modifier.PRIVATE) + .create(); + private static Path CONFIG_PATH; public VideoModeSet.VideoMode videoMode = VideoModeManager.getFirstAvailable().getVideoMode(); public int windowMode = 0; - public int advCulling = 2; public boolean indirectDraw = true; - public boolean uniqueOpaqueLayer = true; public boolean entityCulling = true; public int device = -1; - public int ambientOcclusion = 1; public int frameQueueSize = 2; public int builderThreads = 0; - public boolean backFaceCulling = true; public boolean textureAnimations = true; + public static Config load(Path path) { + Config config; + Config.CONFIG_PATH = path; + + if (Files.exists(path)) { + try (FileReader fileReader = new FileReader(path.toFile())) { + config = GSON.fromJson(fileReader, Config.class); + } catch (IOException exception) { + throw new RuntimeException(exception.getMessage()); + } + } else { + config = null; + } + + return config; + } + public void write() { - if(!Files.exists(CONFIG_PATH.getParent())) { + if (!Files.exists(CONFIG_PATH.getParent())) { try { Files.createDirectories(CONFIG_PATH); } catch (IOException e) { @@ -46,30 +64,4 @@ public void write() { e.printStackTrace(); } } - - private static Path CONFIG_PATH; - - private static final Gson GSON = new GsonBuilder() - .setPrettyPrinting() - .excludeFieldsWithModifiers(Modifier.PRIVATE) - .create(); - - public static Config load(Path path) { - Config config; - Config.CONFIG_PATH = path; - - if (Files.exists(path)) { - try (FileReader fileReader = new FileReader(path.toFile())) { - config = GSON.fromJson(fileReader, Config.class); - } - catch (IOException exception) { - throw new RuntimeException(exception.getMessage()); - } - } - else { - config = null; - } - - return config; - } } diff --git a/src/main/java/net/vulkanmod/config/gui/GuiElement.java b/src/main/java/net/vulkanmod/config/gui/GuiElement.java index 04b85d2a1..88cf40ce5 100644 --- a/src/main/java/net/vulkanmod/config/gui/GuiElement.java +++ b/src/main/java/net/vulkanmod/config/gui/GuiElement.java @@ -7,16 +7,14 @@ import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.navigation.FocusNavigationEvent; import net.minecraft.client.gui.navigation.ScreenRectangle; -import net.minecraft.client.input.MouseButtonEvent; import org.jetbrains.annotations.Nullable; public abstract class GuiElement implements GuiEventListener, NarratableEntry { - protected int width; - protected int height; public int x; public int y; - + protected int width; + protected int height; protected boolean hovered; protected long hoverStartTime; protected int hoverTime; @@ -76,8 +74,7 @@ public void updateState(double mX, double mY) { public float getHoverMultiplier(float time) { if (this.hovered) { return Math.min(((this.hoverTime) / time), 1.0f); - } - else { + } else { int delta = (int) (Util.getMillis() - this.hoverStopTime); return Math.max(1.0f - (delta / time), 0.0f); } @@ -107,13 +104,13 @@ public ScreenRectangle getRectangle() { } @Override - public void setFocused(boolean bl) { - + public boolean isFocused() { + return false; } @Override - public boolean isFocused() { - return false; + public void setFocused(boolean bl) { + } @Override diff --git a/src/main/java/net/vulkanmod/config/gui/VOptionScreen.java b/src/main/java/net/vulkanmod/config/gui/VOptionScreen.java index fcf879d71..eb2ea5b37 100644 --- a/src/main/java/net/vulkanmod/config/gui/VOptionScreen.java +++ b/src/main/java/net/vulkanmod/config/gui/VOptionScreen.java @@ -30,21 +30,16 @@ public class VOptionScreen extends Screen { private final Screen parent; private final List optionPages; - + private final List pageButtons = Lists.newArrayList(); + private final List buttons = Lists.newArrayList(); private int currentListIdx = 0; - private int tooltipX; private int tooltipY; private int tooltipWidth; - private VButtonWidget supportButton; - private VButtonWidget doneButton; private VButtonWidget applyButton; - private final List pageButtons = Lists.newArrayList(); - private final List buttons = Lists.newArrayList(); - public VOptionScreen(Component title, Screen parent) { super(title); this.parent = parent; diff --git a/src/main/java/net/vulkanmod/config/gui/render/GuiRenderer.java b/src/main/java/net/vulkanmod/config/gui/render/GuiRenderer.java index e268dab92..93d54a515 100644 --- a/src/main/java/net/vulkanmod/config/gui/render/GuiRenderer.java +++ b/src/main/java/net/vulkanmod/config/gui/render/GuiRenderer.java @@ -1,7 +1,8 @@ package net.vulkanmod.config.gui.render; import com.mojang.blaze3d.pipeline.RenderPipeline; -import com.mojang.blaze3d.vertex.*; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; diff --git a/src/main/java/net/vulkanmod/config/gui/render/PolygonRenderState.java b/src/main/java/net/vulkanmod/config/gui/render/PolygonRenderState.java index ff4b2b03d..b3a509aaf 100644 --- a/src/main/java/net/vulkanmod/config/gui/render/PolygonRenderState.java +++ b/src/main/java/net/vulkanmod/config/gui/render/PolygonRenderState.java @@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable; import org.joml.Matrix3x2f; -public record PolygonRenderState ( +public record PolygonRenderState( RenderPipeline pipeline, TextureSetup textureSetup, Matrix3x2f pose, @@ -27,17 +27,7 @@ public PolygonRenderState( @Nullable ScreenRectangle screenRectangle ) { this(renderPipeline, textureSetup, pose, vertices, color, screenRectangle, - getBounds(vertices, pose, screenRectangle)); - } - - @Override - public void buildVertices(VertexConsumer vertexConsumer) { - for (float[] vertex : vertices) { - float x = vertex[0]; - float y = vertex[1]; - vertexConsumer.addVertexWith2DPose(this.pose(), x, y) - .setColor(this.col); - } + getBounds(vertices, pose, screenRectangle)); } @Nullable @@ -69,5 +59,15 @@ private static ScreenRectangle getBounds(float[][] vertices, Matrix3x2f matrix3x ScreenRectangle screenRectangle2 = new ScreenRectangle((int) x0, (int) y0, (int) (x1 - x0), (int) (y1 - y0)).transformMaxBounds(matrix3x2f); return screenRectangle != null ? screenRectangle.intersection(screenRectangle2) : screenRectangle2; } + + @Override + public void buildVertices(VertexConsumer vertexConsumer) { + for (float[] vertex : vertices) { + float x = vertex[0]; + float y = vertex[1]; + vertexConsumer.addVertexWith2DPose(this.pose(), x, y) + .setColor(this.col); + } + } } diff --git a/src/main/java/net/vulkanmod/config/gui/widget/CyclingOptionWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/CyclingOptionWidget.java index 6ec5157d2..fb6c51a67 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/CyclingOptionWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/CyclingOptionWidget.java @@ -10,8 +10,8 @@ import net.vulkanmod.vulkan.util.ColorUtil; public class CyclingOptionWidget extends OptionWidget> { - private Button leftButton; - private Button rightButton; + private final Button leftButton; + private final Button rightButton; private boolean focused; @@ -72,8 +72,7 @@ public void renderBars() { public void onClick(double mouseX, double mouseY) { if (leftButton.isHovered(mouseX, mouseY)) { option.prevValue(); - } - else if (rightButton.isHovered(mouseX, mouseY)) { + } else if (rightButton.isHovered(mouseX, mouseY)) { option.nextValue(); } } @@ -89,13 +88,13 @@ protected void onDrag(double mouseX, double mouseY, double deltaX, double deltaY } @Override - public void setFocused(boolean bl) { - this.focused = bl; + public boolean isFocused() { + return this.focused; } @Override - public boolean isFocused() { - return this.focused; + public void setFocused(boolean bl) { + this.focused = bl; } class Button { @@ -129,11 +128,9 @@ void renderButton(double mouseX, double mouseY) { int color; if (this.isHovered(mouseX, mouseY) && this.active) { color = HOVERED_COLOR; - } - else if (this.active) { + } else if (this.active) { color = ACTIVE_COLOR; - } - else { + } else { color = INACTIVE_COLOR; } @@ -149,8 +146,7 @@ else if (this.active) { {xC + w, yC + h}, {xC + w, yC - h}, }; - } - else { + } else { vertices = new float[][]{ {xC + w, yC}, {xC - w, yC - h}, diff --git a/src/main/java/net/vulkanmod/config/gui/widget/OptionWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/OptionWidget.java index b3ee79345..59e2b37be 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/OptionWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/OptionWidget.java @@ -16,9 +16,9 @@ public abstract class OptionWidget> extends VAbstractWidget implements NarratableEntry { + private final Component name; public int controlX; public int controlWidth; - private final Component name; protected Component displayedValue; protected boolean controlHovered; @@ -137,21 +137,21 @@ public boolean mouseReleased(MouseButtonEvent event) { @Override public boolean isMouseOver(double mouseX, double mouseY) { - return this.active && this.visible && mouseX >= (double)this.x && mouseY >= (double)this.y && mouseX < (double)(this.x + this.width) && mouseY < (double)(this.y + this.height); + return this.active && this.visible && mouseX >= (double) this.x && mouseY >= (double) this.y && mouseX < (double) (this.x + this.width) && mouseY < (double) (this.y + this.height); } @Override - public void setFocused(boolean bl) { - this.focused = bl; + public boolean isFocused() { + return this.focused; } @Override - public boolean isFocused() { - return this.focused; + public void setFocused(boolean bl) { + this.focused = bl; } protected boolean clicked(double mouseX, double mouseY) { - return this.active && this.visible && mouseX >= (double)this.controlX && mouseY >= (double)this.y && mouseX < (double)(this.x + this.width) && mouseY < (double)(this.y + this.height); + return this.active && this.visible && mouseX >= (double) this.controlX && mouseY >= (double) this.y && mouseX < (double) (this.x + this.width) && mouseY < (double) (this.y + this.height); } public Component getName() { diff --git a/src/main/java/net/vulkanmod/config/gui/widget/RangeOptionWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/RangeOptionWidget.java index 277386177..8dea9fa93 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/RangeOptionWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/RangeOptionWidget.java @@ -8,7 +8,6 @@ import net.minecraft.util.Mth; import net.vulkanmod.config.gui.render.GuiRenderer; import net.vulkanmod.config.option.RangeOption; -import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.util.ColorUtil; import org.lwjgl.glfw.GLFW; @@ -82,13 +81,13 @@ public boolean keyPressed(KeyEvent event) { } @Override - public void setFocused(boolean bl) { - this.focused = bl; + public boolean isFocused() { + return this.focused; } @Override - public boolean isFocused() { - return this.focused; + public void setFocused(boolean bl) { + this.focused = bl; } private void setValueFromMouse(double mouseX) { diff --git a/src/main/java/net/vulkanmod/config/gui/widget/SwitchOptionWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/SwitchOptionWidget.java index f4b0b5f9f..7c81fd31b 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/SwitchOptionWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/SwitchOptionWidget.java @@ -41,7 +41,7 @@ protected void renderControls(double mouseX, double mouseY) { } color = ColorUtil.ARGB.pack(0.6f, 0.6f, 0.6f, 1.0f); - GuiRenderer.renderBoxBorder(x0, y0, halfWidth * 2, height, 1, color); + GuiRenderer.renderBoxBorder(x0, y0, halfWidth * 2, height, 1, color); color = this.active ? 0xFFFFFFFF : 0xFFA0A0A0; Font textRenderer = Minecraft.getInstance().font; @@ -77,13 +77,13 @@ protected void updateDisplayedValue() { } @Override - public void setFocused(boolean bl) { - this.focused = bl; + public boolean isFocused() { + return this.focused; } @Override - public boolean isFocused() { - return this.focused; + public void setFocused(boolean bl) { + this.focused = bl; } } diff --git a/src/main/java/net/vulkanmod/config/gui/widget/VAbstractWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/VAbstractWidget.java index 0a76bd6ff..8eb82d9b1 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/VAbstractWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/VAbstractWidget.java @@ -75,10 +75,10 @@ public boolean mouseClicked(MouseButtonEvent event, boolean bl) { protected boolean clicked(double mX, double mY) { return this.active && this.visible - && mX >= (double)this.getX() - && mY >= (double)this.getY() - && mX < (double)(this.getX() + this.getWidth()) - && mY < (double)(this.getY() + this.getHeight()); + && mX >= (double) this.getX() + && mY >= (double) this.getY() + && mX < (double) (this.getX() + this.getWidth()) + && mY < (double) (this.getY() + this.getHeight()); } @Override diff --git a/src/main/java/net/vulkanmod/config/gui/widget/VButtonWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/VButtonWidget.java index 3055259d6..5c268c6dc 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/VButtonWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/VButtonWidget.java @@ -5,7 +5,6 @@ import net.minecraft.network.chat.Component; import net.minecraft.util.Mth; import net.vulkanmod.config.gui.render.GuiRenderer; -import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.util.ColorUtil; import java.util.function.Consumer; @@ -41,12 +40,12 @@ public void renderWidget(double mouseX, double mouseY) { GuiRenderer.drawCenteredString(textRenderer, this.message, this.x + this.width / 2, this.y + (this.height - 8) / 2, j | Mth.ceil(this.alpha * 255.0f) << 24); - if(this.selected) { + if (this.selected) { color = ColorUtil.ARGB.pack(0.3f, 0.0f, 0.0f, 1.0f); GuiRenderer.fillBox(this.x, this.y, (int) 1.5f, this.height, color); color = ColorUtil.ARGB.pack(0.3f, 0.0f, 0.0f, 0.2f); - GuiRenderer.fillBox(this.x, this.y, this.width, this.height, color); + GuiRenderer.fillBox(this.x, this.y, this.width, this.height, color); } } diff --git a/src/main/java/net/vulkanmod/config/option/CyclingOption.java b/src/main/java/net/vulkanmod/config/option/CyclingOption.java index d6080f7fd..a8ec440bd 100644 --- a/src/main/java/net/vulkanmod/config/option/CyclingOption.java +++ b/src/main/java/net/vulkanmod/config/option/CyclingOption.java @@ -32,26 +32,24 @@ public void updateOption(E[] values, Consumer setter, Supplier getter) { this.index = ArrayUtils.indexOf(this.values, this.getNewValue()); } - public int index() { return this.index; } - - public void setValues(E[] values) { - this.values = values; + public int index() { + return this.index; } public void prevValue() { - if(this.index > 0) + if (this.index > 0) this.index--; this.updateValue(); } public void nextValue() { - if(this.index < values.length - 1) + if (this.index < values.length - 1) this.index++; this.updateValue(); } private void updateValue() { - if(this.index >= 0 && this.index < this.values.length) { + if (this.index >= 0 && this.index < this.values.length) { this.newValue = values[this.index]; if (onChange != null) @@ -75,4 +73,8 @@ private int findNewValueIndex() { public E[] getValues() { return values; } + + public void setValues(E[] values) { + this.values = values; + } } diff --git a/src/main/java/net/vulkanmod/config/option/Option.java b/src/main/java/net/vulkanmod/config/option/Option.java index a1425ccf8..8d24507ce 100644 --- a/src/main/java/net/vulkanmod/config/option/Option.java +++ b/src/main/java/net/vulkanmod/config/option/Option.java @@ -64,13 +64,6 @@ public Option setActive(boolean active) { public abstract OptionWidget createOptionWidget(int x, int y, int width, int height); - public void setNewValue(T t) { - this.newValue = t; - - if (onChange != null) - onChange.run(); - } - public Component getName() { return this.name; } @@ -84,7 +77,7 @@ public boolean isChanged() { } public void apply() { - if(!isChanged()) + if (!isChanged()) return; onApply.accept(this.newValue); @@ -95,16 +88,23 @@ public T getNewValue() { return this.newValue; } + public void setNewValue(T t) { + this.newValue = t; + + if (onChange != null) + onChange.run(); + } + public Component getDisplayedValue() { return this.translator.apply(this.newValue); } + public Component getTooltip() { + return this.tooltip; + } + public Option setTooltip(Component text) { this.tooltip = text; return this; } - - public Component getTooltip() { - return this.tooltip; - } } diff --git a/src/main/java/net/vulkanmod/config/option/Options.java b/src/main/java/net/vulkanmod/config/option/Options.java index 560e6d2c9..751ccfe6e 100644 --- a/src/main/java/net/vulkanmod/config/option/Options.java +++ b/src/main/java/net/vulkanmod/config/option/Options.java @@ -85,7 +85,7 @@ public static OptionBlock[] getVideoOpts() { value -> { boolean exclusiveFullscreen = value == WindowMode.EXCLUSIVE_FULLSCREEN; minecraftOptions.fullscreen() - .set(exclusiveFullscreen); + .set(exclusiveFullscreen); config.windowMode = value.mode; fullscreenDirty = true; @@ -93,63 +93,63 @@ public static OptionBlock[] getVideoOpts() { () -> 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 ? - Component.translatable( - "options.framerateLimit.max") - .getString() : - String.valueOf(value)), - value -> { - minecraftOptions.framerateLimit().set(value); - minecraft.getFramerateLimitTracker().setFramerateLimit(value); - }, - () -> minecraftOptions.framerateLimit().get()), + 10, 260, 10, + value -> Component.nullToEmpty(value == 260 ? + Component.translatable( + "options.framerateLimit.max") + .getString() : + String.valueOf(value)), + value -> { + minecraftOptions.framerateLimit().set(value); + minecraft.getFramerateLimitTracker().setFramerateLimit(value); + }, + () -> minecraftOptions.framerateLimit().get()), new SwitchOption(Component.translatable("options.vsync"), - value -> { - minecraftOptions.enableVsync().set(value); - window.updateVsync(value); - }, - () -> minecraftOptions.enableVsync().get()), + value -> { + minecraftOptions.enableVsync().set(value); + window.updateVsync(value); + }, + () -> minecraftOptions.enableVsync().get()), new CyclingOption<>(Component.translatable("options.inactivityFpsLimit"), - InactivityFpsLimit.values(), - value -> minecraftOptions.inactivityFpsLimit().set(value), - () -> minecraftOptions.inactivityFpsLimit().get()) + InactivityFpsLimit.values(), + value -> minecraftOptions.inactivityFpsLimit().set(value), + () -> minecraftOptions.inactivityFpsLimit().get()) .setTranslator(inactivityFpsLimit -> Component.translatable(inactivityFpsLimit.getKey())) }), new OptionBlock("", new Option[]{ new RangeOption(Component.translatable("options.guiScale"), - 0, window.calculateScale(0, minecraft.isEnforceUnicode()), 1, - value -> Component.translatable((value == 0) - ? "options.guiScale.auto" - : String.valueOf(value)), - value -> { - minecraftOptions.guiScale().set(value); - minecraft.resizeDisplay(); - }, - () -> (minecraftOptions.guiScale().get())), + 0, window.calculateScale(0, minecraft.isEnforceUnicode()), 1, + value -> Component.translatable((value == 0) + ? "options.guiScale.auto" + : String.valueOf(value)), + value -> { + minecraftOptions.guiScale().set(value); + minecraft.resizeDisplay(); + }, + () -> (minecraftOptions.guiScale().get())), new RangeOption(Component.translatable("options.gamma"), - 0, 100, 1, - value -> Component.translatable(switch (value) { - case 0 -> "options.gamma.min"; - case 50 -> "options.gamma.default"; - case 100 -> "options.gamma.max"; - default -> String.valueOf(value); - }), - value -> minecraftOptions.gamma().set(value * 0.01), - () -> (int) (minecraftOptions.gamma().get() * 100.0)), + 0, 100, 1, + value -> Component.translatable(switch (value) { + case 0 -> "options.gamma.min"; + case 50 -> "options.gamma.default"; + case 100 -> "options.gamma.max"; + default -> String.valueOf(value); + }), + value -> minecraftOptions.gamma().set(value * 0.01), + () -> (int) (minecraftOptions.gamma().get() * 100.0)), }), new OptionBlock("", new Option[]{ new SwitchOption(Component.translatable("options.viewBobbing"), - (value) -> minecraftOptions.bobView().set(value), - () -> minecraftOptions.bobView().get()), + (value) -> minecraftOptions.bobView().set(value), + () -> minecraftOptions.bobView().get()), new CyclingOption<>(Component.translatable("options.attackIndicator"), - AttackIndicatorStatus.values(), - value -> minecraftOptions.attackIndicator().set(value), - () -> minecraftOptions.attackIndicator().get()) + AttackIndicatorStatus.values(), + value -> minecraftOptions.attackIndicator().set(value), + () -> minecraftOptions.attackIndicator().get()) .setTranslator(value -> Component.translatable(value.getKey())), new SwitchOption(Component.translatable("options.autosaveIndicator"), - value -> minecraftOptions.showAutosaveIndicator().set(value), - () -> minecraftOptions.showAutosaveIndicator().get()), + value -> minecraftOptions.showAutosaveIndicator().set(value), + () -> minecraftOptions.showAutosaveIndicator().get()), }) }; } @@ -158,52 +158,52 @@ public static OptionBlock[] getGraphicsOpts() { return new OptionBlock[]{ new OptionBlock("", new Option[]{ new RangeOption(Component.translatable("options.renderDistance"), - 2, 32, 1, - (value) -> minecraftOptions.renderDistance().set(value), - () -> minecraftOptions.renderDistance().get()), + 2, 32, 1, + (value) -> minecraftOptions.renderDistance().set(value), + () -> minecraftOptions.renderDistance().get()), new RangeOption(Component.translatable("options.simulationDistance"), - 5, 32, 1, - (value) -> minecraftOptions.simulationDistance().set(value), - () -> minecraftOptions.simulationDistance().get()), + 5, 32, 1, + (value) -> minecraftOptions.simulationDistance().set(value), + () -> minecraftOptions.simulationDistance().get()), new CyclingOption<>(Component.translatable("options.prioritizeChunkUpdates"), - PrioritizeChunkUpdates.values(), - value -> minecraftOptions.prioritizeChunkUpdates().set(value), - () -> minecraftOptions.prioritizeChunkUpdates().get()) + PrioritizeChunkUpdates.values(), + value -> minecraftOptions.prioritizeChunkUpdates().set(value), + () -> minecraftOptions.prioritizeChunkUpdates().get()) .setTranslator(value -> Component.translatable(value.getKey())), }), new OptionBlock("", new Option[]{ new CyclingOption<>(Component.translatable("options.graphics"), - new GraphicsStatus[]{GraphicsStatus.FAST, GraphicsStatus.FANCY}, - value -> minecraftOptions.graphicsMode().set(value), - () -> minecraftOptions.graphicsMode().get()) + new GraphicsStatus[]{GraphicsStatus.FAST, GraphicsStatus.FANCY}, + value -> minecraftOptions.graphicsMode().set(value), + () -> minecraftOptions.graphicsMode().get()) .setTranslator(graphicsMode -> Component.translatable(graphicsMode.getKey())), new CyclingOption<>(Component.translatable("options.particles"), - new ParticleStatus[]{ParticleStatus.MINIMAL, ParticleStatus.DECREASED, ParticleStatus.ALL}, - value -> minecraftOptions.particles().set(value), - () -> minecraftOptions.particles().get()) + new ParticleStatus[]{ParticleStatus.MINIMAL, ParticleStatus.DECREASED, ParticleStatus.ALL}, + value -> minecraftOptions.particles().set(value), + () -> minecraftOptions.particles().get()) .setTranslator(particlesMode -> Component.translatable(particlesMode.getKey())), new CyclingOption<>(Component.translatable("options.renderClouds"), - CloudStatus.values(), - value -> minecraftOptions.cloudStatus().set(value), - () -> minecraftOptions.cloudStatus().get()) + CloudStatus.values(), + value -> minecraftOptions.cloudStatus().set(value), + () -> minecraftOptions.cloudStatus().get()) .setTranslator(value -> Component.translatable(value.getKey())), new RangeOption(Component.translatable("options.renderCloudsDistance"), - 2, 128, 1, - (value) -> minecraftOptions.cloudRange().set(value), - () -> minecraftOptions.cloudRange().get()), + 2, 128, 1, + (value) -> minecraftOptions.cloudRange().set(value), + () -> minecraftOptions.cloudRange().get()), new CyclingOption<>(Component.translatable("options.ao"), - new Integer[]{LightMode.FLAT, LightMode.SMOOTH, LightMode.SUB_BLOCK}, - (value) -> { - if (value > LightMode.FLAT) - minecraftOptions.ambientOcclusion().set(true); - else - minecraftOptions.ambientOcclusion().set(false); + new Integer[]{LightMode.FLAT, LightMode.SMOOTH, LightMode.SUB_BLOCK}, + (value) -> { + if (value > LightMode.FLAT) + minecraftOptions.ambientOcclusion().set(true); + else + minecraftOptions.ambientOcclusion().set(false); - config.ambientOcclusion = value; + config.ambientOcclusion = value; - minecraft.levelRenderer.allChanged(); - }, - () -> config.ambientOcclusion) + minecraft.levelRenderer.allChanged(); + }, + () -> config.ambientOcclusion) .setTranslator(value -> Component.translatable(switch (value) { case LightMode.FLAT -> "options.off"; case LightMode.SMOOTH -> "options.on"; @@ -212,33 +212,33 @@ public static OptionBlock[] getGraphicsOpts() { })) .setTooltip(Component.translatable("vulkanmod.options.ao.subBlock.tooltip")), new RangeOption(Component.translatable("options.biomeBlendRadius"), - 0, 7, 1, - value -> { - int v = value * 2 + 1; - return Component.nullToEmpty("%d x %d".formatted(v, v)); - }, - (value) -> { - minecraftOptions.biomeBlendRadius().set(value); - minecraft.levelRenderer.allChanged(); - }, - () -> minecraftOptions.biomeBlendRadius().get()), + 0, 7, 1, + value -> { + int v = value * 2 + 1; + return Component.nullToEmpty("%d x %d".formatted(v, v)); + }, + (value) -> { + minecraftOptions.biomeBlendRadius().set(value); + minecraft.levelRenderer.allChanged(); + }, + () -> minecraftOptions.biomeBlendRadius().get()), }), new OptionBlock("", new Option[]{ new SwitchOption(Component.translatable("options.entityShadows"), - value -> minecraftOptions.entityShadows().set(value), - () -> minecraftOptions.entityShadows().get()), + value -> minecraftOptions.entityShadows().set(value), + () -> minecraftOptions.entityShadows().get()), new RangeOption(Component.translatable("options.entityDistanceScaling"), - 50, 500, 25, - value -> minecraftOptions.entityDistanceScaling().set(value * 0.01), - () -> minecraftOptions.entityDistanceScaling().get().intValue() * 100), + 50, 500, 25, + value -> minecraftOptions.entityDistanceScaling().set(value * 0.01), + () -> minecraftOptions.entityDistanceScaling().get().intValue() * 100), new CyclingOption<>(Component.translatable("options.mipmapLevels"), - new Integer[]{0, 1, 2, 3, 4}, - value -> { - minecraftOptions.mipmapLevels().set(value); - minecraft.updateMaxMipLevel(value); - minecraft.delayTextureReload(); - }, - () -> minecraftOptions.mipmapLevels().get()) + new Integer[]{0, 1, 2, 3, 4}, + value -> { + minecraftOptions.mipmapLevels().set(value); + minecraft.updateMaxMipLevel(value); + minecraft.delayTextureReload(); + }, + () -> minecraftOptions.mipmapLevels().get()) .setTranslator(value -> Component.nullToEmpty(value.toString())) }) }; @@ -248,9 +248,9 @@ public static OptionBlock[] getOptimizationOpts() { return new OptionBlock[]{ new OptionBlock("", new Option[]{ new CyclingOption<>(Component.translatable("vulkanmod.options.advCulling"), - new Integer[]{1, 2, 3, 10}, - value -> config.advCulling = value, - () -> config.advCulling) + new Integer[]{1, 2, 3, 10}, + value -> config.advCulling = value, + () -> config.advCulling) .setTranslator(value -> Component.translatable(switch (value) { case 1 -> "vulkanmod.options.advCulling.aggressive"; case 2 -> "vulkanmod.options.advCulling.normal"; @@ -260,27 +260,27 @@ public static OptionBlock[] getOptimizationOpts() { })) .setTooltip(Component.translatable("vulkanmod.options.advCulling.tooltip")), new SwitchOption(Component.translatable("vulkanmod.options.entityCulling"), - value -> config.entityCulling = value, - () -> config.entityCulling) + value -> config.entityCulling = value, + () -> config.entityCulling) .setTooltip(Component.translatable("vulkanmod.options.entityCulling.tooltip")), new SwitchOption(Component.translatable("vulkanmod.options.uniqueOpaqueLayer"), - value -> { - config.uniqueOpaqueLayer = value; - TerrainRenderType.updateMapping(); - minecraft.levelRenderer.allChanged(); - }, - () -> config.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) + 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) + value -> config.indirectDraw = value, + () -> config.indirectDraw) .setTooltip(Component.translatable("vulkanmod.options.indirectDraw.tooltip")), }) }; @@ -291,12 +291,12 @@ public static OptionBlock[] getOtherOpts() { return new OptionBlock[]{ new OptionBlock("", new Option[]{ new RangeOption(Component.translatable("vulkanmod.options.builderThreads"), - 0, (Runtime.getRuntime().availableProcessors() - 1), 1, - value -> { - config.builderThreads = value; - WorldRenderer.getInstance().getTaskDispatcher().createThreads(value); - }, - () -> config.builderThreads) + 0, (Runtime.getRuntime().availableProcessors() - 1), 1, + value -> { + config.builderThreads = value; + WorldRenderer.getInstance().getTaskDispatcher().createThreads(value); + }, + () -> config.builderThreads) .setTranslator(value -> { if (value == 0) return Component.translatable("vulkanmod.options.builderThreads.auto"); @@ -304,27 +304,27 @@ public static OptionBlock[] getOtherOpts() { return Component.nullToEmpty(String.valueOf(value)); }), new RangeOption(Component.translatable("vulkanmod.options.frameQueue"), - 2, 5, 1, - value -> { - config.frameQueueSize = value; - Renderer.scheduleSwapChainUpdate(); - }, () -> config.frameQueueSize) + 2, 5, 1, + value -> { + config.frameQueueSize = value; + Renderer.scheduleSwapChainUpdate(); + }, () -> config.frameQueueSize) .setTooltip(Component.translatable("vulkanmod.options.frameQueue.tooltip")), new SwitchOption(Component.translatable("vulkanmod.options.textureAnimations"), - value -> { - config.textureAnimations = value; - }, - () -> config.textureAnimations), + value -> { + config.textureAnimations = value; + }, + () -> config.textureAnimations), }), new OptionBlock("", new Option[]{ new CyclingOption<>(Component.translatable("vulkanmod.options.deviceSelector"), - IntStream.range(-1, DeviceManager.suitableDevices.size()).boxed() - .toArray(Integer[]::new), - value -> config.device = value, - () -> config.device) + IntStream.range(-1, DeviceManager.suitableDevices.size()).boxed() + .toArray(Integer[]::new), + value -> config.device = value, + () -> config.device) .setTranslator(value -> Component.translatable((value == -1) - ? "vulkanmod.options.deviceSelector.auto" - : DeviceManager.suitableDevices.get( + ? "vulkanmod.options.deviceSelector.auto" + : DeviceManager.suitableDevices.get( value).deviceName) ) .setTooltip(Component.nullToEmpty("%s: %s".formatted( diff --git a/src/main/java/net/vulkanmod/config/video/VideoModeManager.java b/src/main/java/net/vulkanmod/config/video/VideoModeManager.java index 985455a63..7e28e0b48 100644 --- a/src/main/java/net/vulkanmod/config/video/VideoModeManager.java +++ b/src/main/java/net/vulkanmod/config/video/VideoModeManager.java @@ -7,14 +7,13 @@ import java.util.ArrayList; import java.util.List; -import static org.lwjgl.glfw.GLFW.*; +import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor; public abstract class VideoModeManager { + public static VideoModeSet.VideoMode selectedVideoMode; private static VideoModeSet.VideoMode osVideoMode; private static VideoModeSet[] videoModeSets; - public static VideoModeSet.VideoMode selectedVideoMode; - public static void init() { long monitor = glfwGetPrimaryMonitor(); osVideoMode = getCurrentVideoMode(monitor); @@ -30,7 +29,7 @@ public static VideoModeSet[] getVideoResolutions() { } public static VideoModeSet getFirstAvailable() { - if(videoModeSets != null) + if (videoModeSets != null) return videoModeSets[videoModeSets.length - 1]; else return VideoModeSet.getDummy(); @@ -40,7 +39,7 @@ public static VideoModeSet.VideoMode getOsVideoMode() { return osVideoMode; } - public static VideoModeSet.VideoMode getCurrentVideoMode(long monitor){ + public static VideoModeSet.VideoMode getCurrentVideoMode(long monitor) { GLFWVidMode vidMode = GLFW.glfwGetVideoMode(monitor); if (vidMode == null) diff --git a/src/main/java/net/vulkanmod/config/video/VideoModeSet.java b/src/main/java/net/vulkanmod/config/video/VideoModeSet.java index e4fb34fac..a49246981 100644 --- a/src/main/java/net/vulkanmod/config/video/VideoModeSet.java +++ b/src/main/java/net/vulkanmod/config/video/VideoModeSet.java @@ -10,18 +10,18 @@ public class VideoModeSet { public final int bitDepth; List refreshRates = new ObjectArrayList<>(); - public static VideoModeSet getDummy() { - var set = new VideoModeSet(-1, -1, -1); - set.addRefreshRate(-1); - return set; - } - public VideoModeSet(int width, int height, int bitDepth) { this.width = width; this.height = height; this.bitDepth = bitDepth; } + public static VideoModeSet getDummy() { + var set = new VideoModeSet(-1, -1, -1); + set.addRefreshRate(-1); + return set; + } + public int getRefreshRate() { return this.refreshRates.get(0); } @@ -90,6 +90,6 @@ public String toString() { "refreshRate=" + refreshRate + ']'; } - } + } } diff --git a/src/main/java/net/vulkanmod/gl/GlUtil.java b/src/main/java/net/vulkanmod/gl/GlUtil.java index fe8edea75..2112a01a2 100644 --- a/src/main/java/net/vulkanmod/gl/GlUtil.java +++ b/src/main/java/net/vulkanmod/gl/GlUtil.java @@ -29,7 +29,7 @@ public static ByteBuffer RGBtoRGBA_buffer(ByteBuffer in) { ByteBuffer out = MemoryUtil.memAlloc(outSize); int j = 0; - for (int i = 0; i < outSize; i+=4, j+=3) { + for (int i = 0; i < outSize; i += 4, j += 3) { out.put(i, in.get(j)); out.put(i + 1, in.get(j + 1)); out.put(i + 2, in.get(j + 2)); @@ -50,7 +50,7 @@ public static ByteBuffer BGRAtoRGBA_buffer(ByteBuffer in) { long srcPtr = MemoryUtil.memAddress0(in); // TODO write in place (don't free the returned buffer in that case) - for (int i = 0; i < outSize ; i += 4) { + for (int i = 0; i < outSize; i += 4) { int color = MemoryUtil.memGetInt(srcPtr + i); color = (color << 24) & 0xFF000000 | (color >> 8) & 0xFFFFFF; @@ -63,34 +63,29 @@ public static ByteBuffer BGRAtoRGBA_buffer(ByteBuffer in) { public static int vulkanFormat(int glFormat, int type) { return switch (glFormat) { - case GL11.GL_RGBA, GL30.GL_RGBA8 -> - switch (type) { - case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; - case GL11.GL_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; - case GL30.GL_UNSIGNED_INT_8_8_8_8, GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> VK_FORMAT_R8G8B8A8_UNORM; - default -> throw new IllegalStateException("Unexpected type: " + type); - }; - case GL30.GL_BGRA -> - switch (type) { - case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_B8G8R8A8_UNORM; - case GL11.GL_BYTE -> VK_FORMAT_B8G8R8A8_UNORM; - case GL30.GL_UNSIGNED_INT_8_8_8_8, GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> VK_FORMAT_B8G8R8A8_UNORM; - default -> throw new IllegalStateException("Unexpected type: " + type); - }; - case GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> - switch (type) { - case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UINT; - case GL11.GL_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; - default -> throw new IllegalStateException("Unexpected type: " + type); - }; - case GL11.GL_RED -> - switch (type) { - case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8_UNORM; - default -> throw new IllegalStateException("Unexpected type: " + type); - }; + case GL11.GL_RGBA, GL30.GL_RGBA8 -> switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; + case GL11.GL_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; + case GL30.GL_UNSIGNED_INT_8_8_8_8, GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> VK_FORMAT_R8G8B8A8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; + case GL30.GL_BGRA -> switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_B8G8R8A8_UNORM; + case GL11.GL_BYTE -> VK_FORMAT_B8G8R8A8_UNORM; + case GL30.GL_UNSIGNED_INT_8_8_8_8, GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> VK_FORMAT_B8G8R8A8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; + case GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UINT; + case GL11.GL_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; + case GL11.GL_RED -> switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; case GL11.GL_DEPTH_COMPONENT, GL30.GL_DEPTH_COMPONENT32, - GL30.GL_DEPTH_COMPONENT32F, GL30.GL_DEPTH_COMPONENT24 -> - Vulkan.getDefaultDepthFormat(); + GL30.GL_DEPTH_COMPONENT32F, GL30.GL_DEPTH_COMPONENT24 -> Vulkan.getDefaultDepthFormat(); default -> throw new IllegalStateException("Unexpected format: " + glFormat); }; diff --git a/src/main/java/net/vulkanmod/gl/VkGlBuffer.java b/src/main/java/net/vulkanmod/gl/VkGlBuffer.java index 1a2d6b4d5..846ba19a0 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlBuffer.java +++ b/src/main/java/net/vulkanmod/gl/VkGlBuffer.java @@ -10,14 +10,21 @@ // TODO: Implement missing features. // This class is only used to emulate a CPU buffer for texture copying purposes public class VkGlBuffer { - private static int ID_COUNTER = 1; private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); + private static int ID_COUNTER = 1; private static int boundId = 0; private static VkGlBuffer boundBuffer; private static VkGlBuffer arrayBufferBound; private static VkGlBuffer pixelPackBufferBound; private static VkGlBuffer pixelUnpackBufferBound; + int id; + int target; + ByteBuffer data; + + public VkGlBuffer(int id) { + this.id = id; + } public static int glGenBuffers() { int id = ID_COUNTER; @@ -105,15 +112,6 @@ private static void checkTarget(int target) { throw new IllegalArgumentException("target %d not supported".formatted(target)); } - int id; - int target; - - ByteBuffer data; - - public VkGlBuffer(int id) { - this.id = id; - } - private void allocate(int size) { if (this.data != null) this.freeData(); diff --git a/src/main/java/net/vulkanmod/gl/VkGlFramebuffer.java b/src/main/java/net/vulkanmod/gl/VkGlFramebuffer.java index fffacde97..87a301539 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlFramebuffer.java +++ b/src/main/java/net/vulkanmod/gl/VkGlFramebuffer.java @@ -14,11 +14,20 @@ import static org.lwjgl.vulkan.VK11.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; public class VkGlFramebuffer { - private static int idCounter = 1; - private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); + private static int idCounter = 1; private static VkGlFramebuffer boundFramebuffer; private static VkGlFramebuffer readFramebuffer; + public final int id; + Framebuffer framebuffer; + RenderPass renderPass; + VulkanImage colorAttachment; + VulkanImage depthAttachment; + boolean needsUpdate; + + VkGlFramebuffer(int i) { + this.id = i; + } public static void resetBoundFramebuffer() { boundFramebuffer = null; @@ -143,19 +152,6 @@ public static VkGlFramebuffer getFramebuffer(int id) { return map.get(id); } - public final int id; - Framebuffer framebuffer; - RenderPass renderPass; - - VulkanImage colorAttachment; - VulkanImage depthAttachment; - - boolean needsUpdate; - - VkGlFramebuffer(int i) { - this.id = i; - } - boolean beginRendering() { return Renderer.getInstance().beginRendering(this.renderPass, this.framebuffer); } @@ -214,16 +210,16 @@ public void create() { VulkanImage depthImage = this.depthAttachment; this.framebuffer = Framebuffer.builder(this.colorAttachment, depthImage) - .build(); + .build(); RenderPass.Builder builder = RenderPass.builder(this.framebuffer); builder.getColorAttachmentInfo() - .setLoadOp(VK_ATTACHMENT_LOAD_OP_LOAD) - .setFinalLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + .setLoadOp(VK_ATTACHMENT_LOAD_OP_LOAD) + .setFinalLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); if (hasDepthImage) { builder.getDepthAttachmentInfo() - .setOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); + .setOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); } this.renderPass = builder.build(); diff --git a/src/main/java/net/vulkanmod/gl/VkGlProgram.java b/src/main/java/net/vulkanmod/gl/VkGlProgram.java index 2cce606f2..38fe4829b 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlProgram.java +++ b/src/main/java/net/vulkanmod/gl/VkGlProgram.java @@ -4,10 +4,16 @@ import net.vulkanmod.vulkan.shader.Pipeline; public class VkGlProgram { - private static int ID_COUNTER = 1; private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); + private static int ID_COUNTER = 1; private static int boundProgramId = 0; private static VkGlProgram boundProgram; + int id; + Pipeline pipeline; + + VkGlProgram(int i) { + this.id = i; + } public static VkGlProgram getBoundProgram() { return boundProgram; @@ -38,13 +44,6 @@ public static void glUseProgram(int id) { } - int id; - Pipeline pipeline; - - VkGlProgram(int i) { - this.id = i; - } - public void bindPipeline(Pipeline pipeline) { this.pipeline = pipeline; } diff --git a/src/main/java/net/vulkanmod/gl/VkGlRenderbuffer.java b/src/main/java/net/vulkanmod/gl/VkGlRenderbuffer.java index e811144a2..453996896 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlRenderbuffer.java +++ b/src/main/java/net/vulkanmod/gl/VkGlRenderbuffer.java @@ -14,10 +14,21 @@ import static org.lwjgl.vulkan.VK10.*; public class VkGlRenderbuffer { - private static int ID_COUNTER = 1; private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); + private static int ID_COUNTER = 1; private static int boundId = 0; private static VkGlRenderbuffer bound; + final int id; + VulkanImage vulkanImage; + int internalFormat; + boolean needsUpdate = false; + int maxLevel = 0; + int maxLod = 0; + int minFilter, magFilter = GL11.GL_LINEAR; + + public VkGlRenderbuffer(int id) { + this.id = id; + } public static int genId() { int id = ID_COUNTER; @@ -65,8 +76,10 @@ public static void texParameteri(int target, int pName, int param) { switch (pName) { case GL30.GL_TEXTURE_MAX_LEVEL -> bound.setMaxLevel(param); case GL30.GL_TEXTURE_MAX_LOD -> bound.setMaxLod(param); - case GL30.GL_TEXTURE_MIN_LOD -> {} - case GL30.GL_TEXTURE_LOD_BIAS -> {} + case GL30.GL_TEXTURE_MIN_LOD -> { + } + case GL30.GL_TEXTURE_LOD_BIAS -> { + } case GL11.GL_TEXTURE_MAG_FILTER -> bound.setMagFilter(param); case GL11.GL_TEXTURE_MIN_FILTER -> bound.setMinFilter(param); @@ -108,19 +121,6 @@ public static VkGlRenderbuffer getBound() { return bound; } - final int id; - VulkanImage vulkanImage; - int internalFormat; - - boolean needsUpdate = false; - int maxLevel = 0; - int maxLod = 0; - int minFilter, magFilter = GL11.GL_LINEAR; - - public VkGlRenderbuffer(int id) { - this.id = id; - } - void allocateIfNeeded(int width, int height, int format) { int vkFormat = GlUtil.vulkanFormat(format); diff --git a/src/main/java/net/vulkanmod/gl/VkGlShader.java b/src/main/java/net/vulkanmod/gl/VkGlShader.java index 95b70bff0..374a278e2 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlShader.java +++ b/src/main/java/net/vulkanmod/gl/VkGlShader.java @@ -3,9 +3,17 @@ import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; public class VkGlShader { - private static int ID_COUNTER = 1; private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); - private static int boundTextureId = 0; + private static int ID_COUNTER = 1; + private static final int boundTextureId = 0; + final int id; + final int type; + String source; + + VkGlShader(int id, int type) { + this.id = id; + this.type = type; + } public static int glCreateShader(int type) { int id = ID_COUNTER++; @@ -32,14 +40,4 @@ public static int glGetShaderi(int i, int j) { return 0; } - final int id; - final int type; - - String source; - - VkGlShader(int id, int type) { - this.id = id; - this.type = type; - } - } diff --git a/src/main/java/net/vulkanmod/gl/VkGlTexture.java b/src/main/java/net/vulkanmod/gl/VkGlTexture.java index 8d39e536e..fc7a7646e 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlTexture.java +++ b/src/main/java/net/vulkanmod/gl/VkGlTexture.java @@ -17,8 +17,8 @@ import static org.lwjgl.vulkan.VK10.*; public class VkGlTexture { - private static int ID_COUNTER = 1; private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); + private static int ID_COUNTER = 1; private static int boundTextureId = 0; private static VkGlTexture boundTexture; private static int activeTexture = 0; @@ -26,6 +26,19 @@ public class VkGlTexture { private static int unpackRowLength; private static int unpackSkipRows; private static int unpackSkipPixels; + public final int id; + VulkanImage vulkanImage; + int width, height; + int vkFormat; + boolean needsUpdate = false; + int maxLevel = 0; + int maxLod = 0; + int minFilter, magFilter = GL11.GL_LINEAR; + boolean clamp = true; + + public VkGlTexture(int id) { + this.id = id; + } public static void bindIdToImage(int id, VulkanImage vulkanImage) { VkGlTexture texture = map.get(id); @@ -104,10 +117,7 @@ public static void texImage2D(int target, int level, int internalFormat, int wid } private static boolean checkParams(int level, int width, int height) { - if (width == 0 || height == 0) - return true; - - return false; + return width == 0 || height == 0; } public static void texSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int type, long pixels) { @@ -143,7 +153,7 @@ private static ByteBuffer getByteBuffer(int width, int height, long pixels) { return src; } - public static void texSubImage2D(int target, int level, int xOffset, int yOffset, int width , int height, int format, int type, @Nullable ByteBuffer pixels) { + public static void texSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int type, @Nullable ByteBuffer pixels) { if (width == 0 || height == 0) return; @@ -175,15 +185,18 @@ public static void texParameteri(int target, int pName, int param) { switch (pName) { case GL30.GL_TEXTURE_MAX_LEVEL -> boundTexture.setMaxLevel(param); case GL30.GL_TEXTURE_MAX_LOD -> boundTexture.setMaxLod(param); - case GL30.GL_TEXTURE_MIN_LOD -> {} - case GL30.GL_TEXTURE_LOD_BIAS -> {} + case GL30.GL_TEXTURE_MIN_LOD -> { + } + case GL30.GL_TEXTURE_LOD_BIAS -> { + } case GL11.GL_TEXTURE_MAG_FILTER -> boundTexture.setMagFilter(param); case GL11.GL_TEXTURE_MIN_FILTER -> boundTexture.setMinFilter(param); case GL11.GL_TEXTURE_WRAP_S, GL11.GL_TEXTURE_WRAP_T -> boundTexture.setClamp(param); - default -> {} + default -> { + } } //TODO @@ -270,23 +283,6 @@ public static VkGlTexture getBoundTexture() { return boundTexture; } - public final int id; - VulkanImage vulkanImage; - - int width, height; - int vkFormat; - - boolean needsUpdate = false; - int maxLevel = 0; - int maxLod = 0; - int minFilter, magFilter = GL11.GL_LINEAR; - - boolean clamp = true; - - public VkGlTexture(int id) { - this.id = id; - } - void updateParams(int level, int width, int height, int internalFormat, int type) { if (level > this.maxLevel) { this.maxLevel = level; @@ -325,8 +321,7 @@ void allocateImage(int width, int height, int vkFormat) { 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) .setName(String.format("GlTexture %d", this.id)) .setMipLevels(maxLevel + 1) @@ -345,7 +340,8 @@ void updateSampler() { samplerFlags |= magFilter == GL11.GL_LINEAR ? SamplerManager.LINEAR_FILTERING_BIT : 0; samplerFlags |= switch (minFilter) { - case GL11.GL_LINEAR_MIPMAP_LINEAR -> SamplerManager.USE_MIPMAPS_BIT | SamplerManager.MIPMAP_LINEAR_FILTERING_BIT; + case GL11.GL_LINEAR_MIPMAP_LINEAR -> + SamplerManager.USE_MIPMAPS_BIT | SamplerManager.MIPMAP_LINEAR_FILTERING_BIT; case GL11.GL_NEAREST_MIPMAP_NEAREST -> SamplerManager.USE_MIPMAPS_BIT; default -> 0; }; @@ -422,11 +418,7 @@ void setMinFilter(int v) { } void setClamp(int v) { - if (v == GL30.GL_CLAMP_TO_EDGE) { - this.clamp = true; - } else { - this.clamp = false; - } + this.clamp = v == GL30.GL_CLAMP_TO_EDGE; updateSampler(); } diff --git a/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java b/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java index 441fe41b3..bb74ff830 100644 --- a/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java +++ b/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java @@ -19,5 +19,6 @@ default boolean canUseFastVertex() { void vertex(float x, float y, float z, int packedColor, float u, float v, int overlay, int light, int packedNormal); // Used for particles - default void vertex(float x, float y, float z, float u, float v, int packedColor, int light) {} + default void vertex(float x, float y, float z, float u, float v, int packedColor, int light) { + } } diff --git a/src/main/java/net/vulkanmod/interfaces/shader/ExtendedRenderPipeline.java b/src/main/java/net/vulkanmod/interfaces/shader/ExtendedRenderPipeline.java index dc927f0f0..4f763d34a 100644 --- a/src/main/java/net/vulkanmod/interfaces/shader/ExtendedRenderPipeline.java +++ b/src/main/java/net/vulkanmod/interfaces/shader/ExtendedRenderPipeline.java @@ -11,11 +11,11 @@ static ExtendedRenderPipeline of(RenderPipeline renderPipeline) { return (ExtendedRenderPipeline) renderPipeline; } - void setPipeline(GraphicsPipeline pipeline); - - void setProgram(EGlProgram program); - Pipeline getPipeline(); + void setPipeline(GraphicsPipeline pipeline); + EGlProgram getProgram(); + + void setProgram(EGlProgram program); } diff --git a/src/main/java/net/vulkanmod/mixin/chunk/ClientChunkCacheM.java b/src/main/java/net/vulkanmod/mixin/chunk/ClientChunkCacheM.java index 0f5e9d392..08ca14556 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/ClientChunkCacheM.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/ClientChunkCacheM.java @@ -1,14 +1,12 @@ package net.vulkanmod.mixin.chunk; import net.minecraft.client.multiplayer.ClientChunkCache; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.levelgen.Heightmap; import net.vulkanmod.render.chunk.ChunkStatusMap; -import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/net/vulkanmod/mixin/chunk/DirectionMixin.java b/src/main/java/net/vulkanmod/mixin/chunk/DirectionMixin.java index 81b0248d3..76e6c4794 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/DirectionMixin.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/DirectionMixin.java @@ -9,9 +9,13 @@ @Mixin(Direction.class) public class DirectionMixin { - @Shadow @Final private static Direction[] BY_3D_DATA; + @Shadow + @Final + private static Direction[] BY_3D_DATA; - @Shadow @Final private int oppositeIndex; + @Shadow + @Final + private int oppositeIndex; /** * @author diff --git a/src/main/java/net/vulkanmod/mixin/chunk/FrustumMixin.java b/src/main/java/net/vulkanmod/mixin/chunk/FrustumMixin.java index 7fdfcc70e..a8d2e81c5 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/FrustumMixin.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/FrustumMixin.java @@ -16,13 +16,19 @@ @Mixin(Frustum.class) public class FrustumMixin implements FrustumMixed { - @Shadow private double camX; - @Shadow private double camY; - @Shadow private double camZ; - @Shadow @Final private Matrix4f matrix; - @Shadow private Vector4f viewVector; - - @Unique private final VFrustum vFrustum = new VFrustum(); + @Unique + private final VFrustum vFrustum = new VFrustum(); + @Shadow + private double camX; + @Shadow + private double camY; + @Shadow + private double camZ; + @Shadow + @Final + private Matrix4f matrix; + @Shadow + private Vector4f viewVector; @Inject(method = "calculateFrustum", at = @At("HEAD")) private void calculateFrustum(Matrix4f modelView, Matrix4f projection, CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java b/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java index c4471218b..acc21dc78 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java @@ -8,7 +8,10 @@ import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.RenderBuffers; +import net.minecraft.client.renderer.SubmitNodeStorage; import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher; import net.minecraft.client.renderer.chunk.ChunkSectionLayerGroup; import net.minecraft.client.renderer.chunk.ChunkSectionsToRender; @@ -19,7 +22,6 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.BlockDestructionProgress; import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.phys.Vec3; import net.vulkanmod.render.chunk.WorldRenderer; import net.vulkanmod.render.profiling.Profiler; import net.vulkanmod.render.vertex.TerrainRenderType; @@ -36,12 +38,15 @@ @Mixin(LevelRenderer.class) public abstract class LevelRendererMixin { - @Shadow @Final private Long2ObjectMap> destructionProgress; - - @Unique private WorldRenderer worldRenderer; - - @Unique double camX, camY, camZ; - @Unique Matrix4f modelView, projection; + @Unique + double camX, camY, camZ; + @Unique + Matrix4f modelView, projection; + @Shadow + @Final + private Long2ObjectMap> destructionProgress; + @Unique + private WorldRenderer worldRenderer; @Inject(method = "", at = @At("RETURN")) private void init(Minecraft minecraft, EntityRenderDispatcher entityRenderDispatcher, @@ -71,7 +76,7 @@ private void onExtractVisibleBlockEntities(Camera camera, float partialTick, Lev @Inject(method = "submitBlockEntities", at = @At(value = "RETURN"), cancellable = true) private void onSubmitBlockEntities(PoseStack poseStack, LevelRenderState levelRenderState, - SubmitNodeStorage submitNodeStorage, CallbackInfo ci) { + SubmitNodeStorage submitNodeStorage, CallbackInfo ci) { this.worldRenderer.renderBlockEntities(poseStack, levelRenderState, submitNodeStorage, this.destructionProgress); ci.cancel(); @@ -122,8 +127,7 @@ private void renderSectionLayer(ChunkSectionsToRender instance, ChunkSectionLaye this.worldRenderer.renderSectionLayer(TerrainRenderType.SOLID, camX, camY, camZ, modelView, projection); this.worldRenderer.renderSectionLayer(TerrainRenderType.CUTOUT, camX, camY, camZ, modelView, projection); this.worldRenderer.renderSectionLayer(TerrainRenderType.CUTOUT_MIPPED, camX, camY, camZ, modelView, projection); - } - else if (chunkSectionLayerGroup == ChunkSectionLayerGroup.TRANSLUCENT) { + } else if (chunkSectionLayerGroup == ChunkSectionLayerGroup.TRANSLUCENT) { Profiler profiler = Profiler.getMainProfiler(); profiler.pop(); profiler.push("Translucent_terrain"); diff --git a/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java b/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java index 18e653849..516cc77d8 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java @@ -8,8 +8,8 @@ @Mixin(SectionBufferBuilderPool.class) public class SectionBufferBuilderPoolM { - @ModifyVariable(method = "allocate", at = @At("STORE"), ordinal = 1) - private static int skipAllocation(int value) { - return 0; - } + @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/chunk/SectionRenderDispatcherM.java b/src/main/java/net/vulkanmod/mixin/chunk/SectionRenderDispatcherM.java index 35a1bafc7..4b77e59ee 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/SectionRenderDispatcherM.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/SectionRenderDispatcherM.java @@ -2,13 +2,11 @@ import net.minecraft.client.renderer.chunk.SectionRenderDispatcher; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(SectionRenderDispatcher.class) public class SectionRenderDispatcherM { - // TODO + // TODO // @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/thread/ProcessorMailbox;tell(Ljava/lang/Object;)V")) // private void redirectTask(ProcessorMailbox instance, Object object) {} } diff --git a/src/main/java/net/vulkanmod/mixin/chunk/ViewAreaM.java b/src/main/java/net/vulkanmod/mixin/chunk/ViewAreaM.java index ef958df3f..3536c5d40 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/ViewAreaM.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/ViewAreaM.java @@ -11,13 +11,15 @@ @Mixin(ViewArea.class) public abstract class ViewAreaM { - @Shadow public SectionRenderDispatcher.RenderSection[] sections; + @Shadow + public SectionRenderDispatcher.RenderSection[] sections; - @Shadow protected abstract void setViewDistance(int i); + @Shadow + protected abstract void setViewDistance(int i); - @Inject(method = "createSections", at = @At("HEAD")) - private void skipAllocation(SectionRenderDispatcher sectionRenderDispatcher, CallbackInfo ci) { - // It's not possible to completely skip allocation since it would cause an error if repositionCamera is called - this.setViewDistance(0); - } + @Inject(method = "createSections", at = @At("HEAD")) + private void skipAllocation(SectionRenderDispatcher sectionRenderDispatcher, CallbackInfo ci) { + // It's not possible to completely skip allocation since it would cause an error if repositionCamera is called + this.setViewDistance(0); + } } diff --git a/src/main/java/net/vulkanmod/mixin/chunk/VisibilitySetMixin.java b/src/main/java/net/vulkanmod/mixin/chunk/VisibilitySetMixin.java index 824abb3ba..3b4b9a0fa 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/VisibilitySetMixin.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/VisibilitySetMixin.java @@ -9,7 +9,7 @@ @Mixin(VisibilitySet.class) public class VisibilitySetMixin implements VisibilitySetExtended { -// private int vis2 = 0; + // private int vis2 = 0; private long vis = 0; /** @@ -29,7 +29,7 @@ public void set(Direction dir1, Direction dir2, boolean p_112989_) { */ @Overwrite public void setAll(boolean bl) { - if(bl) this.vis = 0xFFFFFFFFFFFFFFFFL; + if (bl) this.vis = 0xFFFFFFFFFFFFFFFFL; } /** diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java b/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java index 99580bb1d..082c23011 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java @@ -13,12 +13,11 @@ import com.mojang.blaze3d.systems.RenderPass; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.textures.GpuTextureView; -import com.mojang.blaze3d.vertex.*; import com.mojang.datafixers.util.Pair; import net.minecraft.client.renderer.MappableRingBuffer; import net.minecraft.client.renderer.PostPass; import net.minecraft.resources.ResourceLocation; -import net.vulkanmod.render.engine.*; +import net.vulkanmod.render.engine.VkGpuTexture; import net.vulkanmod.vulkan.Renderer; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -32,12 +31,24 @@ @Mixin(PostPass.class) public abstract class PostPassM { - @Shadow @Final private String name; - @Shadow @Final private List inputs; - @Shadow @Final private ResourceLocation outputTargetId; - @Shadow @Final private RenderPipeline pipeline; - @Shadow @Final private MappableRingBuffer infoUbo; - @Shadow @Final private Map customUniforms; + @Shadow + @Final + private String name; + @Shadow + @Final + private List inputs; + @Shadow + @Final + private ResourceLocation outputTargetId; + @Shadow + @Final + private RenderPipeline pipeline; + @Shadow + @Final + private MappableRingBuffer infoUbo; + @Shadow + @Final + private Map customUniforms; /** * @author @@ -51,7 +62,7 @@ public void addToFrame(FrameGraphBuilder frameGraphBuilder, Map resourceHandle = (ResourceHandle)map.computeIfPresent( + ResourceHandle resourceHandle = map.computeIfPresent( this.outputTargetId, (resourceLocation, resourceHandlex) -> framePass.readsAndWrites(resourceHandlex) ); if (resourceHandle == null) { @@ -93,7 +104,7 @@ public void addToFrame(FrameGraphBuilder frameGraphBuilder, Map entry : this.customUniforms.entrySet()) { - renderPass.setUniform((String)entry.getKey(), (GpuBuffer)entry.getValue()); + renderPass.setUniform(entry.getKey(), entry.getValue()); } for (Pair pair2 : list) { 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 7793470bf..0f42fe99e 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java @@ -3,13 +3,13 @@ import net.vulkanmod.gl.VkGlTexture; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; +import org.jetbrains.annotations.Nullable; import org.lwjgl.opengl.GL11; import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.NativeType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; -import org.jetbrains.annotations.Nullable; import java.nio.ByteBuffer; import java.nio.IntBuffer; @@ -315,7 +315,6 @@ public static void glBlendFunc(@NativeType("GLenum") int sfactor, @NativeType("G } - /** * @author * @reason diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL14M.java b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL14M.java index 6d6781524..b43a1b5d8 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL14M.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL14M.java @@ -2,7 +2,6 @@ import net.vulkanmod.vulkan.VRenderSystem; import org.lwjgl.opengl.GL14; -import org.lwjgl.opengl.GL14C; import org.lwjgl.system.NativeType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; diff --git a/src/main/java/net/vulkanmod/mixin/debug/DebugEntryMemoryM.java b/src/main/java/net/vulkanmod/mixin/debug/DebugEntryMemoryM.java index cd6e90fd6..2ccf53e76 100644 --- a/src/main/java/net/vulkanmod/mixin/debug/DebugEntryMemoryM.java +++ b/src/main/java/net/vulkanmod/mixin/debug/DebugEntryMemoryM.java @@ -19,7 +19,9 @@ @Mixin(DebugEntryMemory.class) public abstract class DebugEntryMemoryM { - @Shadow @Final private static ResourceLocation GROUP; + @Shadow + @Final + private static ResourceLocation GROUP; @Shadow protected static long bytesToMegabytes(long l) { diff --git a/src/main/java/net/vulkanmod/mixin/debug/DebugScreenEntriesM.java b/src/main/java/net/vulkanmod/mixin/debug/DebugScreenEntriesM.java index 1f0843edd..ca8a193b9 100644 --- a/src/main/java/net/vulkanmod/mixin/debug/DebugScreenEntriesM.java +++ b/src/main/java/net/vulkanmod/mixin/debug/DebugScreenEntriesM.java @@ -20,6 +20,6 @@ public static ResourceLocation register(ResourceLocation resourceLocation, Debug @Inject(method = "", at = @At("RETURN")) private static void addEntry(CallbackInfo ci) { - register(ResourceLocation.fromNamespaceAndPath("vkmod","stats"), new DebugEntryMemoryStats()); + register(ResourceLocation.fromNamespaceAndPath("vkmod", "stats"), new DebugEntryMemoryStats()); } } diff --git a/src/main/java/net/vulkanmod/mixin/debug/KeyboardHandlerM.java b/src/main/java/net/vulkanmod/mixin/debug/KeyboardHandlerM.java index e01a76c91..6a9ed9a7f 100644 --- a/src/main/java/net/vulkanmod/mixin/debug/KeyboardHandlerM.java +++ b/src/main/java/net/vulkanmod/mixin/debug/KeyboardHandlerM.java @@ -13,9 +13,11 @@ @Mixin(KeyboardHandler.class) public abstract class KeyboardHandlerM { - @Shadow protected abstract boolean handleChunkDebugKeys(KeyEvent keyEvent); + @Shadow + private boolean handledDebugKey; - @Shadow private boolean handledDebugKey; + @Shadow + protected abstract boolean handleChunkDebugKeys(KeyEvent keyEvent); @Inject(method = "keyPress", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/KeyMapping;set(Lcom/mojang/blaze3d/platform/InputConstants$Key;Z)V", ordinal = 1)) private void chunkDebug(long l, int i, KeyEvent keyEvent, CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/debug/crash_report/SystemReportM.java b/src/main/java/net/vulkanmod/mixin/debug/crash_report/SystemReportM.java index 621a389a7..7a2d36f2c 100644 --- a/src/main/java/net/vulkanmod/mixin/debug/crash_report/SystemReportM.java +++ b/src/main/java/net/vulkanmod/mixin/debug/crash_report/SystemReportM.java @@ -10,9 +10,9 @@ @Mixin(SystemReport.class) public class SystemReportM { - @Inject(method = "appendToCrashReportString", at = @At("RETURN")) - private void addVulkanDevicesInfo(StringBuilder stringBuilder, CallbackInfo ci) { - stringBuilder.append("\n\n -- VulkanMod Device Report --"); - stringBuilder.append(DeviceManager.getAvailableDevicesInfo()); - } + @Inject(method = "appendToCrashReportString", at = @At("RETURN")) + private void addVulkanDevicesInfo(StringBuilder stringBuilder, CallbackInfo ci) { + stringBuilder.append("\n\n -- VulkanMod Device Report --"); + stringBuilder.append(DeviceManager.getAvailableDevicesInfo()); + } } diff --git a/src/main/java/net/vulkanmod/mixin/matrix/Matrix4fM.java b/src/main/java/net/vulkanmod/mixin/matrix/Matrix4fM.java index d39d9647b..d2189832a 100644 --- a/src/main/java/net/vulkanmod/mixin/matrix/Matrix4fM.java +++ b/src/main/java/net/vulkanmod/mixin/matrix/Matrix4fM.java @@ -8,10 +8,17 @@ @Mixin(Matrix4f.class) public abstract class Matrix4fM { - @Shadow public abstract Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne); - @Shadow public abstract Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne); - @Shadow public abstract Matrix4f setPerspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne); - @Shadow public abstract Matrix4f setOrtho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne); + @Shadow + public abstract Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne); + + @Shadow + public abstract Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne); + + @Shadow + public abstract Matrix4f setPerspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne); + + @Shadow + public abstract Matrix4f setOrtho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne); /** * @author @@ -20,7 +27,7 @@ public abstract class Matrix4fM { @Overwrite(remap = false) public Matrix4f setOrtho(float left, float right, float bottom, float top, float zNear, float zFar) { this.setOrtho(left, right, bottom, top, zNear, zFar, true); - return (Matrix4f)(Object)this; + return (Matrix4f) (Object) this; } /** @@ -48,6 +55,6 @@ public Matrix4f perspective(float fovy, float aspect, float zNear, float zFar) { @Overwrite(remap = false) public Matrix4f setPerspective(float fovy, float aspect, float zNear, float zFar) { this.setPerspective(fovy, aspect, zNear, zFar, true); - return (Matrix4f)(Object)this; + return (Matrix4f) (Object) this; } } diff --git a/src/main/java/net/vulkanmod/mixin/profiling/GameLoadTimeEventM.java b/src/main/java/net/vulkanmod/mixin/profiling/GameLoadTimeEventM.java index 985d36d76..fd02ace35 100644 --- a/src/main/java/net/vulkanmod/mixin/profiling/GameLoadTimeEventM.java +++ b/src/main/java/net/vulkanmod/mixin/profiling/GameLoadTimeEventM.java @@ -5,7 +5,6 @@ import net.minecraft.client.telemetry.TelemetryEventSender; import net.minecraft.client.telemetry.TelemetryEventType; import net.minecraft.client.telemetry.TelemetryProperty; -import net.minecraft.client.telemetry.TelemetryPropertyMap; import net.minecraft.client.telemetry.events.GameLoadTimesEvent; import org.slf4j.Logger; import org.spongepowered.asm.mixin.Final; @@ -19,11 +18,14 @@ @Mixin(GameLoadTimesEvent.class) public class GameLoadTimeEventM { - @Shadow @Final private Map, Stopwatch> measurements; - - @Shadow @Final private static Logger LOGGER; - - @Shadow private OptionalLong bootstrapTime; + @Shadow + @Final + private static Logger LOGGER; + @Shadow + @Final + private Map, Stopwatch> measurements; + @Shadow + private OptionalLong bootstrapTime; public void send(TelemetryEventSender telemetryEventSender) { Map measurements = new Reference2ReferenceOpenHashMap<>(); @@ -34,7 +36,7 @@ public void send(TelemetryEventSender telemetryEventSender) { (telemetryProperty, stopwatch) -> { if (!stopwatch.isRunning()) { long l = stopwatch.elapsed(TimeUnit.MILLISECONDS); - measurements.put(telemetryProperty, new GameLoadTimesEvent.Measurement((int)l)); + measurements.put(telemetryProperty, new GameLoadTimesEvent.Measurement((int) l)); } else { LOGGER.warn( "Measurement {} was discarded since it was still ongoing when the event {} was sent.", @@ -44,7 +46,7 @@ public void send(TelemetryEventSender telemetryEventSender) { } } ); - this.bootstrapTime.ifPresent(l -> measurements.put(TelemetryProperty.LOAD_TIME_BOOTSTRAP_MS, new GameLoadTimesEvent.Measurement((int)l))); + this.bootstrapTime.ifPresent(l -> measurements.put(TelemetryProperty.LOAD_TIME_BOOTSTRAP_MS, new GameLoadTimesEvent.Measurement((int) l))); this.measurements.clear(); } diff --git a/src/main/java/net/vulkanmod/mixin/profiling/GuiMixin.java b/src/main/java/net/vulkanmod/mixin/profiling/GuiMixin.java index 26563f60a..8802bc485 100644 --- a/src/main/java/net/vulkanmod/mixin/profiling/GuiMixin.java +++ b/src/main/java/net/vulkanmod/mixin/profiling/GuiMixin.java @@ -5,7 +5,6 @@ import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.DebugScreenOverlay; -import net.minecraft.client.renderer.entity.ItemRenderer; import net.vulkanmod.render.profiling.ProfilerOverlay; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -17,7 +16,9 @@ @Mixin(Gui.class) public class GuiMixin { - @Shadow @Final private DebugScreenOverlay debugOverlay; + @Shadow + @Final + private DebugScreenOverlay debugOverlay; @Inject(method = "", at = @At("RETURN")) private void createProfilerOverlay(Minecraft minecraft, CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/profiling/KeyboardHandlerM.java b/src/main/java/net/vulkanmod/mixin/profiling/KeyboardHandlerM.java index 467ec1a73..7cd882964 100644 --- a/src/main/java/net/vulkanmod/mixin/profiling/KeyboardHandlerM.java +++ b/src/main/java/net/vulkanmod/mixin/profiling/KeyboardHandlerM.java @@ -24,8 +24,7 @@ private void injOverlayToggle(long l, int i, KeyEvent keyEvent, CallbackInfo ci) case GLFW.GLFW_KEY_F8 -> ProfilerOverlay.toggle(); case GLFW.GLFW_KEY_F10 -> BuildTimeProfiler.startBench(); } - } - else if (ProfilerOverlay.shouldRender) { + } else if (ProfilerOverlay.shouldRender) { ProfilerOverlay.onKeyPress(keyEvent.key()); } } diff --git a/src/main/java/net/vulkanmod/mixin/profiling/LevelRendererMixin.java b/src/main/java/net/vulkanmod/mixin/profiling/LevelRendererMixin.java index b0061a261..3cbdf3cec 100644 --- a/src/main/java/net/vulkanmod/mixin/profiling/LevelRendererMixin.java +++ b/src/main/java/net/vulkanmod/mixin/profiling/LevelRendererMixin.java @@ -2,9 +2,7 @@ import com.mojang.blaze3d.buffers.GpuBufferSlice; import com.mojang.blaze3d.resource.ResourceHandle; -import net.minecraft.client.Camera; import net.minecraft.client.CloudStatus; -import net.minecraft.client.DeltaTracker; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.client.renderer.state.LevelRenderState; @@ -49,7 +47,7 @@ private void popProfiler3(GpuBufferSlice gpuBufferSlice, ResourceHandle resource @Inject(method = "method_62214", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/renderer/LevelRenderer;submitEntities(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/state/LevelRenderState;Lnet/minecraft/client/renderer/SubmitNodeCollector;)V")) + target = "Lnet/minecraft/client/renderer/LevelRenderer;submitEntities(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/state/LevelRenderState;Lnet/minecraft/client/renderer/SubmitNodeCollector;)V")) private void profilerTerrain2(GpuBufferSlice gpuBufferSlice, LevelRenderState levelRenderState, ProfilerFiller profilerFiller, Matrix4f matrix4f, ResourceHandle resourceHandle, ResourceHandle resourceHandle2, boolean bl, Frustum frustum, diff --git a/src/main/java/net/vulkanmod/mixin/render/CompositeRenderTypeM.java b/src/main/java/net/vulkanmod/mixin/render/CompositeRenderTypeM.java index c701142d7..5efcee406 100644 --- a/src/main/java/net/vulkanmod/mixin/render/CompositeRenderTypeM.java +++ b/src/main/java/net/vulkanmod/mixin/render/CompositeRenderTypeM.java @@ -11,7 +11,9 @@ import com.mojang.blaze3d.vertex.MeshData; import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.renderer.RenderType; -import net.vulkanmod.render.engine.*; +import net.vulkanmod.render.engine.VkCommandEncoder; +import net.vulkanmod.render.engine.VkGpuTexture; +import net.vulkanmod.render.engine.VkRenderPass; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.texture.VTextureSelector; import org.joml.Vector3f; @@ -27,25 +29,30 @@ @Mixin(RenderType.CompositeRenderType.class) public abstract class CompositeRenderTypeM { - @Shadow @Final private RenderType.CompositeState state; - @Shadow @Final private RenderPipeline renderPipeline; + @Shadow + @Final + private RenderType.CompositeState state; + @Shadow + @Final + private RenderPipeline renderPipeline; // TODO + /** * @author * @reason */ @Overwrite public void draw(MeshData meshData) { - ((RenderType.CompositeRenderType)(Object)(this)).setupRenderState(); + ((RenderType.CompositeRenderType) (Object) (this)).setupRenderState(); GpuBufferSlice gpuBufferSlice = RenderSystem.getDynamicUniforms() - .writeTransform( - RenderSystem.getModelViewMatrix(), - new Vector4f(1.0F, 1.0F, 1.0F, 1.0F), - new Vector3f(), - RenderSystem.getTextureMatrix(), - RenderSystem.getShaderLineWidth() - ); + .writeTransform( + RenderSystem.getModelViewMatrix(), + new Vector4f(1.0F, 1.0F, 1.0F, 1.0F), + new Vector3f(), + RenderSystem.getTextureMatrix(), + RenderSystem.getShaderLineWidth() + ); MeshData var3 = meshData; try { @@ -61,7 +68,7 @@ public void draw(MeshData meshData) { indexType = meshData.drawState().indexType(); } - RenderTarget renderTarget = ((CompositeStateAccessor)(Object)this.state).getOutputState().getRenderTarget(); + RenderTarget renderTarget = ((CompositeStateAccessor) (Object) this.state).getOutputState().getRenderTarget(); GpuTextureView gpuTextureView = RenderSystem.outputColorTextureOverride != null ? RenderSystem.outputColorTextureOverride : renderTarget.getColorTextureView(); @@ -70,10 +77,10 @@ public void draw(MeshData meshData) { : null; try (RenderPass renderPass = RenderSystem.getDevice() - .createCommandEncoder() - .createRenderPass(() -> "Immediate draw for " + - ((RenderType.CompositeRenderType) (Object) (this)).getName(), - gpuTextureView, OptionalInt.empty(), gpuTextureView2, OptionalDouble.empty())) { + .createCommandEncoder() + .createRenderPass(() -> "Immediate draw for " + + ((RenderType.CompositeRenderType) (Object) (this)).getName(), + gpuTextureView, OptionalInt.empty(), gpuTextureView2, OptionalDouble.empty())) { renderPass.setPipeline(this.renderPipeline); ScissorState scissorState = RenderSystem.getScissorStateForRenderTypeDraws(); if (scissorState.enabled()) { @@ -117,7 +124,7 @@ public void draw(MeshData meshData) { meshData.close(); } - ((RenderType.CompositeRenderType)(Object)(this)).clearRenderState(); + ((RenderType.CompositeRenderType) (Object) (this)).clearRenderState(); } } diff --git a/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java b/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java index 3f17f536e..bfc2f4e57 100644 --- a/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java +++ b/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java @@ -3,25 +3,31 @@ import com.mojang.blaze3d.opengl.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.jtracy.Plot; -import net.vulkanmod.gl.*; +import net.vulkanmod.gl.VkGlBuffer; +import net.vulkanmod.gl.VkGlFramebuffer; +import net.vulkanmod.gl.VkGlShader; +import net.vulkanmod.gl.VkGlTexture; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; import org.jetbrains.annotations.Nullable; 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.At; import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.Shadow; import java.nio.ByteBuffer; @Mixin(GlStateManager.class) public class GlStateManagerM { - @Shadow @Final private static Plot PLOT_BUFFERS; + @Shadow + @Final + private static Plot PLOT_BUFFERS; - @Shadow private static int numBuffers; + @Shadow + private static int numBuffers; /** * @author @@ -71,7 +77,8 @@ public static void _disableScissorTest() { * @author */ @Overwrite(remap = false) - public static void _enableScissorTest() {} + public static void _enableScissorTest() { + } /** * @author @@ -106,6 +113,7 @@ public static void _scissorBox(int x, int y, int width, int height) { } //TODO + /** * @author */ diff --git a/src/main/java/net/vulkanmod/mixin/render/GuiRendererMixin.java b/src/main/java/net/vulkanmod/mixin/render/GuiRendererMixin.java index 09e25216e..3c0893a88 100644 --- a/src/main/java/net/vulkanmod/mixin/render/GuiRendererMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/GuiRendererMixin.java @@ -22,14 +22,17 @@ @Mixin(GuiRenderer.class) public abstract class GuiRendererMixin { - @Shadow @Final private GuiRenderState renderState; - @Shadow private @Nullable GpuTextureView itemsAtlasView; + @Shadow + @Final + private GuiRenderState renderState; + @Shadow + private @Nullable GpuTextureView itemsAtlasView; @Overwrite private void submitBlitFromItemAtlas(GuiItemRenderState guiItemRenderState, float u, float v, int size, int atlasSize) { v = 1.0f - v; - float u1 = u + (float)size / atlasSize; - float v1 = v + (float)(size) / atlasSize; + float u1 = u + (float) size / atlasSize; + float v1 = v + (float) (size) / atlasSize; this.renderState .submitBlitToCurrentLayer( new BlitRenderState( @@ -65,8 +68,7 @@ private void useVertexCount(RenderPass renderPass, int baseVertex, int firstInde if (vkRenderPass.getPipeline().getVertexFormatMode() != VertexFormat.Mode.TRIANGLES) { int vertexCount = indexCount * 2 / 3; renderPass.drawIndexed(baseVertex, 0, vertexCount, 1); - } - else { + } else { renderPass.drawIndexed(baseVertex, 0, indexCount, 1); } } diff --git a/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java b/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java index d39d1cd18..8f0e8a988 100644 --- a/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java @@ -1,7 +1,5 @@ package net.vulkanmod.mixin.render; -import com.mojang.blaze3d.pipeline.RenderTarget; -import com.mojang.blaze3d.systems.TimerQuery; import net.minecraft.client.GraphicsStatus; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; @@ -19,16 +17,16 @@ 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; - @Mixin(Minecraft.class) public class MinecraftMixin { - @Shadow public boolean noRender; - @Shadow @Final public Options options; + @Shadow + public boolean noRender; + @Shadow + @Final + public Options options; @Inject(method = "", at = @At(value = "RETURN")) private void forceGraphicsMode(GameConfig gameConfig, CallbackInfo ci) { @@ -41,7 +39,7 @@ private void forceGraphicsMode(GameConfig gameConfig, CallbackInfo ci) { } @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, int i, ProfilerFiller profilerFiller, int j) { int n = Math.min(10, i) - 1; boolean doUpload = j == n; @@ -66,6 +64,7 @@ public void onResolutionChanged(CallbackInfo ci) { // 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 74ef4eb5b..949e37fe4 100644 --- a/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java @@ -3,7 +3,6 @@ import com.mojang.blaze3d.shaders.ShaderType; import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.*; import net.minecraft.client.renderer.DynamicUniforms; import net.minecraft.resources.ResourceLocation; import net.vulkanmod.render.engine.VkGpuDevice; @@ -17,20 +16,26 @@ import java.util.function.BiFunction; -import static com.mojang.blaze3d.systems.RenderSystem.*; +import static com.mojang.blaze3d.systems.RenderSystem.getDevice; @Mixin(RenderSystem.class) public abstract class RenderSystemMixin { - @Shadow private static Matrix4f textureMatrix; - @Shadow private static @Nullable Thread renderThread; + @Shadow + private static Matrix4f textureMatrix; + @Shadow + private static @Nullable Thread renderThread; - @Shadow private static @Nullable GpuDevice DEVICE; - @Shadow private static @Nullable DynamicUniforms dynamicUniforms; + @Shadow + private static @Nullable GpuDevice DEVICE; + @Shadow + private static @Nullable DynamicUniforms dynamicUniforms; - @Shadow private static String apiDescription; + @Shadow + private static String apiDescription; @Shadow - public static void assertOnRenderThread() {} + public static void assertOnRenderThread() { + } @Overwrite(remap = false) public static void initRenderer(long l, int i, boolean bl, BiFunction shaderSource, boolean bl2) { diff --git a/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java b/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java index 7ec047b32..4b9d386a0 100644 --- a/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java +++ b/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java @@ -9,7 +9,9 @@ @Mixin(BiomeManager.class) public class BiomeManagerM implements BiomeManagerExtended { - @Shadow @Final private long biomeZoomSeed; + @Shadow + @Final + private long biomeZoomSeed; @Override public long getBiomeZoomSeed() { 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 2d07ba780..de26a6b26 100644 --- a/src/main/java/net/vulkanmod/mixin/render/block/BakedQuadM.java +++ b/src/main/java/net/vulkanmod/mixin/render/block/BakedQuadM.java @@ -5,8 +5,8 @@ import net.minecraft.core.Direction; 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 net.vulkanmod.render.model.quad.ModelQuadView; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -19,14 +19,24 @@ @Mixin(BakedQuad.class) public class BakedQuadM implements ModelQuadView { - @Shadow @Final protected int[] vertices; - @Shadow @Final protected Direction direction; - @Shadow @Final protected int tintIndex; + @Shadow + @Final + protected int[] vertices; + @Shadow + @Final + protected Direction direction; + @Shadow + @Final + protected int tintIndex; private int flags; private int normal; private QuadFacing facing; + private static int vertexOffset(int vertexIndex) { + return vertexIndex * VERTEX_SIZE; + } + @Inject(method = "", at = @At("RETURN")) private void onInit(int[] vertices, int tintIndex, Direction face, TextureAtlasSprite textureAtlasSprite, boolean shade, int lightEmission, CallbackInfo ci) { this.flags = ModelQuadFlags.getQuadFlags(this, face); @@ -43,7 +53,7 @@ public int getFlags() { @Override public float getX(int idx) { - return Float.intBitsToFloat(this.vertices[vertexOffset(idx) + 0]); + return Float.intBitsToFloat(this.vertices[vertexOffset(idx)]); } @Override @@ -100,8 +110,4 @@ public int getNormal() { public boolean isTinted() { return this.tintIndex != -1; } - - private static int vertexOffset(int vertexIndex) { - return vertexIndex * VERTEX_SIZE; - } } diff --git a/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java b/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java index 10231841c..5c68b3c16 100644 --- a/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java +++ b/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java @@ -4,13 +4,17 @@ import com.mojang.blaze3d.framegraph.FramePass; import net.minecraft.client.CloudStatus; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.LevelTargetBundle; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.world.phys.Vec3; import net.vulkanmod.render.profiling.Profiler; import net.vulkanmod.render.sky.CloudRenderer; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.*; +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; @@ -18,11 +22,16 @@ @Mixin(LevelRenderer.class) public abstract class LevelRendererM { - @Shadow private int ticks; - @Shadow private @Nullable ClientLevel level; - @Shadow @Final private LevelTargetBundle targets; + @Shadow + private int ticks; + @Shadow + private @Nullable ClientLevel level; + @Shadow + @Final + private LevelTargetBundle targets; - @Unique private CloudRenderer cloudRenderer; + @Unique + private CloudRenderer cloudRenderer; @Inject(method = "addCloudsPass", at = @At("HEAD"), cancellable = true) public void addCloudsPass(FrameGraphBuilder frameGraphBuilder, CloudStatus cloudStatus, Vec3 camPos, float partialTicks, int i, float g, CallbackInfo ci) { @@ -42,7 +51,7 @@ public void addCloudsPass(FrameGraphBuilder frameGraphBuilder, CloudStatus cloud profiler.push("Clouds"); this.cloudRenderer.renderClouds(this.level, this.ticks, partialTicks, - camPos.x(), camPos.y(), camPos.z()); + camPos.x(), camPos.y(), camPos.z()); profiler.pop(); }); diff --git a/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java b/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java index b3480e5c9..cdae4133b 100644 --- a/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java +++ b/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java @@ -14,16 +14,16 @@ @Mixin(BlockColors.class) public class BlockColorsM implements BlockColorsExtended { - @Unique - private BlockColorRegistry colorResolvers = new BlockColorRegistry(); + @Unique + private final BlockColorRegistry colorResolvers = new BlockColorRegistry(); - @Inject(method = "register", at = @At("RETURN")) - private void onRegister(BlockColor blockColor, Block[] blocks, CallbackInfo ci) { - this.colorResolvers.register(blockColor, blocks); - } + @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; - } + @Override + public BlockColorRegistry getColorResolverMap() { + return this.colorResolvers; + } } diff --git a/src/main/java/net/vulkanmod/mixin/render/entity/EntityRendererM.java b/src/main/java/net/vulkanmod/mixin/render/entity/EntityRendererM.java index c8503bc8d..6f7f733a6 100644 --- a/src/main/java/net/vulkanmod/mixin/render/entity/EntityRendererM.java +++ b/src/main/java/net/vulkanmod/mixin/render/entity/EntityRendererM.java @@ -33,22 +33,22 @@ public class EntityRendererM { // //// WorldRenderer.getInstance().getSectionGrid().getSectionAtBlockPos((int) entity.getX(), (int) entity.getY(), (int) entity.getZ()); // WorldRenderer worldRenderer = WorldRenderer.getInstance(); -//// return (worldRenderer.getLastFrame() == worldRenderer.getSectionGrid().getSectionAtBlockPos(entity.getBlockX(), entity.getBlockY(), entity.getBlockZ()).getLastFrame()); + + /// / return (worldRenderer.getLastFrame() == worldRenderer.getSectionGrid().getSectionAtBlockPos(entity.getBlockX(), entity.getBlockY(), entity.getBlockZ()).getLastFrame()); // // return frustum.isVisible(aABB); // } // } - @Redirect(method = "shouldRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/culling/Frustum;isVisible(Lnet/minecraft/world/phys/AABB;)Z")) private boolean isVisible(Frustum frustum, AABB aABB) { - if(Initializer.CONFIG.entityCulling) { + if (Initializer.CONFIG.entityCulling) { WorldRenderer worldRenderer = WorldRenderer.getInstance(); Vec3 pos = aABB.getCenter(); RenderSection section = worldRenderer.getSectionGrid().getSectionAtBlockPos((int) pos.x(), (int) pos.y(), (int) pos.z()); - if(section == null) + if (section == null) return frustum.isVisible(aABB); return worldRenderer.getLastFrame() == section.getLastFrame(); diff --git a/src/main/java/net/vulkanmod/mixin/render/entity/LevelRendererM.java b/src/main/java/net/vulkanmod/mixin/render/entity/LevelRendererM.java index 2fda4e46d..79d8c13c5 100644 --- a/src/main/java/net/vulkanmod/mixin/render/entity/LevelRendererM.java +++ b/src/main/java/net/vulkanmod/mixin/render/entity/LevelRendererM.java @@ -1,33 +1,7 @@ package net.vulkanmod.mixin.render.entity; -import com.mojang.blaze3d.buffers.GpuBufferSlice; -import com.mojang.blaze3d.resource.GraphicsResourceAllocator; -import com.mojang.blaze3d.vertex.PoseStack; -import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import net.minecraft.client.Camera; -import net.minecraft.client.DeltaTracker; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.util.Mth; -import net.minecraft.world.TickRateManager; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.phys.Vec3; -import net.vulkanmod.Initializer; -import net.vulkanmod.render.chunk.WorldRenderer; -import org.joml.Matrix4f; -import org.joml.Vector4f; -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; - -import java.util.List; -import java.util.Map; +import org.spongepowered.asm.mixin.Mixin; @Mixin(LevelRenderer.class) public class LevelRendererM { diff --git a/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartCubeM.java b/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartCubeM.java index a8be49c77..b6fc47ec7 100644 --- a/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartCubeM.java +++ b/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartCubeM.java @@ -14,7 +14,8 @@ @Mixin(ModelPart.Cube.class) public class ModelPartCubeM implements ModelPartCubeMixed { - @Unique CubeModel cube; + @Unique + CubeModel cube; @Inject(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/client/model/geom/ModelPart$Cube;polygons:[Lnet/minecraft/client/model/geom/ModelPart$Polygon;", 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 514dc0681..c8a7a27d0 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 @@ -11,7 +11,10 @@ import org.joml.Matrix3f; import org.joml.Matrix4f; import org.joml.Vector3f; -import org.spongepowered.asm.mixin.*; +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; @@ -20,9 +23,11 @@ @Mixin(ModelPart.class) public abstract class ModelPartM { - @Shadow @Final private List cubes; - - @Unique Vector3f normal = new Vector3f(); + @Unique + Vector3f normal = new Vector3f(); + @Shadow + @Final + private List cubes; @Inject(method = "compile", at = @At("HEAD"), cancellable = true) private void injCompile(PoseStack.Pose pose, VertexConsumer vertexConsumer, int light, int overlay, int color, CallbackInfo ci) { @@ -43,7 +48,7 @@ public void renderCubes(PoseStack.Pose pose, VertexConsumer vertexConsumer, int color = ColorUtil.RGBA.fromArgb32(color); for (ModelPart.Cube cube : this.cubes) { - ModelPartCubeMixed cubeMixed = (ModelPartCubeMixed)(cube); + ModelPartCubeMixed cubeMixed = (ModelPartCubeMixed) (cube); CubeModel cubeModel = cubeMixed.getCubeModel(); CubeModel.Polygon[] polygons = cubeModel.getPolygons(); @@ -61,16 +66,15 @@ public void renderCubes(PoseStack.Pose pose, VertexConsumer vertexConsumer, int for (CubeModel.Vertex vertex : vertices) { Vector3f pos = vertex.pos(); vertexBuilder.vertex(pos.x(), pos.y(), pos.z(), - color, - vertex.u(), vertex.v(), - overlay, light, packedNormal); + color, + vertex.u(), vertex.v(), + overlay, light, packedNormal); } } } - } - else { + } else { for (ModelPart.Cube cube : this.cubes) { - ModelPartCubeMixed cubeMixed = (ModelPartCubeMixed)(cube); + ModelPartCubeMixed cubeMixed = (ModelPartCubeMixed) (cube); CubeModel cubeModel = cubeMixed.getCubeModel(); CubeModel.Polygon[] polygons = cubeModel.getPolygons(); @@ -86,10 +90,10 @@ public void renderCubes(PoseStack.Pose pose, VertexConsumer vertexConsumer, int for (CubeModel.Vertex vertex : vertices) { Vector3f pos = vertex.pos(); vertexConsumer.addVertex(pos.x(), pos.y(), pos.z(), - color, - vertex.u(), vertex.v(), - overlay, light, - normal.x(), normal.y(), normal.z()); + color, + vertex.u(), vertex.v(), + overlay, light, + normal.x(), normal.y(), normal.z()); } } } diff --git a/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java b/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java index 1298815bf..f8ae6ccad 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java @@ -16,7 +16,8 @@ @Mixin(Minecraft.class) public class MinecraftMixin { - @Shadow public boolean noRender; + @Shadow + public boolean noRender; @Inject(method = "runTick", at = @At(value = "HEAD")) private void preFrameOps(boolean bl, CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/BatchingRenderCommandQueueM.java b/src/main/java/net/vulkanmod/mixin/render/frapi/BatchingRenderCommandQueueM.java index 84906672a..a6a88a227 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frapi/BatchingRenderCommandQueueM.java +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/BatchingRenderCommandQueueM.java @@ -23,9 +23,10 @@ @Mixin(SubmitNodeCollection.class) abstract class BatchingRenderCommandQueueM implements OrderedSubmitNodeCollector, AccessRenderCommandQueue, AccessBatchingRenderCommandQueue { - @Shadow private boolean wasUsed; - - @Unique private final List meshItemCommands = new ArrayList<>(); + @Unique + private final List meshItemCommands = new ArrayList<>(); + @Shadow + private boolean wasUsed; @Inject(method = "clear()V", at = @At("RETURN")) public void clear(CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/BlockRenderDispatcherAccessor.java b/src/main/java/net/vulkanmod/mixin/render/frapi/BlockRenderDispatcherAccessor.java index 3ded98367..393ff845c 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frapi/BlockRenderDispatcherAccessor.java +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/BlockRenderDispatcherAccessor.java @@ -1,13 +1,12 @@ package net.vulkanmod.mixin.render.frapi; -import java.util.function.Supplier; - +import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.renderer.SpecialBlockModelRenderer; import net.minecraft.client.renderer.block.BlockRenderDispatcher; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; -import net.minecraft.client.color.block.BlockColors; +import java.util.function.Supplier; @Mixin(BlockRenderDispatcher.class) public interface BlockRenderDispatcherAccessor { diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/ItemFeatureRendererM.java b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemFeatureRendererM.java index 778b5c308..67804236d 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frapi/ItemFeatureRendererM.java +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemFeatureRendererM.java @@ -20,9 +20,11 @@ @Mixin(ItemFeatureRenderer.class) public class ItemFeatureRendererM { - @Shadow @Final private PoseStack poseStack; - - @Unique private final ItemRenderContext itemRenderContext = new ItemRenderContext(); + @Unique + private final ItemRenderContext itemRenderContext = new ItemRenderContext(); + @Shadow + @Final + private PoseStack poseStack; @Inject(method = "render", at = @At("RETURN")) private void onReturnRender(SubmitNodeCollection queue, MultiBufferSource.BufferSource vertexConsumers, OutlineBufferSource outlineVertexConsumers, CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java index 06ca19723..52e73376e 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java @@ -10,8 +10,8 @@ @Mixin(ItemRenderer.class) public interface ItemRendererAccessor { - @Invoker("getSpecialFoilBuffer") - static VertexConsumer getSpecialFoilBuffer(MultiBufferSource provider, RenderType layer, PoseStack.Pose entry) { - throw new AssertionError(); - } + @Invoker("getSpecialFoilBuffer") + static VertexConsumer getSpecialFoilBuffer(MultiBufferSource provider, RenderType layer, PoseStack.Pose entry) { + throw new AssertionError(); + } } diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/OrderedRenderCommandQueueImplM.java b/src/main/java/net/vulkanmod/mixin/render/frapi/OrderedRenderCommandQueueImplM.java index 17a372de2..43bf4f017 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frapi/OrderedRenderCommandQueueImplM.java +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/OrderedRenderCommandQueueImplM.java @@ -18,12 +18,10 @@ import com.mojang.blaze3d.vertex.PoseStack; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshView; - import net.minecraft.client.renderer.OrderedSubmitNodeCollector; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.SubmitNodeStorage; - import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.world.item.ItemDisplayContext; diff --git a/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleGroupM.java b/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleGroupM.java index 807c85b93..359564186 100644 --- a/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleGroupM.java +++ b/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleGroupM.java @@ -12,14 +12,14 @@ @Mixin(QuadParticleGroup.class) public class QuadParticleGroupM { - @Redirect(method = "extractRenderState", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/culling/Frustum;pointInFrustum(DDD)Z")) - private boolean particleWithinSections(Frustum instance, double x, double y, double z) { - return !cull(WorldRenderer.getInstance(), x, y, z) && instance.pointInFrustum(x,y, z); - } - @Unique private static 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(); } + + @Redirect(method = "extractRenderState", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/culling/Frustum;pointInFrustum(DDD)Z")) + private boolean particleWithinSections(Frustum instance, double x, double y, double z) { + return !cull(WorldRenderer.getInstance(), x, y, z) && instance.pointInFrustum(x, y, z); + } } diff --git a/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleRenderStateM.java b/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleRenderStateM.java index b893f0835..4789f23e7 100644 --- a/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleRenderStateM.java +++ b/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleRenderStateM.java @@ -13,8 +13,10 @@ @Mixin(QuadParticleRenderState.class) public class QuadParticleRenderStateM { - @Unique private final Quaternionf quaternionf = new Quaternionf(); - @Unique private final Vector3f vector3f = new Vector3f(); + @Unique + private final Quaternionf quaternionf = new Quaternionf(); + @Unique + private final Vector3f vector3f = new Vector3f(); @Overwrite public void renderRotatedQuad( @@ -22,7 +24,7 @@ public void renderRotatedQuad( ) { quaternionf.set(xr, yr, zr, wr); - ExtendedVertexBuilder vertexBuilder = (ExtendedVertexBuilder)vertexConsumer; + ExtendedVertexBuilder vertexBuilder = (ExtendedVertexBuilder) vertexConsumer; color = ColorUtil.BGRAtoRGBA(color); diff --git a/src/main/java/net/vulkanmod/mixin/render/shader/RenderPipelineM.java b/src/main/java/net/vulkanmod/mixin/render/shader/RenderPipelineM.java index 465ae4a92..ace6fa23f 100644 --- a/src/main/java/net/vulkanmod/mixin/render/shader/RenderPipelineM.java +++ b/src/main/java/net/vulkanmod/mixin/render/shader/RenderPipelineM.java @@ -10,12 +10,14 @@ @Mixin(RenderPipeline.class) public abstract class RenderPipelineM implements ExtendedRenderPipeline { - @Unique GraphicsPipeline pipeline; - @Unique EGlProgram eGlProgram; + @Unique + GraphicsPipeline pipeline; + @Unique + EGlProgram eGlProgram; @Override - public void setPipeline(GraphicsPipeline pipeline) { - this.pipeline = pipeline; + public EGlProgram getProgram() { + return this.eGlProgram; } @Override @@ -24,12 +26,12 @@ public void setProgram(EGlProgram program) { } @Override - public EGlProgram getProgram() { - return this.eGlProgram; + public Pipeline getPipeline() { + return this.pipeline; } @Override - public Pipeline getPipeline() { - return this.pipeline; + public void setPipeline(GraphicsPipeline pipeline) { + this.pipeline = pipeline; } } diff --git a/src/main/java/net/vulkanmod/mixin/render/shader/ShaderManagerM.java b/src/main/java/net/vulkanmod/mixin/render/shader/ShaderManagerM.java index 4294266e7..a576ba4a3 100644 --- a/src/main/java/net/vulkanmod/mixin/render/shader/ShaderManagerM.java +++ b/src/main/java/net/vulkanmod/mixin/render/shader/ShaderManagerM.java @@ -5,7 +5,6 @@ import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.client.renderer.ShaderManager; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.util.profiling.ProfilerFiller; 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 310d64158..e5cea046c 100644 --- a/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java @@ -9,19 +9,29 @@ import net.vulkanmod.render.engine.VkFbo; import net.vulkanmod.render.engine.VkGpuTexture; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; import java.util.OptionalInt; @Mixin(RenderTarget.class) public abstract class RenderTargetMixin { - @Shadow public int width; - @Shadow public int height; + @Shadow + public int width; + @Shadow + public int height; - @Shadow @Nullable protected GpuTexture colorTexture; - @Shadow @Nullable protected GpuTexture depthTexture; - @Shadow @Nullable protected GpuTextureView colorTextureView; + @Shadow + @Nullable + protected GpuTexture colorTexture; + @Shadow + @Nullable + protected GpuTexture depthTexture; + @Shadow + @Nullable + protected GpuTextureView colorTextureView; @Overwrite public void blitAndBlendToTexture(GpuTextureView gpuTextureView) { @@ -33,8 +43,8 @@ public void blitAndBlendToTexture(GpuTextureView gpuTextureView) { } try (RenderPass renderPass = RenderSystem.getDevice() - .createCommandEncoder() - .createRenderPass(() -> "Blit render target", gpuTextureView, OptionalInt.empty())) { + .createCommandEncoder() + .createRenderPass(() -> "Blit render target", gpuTextureView, OptionalInt.empty())) { renderPass.setPipeline(RenderPipelines.ENTITY_OUTLINE_BLIT); RenderSystem.bindDefaultUniforms(renderPass); renderPass.bindSampler("InSampler", this.colorTextureView); 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 9bb93a893..d822a321e 100644 --- a/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java +++ b/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java @@ -16,24 +16,30 @@ public abstract class BufferBuilderM implements VertexConsumer, ExtendedVertexBuilder { - @Shadow private boolean fastFormat; - @Shadow private boolean fullFormat; - @Shadow private VertexFormat format; - - @Shadow protected abstract long beginVertex(); - - @Shadow private int elementsToFill; - @Shadow @Final private int initialElementsToFill; + @Shadow + private boolean fastFormat; + @Shadow + private boolean fullFormat; + @Shadow + private VertexFormat format; + @Shadow + private int elementsToFill; + @Shadow + @Final + private int initialElementsToFill; + private long ptr; - @Shadow protected abstract long beginElement(VertexFormatElement vertexFormatElement); + @Shadow + protected abstract long beginVertex(); - private long ptr; + @Shadow + protected abstract long beginElement(VertexFormatElement vertexFormatElement); public void vertex(float x, float y, float z, int packedColor, float u, float v, int overlay, int light, int packedNormal) { this.ptr = this.beginVertex(); if (this.format == DefaultVertexFormat.NEW_ENTITY) { - MemoryUtil.memPutFloat(ptr + 0, x); + MemoryUtil.memPutFloat(ptr, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); @@ -47,8 +53,7 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, MemoryUtil.memPutInt(ptr + 28, light); MemoryUtil.memPutInt(ptr + 32, packedNormal); - } - else { + } else { this.elementsToFill = this.initialElementsToFill; this.position(x, y, z); @@ -66,7 +71,7 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, public void vertex(float x, float y, float z, float u, float v, int packedColor, int light) { this.ptr = this.beginVertex(); - MemoryUtil.memPutFloat(ptr + 0, x); + MemoryUtil.memPutFloat(ptr, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); @@ -79,7 +84,7 @@ public void vertex(float x, float y, float z, float u, float v, int packedColor, } public void position(float x, float y, float z) { - MemoryUtil.memPutFloat(ptr + 0, x); + MemoryUtil.memPutFloat(ptr, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); } @@ -127,7 +132,7 @@ public void fastNormal(int packedNormal) { public void addVertex(float x, float y, float z, int color, float u, float v, int overlay, int light, float normalX, float normalY, float normalZ) { if (this.fastFormat) { long ptr = this.beginVertex(); - MemoryUtil.memPutFloat(ptr + 0, x); + MemoryUtil.memPutFloat(ptr, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); @@ -166,7 +171,7 @@ private void putQuadData(PoseStack.Pose matrixEntry, BakedQuad quad, float[] bri Vec3i vec3i = quad.direction().getUnitVec3i(); Matrix4f matrix4f = matrixEntry.pose(); - boolean trustedNormals = ((PoseAccessor)(Object)matrixEntry).trustedNormals(); + 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) { diff --git a/src/main/java/net/vulkanmod/mixin/render/vertex/VertexFormatMixin.java b/src/main/java/net/vulkanmod/mixin/render/vertex/VertexFormatMixin.java index 0fef9b2e9..197bac277 100644 --- a/src/main/java/net/vulkanmod/mixin/render/vertex/VertexFormatMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/vertex/VertexFormatMixin.java @@ -1,14 +1,11 @@ package net.vulkanmod.mixin.render.vertex; -import com.google.common.collect.ImmutableMap; import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormatElement; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.vulkanmod.interfaces.VertexFormatMixed; -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; diff --git a/src/main/java/net/vulkanmod/mixin/screen/OptionsScreenM.java b/src/main/java/net/vulkanmod/mixin/screen/OptionsScreenM.java index e3f20791b..5294a8857 100644 --- a/src/main/java/net/vulkanmod/mixin/screen/OptionsScreenM.java +++ b/src/main/java/net/vulkanmod/mixin/screen/OptionsScreenM.java @@ -15,9 +15,13 @@ @Mixin(OptionsScreen.class) public class OptionsScreenM extends Screen { - @Shadow @Final private Screen lastScreen; + @Shadow + @Final + private Screen lastScreen; - @Shadow @Final private Options options; + @Shadow + @Final + private Options options; protected OptionsScreenM(Component title) { super(title); diff --git a/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java b/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java index 6f47b9740..e50c18d24 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java +++ b/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java @@ -1,10 +1,8 @@ package net.vulkanmod.mixin.texture.mip; import com.mojang.blaze3d.platform.NativeImage; -import net.minecraft.Util; import net.minecraft.client.renderer.texture.MipmapGenerator; import net.vulkanmod.mixin.texture.image.NativeImageAccessor; -import org.lwjgl.opengl.GL30; import org.lwjgl.system.MemoryUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -33,7 +31,7 @@ public static NativeImage[] generateMipLevels(NativeImage[] nativeImages, int i) NativeImage[] nativeImages2 = new NativeImage[i + 1]; nativeImages2[0] = nativeImages[0]; - long srcPtr = ((NativeImageAccessor)(Object)nativeImages2[0]).getPixels(); + long srcPtr = ((NativeImageAccessor) (Object) nativeImages2[0]).getPixels(); boolean bl = hasTransparentPixel(srcPtr, nativeImages2[0].getWidth(), nativeImages2[0].getHeight()); if (bl) { @@ -59,7 +57,7 @@ public static NativeImage[] generateMipLevels(NativeImage[] nativeImages, int i) } - for(int j = 1; j <= i; ++j) { + for (int j = 1; j <= i; ++j) { if (j < nativeImages.length) { nativeImages2[j] = nativeImages[j]; } else { @@ -68,16 +66,16 @@ public static NativeImage[] generateMipLevels(NativeImage[] nativeImages, int i) int width = nativeImage2.getWidth(); int height = nativeImage2.getHeight(); - srcPtr = ((NativeImageAccessor)(Object)nativeImage).getPixels(); - long dstPtr = ((NativeImageAccessor)(Object)nativeImage2).getPixels(); + srcPtr = ((NativeImageAccessor) (Object) nativeImage).getPixels(); + long dstPtr = ((NativeImageAccessor) (Object) nativeImage2).getPixels(); final int width2 = width * 2; - for(int m = 0; m < width; ++m) { - for(int n = 0; n < height; ++n) { - int p0 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 0) + ((n * 2 + 0) * width2)) * 4L); - int p1 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 1) + ((n * 2 + 0) * width2)) * 4L); - int p2 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 0) + ((n * 2 + 1) * width2)) * 4L); - int p3 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 1) + ((n * 2 + 1) * width2)) * 4L); + for (int m = 0; m < width; ++m) { + for (int n = 0; n < height; ++n) { + int p0 = MemoryUtil.memGetInt(srcPtr + ((m * 2L) + ((n * 2L) * width2)) * 4L); + int p1 = MemoryUtil.memGetInt(srcPtr + ((m * 2L + 1) + ((n * 2L) * width2)) * 4L); + int p2 = MemoryUtil.memGetInt(srcPtr + ((m * 2L) + ((n * 2L + 1) * width2)) * 4L); + int p3 = MemoryUtil.memGetInt(srcPtr + ((m * 2L + 1) + ((n * 2L + 1) * width2)) * 4L); int outColor = blend(p0, p1, p2, p3); MemoryUtil.memPutInt(dstPtr + (m + (long) n * width) * 4L, outColor); @@ -93,9 +91,9 @@ public static NativeImage[] generateMipLevels(NativeImage[] nativeImages, int i) } private static boolean hasTransparentPixel(long ptr, int width, int height) { - for(int i = 0; i < width; ++i) { - for(int j = 0; j < height; ++j) { - if (getPixelA(MemoryUtil.memGetInt(ptr + (i + j * width) * 4L)) == 0) { + for (int i = 0; i < width; ++i) { + for (int j = 0; j < height; ++j) { + if (getPixelA(MemoryUtil.memGetInt(ptr + (i + (long) j * width) * 4L)) == 0) { return true; } } @@ -122,8 +120,8 @@ private static int gammaBlend(int i, int j, int k, int l, int m) { float g = getPow22(j >> m); float h = getPow22(k >> m); float n = getPow22(l >> m); - float o = (float)((double)((float)Math.pow((double)(f + g + h + n) * 0.25, 0.45454545454545453))); - return (int)((double)o * 255.0); + float o = (float) ((double) ((float) Math.pow((double) (f + g + h + n) * 0.25, 0.45454545454545453))); + return (int) ((double) o * 255.0); } private static int getPixelA(int rgba) { @@ -137,10 +135,10 @@ private static int calculateAverage(NativeImage nativeImage) { final int[] values = new int[width * height]; int count = 0; - long srcPtr = ((NativeImageAccessor)(Object)nativeImage).getPixels(); + long srcPtr = ((NativeImageAccessor) (Object) nativeImage).getPixels(); - for(int i = 0; i < width; ++i) { - for(int j = 0; j < height; ++j) { + for (int i = 0; i < width; ++i) { + for (int j = 0; j < height; ++j) { // int value = nativeImage.getPixelRGBA(i, j); int value = MemoryUtil.memGetInt(srcPtr + (i + (long) j * width) * 4L); if (((value >> 24) & 0xFF) > 0) { @@ -159,7 +157,7 @@ private static int calculateAverage(NativeImage nativeImage) { sumB += (values[i] >> 16) & 0xFF; } - if(count == 0) + if (count == 0) return 0; sumR /= count; diff --git a/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java b/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java index 6cd861797..f586e8a47 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java +++ b/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java @@ -1,47 +1,44 @@ package net.vulkanmod.mixin.texture.update; import com.mojang.blaze3d.platform.NativeImage; -import com.mojang.blaze3d.systems.CommandEncoder; -import com.mojang.blaze3d.systems.GpuDevice; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.textures.GpuTextureView; 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.util.profiling.Profiler; -import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.LivingEntity; -import net.vulkanmod.gl.VkGlTexture; -import net.vulkanmod.mixin.texture.image.NativeImageAccessor; -import net.vulkanmod.render.engine.VkGpuTexture; -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; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; @Mixin(LightTexture.class) public class MLightTexture { - @Unique private static final Vector3f END_FLASH_SKY_LIGHT_COLOR = new Vector3f(0.9F, 0.5F, 1.0F); + @Unique + private static final Vector3f END_FLASH_SKY_LIGHT_COLOR = new Vector3f(0.9F, 0.5F, 1.0F); - @Shadow @Final private Minecraft minecraft; - @Shadow @Final private GameRenderer renderer; + @Shadow + @Final + private Minecraft minecraft; + @Shadow + @Final + private GameRenderer renderer; - @Shadow private boolean updateLightTexture; - @Shadow private float blockLightRedFlicker; + @Shadow + private boolean updateLightTexture; + @Shadow + private float blockLightRedFlicker; - @Unique private DynamicTexture lightTexture; - @Unique private GpuTextureView textureView; - @Unique private NativeImage lightPixels; + @Unique + private DynamicTexture lightTexture; + @Unique + private GpuTextureView textureView; + @Unique + private NativeImage lightPixels; private Vector3f[] tempVecs; @@ -119,7 +116,25 @@ public class MLightTexture { // // float gamma = this.minecraft.options.gamma().get().floatValue(); // float darkenWorldAmount = this.renderer.getDarkenWorldAmount(partialTicks); -//// boolean forceBrightLightmap = clientLevel.effects().forceBrightLightmap(); + + @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 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); + } + + /// / boolean forceBrightLightmap = clientLevel.effects().forceBrightLightmap(); // float ambientLight = clientLevel.dimensionType().ambientLight(); // // Vector3f vector3f2; @@ -207,7 +222,6 @@ public class MLightTexture { // // ci.cancel(); // } - @Unique private float getDarknessGamma(float f) { MobEffectInstance mobEffectInstance = this.minecraft.player.getEffect(MobEffects.DARKNESS); @@ -217,17 +231,7 @@ private float getDarknessGamma(float f) { @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)); + return Math.max(0.0F, Mth.cos(((float) livingEntity.tickCount - g) * (float) Math.PI * 0.025F) * h); } @Unique @@ -237,11 +241,4 @@ private float notGamma(float f) { 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 index f61bf5539..f16b927b6 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/update/MSpriteContents.java +++ b/src/main/java/net/vulkanmod/mixin/texture/update/MSpriteContents.java @@ -14,9 +14,13 @@ @Mixin(SpriteContents.Ticker.class) public class MSpriteContents { - @Shadow int subFrame; - @Shadow int frame; - @Shadow @Final SpriteContents.AnimatedTexture animationInfo; + @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, GpuTexture gpuTexture, CallbackInfo ci) { @@ -30,8 +34,7 @@ private void checkUpload(int i, int j, GpuTexture gpuTexture, CallbackInfo ci) { } ci.cancel(); - } - else { + } else { SpriteUpdateUtil.addTransitionedLayout(VTextureSelector.getBoundTexture()); } } diff --git a/src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java b/src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java index 595ca054c..cb6296b76 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java +++ b/src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java @@ -15,7 +15,9 @@ @Mixin(TextureManager.class) public abstract class MTextureManager { - @Shadow @Final private Set tickableTextures; + @Shadow + @Final + private Set tickableTextures; /** * @author diff --git a/src/main/java/net/vulkanmod/mixin/util/ScreenshotMixin.java b/src/main/java/net/vulkanmod/mixin/util/ScreenshotMixin.java index 04075bab5..28474e2d1 100644 --- a/src/main/java/net/vulkanmod/mixin/util/ScreenshotMixin.java +++ b/src/main/java/net/vulkanmod/mixin/util/ScreenshotMixin.java @@ -35,15 +35,15 @@ public static void takeScreenshot(RenderTarget renderTarget, int mipLevel, Consu int pixelSize = TextureFormat.RGBA8.pixelSize(); GpuBuffer gpuBuffer = RenderSystem.getDevice() - .createBuffer(() -> "Screenshot buffer", 9, width * height * pixelSize); + .createBuffer(() -> "Screenshot buffer", 9, width * height * pixelSize); CommandEncoder commandEncoder = RenderSystem.getDevice().createCommandEncoder(); RenderSystem.getDevice().createCommandEncoder().copyTextureToBuffer(gpuTexture, gpuBuffer, 0, () -> { try (GpuBuffer.MappedView readView = commandEncoder.mapBuffer(gpuBuffer, true, false)) { NativeImage nativeImage = new NativeImage(width, height, false); var colorAttachment = ((VkGpuTexture) Renderer.getInstance() - .getMainPass() - .getColorAttachment()); + .getMainPass() + .getColorAttachment()); boolean isBgraFormat = (colorAttachment.getVulkanImage().format == VK10.VK_FORMAT_B8G8R8A8_UNORM); int size = mipLevel * mipLevel; diff --git a/src/main/java/net/vulkanmod/mixin/vertex/SpriteCoordinateExpanderM.java b/src/main/java/net/vulkanmod/mixin/vertex/SpriteCoordinateExpanderM.java index c27452a11..5ff63fd3c 100644 --- a/src/main/java/net/vulkanmod/mixin/vertex/SpriteCoordinateExpanderM.java +++ b/src/main/java/net/vulkanmod/mixin/vertex/SpriteCoordinateExpanderM.java @@ -15,7 +15,9 @@ //TODO move @Mixin(SpriteCoordinateExpander.class) public class SpriteCoordinateExpanderM implements ExtendedVertexBuilder { - @Shadow @Final private TextureAtlasSprite sprite; + @Shadow + @Final + private TextureAtlasSprite sprite; @Unique private ExtendedVertexBuilder extDelegate; diff --git a/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java b/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java index 6a23dcf26..bdef849b6 100644 --- a/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java +++ b/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java @@ -22,8 +22,12 @@ public class VertexMultiConsumersM { @Mixin(targets = "com/mojang/blaze3d/vertex/VertexMultiConsumer$Double") public static class DoubleM implements ExtendedVertexBuilder { - @Shadow @Final private VertexConsumer first; - @Shadow @Final private VertexConsumer second; + @Shadow + @Final + private VertexConsumer first; + @Shadow + @Final + private VertexConsumer second; @Unique private ExtendedVertexBuilder firstExt; @@ -58,7 +62,9 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, @Mixin(targets = "com/mojang/blaze3d/vertex/VertexMultiConsumer$Multiple") public static class MultipleM implements ExtendedVertexBuilder { - @Shadow @Final private VertexConsumer[] delegates; + @Shadow + @Final + private VertexConsumer[] delegates; @Unique private boolean canUseFastVertex = false; @@ -92,16 +98,24 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, @Mixin(SheetedDecalTextureGenerator.class) public static abstract class SheetDecalM implements ExtendedVertexBuilder { - @Shadow @Final private VertexConsumer delegate; - @Shadow @Final private Matrix3f normalInversePose; - @Shadow @Final private Matrix4f cameraInversePose; - @Shadow @Final private float textureScale; + @Shadow + @Final + private VertexConsumer delegate; + @Shadow + @Final + private Matrix3f normalInversePose; + @Shadow + @Final + private Matrix4f cameraInversePose; + @Shadow + @Final + private float textureScale; @Unique private boolean canUseFastVertex = false; - private Vector3f normal = new Vector3f(); - private Vector4f position = new Vector4f(); + private final Vector3f normal = new Vector3f(); + private final Vector4f position = new Vector4f(); @Override public boolean canUseFastVertex() { @@ -120,7 +134,7 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, float nz = I32_SNorm.unpackZ(packedNormal); normal.set(nx, ny, nz); - position.set(x, y , z, 1.0f); + position.set(x, y, z, 1.0f); this.normalInversePose.transform(normal); Direction direction = Direction.getApproximateNearest(normal.x(), normal.y(), normal.z()); diff --git a/src/main/java/net/vulkanmod/mixin/voxel/VoxelShapeMixin.java b/src/main/java/net/vulkanmod/mixin/voxel/VoxelShapeMixin.java index 5331d81c7..a749071a3 100644 --- a/src/main/java/net/vulkanmod/mixin/voxel/VoxelShapeMixin.java +++ b/src/main/java/net/vulkanmod/mixin/voxel/VoxelShapeMixin.java @@ -1,6 +1,8 @@ package net.vulkanmod.mixin.voxel; -import net.minecraft.world.phys.shapes.*; +import net.minecraft.world.phys.shapes.CubeVoxelShape; +import net.minecraft.world.phys.shapes.DiscreteVoxelShape; +import net.minecraft.world.phys.shapes.VoxelShape; import net.vulkanmod.interfaces.VoxelShapeExtended; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -11,7 +13,9 @@ @Mixin(VoxelShape.class) public class VoxelShapeMixin implements VoxelShapeExtended { - @Shadow @Final protected DiscreteVoxelShape shape; + @Shadow + @Final + protected DiscreteVoxelShape shape; int co; @@ -22,8 +26,8 @@ private void initCornerOcclusion(DiscreteVoxelShape discreteVoxelShape, Callback // TODO: lithium subclasses // lithium is using its own classes for simple cube shapes - VoxelShape shape = (VoxelShape)((Object)this); - if(!(shape instanceof CubeVoxelShape) || disShape == null) { + VoxelShape shape = (VoxelShape) ((Object) this); + if (!(shape instanceof CubeVoxelShape) || disShape == null) { this.co = 0; return; } diff --git a/src/main/java/net/vulkanmod/mixin/wayland/InputConstantsM.java b/src/main/java/net/vulkanmod/mixin/wayland/InputConstantsM.java index 7c4ee506c..f86c7c34a 100644 --- a/src/main/java/net/vulkanmod/mixin/wayland/InputConstantsM.java +++ b/src/main/java/net/vulkanmod/mixin/wayland/InputConstantsM.java @@ -2,7 +2,7 @@ import com.mojang.blaze3d.platform.InputConstants; import net.vulkanmod.config.Platform; -import org.lwjgl.glfw.*; +import org.lwjgl.glfw.GLFW; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; diff --git a/src/main/java/net/vulkanmod/mixin/wayland/MinecraftMixin.java b/src/main/java/net/vulkanmod/mixin/wayland/MinecraftMixin.java index 19d93d508..c6cd0f544 100644 --- a/src/main/java/net/vulkanmod/mixin/wayland/MinecraftMixin.java +++ b/src/main/java/net/vulkanmod/mixin/wayland/MinecraftMixin.java @@ -8,7 +8,6 @@ import net.minecraft.server.packs.PackResources; import net.minecraft.server.packs.VanillaPackResources; import net.vulkanmod.config.Platform; -import net.vulkanmod.config.video.VideoModeManager; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -20,19 +19,23 @@ @Mixin(Minecraft.class) public class MinecraftMixin { - @Shadow @Final private Window window; - @Shadow @Final public Options options; - - @Shadow @Final private VanillaPackResources vanillaPackResources; + @Shadow + @Final + public Options options; + @Shadow + @Final + private Window window; + @Shadow + @Final + private VanillaPackResources vanillaPackResources; /** * @author * @reason Only KWin supports setting the Icon on Wayland AFAIK */ - @Redirect(method="", at=@At(value="INVOKE", target="Lcom/mojang/blaze3d/platform/Window;setIcon(Lnet/minecraft/server/packs/PackResources;Lcom/mojang/blaze3d/platform/IconSet;)V")) + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/Window;setIcon(Lnet/minecraft/server/packs/PackResources;Lcom/mojang/blaze3d/platform/IconSet;)V")) private void bypassWaylandIcon(Window instance, PackResources packResources, IconSet iconSet) throws IOException { - if (!Platform.isWayLand()) - { + if (!Platform.isWayLand()) { this.window.setIcon(this.vanillaPackResources, SharedConstants.getCurrentVersion().stable() ? IconSet.RELEASE : IconSet.SNAPSHOT); } } diff --git a/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java b/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java index 4827f9043..02a62e9be 100644 --- a/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java +++ b/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java @@ -1,13 +1,16 @@ package net.vulkanmod.mixin.window; import com.mojang.blaze3d.TracyFrameCapture; -import com.mojang.blaze3d.platform.*; +import com.mojang.blaze3d.platform.DisplayData; +import com.mojang.blaze3d.platform.ScreenManager; +import com.mojang.blaze3d.platform.Window; +import com.mojang.blaze3d.platform.WindowEventHandler; import com.mojang.blaze3d.systems.RenderSystem; import net.vulkanmod.Initializer; import net.vulkanmod.config.Config; import net.vulkanmod.config.Platform; -import net.vulkanmod.config.video.VideoModeManager; import net.vulkanmod.config.option.Options; +import net.vulkanmod.config.video.VideoModeManager; import net.vulkanmod.config.video.VideoModeSet; import net.vulkanmod.config.video.WindowMode; import net.vulkanmod.vulkan.Renderer; @@ -29,33 +32,51 @@ @Mixin(Window.class) public abstract class WindowMixin { - @Final @Shadow private long handle; - - @Shadow private boolean vsync; - @Shadow private boolean fullscreen; - - @Shadow @Final private static Logger LOGGER; - - @Shadow private int windowedX; - @Shadow private int windowedY; - @Shadow private int windowedWidth; - @Shadow private int windowedHeight; - @Shadow private int x; - @Shadow private int y; - @Shadow private int width; - @Shadow private int height; - - @Shadow private int framebufferWidth; - @Shadow private int framebufferHeight; + @Shadow + @Final + private static Logger LOGGER; + @Final + @Shadow + private long handle; + @Shadow + private boolean vsync; + @Shadow + private boolean fullscreen; + @Shadow + private int windowedX; + @Shadow + private int windowedY; + @Shadow + private int windowedWidth; + @Shadow + private int windowedHeight; + @Shadow + private int x; + @Shadow + private int y; + @Shadow + private int width; + @Shadow + private int height; + + @Shadow + private int framebufferWidth; + @Shadow + private int framebufferHeight; + private boolean wasOnFullscreen = false; - @Shadow public abstract int getWidth(); + @Shadow + public abstract int getWidth(); - @Shadow public abstract int getHeight(); + @Shadow + public abstract int getHeight(); - @Shadow protected abstract void updateFullscreen(boolean bl, @Nullable TracyFrameCapture tracyFrameCapture); + @Shadow + protected abstract void updateFullscreen(boolean bl, @Nullable TracyFrameCapture tracyFrameCapture); @Redirect(method = "", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwWindowHint(II)V")) - private void redirect(int hint, int value) { } + private void redirect(int hint, int value) { + } @Inject(method = "", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwCreateWindow(IILjava/lang/CharSequence;JJ)J")) private void vulkanHint(WindowEventHandler windowEventHandler, ScreenManager screenManager, DisplayData displayData, String string, String string2, CallbackInfo ci) { @@ -94,7 +115,7 @@ public void toggleFullScreen() { */ @Overwrite public void updateDisplay(@Nullable TracyFrameCapture tracyFrameCapture) { - RenderSystem.flipFrame((Window) ((Object)this), tracyFrameCapture); + RenderSystem.flipFrame((Window) ((Object) this), tracyFrameCapture); if (Options.fullscreenDirty) { Options.fullscreenDirty = false; @@ -102,8 +123,6 @@ public void updateDisplay(@Nullable TracyFrameCapture tracyFrameCapture) { } } - private boolean wasOnFullscreen = false; - /** * @author */ @@ -121,12 +140,11 @@ private void setMode() { if (set != null) { supported = set.hasRefreshRate(videoMode.refreshRate); - } - else { + } else { supported = false; } - if(!supported) { + if (!supported) { LOGGER.error("Resolution not supported, using first available as fallback"); videoMode = VideoModeManager.getFirstAvailable().getVideoMode(); } @@ -146,8 +164,7 @@ private void setMode() { this.wasOnFullscreen = true; } - } - else if (config.windowMode == WindowMode.WINDOWED_FULLSCREEN.mode) { + } else if (config.windowMode == WindowMode.WINDOWED_FULLSCREEN.mode) { VideoModeSet.VideoMode videoMode = VideoModeManager.getOsVideoMode(); if (!this.wasOnFullscreen) { @@ -189,7 +206,7 @@ private void onFramebufferResize(long window, int width, int height) { int prevWidth = this.getWidth(); int prevHeight = this.getHeight(); - if(width > 0 && height > 0) { + if (width > 0 && height > 0) { this.framebufferWidth = width; this.framebufferHeight = height; // if (this.framebufferWidth != prevWidth || this.framebufferHeight != prevHeight) { @@ -211,7 +228,7 @@ private void onResize(long window, int width, int height) { this.width = width; this.height = height; - if(width > 0 && height > 0) + if (width > 0 && height > 0) Renderer.scheduleSwapChainUpdate(); } diff --git a/src/main/java/net/vulkanmod/render/PipelineManager.java b/src/main/java/net/vulkanmod/render/PipelineManager.java index 9368e5ad1..928782453 100644 --- a/src/main/java/net/vulkanmod/render/PipelineManager.java +++ b/src/main/java/net/vulkanmod/render/PipelineManager.java @@ -15,17 +15,15 @@ public abstract class PipelineManager { public static VertexFormat terrainVertexFormat; - - public static void setTerrainVertexFormat(VertexFormat format) { - terrainVertexFormat = format; - } - static GraphicsPipeline terrainShader, terrainShaderEarlyZ, fastBlitPipeline, cloudsPipeline; - private static Function shaderGetter; + public static void setTerrainVertexFormat(VertexFormat format) { + terrainVertexFormat = format; + } + public static void init() { setTerrainVertexFormat(CustomVertexFormat.COMPRESSED_TERRAIN); createBasicPipelines(); diff --git a/src/main/java/net/vulkanmod/render/VBO.java b/src/main/java/net/vulkanmod/render/VBO.java index e3c4153ec..c6a9cce0b 100644 --- a/src/main/java/net/vulkanmod/render/VBO.java +++ b/src/main/java/net/vulkanmod/render/VBO.java @@ -3,7 +3,8 @@ import com.mojang.blaze3d.vertex.MeshData; import com.mojang.blaze3d.vertex.VertexFormat; import net.vulkanmod.vulkan.Renderer; -import net.vulkanmod.vulkan.memory.*; +import net.vulkanmod.vulkan.memory.MemoryType; +import net.vulkanmod.vulkan.memory.MemoryTypes; import net.vulkanmod.vulkan.memory.buffer.IndexBuffer; import net.vulkanmod.vulkan.memory.buffer.VertexBuffer; import net.vulkanmod.vulkan.memory.buffer.index.AutoIndexBuffer; @@ -24,7 +25,7 @@ public class VBO { private int vertexCount; public VBO(boolean useGpuMem) { - this.memoryType = useGpuMem ? MemoryTypes.GPU_MEM : MemoryTypes.HOST_MEM; + this.memoryType = useGpuMem ? MemoryTypes.GPU_MEM : MemoryTypes.HOST_MEM; } public void upload(MeshData meshData) { @@ -89,8 +90,7 @@ public void uploadIndexBuffer(ByteBuffer data) { } this.autoIndexed = true; - } - else { + } else { if (this.indexBuffer != null && !this.autoIndexed) { this.indexBuffer.scheduleFree(); } @@ -115,8 +115,7 @@ public void draw() { if (this.indexBuffer != null) { Renderer.getDrawer().drawIndexed(this.vertexBuffer, this.indexBuffer, this.indexCount); - } - else { + } else { Renderer.getDrawer().draw(this.vertexBuffer, this.vertexCount); } } diff --git a/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java b/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java index 85400a8f1..4c30c3394 100644 --- a/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java +++ b/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java @@ -11,15 +11,13 @@ public class ChunkArea { public final int index; + //Help JIT optimisations by hardcoding the queue size to the max possible ChunkArea limit + public final StaticQueue sectionQueue = new StaticQueue<>(512); final DrawBuffers drawBuffers; final Vector3i position; final byte[] frustumBuffer = new byte[64]; - int sectionsContained = 0; - //Help JIT optimisations by hardcoding the queue size to the max possible ChunkArea limit - public final StaticQueue sectionQueue = new StaticQueue<>(512); - public ChunkArea(int i, Vector3i origin, int minHeight) { this.index = i; this.position = origin; @@ -29,17 +27,17 @@ public ChunkArea(int i, Vector3i origin, int minHeight) { public void updateFrustum(VFrustum frustum) { //TODO: maybe move to an aux class int frustumResult = frustum.cubeInFrustum(this.position.x(), this.position.y(), this.position.z(), - this.position.x() + (8 << 4) , this.position.y() + (8 << 4), this.position.z() + (8 << 4)); + this.position.x() + (8 << 4), this.position.y() + (8 << 4), this.position.z() + (8 << 4)); //Inner cubes if (frustumResult == FrustumIntersection.INTERSECT) { int width = 8 << 4; int l = width >> 1; - for(int x1 = 0; x1 < 2; x1++) { + for (int x1 = 0; x1 < 2; x1++) { float xMin = this.position.x() + (x1 * l); float xMax = xMin + l; - for(int y1 = 0; y1 < 2; y1++) { + for (int y1 = 0; y1 < 2; y1++) { float yMin = this.position.y() + (y1 * l); float yMax = yMin + l; for (int z1 = 0; z1 < 2; z1++) { @@ -47,7 +45,7 @@ public void updateFrustum(VFrustum frustum) { float zMax = zMin + l; frustumResult = frustum.cubeInFrustum(xMin, yMin, zMin, - xMax , yMax, zMax); + xMax, yMax, zMax); int beginIdx = (x1 << 5) + (y1 << 4) + (z1 << 3); if (frustumResult == FrustumIntersection.INTERSECT) { @@ -72,11 +70,10 @@ public void updateFrustum(VFrustum frustum) { } } - } - else { + } else { int end = beginIdx + 8; - for(int i = beginIdx; i < end; ++i) { + for (int i = beginIdx; i < end; ++i) { this.frustumBuffer[i] = (byte) frustumResult; } } diff --git a/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java b/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java index 4b79212b6..daed29320 100644 --- a/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java +++ b/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java @@ -15,25 +15,21 @@ public class ChunkAreaManager { 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); - - public static final int SEC_SH = 4; public static final int BLOCK_TO_AREA_SH_XZ = AREA_SH_XZ + SEC_SH; + public static final int AREA_SH_Y = Util.flooredLog(HEIGHT); public static final int BLOCK_TO_AREA_SH_Y = AREA_SH_Y + SEC_SH; - + public static final int SEC_SH = 4; public final int size; final int sectionGridWidth; final int xzSize; final int ySize; final int minHeight; final ChunkArea[] chunkAreasArr; - - int prevX; - int prevZ; - private final CircularIntList xList; private final CircularIntList zList; private final CircularIntList.RangeIterator xComplIterator; + int prevX; + int prevZ; public ChunkAreaManager(int width, int height, int minHeight) { this.minHeight = minHeight; @@ -246,7 +242,7 @@ public String[] getStats() { vbUsed /= div; ibSize /= div; ibUsed /= div; - frag /= 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/ChunkStatusMap.java b/src/main/java/net/vulkanmod/render/chunk/ChunkStatusMap.java index 56e2206d5..0a4b5da2b 100644 --- a/src/main/java/net/vulkanmod/render/chunk/ChunkStatusMap.java +++ b/src/main/java/net/vulkanmod/render/chunk/ChunkStatusMap.java @@ -11,11 +11,6 @@ public class ChunkStatusMap { public static final byte ALL_FLAGS = CHUNK_READY | NEIGHBOURS_READY; public static ChunkStatusMap INSTANCE; - - public static void createInstance(int renderDistance) { - INSTANCE = new ChunkStatusMap(renderDistance); - } - private final Long2ByteOpenHashMap map; public ChunkStatusMap(int renderDistance) { @@ -24,6 +19,10 @@ public ChunkStatusMap(int renderDistance) { map.defaultReturnValue((byte) 0); } + public static void createInstance(int renderDistance) { + INSTANCE = new ChunkStatusMap(renderDistance); + } + public void updateDistance(int renderDistance) { int diameter = renderDistance * 2 + 1; this.map.ensureCapacity(diameter * diameter); @@ -55,8 +54,7 @@ public void updateNeighbours(int x, int z) { for (int z1 = z - 1; z1 <= z + 1; ++z1) { if (checkNeighbours(x1, z1)) { map.put(ChunkPos.asLong(x1, z1), ALL_FLAGS); - } - else { + } else { long l = ChunkPos.asLong(x1, z1); byte current = map.get(l); diff --git a/src/main/java/net/vulkanmod/render/chunk/RenderSection.java b/src/main/java/net/vulkanmod/render/chunk/RenderSection.java index 0ec0365c5..97b4588af 100644 --- a/src/main/java/net/vulkanmod/render/chunk/RenderSection.java +++ b/src/main/java/net/vulkanmod/render/chunk/RenderSection.java @@ -2,7 +2,6 @@ import com.google.common.collect.Sets; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -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; @@ -10,11 +9,7 @@ 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.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.build.task.*; import net.vulkanmod.render.chunk.cull.QuadFacing; import net.vulkanmod.render.chunk.graph.GraphDirections; import net.vulkanmod.render.chunk.util.Util; @@ -24,35 +19,29 @@ import java.util.Set; public class RenderSection { - private ChunkArea chunkArea; + private final CompileStatus compileStatus = new CompileStatus(); public byte frustumIndex; public short lastFrame = -1; - private short lastFrame2 = -1; public short inAreaIndex; - public byte adjDirs; public RenderSection adjDown, adjUp, adjNorth, adjSouth, adjWest, adjEast; - - private final CompileStatus compileStatus = new CompileStatus(); - - private boolean dirty = true; - private boolean playerChanged; - private boolean completelyEmpty = true; - private boolean containsBlockEntities = false; - public long visibility; - public int xOffset, yOffset, zOffset; - // Graph-info public byte mainDir; public byte directions; public byte sourceDirs; public byte steps; public byte directionChanges; + private ChunkArea chunkArea; + private short lastFrame2 = -1; + private boolean dirty = true; + private boolean playerChanged; + private boolean completelyEmpty = true; + private boolean containsBlockEntities = false; public RenderSection(int index, int x, int y, int z) { this.xOffset = x; @@ -274,6 +263,12 @@ public boolean isDirty() { return this.dirty; } + public void setDirty(boolean playerChanged) { + this.playerChanged = playerChanged || this.dirty && this.playerChanged; + this.dirty = true; + WorldRenderer.getInstance().scheduleGraphUpdate(); + } + public boolean isDirtyFromPlayer() { return this.dirty && this.playerChanged; } @@ -306,30 +301,26 @@ public void resetDrawParameters(TerrainRenderType renderType) { } } + public ChunkArea getChunkArea() { + return this.chunkArea; + } + public void setChunkArea(ChunkArea chunkArea) { this.chunkArea = chunkArea; this.frustumIndex = chunkArea.getFrustumIndex(xOffset, yOffset, zOffset); } - public ChunkArea getChunkArea() { - return this.chunkArea; - } - public CompiledSection getCompiledSection() { return compileStatus.compiledSection; } - public boolean isCompiled() { - return this.compileStatus.compiledSection != CompiledSection.UNCOMPILED; - } - - public void setVisibility(long visibility) { - this.visibility = visibility; + public void setCompiledSection(CompiledSection compiledSection) { + this.compileStatus.compiledSection = compiledSection; } - public void setCompletelyEmpty(boolean b) { - this.completelyEmpty = b; + public boolean isCompiled() { + return this.compileStatus.compiledSection != CompiledSection.UNCOMPILED; } public void setContainsBlockEntities(boolean b) { @@ -348,10 +339,18 @@ public long getVisibility() { return visibility; } + public void setVisibility(long visibility) { + this.visibility = visibility; + } + public boolean isCompletelyEmpty() { return this.completelyEmpty; } + public void setCompletelyEmpty(boolean b) { + this.completelyEmpty = b; + } + public boolean containsBlockEntities() { return this.containsBlockEntities; } @@ -396,16 +395,6 @@ private void resetDrawParameters() { } } - public void setDirty(boolean playerChanged) { - this.playerChanged = playerChanged || this.dirty && this.playerChanged; - this.dirty = true; - WorldRenderer.getInstance().scheduleGraphUpdate(); - } - - public void setCompiledSection(CompiledSection compiledSection) { - this.compileStatus.compiledSection = compiledSection; - } - public boolean setLastFrame(short i) { boolean alreadySet = i == this.lastFrame; if (!alreadySet) diff --git a/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java b/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java index f7075774a..ca94a788f 100644 --- a/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java +++ b/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java @@ -15,17 +15,15 @@ public class SectionGrid { protected final Level level; - protected int gridHeight; - protected int gridWidth; - public RenderSection[] sections; final ChunkAreaManager chunkAreaManager; - - private int prevSecX; - private int prevSecZ; - private final CircularIntList xList; private final CircularIntList zList; private final CircularIntList.RangeIterator xComplIterator; + public RenderSection[] sections; + protected int gridHeight; + protected int gridWidth; + private int prevSecX; + private int prevSecZ; public SectionGrid(Level level, int viewDistance) { this.level = level; @@ -147,7 +145,7 @@ public void repositionCamera(double x, double z) { for (int yRel = 0; yRel < this.gridHeight; ++yRel) { moveSection(xRelativeIndex, yRel, zRelativeIndex, x1, z1, - xList, zList, xRangeIterator.getCurrentIndex(), zIterator.getCurrentIndex()); + xList, zList, xRangeIterator.getCurrentIndex(), zIterator.getCurrentIndex()); } } } @@ -166,7 +164,7 @@ public void repositionCamera(double x, double z) { for (int yRel = 0; yRel < this.gridHeight; ++yRel) { moveSection(xRelativeIndex, yRel, zRelativeIndex, x1, z1, - xList, zList, xComplIterator.getCurrentIndex(), zRangeIterator.getCurrentIndex()); + xList, zList, xComplIterator.getCurrentIndex(), zRangeIterator.getCurrentIndex()); } } } @@ -188,7 +186,7 @@ private void moveSection(int xRelativeIndex, int yRel, int zRelativeIndex, renderSection.setOrigin(x1, y1, z1); this.setNeighbours(renderSection, xList, zList, xCurrentIdx, zCurrentIdx, - xRelativeIndex, yRel, zRelativeIndex); + xRelativeIndex, yRel, zRelativeIndex); ChunkArea oldArea = renderSection.getChunkArea(); diff --git a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java index 6bbffe097..095b97372 100644 --- a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java @@ -34,18 +34,18 @@ import net.vulkanmod.render.PipelineManager; import net.vulkanmod.render.chunk.buffer.DrawBuffers; import net.vulkanmod.render.chunk.build.RenderRegionBuilder; -import net.vulkanmod.render.chunk.build.task.TaskDispatcher; import net.vulkanmod.render.chunk.build.task.ChunkTask; +import net.vulkanmod.render.chunk.build.task.TaskDispatcher; import net.vulkanmod.render.chunk.graph.SectionGraph; import net.vulkanmod.render.profiling.BuildTimeProfiler; import net.vulkanmod.render.profiling.Profiler; import net.vulkanmod.render.vertex.TerrainRenderType; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; +import net.vulkanmod.vulkan.memory.MemoryTypes; 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; import org.jetbrains.annotations.Nullable; @@ -56,30 +56,19 @@ public class WorldRenderer { private static WorldRenderer INSTANCE; - - public static WorldRenderer init(EntityRenderDispatcher entityRenderDispatcher, - BlockEntityRenderDispatcher blockEntityRenderDispatcher, - RenderBuffers renderBuffers, - LevelRenderState levelRenderState, - FeatureRenderDispatcher featureRenderDispatcher) { - if (INSTANCE != null) { - return INSTANCE; - } - else { - return INSTANCE = new WorldRenderer(entityRenderDispatcher, blockEntityRenderDispatcher, renderBuffers, levelRenderState, featureRenderDispatcher); - } - } - private final Minecraft minecraft; - private ClientLevel level; - private int renderDistance; private final RenderBuffers renderBuffers; - private final EntityRenderDispatcher entityRenderDispatcher; private final BlockEntityRenderDispatcher blockEntityRenderDispatcher; private final LevelRenderState levelRenderState; private final FeatureRenderDispatcher featureRenderDispatcher; - + private final Set globalBlockEntities = Sets.newHashSet(); + private final TaskDispatcher taskDispatcher; + private final List onAllChangedCallbacks = new ObjectArrayList<>(); + public RenderRegionBuilder renderRegionCache; + IndirectBuffer[] indirectBuffers; + private ClientLevel level; + private int renderDistance; private float partialTick; private Vec3 cameraPos; private int lastCameraSectionX; @@ -90,32 +79,18 @@ public static WorldRenderer init(EntityRenderDispatcher entityRenderDispatcher, private float lastCameraZ; private float lastCamRotX; private float lastCamRotY; - private SectionGrid sectionGrid; - private SectionGraph sectionGraph; private boolean graphNeedsUpdate; - - private final Set globalBlockEntities = Sets.newHashSet(); - - private final TaskDispatcher taskDispatcher; - private double xTransparentOld; private double yTransparentOld; private double zTransparentOld; - IndirectBuffer[] indirectBuffers; - - public RenderRegionBuilder renderRegionCache; - - private final List onAllChangedCallbacks = new ObjectArrayList<>(); - private WorldRenderer(EntityRenderDispatcher entityRenderDispatcher, BlockEntityRenderDispatcher blockEntityRenderDispatcher, RenderBuffers renderBuffers, LevelRenderState levelRenderState, - FeatureRenderDispatcher featureRenderDispatcher) - { + FeatureRenderDispatcher featureRenderDispatcher) { this.minecraft = Minecraft.getInstance(); this.renderBuffers = renderBuffers; this.entityRenderDispatcher = entityRenderDispatcher; @@ -136,6 +111,56 @@ private WorldRenderer(EntityRenderDispatcher entityRenderDispatcher, }); } + public static WorldRenderer init(EntityRenderDispatcher entityRenderDispatcher, + BlockEntityRenderDispatcher blockEntityRenderDispatcher, + RenderBuffers renderBuffers, + LevelRenderState levelRenderState, + FeatureRenderDispatcher featureRenderDispatcher) { + if (INSTANCE != null) { + return INSTANCE; + } else { + return INSTANCE = new WorldRenderer(entityRenderDispatcher, blockEntityRenderDispatcher, renderBuffers, levelRenderState, featureRenderDispatcher); + } + } + + public static WorldRenderer getInstance() { + return INSTANCE; + } + + public static ClientLevel getLevel() { + return INSTANCE.level; + } + + public void setLevel(@Nullable ClientLevel level) { + this.lastCameraX = Float.MIN_VALUE; + this.lastCameraY = Float.MIN_VALUE; + this.lastCameraZ = Float.MIN_VALUE; + this.lastCameraSectionX = Integer.MIN_VALUE; + this.lastCameraSectionY = Integer.MIN_VALUE; + this.lastCameraSectionZ = Integer.MIN_VALUE; + +// this.entityRenderDispatcher.setLevel(level); + this.level = level; + ChunkStatusMap.createInstance(renderDistance); + if (level != null) { + this.allChanged(); + } else { + if (this.sectionGrid != null) { + this.sectionGrid.freeAllBuffers(); + this.sectionGrid = null; + } + + this.taskDispatcher.stopThreads(); + + this.graphNeedsUpdate = true; + } + + } + + public static Vec3 getCameraPos() { + return INSTANCE.cameraPos; + } + private void allocateIndirectBuffers() { if (this.indirectBuffers != null) Arrays.stream(this.indirectBuffers).forEach(Buffer::scheduleFree); @@ -275,32 +300,6 @@ public void allChanged() { } } - public void setLevel(@Nullable ClientLevel level) { - this.lastCameraX = Float.MIN_VALUE; - this.lastCameraY = Float.MIN_VALUE; - this.lastCameraZ = Float.MIN_VALUE; - this.lastCameraSectionX = Integer.MIN_VALUE; - this.lastCameraSectionY = Integer.MIN_VALUE; - this.lastCameraSectionZ = Integer.MIN_VALUE; - -// this.entityRenderDispatcher.setLevel(level); - this.level = level; - ChunkStatusMap.createInstance(renderDistance); - if (level != null) { - this.allChanged(); - } else { - if (this.sectionGrid != null) { - this.sectionGrid.freeAllBuffers(); - this.sectionGrid = null; - } - - this.taskDispatcher.stopThreads(); - - this.graphNeedsUpdate = true; - } - - } - public void addOnAllChangedCallback(Runnable runnable) { this.onAllChangedCallbacks.add(runnable); } @@ -443,7 +442,7 @@ public void renderBlockEntities(PoseStack poseStack, LevelRenderState levelRende poseStack.pushPose(); poseStack.translate(blockPos.getX() - camX, blockPos.getY() - camY, blockPos.getZ() - camZ); crumblingOverlay = new ModelFeatureRenderer.CrumblingOverlay(sortedSet.last() - .getProgress(), poseStack.last()); + .getProgress(), poseStack.last()); poseStack.popPose(); } else { crumblingOverlay = null; @@ -538,16 +537,4 @@ public void cleanUp() { Arrays.stream(indirectBuffers).forEach(Buffer::scheduleFree); } - public static WorldRenderer getInstance() { - return INSTANCE; - } - - public static ClientLevel getLevel() { - return INSTANCE.level; - } - - public static Vec3 getCameraPos() { - return INSTANCE.cameraPos; - } - } 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 c2c02db66..e2df45537 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/AreaBuffer.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/AreaBuffer.java @@ -3,7 +3,9 @@ import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; import net.vulkanmod.Initializer; import net.vulkanmod.render.chunk.util.Util; -import net.vulkanmod.vulkan.memory.*; +import net.vulkanmod.vulkan.memory.MemoryManager; +import net.vulkanmod.vulkan.memory.MemoryType; +import net.vulkanmod.vulkan.memory.MemoryTypes; import net.vulkanmod.vulkan.memory.buffer.Buffer; import net.vulkanmod.vulkan.memory.buffer.IndexBuffer; import net.vulkanmod.vulkan.memory.buffer.VertexBuffer; @@ -23,11 +25,9 @@ public class AreaBuffer { private final Int2ReferenceOpenHashMap usedSegments = new Int2ReferenceOpenHashMap<>(); Segment first, last; - - private Buffer buffer; - int size, used = 0; int segments = 0; + private Buffer buffer; public AreaBuffer(Usage usage, int elementCount, int elementSize) { this.usage = usage.usage; @@ -140,8 +140,7 @@ public Segment reallocate(int uploadSize) { if (last.isFree()) { last.size += increment; - } - else { + } else { int offset = last.offset + last.size; Segment segment = new Segment(offset, newSize - offset); segments++; @@ -349,6 +348,17 @@ public int getUsed() { return used; } + public enum Usage { + VERTEX(0), + INDEX(1); + + final int usage; + + Usage(int i) { + usage = i; + } + } + public static class Segment { int offset, size; boolean free = true; @@ -384,15 +394,4 @@ public void bindNext(Segment s) { } - public enum Usage { - VERTEX(0), - INDEX(1); - - final int usage; - - Usage(int i) { - usage = i; - } - } - } 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 24f3c9550..eb005c518 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/DrawBuffers.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/DrawBuffers.java @@ -26,22 +26,19 @@ public class DrawBuffers { public static final int VERTEX_SIZE = PipelineManager.terrainVertexFormat.getVertexSize(); public static final int INDEX_SIZE = Short.BYTES; - + // TODO: refactor + public static final float POS_OFFSET = PipelineManager.terrainVertexFormat == CustomVertexFormat.COMPRESSED_TERRAIN ? 4.0f : 0.0f; private static final int CMD_STRIDE = 32; - private static final long cmdBufferPtr = MemoryUtil.nmemAlignedAlloc(CMD_STRIDE, (long) ChunkAreaManager.AREA_SIZE * QuadFacing.COUNT * CMD_STRIDE); - + final int[] sectionIndices = new int[512]; + final int[] masks = new int[512]; private final int index; private final Vector3i origin; private final int minHeight; - - private boolean allocated = false; - AreaBuffer indexBuffer; private final EnumMap vertexBuffers = new EnumMap<>(TerrainRenderType.class); - + AreaBuffer indexBuffer; long drawParamsPtr; - final int[] sectionIndices = new int[512]; - final int[] masks = new int[512]; + private boolean allocated = false; //Need ugly minHeight Parameter to fix custom world heights (exceeding 384 Blocks in total) public DrawBuffers(int index, Vector3i origin, int minHeight) { @@ -140,9 +137,6 @@ private int encodeSectionOffset(int xOffset, int yOffset, int zOffset) { return yOffset1 << 16 | zOffset1 << 8 | xOffset1; } - // TODO: refactor - 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); float yOffset = (float) ((this.origin.y) + POS_OFFSET - camY); @@ -218,8 +212,7 @@ public void buildDrawBatchesIndirect(Vec3 cameraPos, IndirectBuffer indirectBuff } } - } - else { + } else { for (var iterator = queue.iterator(isTranslucent); iterator.hasNext(); ) { final RenderSection section = iterator.next(); @@ -317,8 +310,7 @@ public void buildDrawBatchesDirect(Vec3 cameraPos, StaticQueue qu } } - } - else { + } else { final int facing = 6; final long facingOffset = facing * DrawParametersBuffer.STRIDE; drawParamsBasePtr += facingOffset; diff --git a/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java b/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java index f26c2420d..b741a9493 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java @@ -6,13 +6,11 @@ import org.lwjgl.system.MemoryUtil; public abstract class DrawParametersBuffer { + public static final long STRIDE = 16; 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; @@ -32,7 +30,7 @@ public static void freeBuffer(long ptr) { } public static long getParamsPtr(long basePtr, int section, int renderType, int facing) { - return basePtr + (((renderType * SECTIONS + section) * FACINGS) + facing) * STRIDE; + return basePtr + ((((long) renderType * SECTIONS + section) * FACINGS) + facing) * STRIDE; } public static void resetParameters(long ptr) { 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 5ab8bee72..fb032396c 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/UploadManager.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/UploadManager.java @@ -20,16 +20,14 @@ public class UploadManager { public static UploadManager INSTANCE; + Queue queue = DeviceManager.getTransferQueue(); + CommandPool.CommandBuffer commandBuffer; + LongOpenHashSet dstBuffers = new LongOpenHashSet(); public static void createInstance() { INSTANCE = new UploadManager(); } - Queue queue = DeviceManager.getTransferQueue(); - CommandPool.CommandBuffer commandBuffer; - - LongOpenHashSet dstBuffers = new LongOpenHashSet(); - public void submitUploads() { if (this.commandBuffer == null) return; 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 f9402f0ce..83433271f 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/RenderRegion.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/RenderRegion.java @@ -44,13 +44,10 @@ public class RenderRegion implements BlockAndTintGetter { private final PalettedContainer[] blockDataContainers; private final BlockState[] blockData; private final DataLayer[][] lightData; - - private BiomeData biomeData; - private TintCache tintCache; - private final Map blockEntityMap; - private final Function blockStateGetter; + private final BiomeData biomeData; + private TintCache tintCache; RenderRegion(Level level, int x, int y, int z, PalettedContainer[] blockData, DataLayer[][] lightData, BiomeData biomeData, Map blockEntityMap) { @@ -104,7 +101,7 @@ 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); } } @@ -236,8 +233,7 @@ public BlockState debugBlockState(BlockPos blockPos) { BlockState blockState = null; if (y == 60) { blockState = Blocks.BARRIER.defaultBlockState(); - } - else if (y == 70) { + } else if (y == 70) { blockState = DebugLevelSource.getBlockStateFor(x, z); } 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 3254b19c4..571d23d38 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/UploadBuffer.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/UploadBuffer.java @@ -2,7 +2,6 @@ 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; @@ -30,15 +29,13 @@ public UploadBuffer(TerrainBuilder terrainBuilder, TerrainBuilder.DrawState draw this.vertexBuffers[i] = BufferUtil.clone(bufferBuilder.getBuffer()); } } - } - else { + } else { this.vertexBuffers = null; } if (!drawState.sequentialIndex()) { this.indexBuffer = BufferUtil.clone(terrainBuilder.getIndexBuffer()); - } - else { + } else { this.indexBuffer = null; } } 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 index fe701cbe6..07b8712cf 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/biome/BiomeData.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/biome/BiomeData.java @@ -14,10 +14,8 @@ 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; - + Biome[] biomes = new Biome[SIZE]; int secX, secY, secZ; // Cached cell offsets @@ -30,11 +28,42 @@ public BiomeData(long biomeZoomSeed, int secX, int secY, int secZ) { this.secZ = secZ; } + 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; + } + public void getBiomeData(Level level, LevelChunkSection chunkSection, int secX, int secY, int secZ) { Biome defaultValue = level.registryAccess() - .lookupOrThrow(Registries.BIOME) - .getOrThrow(Biomes.PLAINS) - .value(); + .lookupOrThrow(Registries.BIOME) + .getOrThrow(Biomes.PLAINS) + .value(); int baseIdx = getRelativeSectionIdx(secX, secY, secZ); @@ -46,9 +75,8 @@ public void getBiomeData(Level level, LevelChunkSection chunkSection, int secX, if (chunkSection != null) { biomes[idx] = chunkSection.getNoiseBiome(x, y, z) - .value(); - } - else { + .value(); + } else { biomes[idx] = defaultValue; } @@ -119,35 +147,4 @@ private Vector3f getOffset(int baseIndex, int cellX, int cellY, int 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 index b8ec0ca39..a4fcdb56e 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/color/BlockColorRegistry.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/color/BlockColorRegistry.java @@ -6,16 +6,16 @@ public class BlockColorRegistry { - private final Reference2ReferenceOpenHashMap map = new Reference2ReferenceOpenHashMap<>(); + private final Reference2ReferenceOpenHashMap map = new Reference2ReferenceOpenHashMap<>(); - public void register(BlockColor blockColor, Block... blocks) { - for (Block block : blocks) { - this.map.put(block, blockColor); - } - } + 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); - } + public BlockColor getBlockColor(Block block) { + return this.map.get(block); + } } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java b/src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java index f86333de7..4360d9780 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java @@ -16,7 +16,7 @@ public static void horizontalBlur(int[] src, int[] dst, int y0, int width, int f int r = 0, g = 0, b = 0; //init accumulator - for(int x = 0; x < x0 + 1 + filterRadius; ++x) { + for (int x = 0; x < x0 + 1 + filterRadius; ++x) { color = src[getIdx(x, y, totalWidth)]; r += unpackR(color); g += unpackG(color); 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 index e31cc965e..320c57fbd 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/color/TintCache.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/color/TintCache.java @@ -62,8 +62,7 @@ public void init(BiomeData biomeData, int blendRadius, int secX, int secY, int s } this.temp = new int[size]; - } - else { + } else { for (Layer[] layers : layers.values()) { for (Layer layer : layers) { layer.invalidate(); 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 index eea26fc79..668215602 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/VulkanModRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/VulkanModRenderer.java @@ -1,6 +1,7 @@ package net.vulkanmod.render.chunk.build.frapi; import com.mojang.blaze3d.vertex.PoseStack; +import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableMesh; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.render.BlockVertexConsumerProvider; @@ -13,8 +14,6 @@ import net.minecraft.client.renderer.block.model.BlockStateModel; import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.core.BlockPos; - -import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.RenderShape; @@ -29,48 +28,49 @@ * Fabric renderer implementation. */ public class VulkanModRenderer implements Renderer { - public static final VulkanModRenderer INSTANCE = new VulkanModRenderer(); + public static final VulkanModRenderer INSTANCE = new VulkanModRenderer(); - private VulkanModRenderer() {} + private VulkanModRenderer() { + } - @Override - public MutableMesh mutableMesh() { - return new MutableMeshImpl(); - } + @Override + public MutableMesh mutableMesh() { + return new MutableMeshImpl(); + } - @Override - public void render(ModelBlockRenderer modelBlockRenderer, BlockAndTintGetter blockAndTintGetter, - BlockStateModel blockStateModel, BlockState blockState, BlockPos blockPos, PoseStack poseStack, - BlockVertexConsumerProvider blockVertexConsumerProvider, boolean cull, long seed, int overlay) { - BlockRenderContext.POOL.get().render(blockAndTintGetter, blockStateModel, blockState, blockPos, poseStack, blockVertexConsumerProvider, cull, seed, overlay); - } + @Override + public void render(ModelBlockRenderer modelBlockRenderer, BlockAndTintGetter blockAndTintGetter, + BlockStateModel blockStateModel, BlockState blockState, BlockPos blockPos, PoseStack poseStack, + BlockVertexConsumerProvider blockVertexConsumerProvider, boolean cull, long seed, int overlay) { + BlockRenderContext.POOL.get().render(blockAndTintGetter, blockStateModel, blockState, blockPos, poseStack, blockVertexConsumerProvider, cull, seed, overlay); + } - @Override - public void render(PoseStack.Pose pose, BlockVertexConsumerProvider blockVertexConsumerProvider, BlockStateModel blockStateModel, - float v, float v1, float v2, int i, int i1, BlockAndTintGetter blockAndTintGetter, - BlockPos blockPos, BlockState blockState) { - SimpleBlockRenderContext.POOL.get().bufferModel(pose, blockVertexConsumerProvider, blockStateModel, v, v1, v2, i, i1, blockAndTintGetter, blockPos, blockState); - } + @Override + public void render(PoseStack.Pose pose, BlockVertexConsumerProvider blockVertexConsumerProvider, BlockStateModel blockStateModel, + float v, float v1, float v2, int i, int i1, BlockAndTintGetter blockAndTintGetter, + BlockPos blockPos, BlockState blockState) { + SimpleBlockRenderContext.POOL.get().bufferModel(pose, blockVertexConsumerProvider, blockStateModel, v, v1, v2, i, i1, blockAndTintGetter, blockPos, blockState); + } - @Override - public void renderBlockAsEntity(BlockRenderDispatcher blockRenderDispatcher, BlockState blockState, - PoseStack poseStack, MultiBufferSource multiBufferSource, int light, int overlay, - BlockAndTintGetter blockAndTintGetter, BlockPos pos) { - RenderShape blockRenderType = blockState.getRenderShape(); + @Override + public void renderBlockAsEntity(BlockRenderDispatcher blockRenderDispatcher, BlockState blockState, + PoseStack poseStack, MultiBufferSource multiBufferSource, int light, int overlay, + BlockAndTintGetter blockAndTintGetter, BlockPos pos) { + RenderShape blockRenderType = blockState.getRenderShape(); - if (blockRenderType != RenderShape.INVISIBLE) { - BlockStateModel model = blockRenderDispatcher.getBlockModel(blockState); - int tint = ((BlockRenderDispatcherAccessor) blockRenderDispatcher).getBlockColors().getColor(blockState, null, null, 0); - float red = (tint >> 16 & 255) / 255.0F; - float green = (tint >> 8 & 255) / 255.0F; - float blue = (tint & 255) / 255.0F; - FabricBlockModelRenderer.render(poseStack.last(), layer -> multiBufferSource.getBuffer(RenderLayerHelper.getEntityBlockLayer(layer)), model, red, green, blue, light, overlay, blockAndTintGetter, pos, blockState); + if (blockRenderType != RenderShape.INVISIBLE) { + BlockStateModel model = blockRenderDispatcher.getBlockModel(blockState); + int tint = ((BlockRenderDispatcherAccessor) blockRenderDispatcher).getBlockColors().getColor(blockState, null, null, 0); + float red = (tint >> 16 & 255) / 255.0F; + float green = (tint >> 8 & 255) / 255.0F; + float blue = (tint & 255) / 255.0F; + FabricBlockModelRenderer.render(poseStack.last(), layer -> multiBufferSource.getBuffer(RenderLayerHelper.getEntityBlockLayer(layer)), model, red, green, blue, light, overlay, blockAndTintGetter, pos, blockState); ((BlockRenderDispatcherAccessor) blockRenderDispatcher).getBlockEntityModelsGetter().get().renderByBlock(blockState.getBlock(), ItemDisplayContext.NONE, poseStack, Minecraft.getInstance().gameRenderer.getSubmitNodeStorage(), light, overlay, 0); - } - } + } + } - @Override - public QuadEmitter getLayerRenderStateEmitter(ItemStackRenderState.LayerRenderState layer) { - return ((AccessLayerRenderState) layer).getMutableMesh().emitter(); - } + @Override + public QuadEmitter getLayerRenderStateEmitter(ItemStackRenderState.LayerRenderState layer) { + return ((AccessLayerRenderState) layer).getMutableMesh().emitter(); + } } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessBatchingRenderCommandQueue.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessBatchingRenderCommandQueue.java index aa1b3f992..eed65f1b7 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessBatchingRenderCommandQueue.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessBatchingRenderCommandQueue.java @@ -6,5 +6,5 @@ import java.util.List; public interface AccessBatchingRenderCommandQueue { - List getMeshItemCommands(); + List getMeshItemCommands(); } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessChunkRendererRegion.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessChunkRendererRegion.java index a24048ae3..1dbf93086 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessChunkRendererRegion.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessChunkRendererRegion.java @@ -23,7 +23,7 @@ * chunk rebuild, thus avoiding repeated thread-local lookups. */ public interface AccessChunkRendererRegion { - TerrainRenderContext fabric_getRenderer(); + TerrainRenderContext fabric_getRenderer(); - void fabric_setRenderer(TerrainRenderContext renderer); + void fabric_setRenderer(TerrainRenderContext renderer); } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessLayerRenderState.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessLayerRenderState.java index f2d56f756..870439ba5 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessLayerRenderState.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessLayerRenderState.java @@ -20,5 +20,5 @@ import net.vulkanmod.render.chunk.build.frapi.mesh.MutableMeshImpl; public interface AccessLayerRenderState { - MutableMeshImpl getMutableMesh(); + MutableMeshImpl getMutableMesh(); } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessRenderCommandQueue.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessRenderCommandQueue.java index 5d958f088..fc60db25a 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessRenderCommandQueue.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessRenderCommandQueue.java @@ -7,9 +7,8 @@ import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.world.item.ItemDisplayContext; - import java.util.List; public interface AccessRenderCommandQueue { - void submitItem(PoseStack matrices, ItemDisplayContext displayContext, int light, int overlay, int outlineColors, int[] tintLayers, List quads, RenderType renderLayer, ItemStackRenderState.FoilType glintType, MeshView mesh); + void submitItem(PoseStack matrices, ItemDisplayContext displayContext, int light, int overlay, int outlineColors, int[] tintLayers, List quads, RenderType renderLayer, ItemStackRenderState.FoilType glintType, MeshView mesh); } 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 index 80003422e..0af344de7 100644 --- 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 @@ -24,55 +24,60 @@ * 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 max. - */ - public static int maxLight(int l0, int l1) { - if (l0 == 0) return l1; - if (l1 == 0) return l0; - - return Math.max(l0 & 0xFFFF, l1 & 0xFFFF) | Math.max(l0 & 0xFFFF0000, l1 & 0xFFFF0000); - } - - /** 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); - } + private static final boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + + private ColorHelper() { + } + + /** + * Component-wise max. + */ + public static int maxLight(int l0, int l1) { + if (l0 == 0) return l1; + if (l1 == 0) return l0; + + return Math.max(l0 & 0xFFFF, l1 & 0xFFFF) | Math.max(l0 & 0xFFFF0000, l1 & 0xFFFF0000); + } + + /** + * 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) @@ -90,37 +95,37 @@ Vanilla color format (big endian): RGBA (0xRRGGBBAA) 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); - } - } + /** + * 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 index fc68442cd..2c32042df 100644 --- 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 @@ -16,8 +16,6 @@ package net.vulkanmod.render.chunk.build.frapi.helper; -import static net.minecraft.util.Mth.equal; - import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.core.Direction; @@ -25,215 +23,221 @@ import net.minecraft.core.Direction.AxisDirection; import org.joml.Vector3fc; +import static net.minecraft.util.Mth.equal; + /** * 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 Vector3fc 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(Vector3fc 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; - } + /** + * 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; + private GeometryHelper() { + } + + /** + * 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 Vector3fc 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(Vector3fc 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 index 8b8ebb1b0..46246fb83 100644 --- 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 @@ -16,14 +16,14 @@ 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; +import net.vulkanmod.render.model.quad.ModelQuadView; +import net.vulkanmod.render.vertex.format.I32_SNorm; +import org.jetbrains.annotations.NotNull; +import org.joml.Vector3f; /** * Static routines of general utility for renderer implementations. @@ -31,165 +31,165 @@ * 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.getUnitVec3i(); - 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.getUnitVec3i(); - - 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)); - } + private static final float PACK = 127.0f; + private static final float UNPACK = 1.0f / PACK; + private NormalHelper() { + } + + /** + * 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.getUnitVec3i(); + 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.getUnitVec3i(); + + 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 index bc622cd92..902b94747 100644 --- 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 @@ -26,85 +26,84 @@ * 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)); - } + private static final float NORMALIZER = 1f / 16f; + 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)); + } + + private TextureHelper() { + } + + /** + * 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); + } + } + + private static void applyModifier(MutableQuadView quad, VertexModifier modifier) { + for (int i = 0; i < 4; i++) { + modifier.apply(quad, i); + } + } + + @FunctionalInterface + private interface VertexModifier { + void apply(MutableQuadView quad, int vertexIndex); + } } 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 index a0de50146..1c1039d37 100644 --- 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 @@ -19,17 +19,17 @@ import com.google.common.base.Preconditions; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.ShadeMode; +import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; import net.fabricmc.fabric.api.util.TriState; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.client.renderer.item.ItemStackRenderState; -import org.apache.commons.lang3.ArrayUtils; -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.minecraft.core.Direction; import net.minecraft.util.Mth; +import net.vulkanmod.render.chunk.build.frapi.helper.GeometryHelper; +import org.apache.commons.lang3.ArrayUtils; +import org.jetbrains.annotations.Nullable; /** * Holds all the array offsets and bit-wise encoders/decoders for @@ -37,187 +37,182 @@ * All of this is implementation-specific - that's why it isn't a "helper" class. */ public final class EncodingFormat { - private EncodingFormat() { } - - static final int HEADER_BITS = 0; - static final int HEADER_FACE_NORMAL = 1; - static final int HEADER_TINT_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); - } - - private static final int DIRECTION_COUNT = Direction.values().length; - private static final int NULLABLE_DIRECTION_COUNT = DIRECTION_COUNT + 1; - - private static final @Nullable ChunkSectionLayer[] NULLABLE_BLOCK_RENDER_LAYERS = ArrayUtils.add(ChunkSectionLayer.values(), null); - private static final int NULLABLE_BLOCK_RENDER_LAYER_COUNT = NULLABLE_BLOCK_RENDER_LAYERS.length; - private static final TriState[] TRI_STATES = TriState.values(); - private static final int TRI_STATE_COUNT = TRI_STATES.length; - private static final @Nullable ItemStackRenderState.FoilType[] NULLABLE_GLINTS = ArrayUtils.add(ItemStackRenderState.FoilType.values(), null); - private static final int NULLABLE_GLINT_COUNT = NULLABLE_GLINTS.length; - private static final ShadeMode[] SHADE_MODES = ShadeMode.values(); - private static final int SHADE_MODE_COUNT = SHADE_MODES.length; - - private static final int NULL_RENDER_LAYER_INDEX = NULLABLE_BLOCK_RENDER_LAYER_COUNT - 1; - private static final int NULL_GLINT_INDEX = NULLABLE_GLINT_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 RENDER_LAYER_BIT_LENGTH = Mth.ceillog2(NULLABLE_BLOCK_RENDER_LAYER_COUNT); - private static final int EMISSIVE_BIT_LENGTH = 1; - private static final int DIFFUSE_BIT_LENGTH = 1; - private static final int AO_BIT_LENGTH = Mth.ceillog2(TRI_STATE_COUNT); - private static final int GLINT_BIT_LENGTH = Mth.ceillog2(NULLABLE_GLINT_COUNT); - private static final int SHADE_MODE_BIT_LENGTH = Mth.ceillog2(SHADE_MODE_COUNT); - - 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 RENDER_LAYER_BIT_OFFSET = GEOMETRY_BIT_OFFSET + GEOMETRY_BIT_LENGTH; - private static final int EMISSIVE_BIT_OFFSET = RENDER_LAYER_BIT_OFFSET + RENDER_LAYER_BIT_LENGTH; - private static final int DIFFUSE_BIT_OFFSET = EMISSIVE_BIT_OFFSET + EMISSIVE_BIT_LENGTH; - private static final int AO_BIT_OFFSET = DIFFUSE_BIT_OFFSET + DIFFUSE_BIT_LENGTH; - private static final int GLINT_BIT_OFFSET = AO_BIT_OFFSET + AO_BIT_LENGTH; - private static final int SHADE_MODE_BIT_OFFSET = GLINT_BIT_OFFSET + GLINT_BIT_LENGTH; - private static final int TOTAL_BIT_LENGTH = SHADE_MODE_BIT_OFFSET + SHADE_MODE_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 RENDER_LAYER_MASK = bitMask(RENDER_LAYER_BIT_LENGTH, RENDER_LAYER_BIT_OFFSET); - private static final int EMISSIVE_MASK = bitMask(EMISSIVE_BIT_LENGTH, EMISSIVE_BIT_OFFSET); - private static final int DIFFUSE_MASK = bitMask(DIFFUSE_BIT_LENGTH, DIFFUSE_BIT_OFFSET); - private static final int AO_MASK = bitMask(AO_BIT_LENGTH, AO_BIT_OFFSET); - private static final int GLINT_MASK = bitMask(GLINT_BIT_LENGTH, GLINT_BIT_OFFSET); - private static final int SHADE_MODE_MASK = bitMask(SHADE_MODE_BIT_LENGTH, SHADE_MODE_BIT_OFFSET); - - static { - Preconditions.checkArgument(TOTAL_BIT_LENGTH <= 32, "Indigo header encoding bit count (%s) exceeds integer bit length)", TOTAL_STRIDE); - } - - private 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); - } - - @Nullable - static ChunkSectionLayer renderLayer(int bits) { - return NULLABLE_BLOCK_RENDER_LAYERS[(bits & RENDER_LAYER_MASK) >>> RENDER_LAYER_BIT_OFFSET]; - } - - static int renderLayer(int bits, @Nullable ChunkSectionLayer renderLayer) { - int index = renderLayer == null ? NULL_RENDER_LAYER_INDEX : renderLayer.ordinal(); - return (bits & ~RENDER_LAYER_MASK) | (index << RENDER_LAYER_BIT_OFFSET); - } - - static boolean emissive(int bits) { - return (bits & EMISSIVE_MASK) != 0; - } - - static int emissive(int bits, boolean emissive) { - return emissive ? (bits | EMISSIVE_MASK) : (bits & ~EMISSIVE_MASK); - } - - static boolean diffuseShade(int bits) { - return (bits & DIFFUSE_MASK) != 0; - } - - static int diffuseShade(int bits, boolean shade) { - return shade ? (bits | DIFFUSE_MASK) : (bits & ~DIFFUSE_MASK); - } - - static TriState ambientOcclusion(int bits) { - return TRI_STATES[(bits & AO_MASK) >>> AO_BIT_OFFSET]; - } - - static int ambientOcclusion(int bits, TriState ao) { - return (bits & ~AO_MASK) | (ao.ordinal() << AO_BIT_OFFSET); - } - - @Nullable - static ItemStackRenderState.FoilType glint(int bits) { - return NULLABLE_GLINTS[(bits & GLINT_MASK) >>> GLINT_BIT_OFFSET]; - } - - static int glint(int bits, @Nullable ItemStackRenderState.FoilType glint) { - int index = glint == null ? NULL_GLINT_INDEX : glint.ordinal(); - return (bits & ~GLINT_MASK) | (index << GLINT_BIT_OFFSET); - } - - static ShadeMode shadeMode(int bits) { - return SHADE_MODES[(bits & SHADE_MODE_MASK) >>> SHADE_MODE_BIT_OFFSET]; - } - - static int shadeMode(int bits, ShadeMode mode) { - return (bits & ~SHADE_MODE_MASK) | (mode.ordinal() << SHADE_MODE_BIT_OFFSET); - } + public static final int HEADER_STRIDE = 4; + 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 int HEADER_BITS = 0; + static final int HEADER_FACE_NORMAL = 1; + static final int HEADER_TINT_INDEX = 2; + static final int HEADER_TAG = 3; + 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; + 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_OFFSET = CULL_BIT_OFFSET + CULL_BIT_LENGTH; + private static final int CULL_MASK = bitMask(CULL_BIT_LENGTH, CULL_BIT_OFFSET); + private static final @Nullable ChunkSectionLayer[] NULLABLE_BLOCK_RENDER_LAYERS = ArrayUtils.add(ChunkSectionLayer.values(), null); + private static final int NULLABLE_BLOCK_RENDER_LAYER_COUNT = NULLABLE_BLOCK_RENDER_LAYERS.length; + private static final int NULL_RENDER_LAYER_INDEX = NULLABLE_BLOCK_RENDER_LAYER_COUNT - 1; + private static final int RENDER_LAYER_BIT_LENGTH = Mth.ceillog2(NULLABLE_BLOCK_RENDER_LAYER_COUNT); + private static final TriState[] TRI_STATES = TriState.values(); + private static final int TRI_STATE_COUNT = TRI_STATES.length; + private static final int AO_BIT_LENGTH = Mth.ceillog2(TRI_STATE_COUNT); + private static final @Nullable ItemStackRenderState.FoilType[] NULLABLE_GLINTS = ArrayUtils.add(ItemStackRenderState.FoilType.values(), null); + private static final int NULLABLE_GLINT_COUNT = NULLABLE_GLINTS.length; + private static final int NULL_GLINT_INDEX = NULLABLE_GLINT_COUNT - 1; + private static final int GLINT_BIT_LENGTH = Mth.ceillog2(NULLABLE_GLINT_COUNT); + private static final ShadeMode[] SHADE_MODES = ShadeMode.values(); + private static final int SHADE_MODE_COUNT = SHADE_MODES.length; + private static final int SHADE_MODE_BIT_LENGTH = Mth.ceillog2(SHADE_MODE_COUNT); + private static final int LIGHT_BIT_LENGTH = Mth.ceillog2(DIRECTION_COUNT); + 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 RENDER_LAYER_BIT_OFFSET = GEOMETRY_BIT_OFFSET + GEOMETRY_BIT_LENGTH; + private static final int EMISSIVE_BIT_OFFSET = RENDER_LAYER_BIT_OFFSET + RENDER_LAYER_BIT_LENGTH; + private static final int DIFFUSE_BIT_OFFSET = EMISSIVE_BIT_OFFSET + EMISSIVE_BIT_LENGTH; + private static final int AO_BIT_OFFSET = DIFFUSE_BIT_OFFSET + DIFFUSE_BIT_LENGTH; + private static final int GLINT_BIT_OFFSET = AO_BIT_OFFSET + AO_BIT_LENGTH; + private static final int SHADE_MODE_BIT_OFFSET = GLINT_BIT_OFFSET + GLINT_BIT_LENGTH; + private static final int TOTAL_BIT_LENGTH = SHADE_MODE_BIT_OFFSET + SHADE_MODE_BIT_LENGTH; + private static final int SHADE_MODE_MASK = bitMask(SHADE_MODE_BIT_LENGTH, SHADE_MODE_BIT_OFFSET); + private static final int GLINT_MASK = bitMask(GLINT_BIT_LENGTH, GLINT_BIT_OFFSET); + private static final int AO_MASK = bitMask(AO_BIT_LENGTH, AO_BIT_OFFSET); + private static final int DIFFUSE_MASK = bitMask(DIFFUSE_BIT_LENGTH, DIFFUSE_BIT_OFFSET); + private static final int EMISSIVE_MASK = bitMask(EMISSIVE_BIT_LENGTH, EMISSIVE_BIT_OFFSET); + private static final int RENDER_LAYER_MASK = bitMask(RENDER_LAYER_BIT_LENGTH, RENDER_LAYER_BIT_OFFSET); + private static final int GEOMETRY_MASK = bitMask(GEOMETRY_BIT_LENGTH, GEOMETRY_BIT_OFFSET); + private static final int NORMALS_MASK = bitMask(NORMALS_BIT_LENGTH, NORMALS_BIT_OFFSET); + private static final int LIGHT_MASK = bitMask(LIGHT_BIT_LENGTH, LIGHT_BIT_OFFSET); + private static final int NORMALS_BIT_LENGTH = 4; + private static final int GEOMETRY_BIT_LENGTH = GeometryHelper.FLAG_BIT_COUNT; + private static final int EMISSIVE_BIT_LENGTH = 1; + private static final int DIFFUSE_BIT_LENGTH = 1; + private static final int CULL_BIT_OFFSET = 0; + + static { + final VertexFormat format = DefaultVertexFormat.BLOCK; + VERTEX_X = HEADER_STRIDE; + 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); + } + + static { + Preconditions.checkArgument(TOTAL_BIT_LENGTH <= 32, "Indigo header encoding bit count (%s) exceeds integer bit length)", TOTAL_STRIDE); + } + + private EncodingFormat() { + } + + private 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); + } + + @Nullable + static ChunkSectionLayer renderLayer(int bits) { + return NULLABLE_BLOCK_RENDER_LAYERS[(bits & RENDER_LAYER_MASK) >>> RENDER_LAYER_BIT_OFFSET]; + } + + static int renderLayer(int bits, @Nullable ChunkSectionLayer renderLayer) { + int index = renderLayer == null ? NULL_RENDER_LAYER_INDEX : renderLayer.ordinal(); + return (bits & ~RENDER_LAYER_MASK) | (index << RENDER_LAYER_BIT_OFFSET); + } + + static boolean emissive(int bits) { + return (bits & EMISSIVE_MASK) != 0; + } + + static int emissive(int bits, boolean emissive) { + return emissive ? (bits | EMISSIVE_MASK) : (bits & ~EMISSIVE_MASK); + } + + static boolean diffuseShade(int bits) { + return (bits & DIFFUSE_MASK) != 0; + } + + static int diffuseShade(int bits, boolean shade) { + return shade ? (bits | DIFFUSE_MASK) : (bits & ~DIFFUSE_MASK); + } + + static TriState ambientOcclusion(int bits) { + return TRI_STATES[(bits & AO_MASK) >>> AO_BIT_OFFSET]; + } + + static int ambientOcclusion(int bits, TriState ao) { + return (bits & ~AO_MASK) | (ao.ordinal() << AO_BIT_OFFSET); + } + + @Nullable + static ItemStackRenderState.FoilType glint(int bits) { + return NULLABLE_GLINTS[(bits & GLINT_MASK) >>> GLINT_BIT_OFFSET]; + } + + static int glint(int bits, @Nullable ItemStackRenderState.FoilType glint) { + int index = glint == null ? NULL_GLINT_INDEX : glint.ordinal(); + return (bits & ~GLINT_MASK) | (index << GLINT_BIT_OFFSET); + } + + static ShadeMode shadeMode(int bits) { + return SHADE_MODES[(bits & SHADE_MODE_MASK) >>> SHADE_MODE_BIT_OFFSET]; + } + + static int shadeMode(int bits, ShadeMode mode) { + return (bits & ~SHADE_MODE_MASK) | (mode.ordinal() << SHADE_MODE_BIT_OFFSET); + } } 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 index 834f867b8..ca5a9e520 100644 --- 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 @@ -16,87 +16,88 @@ package net.vulkanmod.render.chunk.build.frapi.mesh; -import java.util.function.Consumer; - import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import org.jetbrains.annotations.Range; - 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; +import org.jetbrains.annotations.Range; + +import java.util.function.Consumer; public class MeshImpl implements Mesh { - /** Used to satisfy external calls to {@link #forEach(Consumer)}. */ - private static final ThreadLocal> CURSOR_POOLS = ThreadLocal.withInitial(ObjectArrayList::new); - - int[] data; - int limit; - - MeshImpl(int[] data) { - this.data = data; - limit = data.length; - } - - MeshImpl() { - } - - @Override - @Range(from = 0, to = Integer.MAX_VALUE) - public int size() { - return limit / EncodingFormat.TOTAL_STRIDE; - } - - @Override - public void forEach(Consumer action) { - ObjectArrayList pool = CURSOR_POOLS.get(); - QuadViewImpl cursor; - - if (pool.isEmpty()) { - cursor = new QuadViewImpl(); - } else { - cursor = pool.pop(); - } - - forEach(action, cursor); - - pool.push(cursor); - } - - /** - * The renderer can call this with its own cursor to avoid the performance hit of a - * thread-local lookup or to use a mutable cursor. - */ - void forEach(Consumer action, C cursor) { - final int limit = this.limit; - int index = 0; - cursor.data = data; - - while (index < limit) { - cursor.baseIndex = index; - cursor.load(); - action.accept(cursor); - index += EncodingFormat.TOTAL_STRIDE; - } - - cursor.data = null; - } - - // TODO: This could be optimized by checking if the emitter is that of a MutableMeshImpl and if - // it has no transforms, in which case the entire data array can be copied in bulk. - @Override - public void outputTo(QuadEmitter emitter) { - MutableQuadViewImpl e = (MutableQuadViewImpl) emitter; - final int[] data = this.data; - final int limit = this.limit; - int index = 0; - - while (index < limit) { - System.arraycopy(data, index, e.data, e.baseIndex, EncodingFormat.TOTAL_STRIDE); - e.load(); - e.transformAndEmit(); - index += EncodingFormat.TOTAL_STRIDE; - } - - e.clear(); - } + /** + * Used to satisfy external calls to {@link #forEach(Consumer)}. + */ + private static final ThreadLocal> CURSOR_POOLS = ThreadLocal.withInitial(ObjectArrayList::new); + + int[] data; + int limit; + + MeshImpl(int[] data) { + this.data = data; + limit = data.length; + } + + MeshImpl() { + } + + @Override + @Range(from = 0, to = Integer.MAX_VALUE) + public int size() { + return limit / EncodingFormat.TOTAL_STRIDE; + } + + @Override + public void forEach(Consumer action) { + ObjectArrayList pool = CURSOR_POOLS.get(); + QuadViewImpl cursor; + + if (pool.isEmpty()) { + cursor = new QuadViewImpl(); + } else { + cursor = pool.pop(); + } + + forEach(action, cursor); + + pool.push(cursor); + } + + /** + * The renderer can call this with its own cursor to avoid the performance hit of a + * thread-local lookup or to use a mutable cursor. + */ + void forEach(Consumer action, C cursor) { + final int limit = this.limit; + int index = 0; + cursor.data = data; + + while (index < limit) { + cursor.baseIndex = index; + cursor.load(); + action.accept(cursor); + index += EncodingFormat.TOTAL_STRIDE; + } + + cursor.data = null; + } + + // TODO: This could be optimized by checking if the emitter is that of a MutableMeshImpl and if + // it has no transforms, in which case the entire data array can be copied in bulk. + @Override + public void outputTo(QuadEmitter emitter) { + MutableQuadViewImpl e = (MutableQuadViewImpl) emitter; + final int[] data = this.data; + final int limit = this.limit; + int index = 0; + + while (index < limit) { + System.arraycopy(data, index, e.data, e.baseIndex, EncodingFormat.TOTAL_STRIDE); + e.load(); + e.transformAndEmit(); + index += EncodingFormat.TOTAL_STRIDE; + } + + e.clear(); + } } \ No newline at end of file diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableMeshImpl.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableMeshImpl.java index 79ab94df6..32c492279 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableMeshImpl.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableMeshImpl.java @@ -16,13 +16,13 @@ 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.MutableMesh; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import java.util.function.Consumer; + /** * Our implementation of {@link MutableMesh}, mainly used for optimized mesh creation. * Not much to it - mainly it just needs to grow the int[] array as quads are appended @@ -31,7 +31,15 @@ * The one interesting bit is in {@link #emitter}. */ public class MutableMeshImpl extends MeshImpl implements MutableMesh { - private final MutableQuadViewImpl emitter = new MutableQuadViewImpl() { + public MutableMeshImpl() { + data = new int[8 * EncodingFormat.TOTAL_STRIDE]; + limit = 0; + + ensureCapacity(EncodingFormat.TOTAL_STRIDE); + emitter.data = data; + emitter.baseIndex = limit; + emitter.clear(); + } private final MutableQuadViewImpl emitter = new MutableQuadViewImpl() { @Override protected void emitDirectly() { // Necessary because the validity of geometry is not encoded; reading mesh data always @@ -44,16 +52,6 @@ protected void emitDirectly() { } }; - public MutableMeshImpl() { - data = new int[8 * EncodingFormat.TOTAL_STRIDE]; - limit = 0; - - ensureCapacity(EncodingFormat.TOTAL_STRIDE); - emitter.data = data; - emitter.baseIndex = limit; - emitter.clear(); - } - private void ensureCapacity(int stride) { if (stride > data.length - limit) { final int[] bigger = new int[data.length * 2]; @@ -90,4 +88,6 @@ public void clear() { emitter.baseIndex = limit; emitter.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 index 215db6398..0dbf73398 100644 --- 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 @@ -17,22 +17,22 @@ package net.vulkanmod.render.chunk.build.frapi.mesh; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadTransform; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.ShadeMode; import net.fabricmc.fabric.api.util.TriState; import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.vulkanmod.render.model.quad.ModelQuadView; -import org.jetbrains.annotations.Nullable; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadTransform; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import net.minecraft.core.Direction; 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.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.core.Direction; +import net.vulkanmod.render.model.quad.ModelQuadView; +import org.jetbrains.annotations.Nullable; import java.util.Objects; @@ -49,301 +49,301 @@ * numbers. It also allows for a consistent interface for those transformations. */ public abstract class MutableQuadViewImpl extends QuadViewImpl implements QuadEmitter { - private static final QuadTransform NO_TRANSFORM = q -> true; - - private static final int[] DEFAULT_QUAD_DATA = new int[EncodingFormat.TOTAL_STRIDE]; - - static { - MutableQuadViewImpl quad = new MutableQuadViewImpl() { - @Override - protected void emitDirectly() { - // This quad won't be emitted. It's only used to configure the default quad data. - } - }; - - // Start with all zeroes - quad.data = DEFAULT_QUAD_DATA; - // Apply non-zero defaults - quad.color(-1, -1, -1, -1); - quad.cullFace(null); - quad.renderLayer(null); - quad.diffuseShade(true); - quad.ambientOcclusion(TriState.DEFAULT); - quad.glint(null); - quad.tintIndex(-1); - quad.tintIndex(-1); - } - - protected boolean hasTransform = false; - 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; - }; - - public final void clear() { - System.arraycopy(DEFAULT_QUAD_DATA, 0, data, baseIndex, EncodingFormat.TOTAL_STRIDE); - isGeometryInvalid = true; - nominalFace = null; - } - - @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 nominalFace(@Nullable Direction face) { - nominalFace = face; - return this; - } - - @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 MutableQuadViewImpl renderLayer(@Nullable ChunkSectionLayer renderLayer) { - data[baseIndex + HEADER_BITS] = EncodingFormat.renderLayer(data[baseIndex + HEADER_BITS], renderLayer); - return this; - } - - @Override - public MutableQuadViewImpl emissive(boolean emissive) { - data[baseIndex + HEADER_BITS] = EncodingFormat.emissive(data[baseIndex + HEADER_BITS], emissive); - return this; - } - - @Override - public MutableQuadViewImpl diffuseShade(boolean shade) { - data[baseIndex + HEADER_BITS] = EncodingFormat.diffuseShade(data[baseIndex + HEADER_BITS], shade); - return this; - } - - @Override - public MutableQuadViewImpl ambientOcclusion(TriState ao) { - Objects.requireNonNull(ao, "ambient occlusion TriState may not be null"); - data[baseIndex + HEADER_BITS] = EncodingFormat.ambientOcclusion(data[baseIndex + HEADER_BITS], ao); - return this; - } - - @Override - public MutableQuadViewImpl glint(@Nullable ItemStackRenderState.FoilType glint) { - data[baseIndex + HEADER_BITS] = EncodingFormat.glint(data[baseIndex + HEADER_BITS], glint); - return this; - } - - @Override - public MutableQuadViewImpl shadeMode(ShadeMode mode) { - Objects.requireNonNull(mode, "ShadeMode may not be null"); - data[baseIndex + HEADER_BITS] = EncodingFormat.shadeMode(data[baseIndex + HEADER_BITS], mode); - return this; - } - - @Override - public final MutableQuadViewImpl tintIndex(int tintIndex) { - data[baseIndex + HEADER_TINT_INDEX] = tintIndex; - 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; - System.arraycopy(q.data, q.baseIndex, data, baseIndex, EncodingFormat.TOTAL_STRIDE); - nominalFace = q.nominalFace; - isGeometryInvalid = q.isGeometryInvalid; - - if (!isGeometryInvalid) { - faceNormal.set(q.faceNormal); - } - - 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 normalFlags = 0; - int colorIndex = baseIndex + VERTEX_COLOR; - int normalIndex = baseIndex + VERTEX_NORMAL; - - for (int i = 0; i < 4; i++) { - data[colorIndex] = ColorHelper.fromVanillaColor(data[colorIndex]); - - // Set normal flag if normal is not zero, ignoring W component - if ((data[normalIndex] & 0xFFFFFF) != 0) { - normalFlags |= 1 << i; - } - - colorIndex += VERTEX_STRIDE; - normalIndex += VERTEX_STRIDE; - } - - normalFlags(normalFlags); - return this; - } - - @Override - public final MutableQuadViewImpl fromBakedQuad(BakedQuad quad) { - fromVanilla(quad.vertices(), 0); + private static final QuadTransform NO_TRANSFORM = q -> true; + + private static final int[] DEFAULT_QUAD_DATA = new int[EncodingFormat.TOTAL_STRIDE]; + + static { + MutableQuadViewImpl quad = new MutableQuadViewImpl() { + @Override + protected void emitDirectly() { + // This quad won't be emitted. It's only used to configure the default quad data. + } + }; + + // Start with all zeroes + quad.data = DEFAULT_QUAD_DATA; + // Apply non-zero defaults + quad.color(-1, -1, -1, -1); + quad.cullFace(null); + quad.renderLayer(null); + quad.diffuseShade(true); + quad.ambientOcclusion(TriState.DEFAULT); + quad.glint(null); + quad.tintIndex(-1); + quad.tintIndex(-1); + } + + 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; + }; + protected boolean hasTransform = false; + private QuadTransform activeTransform = NO_TRANSFORM; + + public final void clear() { + System.arraycopy(DEFAULT_QUAD_DATA, 0, data, baseIndex, EncodingFormat.TOTAL_STRIDE); + isGeometryInvalid = true; + nominalFace = null; + } + + @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 nominalFace(@Nullable Direction face) { + nominalFace = face; + return this; + } + + @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 MutableQuadViewImpl renderLayer(@Nullable ChunkSectionLayer renderLayer) { + data[baseIndex + HEADER_BITS] = EncodingFormat.renderLayer(data[baseIndex + HEADER_BITS], renderLayer); + return this; + } + + @Override + public MutableQuadViewImpl emissive(boolean emissive) { + data[baseIndex + HEADER_BITS] = EncodingFormat.emissive(data[baseIndex + HEADER_BITS], emissive); + return this; + } + + @Override + public MutableQuadViewImpl diffuseShade(boolean shade) { + data[baseIndex + HEADER_BITS] = EncodingFormat.diffuseShade(data[baseIndex + HEADER_BITS], shade); + return this; + } + + @Override + public MutableQuadViewImpl ambientOcclusion(TriState ao) { + Objects.requireNonNull(ao, "ambient occlusion TriState may not be null"); + data[baseIndex + HEADER_BITS] = EncodingFormat.ambientOcclusion(data[baseIndex + HEADER_BITS], ao); + return this; + } + + @Override + public MutableQuadViewImpl glint(@Nullable ItemStackRenderState.FoilType glint) { + data[baseIndex + HEADER_BITS] = EncodingFormat.glint(data[baseIndex + HEADER_BITS], glint); + return this; + } + + @Override + public MutableQuadViewImpl shadeMode(ShadeMode mode) { + Objects.requireNonNull(mode, "ShadeMode may not be null"); + data[baseIndex + HEADER_BITS] = EncodingFormat.shadeMode(data[baseIndex + HEADER_BITS], mode); + return this; + } + + @Override + public final MutableQuadViewImpl tintIndex(int tintIndex) { + data[baseIndex + HEADER_TINT_INDEX] = tintIndex; + 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; + System.arraycopy(q.data, q.baseIndex, data, baseIndex, EncodingFormat.TOTAL_STRIDE); + nominalFace = q.nominalFace; + isGeometryInvalid = q.isGeometryInvalid; + + if (!isGeometryInvalid) { + faceNormal.set(q.faceNormal); + } + + 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 normalFlags = 0; + int colorIndex = baseIndex + VERTEX_COLOR; + int normalIndex = baseIndex + VERTEX_NORMAL; + + for (int i = 0; i < 4; i++) { + data[colorIndex] = ColorHelper.fromVanillaColor(data[colorIndex]); + + // Set normal flag if normal is not zero, ignoring W component + if ((data[normalIndex] & 0xFFFFFF) != 0) { + normalFlags |= 1 << i; + } + + colorIndex += VERTEX_STRIDE; + normalIndex += VERTEX_STRIDE; + } + + normalFlags(normalFlags); + return this; + } + + @Override + public final MutableQuadViewImpl fromBakedQuad(BakedQuad quad) { + fromVanilla(quad.vertices(), 0); // data[baseIndex + HEADER_BITS] = EncodingFormat.cullFace(0, cullFace); - nominalFace(quad.direction()); - diffuseShade(quad.shade()); - tintIndex(quad.tintIndex()); + nominalFace(quad.direction()); + diffuseShade(quad.shade()); + tintIndex(quad.tintIndex()); // tag(0); - // Copy data from BakedQuad instead of calculating properties + // Copy data from BakedQuad instead of calculating properties ModelQuadView quadView = (ModelQuadView) (Object) 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; - - int lightEmission = quad.lightEmission(); - - if (lightEmission > 0) { - for (int i = 0; i < 4; i++) { - lightmap(i, LightTexture.lightCoordsWithEmission(lightmap(i), lightEmission)); - } - } - - return this; - } - - @Override - public void pushTransform(QuadTransform transform) { - if (transform == null) { - throw new NullPointerException("QuadTransform cannot be null!"); - } - - transformStack.push(transform); - hasTransform = true; - - 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; - hasTransform = false; - } else if (transformStack.size() == 1) { - activeTransform = transformStack.get(0); - } - } - - /** - * Emit the quad without applying transforms and without clearing the underlying data. - * Geometry is not guaranteed to be valid when called, but can be computed by calling {@link #computeGeometry()}. - */ - protected abstract void emitDirectly(); - - /** - * Apply transforms and then if transforms return true, emit the quad without clearing the underlying data. - */ - public final void transformAndEmit() { - if (activeTransform.transform(this)) { - emitDirectly(); - } - } - - @Override - public final MutableQuadViewImpl emit() { - transformAndEmit(); - clear(); - return this; - } + 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; + + int lightEmission = quad.lightEmission(); + + if (lightEmission > 0) { + for (int i = 0; i < 4; i++) { + lightmap(i, LightTexture.lightCoordsWithEmission(lightmap(i), lightEmission)); + } + } + + return this; + } + + @Override + public void pushTransform(QuadTransform transform) { + if (transform == null) { + throw new NullPointerException("QuadTransform cannot be null!"); + } + + transformStack.push(transform); + hasTransform = true; + + 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; + hasTransform = false; + } else if (transformStack.size() == 1) { + activeTransform = transformStack.get(0); + } + } + + /** + * Emit the quad without applying transforms and without clearing the underlying data. + * Geometry is not guaranteed to be valid when called, but can be computed by calling {@link #computeGeometry()}. + */ + protected abstract void emitDirectly(); + + /** + * Apply transforms and then if transforms return true, emit the quad without clearing the underlying data. + */ + public final void transformAndEmit() { + if (activeTransform.transform(this)) { + emitDirectly(); + } + } + + @Override + public final MutableQuadViewImpl emit() { + transformAndEmit(); + clear(); + return this; + } } \ No newline at end of file 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 index 723e80792..f6203f5c0 100644 --- 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 @@ -16,26 +16,15 @@ 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_TINT_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.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.ShadeMode; import net.fabricmc.fabric.api.util.TriState; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.client.renderer.item.ItemStackRenderState; +import net.minecraft.core.Direction; +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.cull.QuadFacing; import net.vulkanmod.render.model.quad.ModelQuadFlags; import net.vulkanmod.render.model.quad.ModelQuadView; @@ -43,318 +32,326 @@ 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.minecraft.core.Direction; + +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.*; /** * 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]); - } - - @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 final int normalFlags() { - return EncodingFormat.normalFlags(data[baseIndex + HEADER_BITS]); - } - - @Override - public final boolean hasNormal(int vertexIndex) { - return (normalFlags() & (1 << vertexIndex)) != 0; - } - - /** True if any vertex normal has been set. */ - public final boolean hasVertexNormals() { - return normalFlags() != 0; - } - - /** True if all vertex normals have been set. */ - public final boolean hasAllVertexNormals() { - return (normalFlags() & 0b1111) == 0b1111; - } - - protected final int normalIndex(int vertexIndex) { - return baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_NORMAL; - } - - @Override - public final float normalX(int vertexIndex) { - return hasNormal(vertexIndex) ? NormalHelper.unpackNormalX(data[normalIndex(vertexIndex)]) : Float.NaN; - } - - @Override - public final float normalY(int vertexIndex) { - return hasNormal(vertexIndex) ? NormalHelper.unpackNormalY(data[normalIndex(vertexIndex)]) : Float.NaN; - } - - @Override - public final float normalZ(int vertexIndex) { - return hasNormal(vertexIndex) ? NormalHelper.unpackNormalZ(data[normalIndex(vertexIndex)]) : Float.NaN; - } - - @Override - @Nullable - public final 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 - @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 - @Nullable - public final Direction cullFace() { - return EncodingFormat.cullFace(data[baseIndex + HEADER_BITS]); - } - - @Override - @Nullable - public ChunkSectionLayer renderLayer() { - return EncodingFormat.renderLayer(data[baseIndex + HEADER_BITS]); - } - - @Override - public boolean emissive() { - return EncodingFormat.emissive(data[baseIndex + HEADER_BITS]); - } - - @Override - public boolean diffuseShade() { - return EncodingFormat.diffuseShade(data[baseIndex + HEADER_BITS]); - } - - @Override - public TriState ambientOcclusion() { - return EncodingFormat.ambientOcclusion(data[baseIndex + HEADER_BITS]); - } - - @Override - @Nullable - public ItemStackRenderState.FoilType glint() { - return EncodingFormat.glint(data[baseIndex + HEADER_BITS]); - } - - @Override - public ShadeMode shadeMode() { - return EncodingFormat.shadeMode(data[baseIndex + HEADER_BITS]); - } - - @Override - public final int tintIndex() { - return data[baseIndex + HEADER_TINT_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); - - int colorIndex = targetIndex + VERTEX_COLOR - HEADER_STRIDE; - - 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.tintIndex(); - } - - @Override - public Direction getFacingDirection() { - return this.lightFace(); - } - - @Override - public int getNormal() { - return packedFaceNormal(); - } - - @Override - public QuadFacing getQuadFacing() { - return this.facing; - } + protected final Vector3f faceNormal = new Vector3f(); + @Nullable + protected Direction nominalFace; + /** + * True when face normal, light face, or geometry flags may not match geometry. + */ + protected boolean isGeometryInvalid = true; + /** + * 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]); + } + + @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 final int normalFlags() { + return EncodingFormat.normalFlags(data[baseIndex + HEADER_BITS]); + } + + @Override + public final boolean hasNormal(int vertexIndex) { + return (normalFlags() & (1 << vertexIndex)) != 0; + } + + /** + * True if any vertex normal has been set. + */ + public final boolean hasVertexNormals() { + return normalFlags() != 0; + } + + /** + * True if all vertex normals have been set. + */ + public final boolean hasAllVertexNormals() { + return (normalFlags() & 0b1111) == 0b1111; + } + + protected final int normalIndex(int vertexIndex) { + return baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_NORMAL; + } + + @Override + public final float normalX(int vertexIndex) { + return hasNormal(vertexIndex) ? NormalHelper.unpackNormalX(data[normalIndex(vertexIndex)]) : Float.NaN; + } + + @Override + public final float normalY(int vertexIndex) { + return hasNormal(vertexIndex) ? NormalHelper.unpackNormalY(data[normalIndex(vertexIndex)]) : Float.NaN; + } + + @Override + public final float normalZ(int vertexIndex) { + return hasNormal(vertexIndex) ? NormalHelper.unpackNormalZ(data[normalIndex(vertexIndex)]) : Float.NaN; + } + + @Override + @Nullable + public final 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 + @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 + @Nullable + public final Direction cullFace() { + return EncodingFormat.cullFace(data[baseIndex + HEADER_BITS]); + } + + @Override + @Nullable + public ChunkSectionLayer renderLayer() { + return EncodingFormat.renderLayer(data[baseIndex + HEADER_BITS]); + } + + @Override + public boolean emissive() { + return EncodingFormat.emissive(data[baseIndex + HEADER_BITS]); + } + + @Override + public boolean diffuseShade() { + return EncodingFormat.diffuseShade(data[baseIndex + HEADER_BITS]); + } + + @Override + public TriState ambientOcclusion() { + return EncodingFormat.ambientOcclusion(data[baseIndex + HEADER_BITS]); + } + + @Override + @Nullable + public ItemStackRenderState.FoilType glint() { + return EncodingFormat.glint(data[baseIndex + HEADER_BITS]); + } + + @Override + public ShadeMode shadeMode() { + return EncodingFormat.shadeMode(data[baseIndex + HEADER_BITS]); + } + + @Override + public final int tintIndex() { + return data[baseIndex + HEADER_TINT_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); + + int colorIndex = targetIndex + VERTEX_COLOR - HEADER_STRIDE; + + 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.tintIndex(); + } + + @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 index 9750c2f47..dd0cce20a 100644 --- 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 @@ -9,49 +9,65 @@ import net.minecraft.client.color.block.BlockColor; import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.renderer.ItemBlockRenderTypes; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.block.model.BlockModelPart; import net.minecraft.client.renderer.block.model.BlockStateModel; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.state.BlockState; 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.frapi.VulkanModRenderer; -import net.vulkanmod.render.chunk.build.light.LightPipeline; -import net.vulkanmod.render.chunk.build.light.data.QuadLightData; -import org.jetbrains.annotations.Nullable; 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.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.block.state.BlockState; +import net.vulkanmod.render.chunk.build.light.LightPipeline; +import net.vulkanmod.render.chunk.build.light.data.QuadLightData; +import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Predicate; import java.util.function.Supplier; public abstract class AbstractBlockRenderContext extends AbstractRenderContext { - private static final Renderer RENDERER = VulkanModRenderer.INSTANCE; - - protected final BlockColorRegistry blockColorRegistry; - - private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { - { - data = new int[EncodingFormat.TOTAL_STRIDE]; - clear(); - } - - @Override - public void emitDirectly() { - renderQuad(this); - } + private static final Renderer RENDERER = VulkanModRenderer.INSTANCE; + + protected final BlockColorRegistry blockColorRegistry; + protected final Object2ByteLinkedOpenHashMap occlusionCache = new Object2ByteLinkedOpenHashMap<>(2048, 0.25F) { + protected void rehash(int i) { + } + }; + protected final QuadLightData quadLightData = new QuadLightData(); + protected BlockState blockState; + protected BlockPos blockPos; + protected BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos(); + protected ChunkSectionLayer defaultLayer; + protected BlockAndTintGetter renderRegion; + protected LightPipeline smoothLightPipeline; + protected LightPipeline flatLightPipeline; + protected boolean useAO; + protected boolean defaultAO; + protected RandomSource random; + protected boolean enableCulling = true; + protected int cullCompletionFlags; + protected int cullResultFlags; + private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { + { + data = new int[EncodingFormat.TOTAL_STRIDE]; + clear(); + } + + @Override + public void emitDirectly() { + renderQuad(this); + } // @Override // public void emitBlockQuads(QuadEmitter emitter, BakedModel model, BlockState state, @@ -62,234 +78,210 @@ public void emitDirectly() { // AbstractBlockRenderContext.this.emitVanillaBlockQuads(model, state, randomSupplier, cullTest); // } // } - }; - - protected BlockState blockState; - protected BlockPos blockPos; - protected BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos(); - protected ChunkSectionLayer defaultLayer; - - protected BlockAndTintGetter renderRegion; + }; - protected final Object2ByteLinkedOpenHashMap occlusionCache = new Object2ByteLinkedOpenHashMap<>(2048, 0.25F) { - protected void rehash(int i) { - } - }; + protected AbstractBlockRenderContext() { + this.occlusionCache.defaultReturnValue((byte) 127); - protected final QuadLightData quadLightData = new QuadLightData(); - protected LightPipeline smoothLightPipeline; - protected LightPipeline flatLightPipeline; + BlockColors blockColors = Minecraft.getInstance().getBlockColors(); + this.blockColorRegistry = BlockColorsExtended.from(blockColors).getColorResolverMap(); + } - protected boolean useAO; - protected boolean defaultAO; + protected void setupLightPipelines(LightPipeline flatLightPipeline, LightPipeline smoothLightPipeline) { + this.flatLightPipeline = flatLightPipeline; + this.smoothLightPipeline = smoothLightPipeline; + } - protected RandomSource random; + public void prepareForWorld(BlockAndTintGetter blockView, boolean enableCulling) { + this.renderRegion = blockView; + this.enableCulling = enableCulling; + } - protected boolean enableCulling = true; - protected int cullCompletionFlags; - protected int cullResultFlags; + public void prepareForBlock(BlockState blockState, BlockPos blockPos, boolean modelAo) { + this.blockPos = blockPos; + this.blockState = blockState; + this.defaultLayer = ItemBlockRenderTypes.getChunkRenderType(blockState); - protected AbstractBlockRenderContext() { - this.occlusionCache.defaultReturnValue((byte) 127); + this.useAO = Minecraft.useAmbientOcclusion(); + this.defaultAO = this.useAO && modelAo && blockState.getLightEmission() == 0; - BlockColors blockColors = Minecraft.getInstance().getBlockColors(); - this.blockColorRegistry = BlockColorsExtended.from(blockColors).getColorResolverMap(); - } + this.cullCompletionFlags = 0; + this.cullResultFlags = 0; + } - protected void setupLightPipelines(LightPipeline flatLightPipeline, LightPipeline smoothLightPipeline) { - this.flatLightPipeline = flatLightPipeline; - this.smoothLightPipeline = smoothLightPipeline; - } + public boolean isFaceCulled(@Nullable Direction face) { + return !this.shouldRenderFace(face); + } - public void prepareForWorld(BlockAndTintGetter blockView, boolean enableCulling) { - this.renderRegion = blockView; - this.enableCulling = enableCulling; - } + public boolean shouldRenderFace(Direction face) { + if (face == null || !enableCulling) { + return true; + } - public void prepareForBlock(BlockState blockState, BlockPos blockPos, boolean modelAo) { - this.blockPos = blockPos; - this.blockState = blockState; - this.defaultLayer = ItemBlockRenderTypes.getChunkRenderType(blockState); + final int mask = 1 << face.get3DDataValue(); - this.useAO = Minecraft.useAmbientOcclusion(); - this.defaultAO = this.useAO && modelAo && blockState.getLightEmission() == 0; + if ((cullCompletionFlags & mask) == 0) { + cullCompletionFlags |= mask; - this.cullCompletionFlags = 0; - this.cullResultFlags = 0; - } + if (this.faceNotOccluded(blockState, face)) { + cullResultFlags |= mask; + return true; + } else { + return false; + } + } else { + return (cullResultFlags & mask) != 0; + } + } - public boolean isFaceCulled(@Nullable Direction face) { - return !this.shouldRenderFace(face); - } + public boolean faceNotOccluded(BlockState blockState, Direction face) { + BlockGetter blockGetter = this.renderRegion; - public boolean shouldRenderFace(Direction face) { - if (face == null || !enableCulling) { - return true; - } + BlockPos adjPos = tempPos.setWithOffset(blockPos, face); + BlockState adjBlockState = blockGetter.getBlockState(adjPos); - final int mask = 1 << face.get3DDataValue(); + if (blockState.skipRendering(adjBlockState, face)) { + return false; + } - if ((cullCompletionFlags & mask) == 0) { - cullCompletionFlags |= mask; + if (adjBlockState.canOcclude()) { + VoxelShape shape = blockState.getFaceOcclusionShape(face); - if (this.faceNotOccluded(blockState, face)) { - cullResultFlags |= mask; - return true; - } else { - return false; - } - } else { - return (cullResultFlags & mask) != 0; - } - } + if (shape.isEmpty()) + return true; - public boolean faceNotOccluded(BlockState blockState, Direction face) { - BlockGetter blockGetter = this.renderRegion; + VoxelShape adjShape = adjBlockState.getFaceOcclusionShape(face.getOpposite()); - BlockPos adjPos = tempPos.setWithOffset(blockPos, face); - BlockState adjBlockState = blockGetter.getBlockState(adjPos); + if (adjShape.isEmpty()) + return true; - if (blockState.skipRendering(adjBlockState, face)) { - return false; - } + if (shape == Shapes.block() && adjShape == Shapes.block()) { + return false; + } - if (adjBlockState.canOcclude()) { - VoxelShape shape = blockState.getFaceOcclusionShape(face); + ShapePairKey blockStatePairKey = new ShapePairKey(shape, adjShape); - if (shape.isEmpty()) - return true; + byte b = occlusionCache.getAndMoveToFirst(blockStatePairKey); + if (b != 127) { + return b != 0; + } else { + boolean bl = Shapes.joinIsNotEmpty(shape, adjShape, BooleanOp.ONLY_FIRST); - VoxelShape adjShape = adjBlockState.getFaceOcclusionShape(face.getOpposite()); + if (occlusionCache.size() == 2048) { + occlusionCache.removeLastByte(); + } - if (adjShape.isEmpty()) - return true; + occlusionCache.putAndMoveToFirst(blockStatePairKey, (byte) (bl ? 1 : 0)); + return bl; + } + } - if (shape == Shapes.block() && adjShape == Shapes.block()) { - return false; - } + return true; + } - ShapePairKey blockStatePairKey = new ShapePairKey(shape, adjShape); + public QuadEmitter getEmitter() { + editorQuad.clear(); + return editorQuad; + } - byte b = occlusionCache.getAndMoveToFirst(blockStatePairKey); - if (b != 127) { - return b != 0; - } else { - boolean bl = Shapes.joinIsNotEmpty(shape, adjShape, BooleanOp.ONLY_FIRST); + @Override + protected void bufferQuad(MutableQuadViewImpl quadView) { + this.renderQuad(quadView); + } - if (occlusionCache.size() == 2048) { - occlusionCache.removeLastByte(); - } + protected abstract VertexConsumer getVertexConsumer(ChunkSectionLayer layer); - occlusionCache.putAndMoveToFirst(blockStatePairKey, (byte) (bl ? 1 : 0)); - return bl; - } - } + private void renderQuad(MutableQuadViewImpl quad) { + if (isFaceCulled(quad.cullFace())) { + return; + } - return true; - } + endRenderQuad(quad); + } - public QuadEmitter getEmitter() { - editorQuad.clear(); - return editorQuad; - } + protected void endRenderQuad(MutableQuadViewImpl quad) { + } - @Override - protected void bufferQuad(MutableQuadViewImpl quadView) { - this.renderQuad(quadView); - } + /** + * handles block color, common to all renders. + */ + protected void tintQuad(MutableQuadViewImpl quad) { + int tintIndex = quad.tintIndex(); - protected abstract VertexConsumer getVertexConsumer(ChunkSectionLayer layer); + if (tintIndex != -1) { + final int blockColor = getBlockColor(this.renderRegion, tintIndex); - private void renderQuad(MutableQuadViewImpl quad) { - if (isFaceCulled(quad.cullFace())) { - return; - } + for (int i = 0; i < 4; i++) { + quad.color(i, ColorHelper.multiplyColor(blockColor, quad.color(i))); + } + } + } - endRenderQuad(quad); - } + private int getBlockColor(BlockAndTintGetter region, int colorIndex) { + BlockColor blockColor = this.blockColorRegistry.getBlockColor(this.blockState.getBlock()); - protected void endRenderQuad(MutableQuadViewImpl quad) {} + int color = blockColor != null ? blockColor.getColor(blockState, region, blockPos, colorIndex) : -1; + return 0xFF000000 | color; + } - /** handles block color, common to all renders. */ - protected void tintQuad(MutableQuadViewImpl quad) { - int tintIndex = quad.tintIndex(); + protected void shadeQuad(MutableQuadViewImpl quad, LightPipeline lightPipeline, boolean emissive, boolean vanillaShade) { + QuadLightData data = this.quadLightData; - if (tintIndex != -1) { - final int blockColor = getBlockColor(this.renderRegion, tintIndex); + // TODO: enhanced AO + lightPipeline.calculate(quad, this.blockPos, data, quad.cullFace(), quad.lightFace(), quad.diffuseShade()); - 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.diffuseShade()); - - if (emissive) { - for (int i = 0; i < 4; i++) { - quad.color(i, ColorHelper.multiplyRGB(quad.color(i), data.br[i])); + 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); - data.lm[i] = LightTexture.FULL_BRIGHT; - } - } else { - for (int i = 0; i < 4; i++) { - quad.color(i, ColorHelper.multiplyRGB(quad.color(i), data.br[i])); + data.lm[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])); - data.lm[i] = ColorHelper.maxBrightness(quad.lightmap(i), data.lm[i]); - } - } - } + data.lm[i] = ColorHelper.maxBrightness(quad.lightmap(i), data.lm[i]); + } + } + } - public ChunkSectionLayer effectiveRenderLayer(@Nullable ChunkSectionLayer quadRenderLayer) { - return quadRenderLayer == null ? defaultLayer : quadRenderLayer; - } + public ChunkSectionLayer effectiveRenderLayer(@Nullable ChunkSectionLayer quadRenderLayer) { + return quadRenderLayer == null ? defaultLayer : quadRenderLayer; + } - public void emitVanillaBlockQuads(BlockStateModel model, @Nullable BlockState state, Supplier randomSupplier, Predicate cullTest) { - MutableQuadViewImpl quad = this.editorQuad; + public void emitVanillaBlockQuads(BlockStateModel model, @Nullable BlockState state, Supplier randomSupplier, Predicate cullTest) { + MutableQuadViewImpl quad = this.editorQuad; // final RenderMaterial defaultMaterial = state.getLightEmission() == 0 ? STANDARD_MATERIAL : NO_AO_MATERIAL; - for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) { - final Direction cullFace = ModelHelper.faceFromIndex(i); - - if (cullTest.test(cullFace)) { - // Skip entire quad list if possible. - continue; - } + for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) { + final Direction cullFace = ModelHelper.faceFromIndex(i); - final List parts = ((BlockStateModel) this).collectParts(random); - final int partCount = parts.size(); + if (cullTest.test(cullFace)) { + // Skip entire quad list if possible. + continue; + } - for (int j = 0; j < partCount; j++) { - parts.get(j).emitQuads(quad, cullTest); - } - } + final List parts = ((BlockStateModel) this).collectParts(random); + final int partCount = parts.size(); - } + for (int j = 0; j < partCount; j++) { + parts.get(j).emitQuads(quad, cullTest); + } + } - // TODO move elsewhere - record ShapePairKey(VoxelShape first, VoxelShape second) { - public boolean equals(Object object) { - if (object instanceof ShapePairKey shapePairKey && this.first == shapePairKey.first && this.second == shapePairKey.second) { - return true; - } + } - return false; - } + // TODO move elsewhere + record ShapePairKey(VoxelShape first, VoxelShape second) { + public boolean equals(Object object) { + return object instanceof ShapePairKey( + VoxelShape first1, VoxelShape second1 + ) && this.first == first1 && this.second == second1; + } - public int hashCode() { - return System.identityHashCode(this.first) * 31 + System.identityHashCode(this.second); - } - } + public int hashCode() { + return System.identityHashCode(this.first) * 31 + System.identityHashCode(this.second); + } + } } 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 index d98321876..126e0641e 100644 --- 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 @@ -21,62 +21,63 @@ import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat; import net.vulkanmod.render.chunk.build.frapi.mesh.MutableQuadViewImpl; -import org.joml.Matrix3f; import org.joml.Matrix4f; import org.joml.Vector3f; import org.joml.Vector4f; public abstract class AbstractRenderContext { - private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { - { - data = new int[EncodingFormat.TOTAL_STRIDE]; - clear(); - } + private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { + { + data = new int[EncodingFormat.TOTAL_STRIDE]; + clear(); + } - @Override - protected void emitDirectly() { - bufferQuad(this); - } - }; + @Override + protected void emitDirectly() { + bufferQuad(this); + } + }; - private final Vector4f posVec = new Vector4f(); - private final Vector3f normalVec = new Vector3f(); + private final Vector4f posVec = new Vector4f(); + private final Vector3f normalVec = new Vector3f(); - protected PoseStack.Pose matrices; - protected int overlay; + protected PoseStack.Pose matrices; + protected int overlay; - protected QuadEmitter getEmitter() { - editorQuad.clear(); - return editorQuad; - } + protected QuadEmitter getEmitter() { + editorQuad.clear(); + return editorQuad; + } - protected abstract void bufferQuad(MutableQuadViewImpl quadView); + protected abstract void bufferQuad(MutableQuadViewImpl quadView); - /** 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 PoseStack.Pose matrices = this.matrices; - final Matrix4f posMatrix = matrices.pose(); - final boolean useNormals = quad.hasVertexNormals(); + /** + * 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 PoseStack.Pose matrices = this.matrices; + final Matrix4f posMatrix = matrices.pose(); + final boolean useNormals = quad.hasVertexNormals(); - if (useNormals) { - quad.populateMissingNormals(); - } else { - matrices.transformNormal(quad.faceNormal(), normalVec); - } + if (useNormals) { + quad.populateMissingNormals(); + } else { + matrices.transformNormal(quad.faceNormal(), normalVec); + } - for (int i = 0; i < 4; i++) { - posVec.set(quad.x(i), quad.y(i), quad.z(i), 1.0f); - posVec.mul(posMatrix); + for (int i = 0; i < 4; i++) { + posVec.set(quad.x(i), quad.y(i), quad.z(i), 1.0f); + posVec.mul(posMatrix); - if (useNormals) { - quad.copyNormal(i, normalVec); - matrices.transformNormal(normalVec, normalVec); - } + if (useNormals) { + quad.copyNormal(i, normalVec); + matrices.transformNormal(normalVec, normalVec); + } - vertexConsumer.addVertex(posVec.x(), posVec.y(), posVec.z(), quad.color(i), quad.u(i), quad.v(i), overlay, quad.lightmap(i), normalVec.x(), normalVec.y(), normalVec.z()); - } - } + vertexConsumer.addVertex(posVec.x(), posVec.y(), posVec.z(), quad.color(i), quad.u(i), quad.v(i), overlay, quad.lightmap(i), normalVec.x(), normalVec.y(), normalVec.z()); + } + } } \ No newline at end of file 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 index 872671b4b..a63ec22ba 100644 --- 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 @@ -26,76 +26,73 @@ * Context for non-terrain block rendering. */ public class BlockRenderContext extends AbstractBlockRenderContext { - public static final ThreadLocal POOL = ThreadLocal.withInitial(BlockRenderContext::new); - - private BlockVertexConsumerProvider vertexConsumers; + public static final ThreadLocal POOL = ThreadLocal.withInitial(BlockRenderContext::new); + private final ArrayLightDataCache lightDataCache = new ArrayLightDataCache(); + private BlockVertexConsumerProvider vertexConsumers; private ChunkSectionLayer defaultRenderLayer; - private final ArrayLightDataCache lightDataCache = new ArrayLightDataCache(); - - public BlockRenderContext() { - LightPipeline flatLightPipeline = new FlatLightPipeline(this.lightDataCache); + 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); - } + LightPipeline smoothLightPipeline; + if (Initializer.CONFIG.ambientOcclusion == LightMode.SUB_BLOCK) { + smoothLightPipeline = new NewSmoothLightPipeline(lightDataCache); + } else { + smoothLightPipeline = new SmoothLightPipeline(lightDataCache); + } - this.setupLightPipelines(flatLightPipeline, smoothLightPipeline); + this.setupLightPipelines(flatLightPipeline, smoothLightPipeline); - random = RandomSource.create(); + random = RandomSource.create(); } - public void render(BlockAndTintGetter blockView, BlockStateModel model, BlockState state, BlockPos pos, PoseStack matrixStack, BlockVertexConsumerProvider buffers, boolean cull, long seed, int overlay) { - Vec3 offset = state.getOffset(pos); - matrixStack.translate(offset.x, offset.y, offset.z); + public void render(BlockAndTintGetter blockView, BlockStateModel model, BlockState state, BlockPos pos, PoseStack matrixStack, BlockVertexConsumerProvider buffers, boolean cull, long seed, int overlay) { + Vec3 offset = state.getOffset(pos); + matrixStack.translate(offset.x, offset.y, offset.z); - this.blockPos = pos; - this.vertexConsumers = buffers; + this.blockPos = pos; + this.vertexConsumers = buffers; this.defaultRenderLayer = ItemBlockRenderTypes.getChunkRenderType(state); - this.matrices = matrixStack.last(); - this.overlay = overlay; - this.random.setSeed(seed); + this.matrices = matrixStack.last(); + this.overlay = overlay; + this.random.setSeed(seed); - this.lightDataCache.reset(blockView, pos); + this.lightDataCache.reset(blockView, pos); - this.prepareForWorld(blockView, cull); - this.prepareForBlock(state, pos, state.getLightEmission() == 0); + this.prepareForWorld(blockView, cull); + this.prepareForBlock(state, pos, state.getLightEmission() == 0); - model.emitQuads(getEmitter(), blockView, pos, state, random, this::isFaceCulled); + model.emitQuads(getEmitter(), blockView, pos, state, random, this::isFaceCulled); - this.vertexConsumers = null; - } + this.vertexConsumers = null; + } - @Override - protected VertexConsumer getVertexConsumer(ChunkSectionLayer layer) { - return vertexConsumers.getBuffer(layer); - } + @Override + protected VertexConsumer getVertexConsumer(ChunkSectionLayer layer) { + return vertexConsumers.getBuffer(layer); + } - protected void endRenderQuad(MutableQuadViewImpl quad) { - final TriState aoMode = quad.ambientOcclusion(); - final boolean ao = this.useAO && (aoMode == TriState.TRUE || (aoMode == TriState.DEFAULT && this.defaultAO)); - final boolean emissive = quad.emissive(); - final boolean vanillaShade = quad.shadeMode() == ShadeMode.VANILLA; + protected void endRenderQuad(MutableQuadViewImpl quad) { + final TriState aoMode = quad.ambientOcclusion(); + final boolean ao = this.useAO && (aoMode == TriState.TRUE || (aoMode == TriState.DEFAULT && this.defaultAO)); + final boolean emissive = quad.emissive(); + final boolean vanillaShade = quad.shadeMode() == ShadeMode.VANILLA; final ChunkSectionLayer quadRenderLayer = quad.renderLayer(); final ChunkSectionLayer renderLayer = quadRenderLayer == null ? defaultRenderLayer : quadRenderLayer; - final VertexConsumer vertexConsumer = getVertexConsumer(renderLayer); + final VertexConsumer vertexConsumer = getVertexConsumer(renderLayer); - LightPipeline lightPipeline = ao ? this.smoothLightPipeline : this.flatLightPipeline; + LightPipeline lightPipeline = ao ? this.smoothLightPipeline : this.flatLightPipeline; - tintQuad(quad); - shadeQuad(quad, lightPipeline, emissive, vanillaShade); - copyLightData(quad); + tintQuad(quad); + shadeQuad(quad, lightPipeline, emissive, vanillaShade); + copyLightData(quad); bufferQuad(quad, vertexConsumer); - } + } - private void copyLightData(MutableQuadViewImpl quad) { + private void copyLightData(MutableQuadViewImpl quad) { for (int i = 0; i < 4; i++) { - quad.lightmap(i, this.quadLightData.lm[i]); - } - } + quad.lightmap(i, this.quadLightData.lm[i]); + } + } } 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 index 3448ad0a9..120314ca2 100644 --- 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 @@ -3,71 +3,65 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.MatrixUtil; - -import java.util.Arrays; -import java.util.List; -import java.util.function.Supplier; - import net.fabricmc.fabric.api.renderer.v1.mesh.MeshView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.render.FabricLayerRenderState; import net.fabricmc.fabric.api.renderer.v1.render.RenderLayerHelper; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.chunk.ChunkSectionLayer; -import net.minecraft.client.renderer.item.ItemStackRenderState; -import net.vulkanmod.mixin.render.frapi.ItemRendererAccessor; 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.block.model.BakedQuad; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.util.RandomSource; +import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.world.item.ItemDisplayContext; +import net.vulkanmod.mixin.render.frapi.ItemRendererAccessor; import net.vulkanmod.render.chunk.build.frapi.helper.ColorHelper; import net.vulkanmod.render.chunk.build.frapi.mesh.MutableQuadViewImpl; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; +import java.util.List; + /** * Used during item buffering to support geometry added through {@link FabricLayerRenderState#emitter()}. */ public class ItemRenderContext extends AbstractRenderContext { - private static final int GLINT_COUNT = ItemStackRenderState.FoilType.values().length; - - private ItemDisplayContext itemDisplayContext; - private PoseStack matrixStack; - private MultiBufferSource vertexConsumerProvider; - private int lightmap; - private int[] tints; - - private RenderType defaultLayer; - private ItemStackRenderState.FoilType defaultGlint; + private static final int GLINT_COUNT = ItemStackRenderState.FoilType.values().length; + private final VertexConsumer[] vertexConsumerCache = new VertexConsumer[3 * GLINT_COUNT]; + private ItemDisplayContext itemDisplayContext; + private PoseStack matrixStack; + private MultiBufferSource vertexConsumerProvider; + private int lightmap; + private int[] tints; + private RenderType defaultLayer; + private ItemStackRenderState.FoilType defaultGlint; private boolean ignoreQuadGlint; - - private PoseStack.Pose specialGlintEntry; - private final VertexConsumer[] vertexConsumerCache = new VertexConsumer[3 * GLINT_COUNT]; - - public void renderModel(ItemDisplayContext itemDisplayContext, PoseStack matrixStack, MultiBufferSource bufferSource, int lightmap, int overlay, int[] tints, List modelQuads, MeshView mesh, RenderType renderType, ItemStackRenderState.FoilType foilType, boolean ignoreQuadGlint) { - this.itemDisplayContext = itemDisplayContext; - this.matrixStack = matrixStack; - this.vertexConsumerProvider = bufferSource; - this.lightmap = lightmap; - this.overlay = overlay; - this.tints = tints; - - defaultLayer = renderType; - defaultGlint = foilType; + private PoseStack.Pose specialGlintEntry; + + public void renderModel(ItemDisplayContext itemDisplayContext, PoseStack matrixStack, MultiBufferSource bufferSource, int lightmap, int overlay, int[] tints, List modelQuads, MeshView mesh, RenderType renderType, ItemStackRenderState.FoilType foilType, boolean ignoreQuadGlint) { + this.itemDisplayContext = itemDisplayContext; + this.matrixStack = matrixStack; + this.vertexConsumerProvider = bufferSource; + this.lightmap = lightmap; + this.overlay = overlay; + this.tints = tints; + + defaultLayer = renderType; + defaultGlint = foilType; this.ignoreQuadGlint = ignoreQuadGlint; - bufferQuads(modelQuads, mesh); + bufferQuads(modelQuads, mesh); - this.matrixStack = null; - this.vertexConsumerProvider = null; - this.tints = null; + this.matrixStack = null; + this.vertexConsumerProvider = null; + this.tints = null; - specialGlintEntry = null; - Arrays.fill(vertexConsumerCache, null); - } + specialGlintEntry = null; + Arrays.fill(vertexConsumerCache, null); + } private void bufferQuads(List vanillaQuads, MeshView mesh) { QuadEmitter emitter = getEmitter(); @@ -83,40 +77,40 @@ private void bufferQuads(List vanillaQuads, MeshView mesh) { mesh.outputTo(emitter); } - @Override - protected void bufferQuad(MutableQuadViewImpl quad) { + @Override + protected void bufferQuad(MutableQuadViewImpl quad) { final VertexConsumer vertexConsumer = getVertexConsumer(quad.renderLayer(), quad.glint()); tintQuad(quad); shadeQuad(quad, quad.emissive()); bufferQuad(quad, vertexConsumer); - } - - private void tintQuad(MutableQuadViewImpl quad) { - int tintIndex = quad.tintIndex(); - - if (tintIndex != -1 && tintIndex < tints.length) { - final int tint = tints[tintIndex]; - - for (int i = 0; i < 4; i++) { - quad.color(i, ColorHelper.multiplyColor(tint, 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)); - } - } - } + } + + private void tintQuad(MutableQuadViewImpl quad) { + int tintIndex = quad.tintIndex(); + + if (tintIndex != -1 && tintIndex < tints.length) { + final int tint = tints[tintIndex]; + + for (int i = 0; i < 4; i++) { + quad.color(i, ColorHelper.multiplyColor(tint, 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)); + } + } + } private VertexConsumer getVertexConsumer(@Nullable ChunkSectionLayer quadRenderLayer, @Nullable ItemStackRenderState.FoilType quadGlint) { RenderType layer; @@ -155,22 +149,22 @@ private VertexConsumer getVertexConsumer(@Nullable ChunkSectionLayer quadRenderL return vertexConsumer; } - private VertexConsumer createVertexConsumer(RenderType layer, ItemStackRenderState.FoilType glint) { - if (glint == ItemStackRenderState.FoilType.SPECIAL) { - if (specialGlintEntry == null) { - specialGlintEntry = matrixStack.last().copy(); + private VertexConsumer createVertexConsumer(RenderType layer, ItemStackRenderState.FoilType glint) { + if (glint == ItemStackRenderState.FoilType.SPECIAL) { + if (specialGlintEntry == null) { + specialGlintEntry = matrixStack.last().copy(); - if (itemDisplayContext == ItemDisplayContext.GUI) { - MatrixUtil.mulComponentWise(specialGlintEntry.pose(), 0.5F); - } else if (itemDisplayContext.firstPerson()) { - MatrixUtil.mulComponentWise(specialGlintEntry.pose(), 0.75F); - } - } + if (itemDisplayContext == ItemDisplayContext.GUI) { + MatrixUtil.mulComponentWise(specialGlintEntry.pose(), 0.5F); + } else if (itemDisplayContext.firstPerson()) { + MatrixUtil.mulComponentWise(specialGlintEntry.pose(), 0.75F); + } + } - return ItemRendererAccessor.getSpecialFoilBuffer(vertexConsumerProvider, layer, specialGlintEntry); - } + return ItemRendererAccessor.getSpecialFoilBuffer(vertexConsumerProvider, layer, specialGlintEntry); + } - return ItemRenderer.getFoilBuffer(vertexConsumerProvider, layer, true, glint != ItemStackRenderState.FoilType.NONE); - } + return ItemRenderer.getFoilBuffer(vertexConsumerProvider, layer, true, glint != ItemStackRenderState.FoilType.NONE); + } } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/MeshItemCommand.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/MeshItemCommand.java index 52acc30b1..0618c7854 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/MeshItemCommand.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/MeshItemCommand.java @@ -1,12 +1,15 @@ package net.vulkanmod.render.chunk.build.frapi.render; import com.mojang.blaze3d.vertex.PoseStack; -import java.util.List; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshView; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.world.item.ItemDisplayContext; -public record MeshItemCommand(PoseStack.Pose positionMatrix, ItemDisplayContext displayContext, int lightCoords, int overlayCoords, int outlineColor, int[] tintLayers, List quads, RenderType renderLayer, ItemStackRenderState.FoilType glintType, MeshView mesh) { +import java.util.List; + +public record MeshItemCommand(PoseStack.Pose positionMatrix, ItemDisplayContext displayContext, int lightCoords, + int overlayCoords, int outlineColor, int[] tintLayers, List quads, + RenderType renderLayer, ItemStackRenderState.FoilType glintType, MeshView mesh) { } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/SimpleBlockRenderContext.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/SimpleBlockRenderContext.java index 275738cfb..4a1f61a08 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/SimpleBlockRenderContext.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/SimpleBlockRenderContext.java @@ -20,8 +20,6 @@ import net.fabricmc.fabric.api.renderer.v1.render.BlockVertexConsumerProvider; 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.block.model.BlockStateModel; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.core.BlockPos; 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 69d3c184e..f7fd90abe 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,22 +2,23 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.vulkanmod.render.model.quad.ModelQuadView; import net.vulkanmod.render.chunk.build.light.data.QuadLightData; +import net.vulkanmod.render.model.quad.ModelQuadView; /** * Light pipelines allow model quads for any location in the world to be lit using various backends, including fluids - * and block entities. + * and block entities. */ public interface LightPipeline { /** * Calculates the light data for a given block model quad, storing the result in {@param out}. - * @param quad The block model quad - * @param pos The block position of the model this quad belongs to - * @param out The data arrays which will store the calculated light data results - * @param cullFace The cull face of the quad + * + * @param quad The block model quad + * @param pos The block position of the model this quad belongs to + * @param out The data arrays which will store the calculated light data results + * @param cullFace The cull face of the quad * @param lightFace The light face of the quad - * @param shade True if the block is shaded by ambient occlusion + * @param shade True if the block is shaded by ambient occlusion */ 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/LightDataAccess.java b/src/main/java/net/vulkanmod/render/chunk/build/light/data/LightDataAccess.java index d2e532738..d662ff735 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 @@ -42,100 +42,14 @@ public abstract class LightDataAccess { private static final int FC_OFFSET = 31; private static final float AO_INV = 1.0f / 2048.0f; - + final boolean subBlockLighting; private final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); protected BlockAndTintGetter region; - final boolean subBlockLighting; - protected LightDataAccess() { this.subBlockLighting = Initializer.CONFIG.ambientOcclusion == LightMode.SUB_BLOCK; } - 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()); - } - - public int get(int x, int y, int z, SimpleDirection dir) { - return this.get(x + dir.getStepX(), - y + dir.getStepY(), - z + dir.getStepZ()); - } - - public int get(BlockPos pos, SimpleDirection dir) { - return this.get(pos.getX(), pos.getY(), pos.getZ(), dir); - } - - public int get(BlockPos pos) { - return this.get(pos.getX(), pos.getY(), pos.getZ()); - } - - /** - * Returns the light data for the block at the given position. The property fields can then be accessed using - * the various unpack methods below. - */ - public abstract int get(int x, int y, int z); - - protected int compute(int x, int y, int z) { - BlockPos pos = this.pos.set(x, y, z); - BlockState state = region.getBlockState(pos); - - boolean em = state.emissiveRendering(region, pos); - - boolean op; - if (this.subBlockLighting) - op = state.canOcclude(); - else - op = state.isViewBlocking(region, pos) && state.getLightBlock() != 0; - - boolean fo = state.isSolidRender(); - boolean fc = state.isCollisionShapeFullBlock(region, pos); - - int lu = state.getLightEmission(); - - // OPTIMIZE: Do not calculate light data if the block is full and opaque and does not emit light. - int bl; - int sl; - if (fo && lu == 0) { - bl = 0; - sl = 0; - } - else { - if (em) { - bl = region.getBrightness(LightLayer.BLOCK, pos); - sl = region.getBrightness(LightLayer.SKY, pos); - } - else { - int light = LevelRenderer.getLightColor(LevelRenderer.BrightnessGetter.DEFAULT, 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(region, pos); - } - else { - ao = 1.0f; - } - - boolean useAo = ao < 1.0f; - - bl = Math.max(bl, lu); - - int crs = (fo || fc) && lu == 0 && useAo ? 0xFF : 0; - 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); - } - public static int packBL(int blockLight) { return (blockLight & 0xF) << BL_OFFSET; } @@ -222,6 +136,87 @@ public static int getEmissiveLightmap(int word) { } } + 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()); + } + + public int get(int x, int y, int z, SimpleDirection dir) { + return this.get(x + dir.getStepX(), + y + dir.getStepY(), + z + dir.getStepZ()); + } + + public int get(BlockPos pos, SimpleDirection dir) { + return this.get(pos.getX(), pos.getY(), pos.getZ(), dir); + } + + public int get(BlockPos pos) { + return this.get(pos.getX(), pos.getY(), pos.getZ()); + } + + /** + * Returns the light data for the block at the given position. The property fields can then be accessed using + * the various unpack methods below. + */ + public abstract int get(int x, int y, int z); + + protected int compute(int x, int y, int z) { + BlockPos pos = this.pos.set(x, y, z); + BlockState state = region.getBlockState(pos); + + boolean em = state.emissiveRendering(region, pos); + + boolean op; + if (this.subBlockLighting) + op = state.canOcclude(); + else + op = state.isViewBlocking(region, pos) && state.getLightBlock() != 0; + + boolean fo = state.isSolidRender(); + boolean fc = state.isCollisionShapeFullBlock(region, pos); + + int lu = state.getLightEmission(); + + // OPTIMIZE: Do not calculate light data if the block is full and opaque and does not emit light. + int bl; + int sl; + if (fo && lu == 0) { + bl = 0; + sl = 0; + } else { + if (em) { + bl = region.getBrightness(LightLayer.BLOCK, pos); + sl = region.getBrightness(LightLayer.SKY, pos); + } else { + int light = LevelRenderer.getLightColor(LevelRenderer.BrightnessGetter.DEFAULT, 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(region, pos); + } else { + ao = 1.0f; + } + + boolean useAo = ao < 1.0f; + + bl = Math.max(bl, lu); + + int crs = (fo || fc) && lu == 0 && useAo ? 0xFF : 0; + 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); + } + public BlockAndTintGetter getRegion() { return this.region; } 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 b11f4e352..333c09f0f 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 @@ -3,12 +3,12 @@ import net.minecraft.client.renderer.LightTexture; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.vulkanmod.render.chunk.util.SimpleDirection; -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.LightDataAccess; import net.vulkanmod.render.chunk.build.light.data.QuadLightData; +import net.vulkanmod.render.chunk.util.SimpleDirection; import net.vulkanmod.render.model.quad.ModelQuadFlags; +import net.vulkanmod.render.model.quad.ModelQuadView; import java.util.Arrays; diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoFaceData.java b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoFaceData.java index d4be249f3..9d51ea902 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoFaceData.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoFaceData.java @@ -2,8 +2,8 @@ import net.minecraft.client.renderer.LightTexture; import net.minecraft.core.BlockPos; -import net.vulkanmod.render.chunk.util.SimpleDirection; import net.vulkanmod.render.chunk.build.light.data.LightDataAccess; +import net.vulkanmod.render.chunk.util.SimpleDirection; import static net.vulkanmod.render.chunk.build.light.data.LightDataAccess.*; @@ -16,6 +16,65 @@ class AoFaceData { protected int flags; + static float weightedSum(float[] v, float[] w) { + float t0 = v[0] * w[0]; + float t1 = v[1] * w[1]; + float t2 = v[2] * w[2]; + float t3 = v[3] * w[3]; + + return t0 + t1 + t2 + t3; + } + + static float unpackSkyLight(int i) { + return (i >> 16) & 0xFF; + } + + static float unpackBlockLight(int i) { + return i & 0xFF; + } + + static int calculateCornerBrightness(int a, int b, int c, int d, boolean aem, boolean bem, boolean cem, boolean dem) { + // FIX: Normalize corner vectors correctly to the minimum non-zero value between each one to prevent + // strange issues + if ((a == 0) || (b == 0) || (c == 0) || (d == 0)) { + // Find the minimum value between all corners + final int min = minNonZero(minNonZero(a, b), minNonZero(c, d)); + + // Normalize the corner values + a = Math.max(a, min); + b = Math.max(b, min); + c = Math.max(c, min); + d = Math.max(d, min); + } + + // FIX: Apply the fullbright lightmap from emissive blocks at the very end so it cannot influence + // the minimum lightmap and produce incorrect results (for example, sculk sensors in a dark room) + if (aem) { + a = LightTexture.FULL_BRIGHT; + } + if (bem) { + b = LightTexture.FULL_BRIGHT; + } + if (cem) { + c = LightTexture.FULL_BRIGHT; + } + if (dem) { + d = LightTexture.FULL_BRIGHT; + } + + return ((a + b + c + d) >> 2) & 0xFF00FF; + } + + static int minNonZero(int a, int b) { + if (a == 0) { + return b; + } else if (b == 0) { + return a; + } + + return Math.min(a, b); + } + public void initLightData(LightDataAccess cache, BlockPos pos, SimpleDirection direction, boolean offset) { final int oX = pos.getX(); final int oY = pos.getY(); @@ -191,65 +250,6 @@ public float getBlendedShade(float[] w) { return weightedSum(this.ao, w); } - static float weightedSum(float[] v, float[] w) { - float t0 = v[0] * w[0]; - float t1 = v[1] * w[1]; - float t2 = v[2] * w[2]; - float t3 = v[3] * w[3]; - - return t0 + t1 + t2 + t3; - } - - static float unpackSkyLight(int i) { - return (i >> 16) & 0xFF; - } - - static float unpackBlockLight(int i) { - return i & 0xFF; - } - - static int calculateCornerBrightness(int a, int b, int c, int d, boolean aem, boolean bem, boolean cem, boolean dem) { - // FIX: Normalize corner vectors correctly to the minimum non-zero value between each one to prevent - // strange issues - if ((a == 0) || (b == 0) || (c == 0) || (d == 0)) { - // Find the minimum value between all corners - final int min = minNonZero(minNonZero(a, b), minNonZero(c, d)); - - // Normalize the corner values - a = Math.max(a, min); - b = Math.max(b, min); - c = Math.max(c, min); - d = Math.max(d, min); - } - - // FIX: Apply the fullbright lightmap from emissive blocks at the very end so it cannot influence - // the minimum lightmap and produce incorrect results (for example, sculk sensors in a dark room) - if (aem) { - a = LightTexture.FULL_BRIGHT; - } - if (bem) { - b = LightTexture.FULL_BRIGHT; - } - if (cem) { - c = LightTexture.FULL_BRIGHT; - } - if (dem) { - d = LightTexture.FULL_BRIGHT; - } - - return ((a + b + c + d) >> 2) & 0xFF00FF; - } - - static int minNonZero(int a, int b) { - if (a == 0) { - return b; - } else if (b == 0) { - return a; - } - - return Math.min(a, b); - } - public boolean hasLightData() { return (this.flags & FaceDataFlags.HAS_LIGHT_DATA) != 0; } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoNeighborInfo.java b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoNeighborInfo.java index c3ccad908..fe57819db 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoNeighborInfo.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoNeighborInfo.java @@ -8,10 +8,10 @@ */ @SuppressWarnings("UnnecessaryLocalVariable") enum AoNeighborInfo { - DOWN(new SimpleDirection[] { SimpleDirection.SOUTH, SimpleDirection.WEST, SimpleDirection.NORTH, SimpleDirection.EAST }, - new int[] {4, 5, 6, 7, - 0, 1, 2, 3}, - 0.5F) { + DOWN(new SimpleDirection[]{SimpleDirection.SOUTH, SimpleDirection.WEST, SimpleDirection.NORTH, SimpleDirection.EAST}, + new int[]{4, 5, 6, 7, + 0, 1, 2, 3}, + 0.5F) { @Override public void calculateCornerWeights(float x, float y, float z, float[] out) { final float u = 1.0f - x; @@ -35,10 +35,10 @@ public float getDepth(float x, float y, float z) { return y; } }, - UP(new SimpleDirection[] { SimpleDirection.NORTH, SimpleDirection.WEST, SimpleDirection.SOUTH, SimpleDirection.EAST }, - new int[] {2, 3, 0, 1, + UP(new SimpleDirection[]{SimpleDirection.NORTH, SimpleDirection.WEST, SimpleDirection.SOUTH, SimpleDirection.EAST}, + new int[]{2, 3, 0, 1, 6, 7, 4, 5}, - 1.0F) { + 1.0F) { @Override public void calculateCornerWeights(float x, float y, float z, float[] out) { final float u = 1.0f - x; @@ -62,8 +62,8 @@ public float getDepth(float x, float y, float z) { return 1.0f - y; } }, - NORTH(new SimpleDirection[] { SimpleDirection.UP, SimpleDirection.EAST, SimpleDirection.DOWN, SimpleDirection.WEST }, - new int[] {3, 2, 7, 6, + NORTH(new SimpleDirection[]{SimpleDirection.UP, SimpleDirection.EAST, SimpleDirection.DOWN, SimpleDirection.WEST}, + new int[]{3, 2, 7, 6, 1, 0, 5, 4}, 0.8F) { @Override @@ -89,8 +89,8 @@ public float getDepth(float x, float y, float z) { return z; } }, - SOUTH(new SimpleDirection[] { SimpleDirection.UP, SimpleDirection.WEST, SimpleDirection.DOWN, SimpleDirection.EAST }, - new int[] {0, 1, 4, 5, + SOUTH(new SimpleDirection[]{SimpleDirection.UP, SimpleDirection.WEST, SimpleDirection.DOWN, SimpleDirection.EAST}, + new int[]{0, 1, 4, 5, 2, 3, 6, 7}, 0.8F) { @Override @@ -116,8 +116,8 @@ public float getDepth(float x, float y, float z) { return 1.0f - z; } }, - WEST(new SimpleDirection[] { SimpleDirection.UP, SimpleDirection.NORTH, SimpleDirection.DOWN, SimpleDirection.SOUTH }, - new int[] {1, 3, 5, 7, + WEST(new SimpleDirection[]{SimpleDirection.UP, SimpleDirection.NORTH, SimpleDirection.DOWN, SimpleDirection.SOUTH}, + new int[]{1, 3, 5, 7, 0, 2, 4, 6}, 0.6F) { @Override @@ -143,8 +143,8 @@ public float getDepth(float x, float y, float z) { return x; } }, - EAST(new SimpleDirection[] { SimpleDirection.UP, SimpleDirection.SOUTH, SimpleDirection.DOWN, SimpleDirection.NORTH }, - new int[] {2, 0, 6, 4, + EAST(new SimpleDirection[]{SimpleDirection.UP, SimpleDirection.SOUTH, SimpleDirection.DOWN, SimpleDirection.NORTH}, + new int[]{2, 0, 6, 4, 3, 1, 7, 5}, 0.6F) { @Override @@ -171,23 +171,21 @@ public float getDepth(float x, float y, float z) { } }; + private static final AoNeighborInfo[] VALUES = AoNeighborInfo.values(); /** * The direction of each corner block from this face, which can be retrieved by offsetting the position of the origin * block by the direction vector. */ public final SimpleDirection[] faces; - /** * The constant brightness modifier for this face. This data exists to emulate the results of the OpenGL lighting * model which gives a faux directional light appearance to blocks in the game. Not currently used. */ public final float strength; - /** * The indexes of each inner corner occlusion bit for every model vertex. */ public final int[] inCornerBits = new int[4 * 2]; - /** * The indexes of each outer corner occlusion bit for every model vertex. */ @@ -201,55 +199,6 @@ public float getDepth(float x, float y, float z) { getOutCornerBits(this.outCornerBits, indices); } - /** - * Calculates how much each corner contributes to the final "darkening" of the vertex at the specified position. The - * weight is a function of the distance from the vertex's position to the corner block's position. - * - * @param x The x-position of the vertex - * @param y The y-position of the vertex - * @param z The z-position of the vertex - * @param out The weight values for each corner - */ - public abstract void calculateCornerWeights(float x, float y, float z, float[] out); - - public abstract float getU(float x, float y, float z); - - public abstract float getV(float x, float y, float z); - - /** - * Maps the light map and occlusion value arrays {@param lm0} and {@param ao0} from {@link AoFaceData} to the - * correct corners for this facing. - * - * @param lm0 The input light map texture coordinates array - * @param ao0 The input ambient occlusion color array - * @param lm1 The re-orientated output light map texture coordinates array - * @param ao1 The re-orientated output ambient occlusion color array - */ - public void copyLightValues(int[] lm0, float[] ao0, int[] lm1, float[] ao1) { - lm1[0] = lm0[0]; - lm1[1] = lm0[1]; - lm1[2] = lm0[2]; - lm1[3] = lm0[3]; - - ao1[0] = ao0[0]; - ao1[1] = ao0[1]; - ao1[2] = ao0[2]; - ao1[3] = ao0[3]; - } - - /** - * Calculates the depth (or inset) of the vertex into this facing of the block. Used to determine - * how much shadow is contributed by the direct neighbors of a block. - * - * @param x The x-position of the vertex - * @param y The y-position of the vertex - * @param z The z-position of the vertex - * @return The depth of the vertex into this face - */ - public abstract float getDepth(float x, float y, float z); - - private static final AoNeighborInfo[] VALUES = AoNeighborInfo.values(); - /** * @return Returns the {@link AoNeighborInfo} which corresponds with the specified direction */ @@ -303,7 +252,7 @@ private static void getOutCornerBits(int[] cornersBits, int[] idxs) { cornersBits[10] = idxs[1]; cornersBits[11] = idxs[0]; - cornersBits[12 + 0] = idxs[4 + 0]; + cornersBits[12] = idxs[4]; cornersBits[12 + 1] = idxs[4 + 3]; cornersBits[12 + 2] = idxs[4 + 1]; @@ -312,11 +261,58 @@ private static void getOutCornerBits(int[] cornersBits, int[] idxs) { cornersBits[12 + 5] = idxs[4 + 3]; cornersBits[12 + 6] = idxs[4 + 3]; - cornersBits[12 + 7] = idxs[4 + 0]; + cornersBits[12 + 7] = idxs[4]; cornersBits[12 + 8] = idxs[4 + 2]; cornersBits[12 + 9] = idxs[4 + 2]; cornersBits[12 + 10] = idxs[4 + 1]; - cornersBits[12 + 11] = idxs[4 + 0]; + cornersBits[12 + 11] = idxs[4]; + } + + /** + * Calculates how much each corner contributes to the final "darkening" of the vertex at the specified position. The + * weight is a function of the distance from the vertex's position to the corner block's position. + * + * @param x The x-position of the vertex + * @param y The y-position of the vertex + * @param z The z-position of the vertex + * @param out The weight values for each corner + */ + public abstract void calculateCornerWeights(float x, float y, float z, float[] out); + + public abstract float getU(float x, float y, float z); + + public abstract float getV(float x, float y, float z); + + /** + * Maps the light map and occlusion value arrays {@param lm0} and {@param ao0} from {@link AoFaceData} to the + * correct corners for this facing. + * + * @param lm0 The input light map texture coordinates array + * @param ao0 The input ambient occlusion color array + * @param lm1 The re-orientated output light map texture coordinates array + * @param ao1 The re-orientated output ambient occlusion color array + */ + public void copyLightValues(int[] lm0, float[] ao0, int[] lm1, float[] ao1) { + lm1[0] = lm0[0]; + lm1[1] = lm0[1]; + lm1[2] = lm0[2]; + lm1[3] = lm0[3]; + + ao1[0] = ao0[0]; + ao1[1] = ao0[1]; + ao1[2] = ao0[2]; + ao1[3] = ao0[3]; } + + /** + * Calculates the depth (or inset) of the vertex into this facing of the block. Used to determine + * how much shadow is contributed by the direct neighbors of a block. + * + * @param x The x-position of the vertex + * @param y The y-position of the vertex + * @param z The z-position of the vertex + * @return The depth of the vertex into this face + */ + public abstract float getDepth(float x, float y, float z); } 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 503d27ff9..81a876727 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 @@ -3,12 +3,12 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.Mth; -import net.vulkanmod.render.chunk.util.SimpleDirection; -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.LightDataAccess; import net.vulkanmod.render.chunk.build.light.data.QuadLightData; +import net.vulkanmod.render.chunk.util.SimpleDirection; import net.vulkanmod.render.model.quad.ModelQuadFlags; +import net.vulkanmod.render.model.quad.ModelQuadView; /** * A smooth light pipeline which introduces sub-block AO computations @@ -25,13 +25,11 @@ public class NewSmoothLightPipeline implements LightPipeline { * Face data to allow face self-occlusion computation. */ private final SubBlockAoFace self = new SubBlockAoFace(); - - private long cachedPos = Long.MIN_VALUE; - /** * A temporary array for storing the intermediary results of weight data for non-aligned face blending. */ private final float[] weights = new float[4]; + private long cachedPos = Long.MIN_VALUE; public NewSmoothLightPipeline(LightDataAccess cache) { this.lightCache = cache; @@ -41,6 +39,26 @@ public NewSmoothLightPipeline(LightDataAccess cache) { } } + /** + * Clamps the given float to the range [0.0, 1.0]. + */ + private static float clamp(float v) { + if (v < 0.0f) { + return 0.0f; + } else if (v > 1.0f) { + return 1.0f; + } + + return v; + } + + /** + * Returns texture coordinates for the light map texture using the given block and sky light values. + */ + private static int packLightMap(float sl, float bl) { + return (((int) sl & 0xFF) << 16) | ((int) bl & 0xFF); + } + @Override public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFaceO, boolean shade) { this.updateCachedData(pos.asLong()); @@ -260,24 +278,4 @@ private void updateCachedData(long key) { } } - /** - * Clamps the given float to the range [0.0, 1.0]. - */ - private static float clamp(float v) { - if (v < 0.0f) { - return 0.0f; - } else if (v > 1.0f) { - return 1.0f; - } - - return v; - } - - /** - * Returns texture coordinates for the light map texture using the given block and sky light values. - */ - private static int packLightMap(float sl, float bl) { - return (((int) sl & 0xFF) << 16) | ((int) bl & 0xFF); - } - } 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 154eb0518..d023fffce 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 @@ -3,39 +3,39 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.Mth; -import net.vulkanmod.render.chunk.util.SimpleDirection; -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.LightDataAccess; import net.vulkanmod.render.chunk.build.light.data.QuadLightData; +import net.vulkanmod.render.chunk.util.SimpleDirection; import net.vulkanmod.render.model.quad.ModelQuadFlags; +import net.vulkanmod.render.model.quad.ModelQuadView; /** * Re-adapted Sodium's smooth light pipeline - * + *

* A light pipeline which produces smooth interpolated lighting and ambient occlusion for model quads. This * implementation makes a number of improvements over vanilla's own "smooth lighting" option. In no particular order: - * + *

* - Corner blocks are now selected from the correct set of neighbors above block faces (fixes MC-148689 and MC-12558) * - Shading issues caused by anisotropy are fixed by re-orientating quads to a consistent ordering (fixes MC-138211) * - Inset block faces are correctly shaded by their neighbors, fixing a number of problems with non-full blocks such as - * grass paths (fixes MC-11783 and MC-108621) + * grass paths (fixes MC-11783 and MC-108621) * - Blocks next to emissive blocks are too bright (MC-260989) * - Synchronization issues between the main render thread's light engine and chunk build worker threads are corrected - * by copying light data alongside block states, fixing a number of inconsistencies in baked chunks (no open issue) - * + * by copying light data alongside block states, fixing a number of inconsistencies in baked chunks (no open issue) + *

* This implementation also includes a significant number of optimizations: - * + *

* - Computed light data for a given block face is cached and re-used again when multiple quads exist for a given - * facing, making complex block models less expensive to render + * facing, making complex block models less expensive to render * - The light data cache encodes as much information as possible into integer words to improve cache locality and - * to eliminate the multiple array lookups that would otherwise be needed, significantly speeding up this section + * to eliminate the multiple array lookups that would otherwise be needed, significantly speeding up this section * - Block faces aligned to the block grid use a fast-path for mapping corner light values to vertices without expensive - * interpolation or blending, speeding up most block renders + * interpolation or blending, speeding up most block renders * - Some critical code paths have been re-written to hit the JVM's happy path, allowing it to perform auto-vectorization - * of the blend functions + * of the blend functions * - Information about a given model quad is cached to enable the light pipeline to make certain assumptions and skip - * unnecessary computation + * unnecessary computation */ public class SmoothLightPipeline implements LightPipeline { /** @@ -47,16 +47,14 @@ public class SmoothLightPipeline implements LightPipeline { * The cached face data for each side of a block, both inner and outer. */ private final AoFaceData[] cachedFaceData = new AoFaceData[6 * 2]; - - /** - * The position at which the cached face data was taken at. - */ - private long cachedPos = Long.MIN_VALUE; - /** * A temporary array for storing the intermediary results of weight data for non-aligned face blending. */ private final float[] weights = new float[4]; + /** + * The position at which the cached face data was taken at. + */ + private long cachedPos = Long.MIN_VALUE; public SmoothLightPipeline(LightDataAccess cache) { this.lightCache = cache; @@ -66,6 +64,20 @@ public SmoothLightPipeline(LightDataAccess cache) { } } + private static float clamp(float v) { + if (v < 0.0f) { + return 0.0f; + } else if (v > 1.0f) { + return 1.0f; + } + + return v; + } + + private static int packLightMap(float sl, float bl) { + return (((int) sl & 0xFF) << 16) | ((int) bl & 0xFF); + } + @Override public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFaceO, boolean shade) { this.updateCachedData(pos.asLong()); @@ -248,18 +260,4 @@ private void updateCachedData(long key) { } } - private static float clamp(float v) { - if (v < 0.0f) { - return 0.0f; - } else if (v > 1.0f) { - return 1.0f; - } - - return v; - } - - private static int packLightMap(float sl, float bl) { - return (((int) sl & 0xFF) << 16) | ((int) bl & 0xFF); - } - } \ No newline at end of file diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SubBlockAoFace.java b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SubBlockAoFace.java index 765039c17..dee91e210 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SubBlockAoFace.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SubBlockAoFace.java @@ -1,8 +1,8 @@ package net.vulkanmod.render.chunk.build.light.smooth; import net.minecraft.core.BlockPos; -import net.vulkanmod.render.chunk.util.SimpleDirection; import net.vulkanmod.render.chunk.build.light.data.LightDataAccess; +import net.vulkanmod.render.chunk.util.SimpleDirection; import static net.vulkanmod.render.chunk.build.light.data.LightDataAccess.*; @@ -83,14 +83,13 @@ public void initLightData(LightDataAccess cache, BlockPos pos, SimpleDirection d float c0ao = c0oc ? 0.2f : 1.0f; final boolean c0em; - if((f0c0 && f1c0) || (c0oc && d0co)) { + if ((f0c0 && f1c0) || (c0oc && d0co)) { c0ao = 1.6f; - } - else { + } else { c0ao += f0c0 ? 0.2f : 1.0f; c0ao += f1c0 ? 0.2f : 1.0f; - if(offset) + if (offset) c0ao += d0co ? 0.2f : 1.0f; else c0ao += unpackFO(d0) ? 0.2f : 1.0f; @@ -115,14 +114,13 @@ public void initLightData(LightDataAccess cache, BlockPos pos, SimpleDirection d float c1ao = c1oc ? 0.2f : 1.0f; final boolean c1em; - if((f1c1 && f2c1) || (c1oc && d1co)) { + if ((f1c1 && f2c1) || (c1oc && d1co)) { c1ao = 1.6f; - } - else { + } else { c1ao += f1c1 ? 0.2f : 1.0f; c1ao += f2c1 ? 0.2f : 1.0f; - if(offset) + if (offset) c1ao += d1co ? 0.2f : 1.0f; else c1ao += unpackFO(d1) ? 0.2f : 1.0f; @@ -147,14 +145,13 @@ public void initLightData(LightDataAccess cache, BlockPos pos, SimpleDirection d float c2ao = c2oc ? 0.2f : 1.0f; final boolean c2em; - if((f2c2 && f3c2) || (c2oc && d2co)) { + if ((f2c2 && f3c2) || (c2oc && d2co)) { c2ao = 1.6f; - } - else { + } else { c2ao += f2c2 ? 0.2f : 1.0f; c2ao += f3c2 ? 0.2f : 1.0f; - if(offset) + if (offset) c2ao += d2co ? 0.2f : 1.0f; else c2ao += unpackFO(d2) ? 0.2f : 1.0f; @@ -179,14 +176,13 @@ public void initLightData(LightDataAccess cache, BlockPos pos, SimpleDirection d float c3ao = c3oc ? 0.2f : 1.0f; final boolean c3em; - if((f3c3 && f0c3) || (c3oc && d3co)) { + if ((f3c3 && f0c3) || (c3oc && d3co)) { c3ao = 1.6f; - } - else { + } else { c3ao += f3c3 ? 0.2f : 1.0f; c3ao += f0c3 ? 0.2f : 1.0f; - if(offset) + if (offset) c3ao += d3co ? 0.2f : 1.0f; else c3ao += unpackFO(d3) ? 0.2f : 1.0f; 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 index 74e75ce19..d76b6b50f 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/renderer/BlockRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/renderer/BlockRenderer.java @@ -5,13 +5,11 @@ import net.fabricmc.fabric.api.util.TriState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ItemBlockRenderTypes; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BlockStateModel; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.SingleThreadedRandomSource; import net.minecraft.world.phys.Vec3; @@ -22,8 +20,8 @@ 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.model.quad.QuadUtils; import net.vulkanmod.render.vertex.TerrainBufferBuilder; import net.vulkanmod.render.vertex.TerrainBuilder; import net.vulkanmod.render.vertex.TerrainRenderType; @@ -32,19 +30,12 @@ import org.joml.Vector3f; public class BlockRenderer extends AbstractBlockRenderContext { + final boolean backFaceCulling = Initializer.CONFIG.backFaceCulling; 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); @@ -52,6 +43,10 @@ public BlockRenderer(LightPipeline flatLightPipeline, LightPipeline smoothLightP this.random = new SingleThreadedRandomSource(42L); } + public void setResources(BuilderResources resources) { + this.resources = resources; + } + public void renderBlock(BlockState blockState, BlockPos blockPos, Vector3f pos) { this.pos = pos; this.blockPos = blockPos; 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 index 0fbbe5415..6f7cf270d 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/renderer/DefaultFluidRenderers.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/renderer/DefaultFluidRenderers.java @@ -5,13 +5,13 @@ public abstract class DefaultFluidRenderers { - private static final ReferenceOpenHashSet set = new ReferenceOpenHashSet<>(); + private static final ReferenceOpenHashSet set = new ReferenceOpenHashSet<>(); - public static void add(FluidRenderHandler handler) { - set.add(handler); - } + public static void add(FluidRenderHandler handler) { + set.add(handler); + } - public static boolean has(FluidRenderHandler handler) { - return set.contains(handler); - } + public static boolean has(FluidRenderHandler handler) { + return set.contains(handler); + } } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java b/src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java index f29acae11..066d69983 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java @@ -40,19 +40,29 @@ public class FluidRenderer implements FluidRendering.DefaultRenderer { private final BlockPos.MutableBlockPos mBlockPos = new BlockPos.MutableBlockPos(); private final ModelQuad modelQuad = new ModelQuad(); - - BuilderResources resources; - private final LightPipeline smoothLightPipeline; private final LightPipeline flatLightPipeline; - private final int[] quadColors = new int[4]; + BuilderResources resources; public FluidRenderer(LightPipeline flatLightPipeline, LightPipeline smoothLightPipeline) { this.smoothLightPipeline = smoothLightPipeline; this.flatLightPipeline = flatLightPipeline; } + public static boolean shouldRenderFace(BlockAndTintGetter blockAndTintGetter, BlockPos blockPos, FluidState fluidState, BlockState blockState, Direction direction, BlockState adjBlockState) { + + if (adjBlockState.getFluidState().getType().isSame(fluidState.getType())) + return false; + + // self-occlusion by waterlogging + if (blockState.canOcclude()) { + return !blockState.isFaceSturdy(blockAndTintGetter, blockPos, direction); + } + + return true; + } + public void setResources(BuilderResources resources) { this.resources = resources; } @@ -70,7 +80,7 @@ public void renderLiquid(BlockState blockState, FluidState fluidState, BlockPos handler = FluidRenderHandlerRegistry.INSTANCE.get(isLava ? Fluids.LAVA : Fluids.WATER); } - FluidRendering.render(handler, this.resources.getRegion(),blockPos, bufferBuilder, blockState, fluidState, this); + FluidRendering.render(handler, this.resources.getRegion(), blockPos, bufferBuilder, blockState, fluidState, this); } private boolean isFaceOccludedByState(BlockGetter blockGetter, float h, Direction direction, BlockPos blockPos, BlockState blockState) { @@ -92,19 +102,6 @@ private boolean isFaceOccludedByState(BlockGetter blockGetter, float h, Directio } } - public static boolean shouldRenderFace(BlockAndTintGetter blockAndTintGetter, BlockPos blockPos, FluidState fluidState, BlockState blockState, Direction direction, BlockState adjBlockState) { - - if (adjBlockState.getFluidState().getType().isSame(fluidState.getType())) - return false; - - // self-occlusion by waterlogging - if (blockState.canOcclude()) { - return !blockState.isFaceSturdy(blockAndTintGetter, blockPos, direction); - } - - return true; - } - public BlockState getAdjBlockState(BlockAndTintGetter blockAndTintGetter, int x, int y, int z, Direction dir) { mBlockPos.set(x + dir.getStepX(), y + dir.getStepY(), z + dir.getStepZ()); return blockAndTintGetter.getBlockState(mBlockPos); 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 0da19e2e1..0307b8030 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 @@ -13,10 +13,10 @@ import net.vulkanmod.Initializer; import net.vulkanmod.render.chunk.RenderSection; import net.vulkanmod.render.chunk.WorldRenderer; -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.renderer.BlockRenderer; +import net.vulkanmod.render.chunk.build.renderer.FluidRenderer; import net.vulkanmod.render.chunk.build.thread.BuilderResources; import net.vulkanmod.render.chunk.build.thread.ThreadBuilderPack; import net.vulkanmod.render.chunk.cull.QuadFacing; 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 c1acc33df..5b692119a 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 @@ -10,17 +10,19 @@ public abstract class ChunkTask { public static final boolean BENCH = true; protected static TaskDispatcher taskDispatcher; + protected final RenderSection section; + public boolean highPriority = false; + protected AtomicBoolean cancelled = new AtomicBoolean(false); + ChunkTask(RenderSection renderSection) { + this.section = renderSection; + } public static BuildTask createBuildTask(RenderSection renderSection, RenderRegion renderRegion, boolean highPriority) { return new BuildTask(renderSection, renderRegion, highPriority); } - protected AtomicBoolean cancelled = new AtomicBoolean(false); - protected final RenderSection section; - public boolean highPriority = false; - - ChunkTask(RenderSection renderSection) { - this.section = renderSection; + public static void setTaskDispatcher(TaskDispatcher dispatcher) { + taskDispatcher = dispatcher; } public abstract String name(); @@ -31,10 +33,6 @@ public void cancel() { this.cancelled.set(true); } - public static void setTaskDispatcher(TaskDispatcher dispatcher) { - taskDispatcher = dispatcher; - } - public enum Result { CANCELLED, SUCCESSFUL diff --git a/src/main/java/net/vulkanmod/render/chunk/build/task/CompileResult.java b/src/main/java/net/vulkanmod/render/chunk/build/task/CompileResult.java index 7a00bcf36..13c1d4322 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/task/CompileResult.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/task/CompileResult.java @@ -15,11 +15,9 @@ public class CompileResult { public final RenderSection renderSection; public final boolean fullUpdate; - + public final EnumMap renderedLayers = new EnumMap<>(TerrainRenderType.class); final List globalBlockEntities = new ArrayList<>(); final List blockEntities = new ArrayList<>(); - public final EnumMap renderedLayers = new EnumMap<>(TerrainRenderType.class); - VisibilitySet visibilitySet; QuadSorter.SortState transparencyState; CompiledSection compiledSection; @@ -32,7 +30,7 @@ public class CompileResult { public void updateSection() { this.renderSection.updateGlobalBlockEntities(globalBlockEntities); this.renderSection.setCompiledSection(compiledSection); - this.renderSection.setVisibility(((VisibilitySetExtended)visibilitySet).getVisibility()); + this.renderSection.setVisibility(((VisibilitySetExtended) visibilitySet).getVisibility()); this.renderSection.setCompletelyEmpty(compiledSection.isCompletelyEmpty); this.renderSection.setContainsBlockEntities(!blockEntities.isEmpty()); } 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 e233ab0a2..d54a3e9d7 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,15 +3,14 @@ import com.google.common.collect.Lists; import net.minecraft.world.level.block.entity.BlockEntity; import net.vulkanmod.render.vertex.QuadSorter; - import org.jetbrains.annotations.Nullable; + import java.util.List; public class CompiledSection { public static final CompiledSection UNCOMPILED = new CompiledSection(); - - boolean isCompletelyEmpty = false; final List blockEntities = Lists.newArrayList(); + boolean isCompletelyEmpty = false; @Nullable QuadSorter.SortState transparencyState; public boolean hasTransparencyState() { diff --git a/src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java b/src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java index e9bdac845..cce281f88 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java @@ -7,24 +7,22 @@ import net.vulkanmod.render.chunk.WorldRenderer; import net.vulkanmod.render.chunk.buffer.DrawBuffers; 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.chunk.build.thread.ThreadBuilderPack; import net.vulkanmod.render.vertex.TerrainRenderType; - import org.jetbrains.annotations.Nullable; import java.util.Queue; public class TaskDispatcher { - private final Queue compileResults = Queues.newLinkedBlockingDeque(); public final ThreadBuilderPack fixedBuffers; - + private final Queue compileResults = Queues.newLinkedBlockingDeque(); + private final Queue highPriorityTasks = Queues.newConcurrentLinkedQueue(); + private final Queue lowPriorityTasks = Queues.newConcurrentLinkedQueue(); private volatile boolean stopThreads; private Thread[] threads; private BuilderResources[] resources; private int idleThreads; - private final Queue highPriorityTasks = Queues.newConcurrentLinkedQueue(); - private final Queue lowPriorityTasks = Queues.newConcurrentLinkedQueue(); public TaskDispatcher() { this.fixedBuffers = new ThreadBuilderPack(); @@ -38,13 +36,13 @@ public void createThreads() { } public void createThreads(int n) { - if(!this.stopThreads) { + if (!this.stopThreads) { this.stopThreads(); } this.stopThreads = false; - if(this.resources != null) { + if (this.resources != null) { for (BuilderResources resources : this.resources) { resources.clear(); } @@ -71,10 +69,10 @@ public void createThreads(int n) { } private void runTaskThread(BuilderResources builderResources) { - while(!this.stopThreads) { + while (!this.stopThreads) { ChunkTask task = this.pollTask(); - if(task == null) + if (task == null) synchronized (this) { try { this.idleThreads++; @@ -85,7 +83,7 @@ private void runTaskThread(BuilderResources builderResources) { this.idleThreads--; } - if(task == null) + if (task == null) continue; task.runTask(builderResources); @@ -93,7 +91,7 @@ private void runTaskThread(BuilderResources builderResources) { } public void schedule(ChunkTask chunkTask) { - if(chunkTask == null) + if (chunkTask == null) return; if (chunkTask.highPriority) { @@ -111,14 +109,14 @@ public void schedule(ChunkTask chunkTask) { private ChunkTask pollTask() { ChunkTask task = this.highPriorityTasks.poll(); - if(task == null) + if (task == null) task = this.lowPriorityTasks.poll(); return task; } public void stopThreads() { - if(this.stopThreads) + if (this.stopThreads) return; this.stopThreads = true; @@ -140,7 +138,7 @@ public void stopThreads() { public boolean updateSections() { CompileResult result; boolean flag = false; - while((result = this.compileResults.poll()) != null) { + while ((result = this.compileResults.poll()) != null) { flag = true; doSectionUpdate(result); } @@ -162,12 +160,12 @@ private void doSectionUpdate(CompileResult compileResult) { if (chunkAreaManager.getChunkArea(renderArea.index) != renderArea) return; - if(compileResult.fullUpdate) { + if (compileResult.fullUpdate) { var renderLayers = compileResult.renderedLayers; - for(TerrainRenderType renderType : TerrainRenderType.VALUES) { + for (TerrainRenderType renderType : TerrainRenderType.VALUES) { UploadBuffer uploadBuffer = renderLayers.get(renderType); - if(uploadBuffer != null) { + if (uploadBuffer != null) { drawBuffers.upload(section, uploadBuffer, renderType); } else { section.resetDrawParameters(renderType); @@ -175,24 +173,25 @@ private void doSectionUpdate(CompileResult compileResult) { } compileResult.updateSection(); - } - else { + } else { UploadBuffer uploadBuffer = compileResult.renderedLayers.get(TerrainRenderType.TRANSLUCENT); drawBuffers.upload(section, uploadBuffer, TerrainRenderType.TRANSLUCENT); } } - public boolean isIdle() { return this.idleThreads == this.threads.length && this.compileResults.isEmpty(); } + public boolean isIdle() { + return this.idleThreads == this.threads.length && this.compileResults.isEmpty(); + } public void clearBatchQueue() { - while(!this.highPriorityTasks.isEmpty()) { + while (!this.highPriorityTasks.isEmpty()) { ChunkTask chunkTask = this.highPriorityTasks.poll(); if (chunkTask != null) { chunkTask.cancel(); } } - while(!this.lowPriorityTasks.isEmpty()) { + while (!this.lowPriorityTasks.isEmpty()) { ChunkTask chunkTask = this.lowPriorityTasks.poll(); if (chunkTask != null) { chunkTask.cancel(); 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 fd6e69f11..35b065ae4 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,8 +2,6 @@ import net.vulkanmod.Initializer; import net.vulkanmod.render.chunk.RenderSection; -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.color.TintCache; import net.vulkanmod.render.chunk.build.light.LightMode; @@ -13,6 +11,8 @@ 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; +import net.vulkanmod.render.chunk.build.renderer.BlockRenderer; +import net.vulkanmod.render.chunk.build.renderer.FluidRenderer; public class BuilderResources { public final ThreadBuilderPack builderPack = new ThreadBuilderPack(); @@ -34,8 +34,7 @@ public BuilderResources() { LightPipeline smoothLightPipeline; if (Initializer.CONFIG.ambientOcclusion == LightMode.SUB_BLOCK) { smoothLightPipeline = new NewSmoothLightPipeline(lightDataCache); - } - else { + } else { smoothLightPipeline = new SmoothLightPipeline(lightDataCache); } 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 64d702603..6ff4bf0f2 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 @@ -10,15 +10,6 @@ public class ThreadBuilderPack { private static Function terrainBuilderConstructor; - - public static void defaultTerrainBuilderConstructor() { - terrainBuilderConstructor = renderType -> new TerrainBuilder(TerrainRenderType.getLayer(renderType).bufferSize()); - } - - public static void setTerrainBuilderConstructor(Function constructor) { - terrainBuilderConstructor = constructor; - } - private final Map builders; public ThreadBuilderPack() { @@ -30,6 +21,14 @@ public ThreadBuilderPack() { builders = map; } + public static void defaultTerrainBuilderConstructor() { + terrainBuilderConstructor = renderType -> new TerrainBuilder(TerrainRenderType.getLayer(renderType).bufferSize()); + } + + public static void setTerrainBuilderConstructor(Function constructor) { + terrainBuilderConstructor = constructor; + } + public TerrainBuilder builder(TerrainRenderType renderType) { return this.builders.get(renderType); } diff --git a/src/main/java/net/vulkanmod/render/chunk/frustum/VFrustum.java b/src/main/java/net/vulkanmod/render/chunk/frustum/VFrustum.java index 396e1f4dd..158ca23ef 100644 --- a/src/main/java/net/vulkanmod/render/chunk/frustum/VFrustum.java +++ b/src/main/java/net/vulkanmod/render/chunk/frustum/VFrustum.java @@ -6,14 +6,13 @@ import org.joml.Vector4f; public class VFrustum { + private final FrustumIntersection frustum = new FrustumIntersection(); + private final Matrix4f matrix = new Matrix4f(); private Vector4f viewVector = new Vector4f(); private double camX; private double camY; private double camZ; - private final FrustumIntersection frustum = new FrustumIntersection(); - private final Matrix4f matrix = new Matrix4f(); - public VFrustum offsetToFullyIncludeCameraCube(int offset) { double d0 = Math.floor(this.camX / (double) offset) * (double) offset; double d1 = Math.floor(this.camY / (double) offset) * (double) offset; 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 58b2d156e..c75737747 100644 --- a/src/main/java/net/vulkanmod/render/chunk/graph/SectionGraph.java +++ b/src/main/java/net/vulkanmod/render/chunk/graph/SectionGraph.java @@ -12,7 +12,10 @@ import net.minecraft.world.phys.Vec3; import net.vulkanmod.Initializer; import net.vulkanmod.interfaces.FrustumMixed; -import net.vulkanmod.render.chunk.*; +import net.vulkanmod.render.chunk.ChunkAreaManager; +import net.vulkanmod.render.chunk.RenderSection; +import net.vulkanmod.render.chunk.SectionGrid; +import net.vulkanmod.render.chunk.WorldRenderer; import net.vulkanmod.render.chunk.build.RenderRegionBuilder; import net.vulkanmod.render.chunk.build.task.TaskDispatcher; import net.vulkanmod.render.chunk.frustum.VFrustum; @@ -24,23 +27,19 @@ import java.util.List; public class SectionGraph { - Minecraft minecraft; private final Level level; - private final SectionGrid sectionGrid; private final ChunkAreaManager chunkAreaManager; private final TaskDispatcher taskDispatcher; private final ResettableQueue sectionQueue = new ResettableQueue<>(); - private AreaSetQueue chunkAreaQueue; - private short lastFrame = 0; - private final ResettableQueue blockEntitiesSections = new ResettableQueue<>(); private final ResettableQueue rebuildQueue = new ResettableQueue<>(); - - private VFrustum frustum; - public RenderRegionBuilder renderRegionCache; + Minecraft minecraft; int nonEmptyChunks; + private final AreaSetQueue chunkAreaQueue; + private short lastFrame = 0; + private VFrustum frustum; public SectionGraph(Level level, SectionGrid sectionGrid, TaskDispatcher taskDispatcher) { @@ -54,6 +53,27 @@ public SectionGraph(Level level, SectionGrid sectionGrid, TaskDispatcher taskDis this.renderRegionCache = WorldRenderer.getInstance().renderRegionCache; } + private static void initFirstNode(RenderSection renderSection, short frame) { + renderSection.mainDir = 7; + renderSection.sourceDirs = (byte) (1 << 7); + renderSection.directions = (byte) 0xFF; + renderSection.setLastFrame(frame); + renderSection.visibility |= initVisibility(); + renderSection.directionChanges = 0; + renderSection.steps = 0; + } + + // Init special value used by first graph node + private static long initVisibility() { + long vis = 0; + for (int dir = 0; dir < 6; dir++) { + vis |= 1L << ((6 << 3) + dir); + vis |= 1L << ((7 << 3) + dir); + } + + return vis; + } + public void update(Camera camera, Frustum frustum, boolean spectator) { Profiler profiler = Profiler.getMainProfiler(); ProfilerFiller mcProfiler = net.minecraft.util.profiling.Profiler.get(); @@ -125,27 +145,6 @@ private void initializeQueueForFullUpdate(Camera camera) { } - private static void initFirstNode(RenderSection renderSection, short frame) { - renderSection.mainDir = 7; - renderSection.sourceDirs = (byte) (1 << 7); - renderSection.directions = (byte) 0xFF; - renderSection.setLastFrame(frame); - renderSection.visibility |= initVisibility(); - renderSection.directionChanges = 0; - renderSection.steps = 0; - } - - // Init special value used by first graph node - private static long initVisibility() { - long vis = 0; - for (int dir = 0; dir < 6; dir++) { - vis |= 1L << ((6 << 3) + dir); - vis |= 1L << ((7 << 3) + dir); - } - - return vis; - } - private void initUpdate() { this.resetUpdateQueues(); 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 d8964eaa9..9d33fa9ff 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/CircularIntList.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/CircularIntList.java @@ -7,10 +7,9 @@ public class CircularIntList { private final int size; private final int[] list; - private int startIndex; - private final OwnIterator iterator; private final RangeIterator rangeIterator; + private int startIndex; public CircularIntList(int size) { this.size = size; @@ -28,11 +27,11 @@ public void updateStartIdx(int startIndex) { list[size + 1] = -1; int k = 1; - for(int i = startIndex; i < size; ++i) { + for (int i = startIndex; i < size; ++i) { list[k] = i; ++k; } - for(int i = 0; i < startIndex; ++i) { + for (int i = 0; i < startIndex; ++i) { list[k] = i; ++k; } @@ -60,8 +59,8 @@ public RangeIterator createRangeIterator() { } public class OwnIterator implements Iterator { - private int currentIndex = 0; private final int maxIndex = size; + private int currentIndex = 0; @Override public boolean hasNext() { diff --git a/src/main/java/net/vulkanmod/render/chunk/util/ResettableQueue.java b/src/main/java/net/vulkanmod/render/chunk/util/ResettableQueue.java index 910b435a4..9893bebe5 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/ResettableQueue.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/ResettableQueue.java @@ -73,8 +73,8 @@ public void clear() { public Iterator iterator(boolean reverseOrder) { return reverseOrder ? new Iterator<>() { - int pos = ResettableQueue.this.limit - 1; final int limit = -1; + int pos = ResettableQueue.this.limit - 1; @Override public boolean hasNext() { @@ -87,8 +87,8 @@ public T next() { } } : new Iterator<>() { - int pos = 0; final int limit = ResettableQueue.this.limit; + int pos = 0; @Override public boolean hasNext() { diff --git a/src/main/java/net/vulkanmod/render/chunk/util/SimpleDirection.java b/src/main/java/net/vulkanmod/render/chunk/util/SimpleDirection.java index b4c53e808..75bdd757d 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/SimpleDirection.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/SimpleDirection.java @@ -12,17 +12,11 @@ public enum SimpleDirection { EAST(5, 4, 3, new Vec3i(1, 0, 0)); private static final SimpleDirection[] VALUES = SimpleDirection.values(); - - public static SimpleDirection of(Direction direction) { - return VALUES[direction.get3DDataValue()]; - } - + public final byte nx, ny, nz; private final int data3d; private final int oppositeIndex; private final int data2d; - public final byte nx, ny, nz; - SimpleDirection(int j, int k, int l, Vec3i normal) { this.data3d = j; this.oppositeIndex = k; @@ -33,6 +27,10 @@ public static SimpleDirection of(Direction direction) { this.nz = (byte) normal.getZ(); } + public static SimpleDirection of(Direction direction) { + return VALUES[direction.get3DDataValue()]; + } + public int get3DDataValue() { return this.data3d; } diff --git a/src/main/java/net/vulkanmod/render/chunk/util/StaticQueue.java b/src/main/java/net/vulkanmod/render/chunk/util/StaticQueue.java index 2d811c072..b2a919a4e 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/StaticQueue.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/StaticQueue.java @@ -7,9 +7,9 @@ public class StaticQueue implements Iterable { final T[] queue; + final int capacity; int position = 0; int limit = 0; - final int capacity; public StaticQueue() { this(1024); @@ -48,8 +48,8 @@ public void clear() { public Iterator iterator(boolean reverseOrder) { return reverseOrder ? new Iterator<>() { - int pos = StaticQueue.this.limit - 1; final int limit = -1; + int pos = StaticQueue.this.limit - 1; @Override public boolean hasNext() { @@ -62,8 +62,8 @@ public T next() { } } : new Iterator<>() { - int pos = 0; final int limit = StaticQueue.this.limit; + int pos = 0; @Override public boolean hasNext() { 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 caa063410..81be1eae0 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/Util.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/Util.java @@ -1,9 +1,6 @@ package net.vulkanmod.render.chunk.util; import net.minecraft.core.Direction; -import org.lwjgl.system.MemoryUtil; - -import java.nio.ByteBuffer; public class Util { diff --git a/src/main/java/net/vulkanmod/render/engine/EGlProgram.java b/src/main/java/net/vulkanmod/render/engine/EGlProgram.java index 9bc7905d9..0a2da7b53 100644 --- a/src/main/java/net/vulkanmod/render/engine/EGlProgram.java +++ b/src/main/java/net/vulkanmod/render/engine/EGlProgram.java @@ -1,7 +1,7 @@ package net.vulkanmod.render.engine; import com.google.common.collect.Sets; -import com.mojang.blaze3d.opengl.*; +import com.mojang.blaze3d.opengl.Uniform; import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.logging.LogUtils; @@ -15,7 +15,7 @@ public class EGlProgram { private static final Logger LOGGER = LogUtils.getLogger(); - public static Set BUILT_IN_UNIFORMS = Sets.newHashSet("Projection", "Lighting", "Fog", "Globals"); + public static Set BUILT_IN_UNIFORMS = Sets.newHashSet("Projection", "Lighting", "Fog", "Globals"); public static EGlProgram INVALID_PROGRAM = new EGlProgram(-1, "invalid"); private final Map uniformsByName = new HashMap(); private final int programId; @@ -65,7 +65,7 @@ public void setupUniforms(Pipeline pipeline, List supplier, GpuTextureView col } else { this.inRenderPass = true; GpuTexture depthTexture1 = depthTexture != null ? depthTexture.texture() : null; - VkFbo fbo = ((VkGpuTexture)colorTexture.texture()).getFbo(depthTexture1); + VkFbo fbo = ((VkGpuTexture) colorTexture.texture()).getFbo(depthTexture1); fbo.bind(); int j = 0; @@ -144,8 +149,7 @@ public RenderPass createRenderPass(Supplier supplier, GpuTextureView col public void clearColorTexture(GpuTexture colorAttachment, int color) { if (this.inRenderPass) { throw new IllegalStateException("Close the existing render pass before creating a new one!"); - } - else if (Renderer.isRecording()) { + } else if (Renderer.isRecording()) { VkGpuTexture vkGpuTexture = (VkGpuTexture) colorAttachment; VkGlFramebuffer.bindFramebuffer(GL30.GL_FRAMEBUFFER, framebufferId); VkGlFramebuffer.framebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, vkGpuTexture.glId(), 0); @@ -154,8 +158,7 @@ else if (Renderer.isRecording()) { VRenderSystem.setClearColor(ARGB.redFloat(color), ARGB.greenFloat(color), ARGB.blueFloat(color), ARGB.alphaFloat(color)); Renderer.clearAttachments(16384); Renderer.getInstance().endRenderPass(); - } - else { + } else { GraphicsQueue graphicsQueue = DeviceManager.getGraphicsQueue(); var commandBuffer = graphicsQueue.getCommandBuffer(); VkGpuTexture vkGpuTexture = (VkGpuTexture) colorAttachment; @@ -184,17 +187,15 @@ else if (Renderer.isRecording()) { public void clearColorAndDepthTextures(GpuTexture colorAttachment, int clearColor, GpuTexture depthAttachment, double clearDepth) { if (this.inRenderPass) { throw new IllegalStateException("Close the existing render pass before creating a new one!"); - } - else { + } else { if (Minecraft.getInstance().getMainRenderTarget().getColorTexture() == colorAttachment) { Renderer.getInstance().getMainPass().rebindMainTarget(); VRenderSystem.clearDepth(clearDepth); VRenderSystem.setClearColor(ARGB.redFloat(clearColor), ARGB.greenFloat(clearColor), ARGB.blueFloat(clearColor), ARGB.alphaFloat(clearColor)); Renderer.clearAttachments(0x4100); - } - else { - VkFbo fbo = ((VkGpuTexture)colorAttachment).getFbo(depthAttachment); + } else { + VkFbo fbo = ((VkGpuTexture) colorAttachment).getFbo(depthAttachment); fbo.clear = 0x4100; fbo.clearColor = clearColor; @@ -202,8 +203,7 @@ public void clearColorAndDepthTextures(GpuTexture colorAttachment, int clearColo Framebuffer boundFramebuffer = Renderer.getInstance().getBoundFramebuffer(); if (boundFramebuffer.getColorAttachment() == ((VkGpuTexture) colorAttachment).getVulkanImage() - && boundFramebuffer.getDepthAttachment() == ((VkGpuTexture) depthAttachment).getVulkanImage()) - { + && boundFramebuffer.getDepthAttachment() == ((VkGpuTexture) depthAttachment).getVulkanImage()) { fbo.clearAttachments(); } } @@ -223,11 +223,9 @@ public void clearColorAndDepthTextures(GpuTexture colorAttachment, int clearColo Framebuffer boundFramebuffer = Renderer.getInstance().getBoundFramebuffer(); if (boundFramebuffer.getColorAttachment() == ((VkGpuTexture) colorAttachment).getVulkanImage() - && boundFramebuffer.getDepthAttachment() == ((VkGpuTexture) depthAttachment).getVulkanImage()) - { + && boundFramebuffer.getDepthAttachment() == ((VkGpuTexture) depthAttachment).getVulkanImage()) { Renderer.clearAttachments(0x4100, x0, y0, width, height); - } - else { + } else { // TODO // throw new IllegalStateException(); } @@ -238,8 +236,7 @@ public void clearColorAndDepthTextures(GpuTexture colorAttachment, int clearColo public void clearDepthTexture(GpuTexture depthAttachment, double clearDepth) { if (this.inRenderPass) { throw new IllegalStateException("Close the existing render pass before creating a new one!"); - } - else { + } else { // depthAttachment is not the target here VRenderSystem.clearDepth(clearDepth); Renderer.clearAttachments(256); @@ -254,8 +251,7 @@ public void writeToBuffer(GpuBufferSlice gpuBufferSlice, ByteBuffer byteBuffer) VkGpuBuffer vkGpuBuffer = (VkGpuBuffer) gpuBufferSlice.buffer(); if (vkGpuBuffer.closed) { throw new IllegalStateException("Buffer already closed"); - } - else { + } else { int size = byteBuffer.remaining(); if (size + gpuBufferSlice.offset() > vkGpuBuffer.size()) { throw new IllegalArgumentException( @@ -298,7 +294,7 @@ public GpuBuffer.MappedView mapBuffer(GpuBufferSlice gpuBufferSlice, boolean rea if (this.inRenderPass) { throw new IllegalStateException("Close the existing render pass before performing additional commands"); } else { - VkGpuBuffer gpuBuffer = (VkGpuBuffer)(gpuBufferSlice.buffer()); + VkGpuBuffer gpuBuffer = (VkGpuBuffer) (gpuBufferSlice.buffer()); if (gpuBuffer.closed) { throw new IllegalStateException("Buffer already closed"); } else if (!readable && !writable) { @@ -310,12 +306,12 @@ public GpuBuffer.MappedView mapBuffer(GpuBufferSlice gpuBufferSlice, boolean rea } else if (gpuBufferSlice.offset() + gpuBufferSlice.length() > gpuBuffer.size()) { throw new IllegalArgumentException( "Cannot map more data than this buffer can hold (attempting to map " - + gpuBufferSlice.length() - + " bytes at offset " - + gpuBufferSlice.offset() - + " from " - + gpuBuffer.size() - + " size buffer)" + + gpuBufferSlice.length() + + " bytes at offset " + + gpuBufferSlice.offset() + + " from " + + gpuBuffer.size() + + " size buffer)" ); } else { int i = 0; @@ -391,17 +387,17 @@ public void writeToTexture(GpuTexture gpuTexture, NativeImage nativeImage, int l if (unpackSkipPixels + width > nativeImage.getWidth() || unpackSkipRows + height > nativeImage.getHeight()) { throw new IllegalArgumentException( "Copy source (" - + nativeImage.getWidth() - + "x" - + nativeImage.getHeight() - + ") is not large enough to read a rectangle of " - + width - + "x" - + height - + " from " - + unpackSkipPixels - + "x" - + unpackSkipRows + + nativeImage.getWidth() + + "x" + + nativeImage.getHeight() + + ") is not large enough to read a rectangle of " + + width + + "x" + + height + + " from " + + unpackSkipPixels + + "x" + + unpackSkipRows ); } else if (xOffset + width > gpuTexture.getWidth(level) || yOffset + height > gpuTexture.getHeight(level)) { throw new IllegalArgumentException( @@ -431,17 +427,17 @@ public void writeToTexture(GpuTexture gpuTexture, ByteBuffer byteBuffer, NativeI } else if (xOffset + width > gpuTexture.getWidth(level) || yOffset + height > gpuTexture.getHeight(level)) { throw new IllegalArgumentException( "Dest texture (" - + gpuTexture.getWidth(level) - + "x" - + gpuTexture.getHeight(level) - + ") is not large enough to write a rectangle of " - + width - + "x" - + height - + " at " - + xOffset - + "x" - + yOffset + + gpuTexture.getWidth(level) + + "x" + + gpuTexture.getHeight(level) + + ") is not large enough to write a rectangle of " + + width + + "x" + + height + + " at " + + xOffset + + "x" + + yOffset ); } else if (gpuTexture.isClosed()) { throw new IllegalStateException("Destination texture is closed"); @@ -449,9 +445,8 @@ public void writeToTexture(GpuTexture gpuTexture, ByteBuffer byteBuffer, NativeI throw new IllegalStateException("Color texture must have USAGE_COPY_DST to be a destination for a write"); } else if (j >= gpuTexture.getDepthOrLayers()) { throw new UnsupportedOperationException("Depth or layer is out of range, must be >= 0 and < " + gpuTexture.getDepthOrLayers()); - } - else { - GlStateManager._bindTexture(((VkGpuTexture)gpuTexture).id); + } else { + GlStateManager._bindTexture(((VkGpuTexture) gpuTexture).id); GlStateManager._pixelStore(3314, width); GlStateManager._pixelStore(3316, 0); @@ -484,31 +479,30 @@ public void copyTextureToBuffer(GpuTexture gpuTexture, GpuBuffer gpuBuffer, int if (gpuTexture.getWidth(mipLevel) * gpuTexture.getHeight(mipLevel) * vkGpuTexture.getVulkanImage().formatSize + dstOffset > gpuBuffer.size()) { throw new IllegalArgumentException( "Buffer of size " - + gpuBuffer.size() - + " is not large enough to hold " - + width - + "x" - + height - + " pixels (" - + vkGpuTexture.getVulkanImage().formatSize - + " bytes each) starting from offset " - + dstOffset + + gpuBuffer.size() + + " is not large enough to hold " + + width + + "x" + + height + + " pixels (" + + vkGpuTexture.getVulkanImage().formatSize + + " bytes each) starting from offset " + + dstOffset ); - } - else if (xOffset + width > gpuTexture.getWidth(mipLevel) || yOffset + height > gpuTexture.getHeight(mipLevel)) { + } else if (xOffset + width > gpuTexture.getWidth(mipLevel) || yOffset + height > gpuTexture.getHeight(mipLevel)) { throw new IllegalArgumentException( "Copy source texture (" - + gpuTexture.getWidth(mipLevel) - + "x" - + gpuTexture.getHeight(mipLevel) - + ") is not large enough to read a rectangle of " - + width - + "x" - + height - + " from " - + xOffset - + "," - + yOffset + + gpuTexture.getWidth(mipLevel) + + "x" + + gpuTexture.getHeight(mipLevel) + + ") is not large enough to read a rectangle of " + + width + + "x" + + height + + " from " + + xOffset + + "," + + yOffset ); } else if (gpuTexture.isClosed()) { throw new IllegalStateException("Source texture is closed"); @@ -532,32 +526,32 @@ public void copyTextureToTexture(GpuTexture gpuTexture, GpuTexture gpuTexture2, if (j + n > gpuTexture2.getWidth(mipLevel) || k + o > gpuTexture2.getHeight(mipLevel)) { throw new IllegalArgumentException( "Dest texture (" - + gpuTexture2.getWidth(mipLevel) - + "x" - + gpuTexture2.getHeight(mipLevel) - + ") is not large enough to write a rectangle of " - + n - + "x" - + o - + " at " - + j - + "x" - + k + + gpuTexture2.getWidth(mipLevel) + + "x" + + gpuTexture2.getHeight(mipLevel) + + ") is not large enough to write a rectangle of " + + n + + "x" + + o + + " at " + + j + + "x" + + k ); } else if (l + n > gpuTexture.getWidth(mipLevel) || m + o > gpuTexture.getHeight(mipLevel)) { throw new IllegalArgumentException( "Source texture (" - + gpuTexture.getWidth(mipLevel) - + "x" - + gpuTexture.getHeight(mipLevel) - + ") is not large enough to read a rectangle of " - + n - + "x" - + o - + " at " - + l - + "x" - + m + + gpuTexture.getWidth(mipLevel) + + "x" + + gpuTexture.getHeight(mipLevel) + + ") is not large enough to read a rectangle of " + + n + + "x" + + o + + " at " + + l + + "x" + + m ); } else if (gpuTexture.isClosed()) { throw new IllegalStateException("Source texture is closed"); @@ -639,11 +633,11 @@ protected void executeDrawMultiple( if (biConsumer != null) { biConsumer.accept(object, (string, gpuBufferSlice) -> { EGlProgram glProgram = ExtendedRenderPipeline.of(renderPass.pipeline).getProgram(); - if (glProgram.getUniform(string) instanceof Uniform.Ubo ubo) { + if (glProgram.getUniform(string) instanceof Uniform.Ubo(int blockBinding)) { int blockBinding; try { - blockBinding = ubo.blockBinding(); + blockBinding = blockBinding; } catch (Throwable var7) { throw new MatchException(var7.toString(), var7); } @@ -688,8 +682,7 @@ protected void executeDraw(VkRenderPass renderPass, int i, int j, int k, @Nullab } public void drawFromBuffers(VkRenderPass renderPass, int vertexOffset, int firstIndex, int vertexCount, - @Nullable VertexFormat.IndexType indexType, RenderPipeline renderPipeline, int instanceCount) - { + @Nullable VertexFormat.IndexType indexType, RenderPipeline renderPipeline, int instanceCount) { if (instanceCount < 1) { instanceCount = 1; } @@ -702,14 +695,14 @@ public void drawFromBuffers(VkRenderPass renderPass, int vertexOffset, int first } VkCommandBuffer vkCommandBuffer = Renderer.getCommandBuffer(); - VkGpuBuffer vertexBuffer = (VkGpuBuffer)renderPass.vertexBuffers[0]; + VkGpuBuffer vertexBuffer = (VkGpuBuffer) renderPass.vertexBuffers[0]; try (MemoryStack stack = stackPush()) { if (vertexBuffer != null) { VK11.vkCmdBindVertexBuffers(vkCommandBuffer, 0, stack.longs(vertexBuffer.buffer.getId()), stack.longs(0)); } if (renderPass.indexBuffer != null) { - VkGpuBuffer indexBuffer = (VkGpuBuffer)renderPass.indexBuffer; + VkGpuBuffer indexBuffer = (VkGpuBuffer) renderPass.indexBuffer; int vkIndexType = switch (indexType) { case SHORT -> VK_INDEX_TYPE_UINT16; @@ -718,15 +711,13 @@ public void drawFromBuffers(VkRenderPass renderPass, int vertexOffset, int first VK11.vkCmdBindIndexBuffer(vkCommandBuffer, indexBuffer.buffer.getId(), 0, vkIndexType); VK11.vkCmdDrawIndexed(vkCommandBuffer, vertexCount, instanceCount, firstIndex, vertexOffset, 0); - } - else { + } else { var autoIndexBuffer = Renderer.getDrawer().getAutoIndexBuffer(renderPipeline.getVertexFormatMode(), vertexCount); if (autoIndexBuffer != null) { int indexCount = autoIndexBuffer.getIndexCount(vertexCount); VK11.vkCmdBindIndexBuffer(vkCommandBuffer, autoIndexBuffer.getIndexBuffer().getId(), 0, autoIndexBuffer.getIndexBuffer().indexType.value); VK11.vkCmdDrawIndexed(vkCommandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, 0); - } - else { + } else { VK11.vkCmdDraw(vkCommandBuffer, vertexCount, instanceCount, vertexOffset, 0); } } diff --git a/src/main/java/net/vulkanmod/render/engine/VkDebugLabel.java b/src/main/java/net/vulkanmod/render/engine/VkDebugLabel.java index 60ac40491..7e9f648e2 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkDebugLabel.java +++ b/src/main/java/net/vulkanmod/render/engine/VkDebugLabel.java @@ -1,17 +1,23 @@ package net.vulkanmod.render.engine; -import com.mojang.blaze3d.opengl.*; +import com.mojang.blaze3d.opengl.GlProgram; +import com.mojang.blaze3d.opengl.GlShaderModule; +import com.mojang.blaze3d.opengl.VertexArrayCache; import com.mojang.logging.LogUtils; -import java.util.Set; - import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import org.slf4j.Logger; +import java.util.Set; + @Environment(EnvType.CLIENT) public class VkDebugLabel { private static final Logger LOGGER = LogUtils.getLogger(); + public static VkDebugLabel create(boolean bl, Set set) { + return new VkDebugLabel(); + } + public void applyLabel(VkGpuBuffer glBuffer) { } @@ -27,10 +33,6 @@ public void applyLabel(GlProgram glProgram) { public void applyLabel(VertexArrayCache.VertexArray vertexArray) { } - public static VkDebugLabel create(boolean bl, Set set) { - return new VkDebugLabel(); - } - public boolean exists() { return true; } diff --git a/src/main/java/net/vulkanmod/render/engine/VkFbo.java b/src/main/java/net/vulkanmod/render/engine/VkFbo.java index 22bb06ac5..6dce9c934 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkFbo.java +++ b/src/main/java/net/vulkanmod/render/engine/VkFbo.java @@ -5,11 +5,7 @@ import net.vulkanmod.gl.VkGlFramebuffer; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; -import net.vulkanmod.vulkan.framebuffer.Framebuffer; import org.lwjgl.opengl.GL33; -import org.lwjgl.system.MemoryStack; - -import static org.lwjgl.system.MemoryStack.stackPush; public class VkFbo { final int glId; diff --git a/src/main/java/net/vulkanmod/render/engine/VkGpuBuffer.java b/src/main/java/net/vulkanmod/render/engine/VkGpuBuffer.java index 1c672841e..e35461b3a 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkGpuBuffer.java +++ b/src/main/java/net/vulkanmod/render/engine/VkGpuBuffer.java @@ -1,9 +1,6 @@ package net.vulkanmod.render.engine; import com.mojang.blaze3d.buffers.GpuBuffer; - -import java.nio.ByteBuffer; -import java.util.function.Supplier; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.vulkanmod.vulkan.memory.MemoryManager; @@ -12,13 +9,16 @@ import net.vulkanmod.vulkan.memory.buffer.Buffer; import org.jetbrains.annotations.Nullable; +import java.nio.ByteBuffer; +import java.util.function.Supplier; + import static org.lwjgl.vulkan.VK10.*; @Environment(EnvType.CLIENT) public class VkGpuBuffer extends GpuBuffer { + @Nullable + protected final Supplier label; protected boolean closed; - @Nullable protected final Supplier label; - Buffer buffer; protected VkGpuBuffer(VkDebugLabel glDebugLabel, @Nullable Supplier supplier, int usage, int size) { @@ -46,15 +46,29 @@ protected VkGpuBuffer(VkDebugLabel glDebugLabel, @Nullable Supplier supp } boolean mappable = (usage & GpuBuffer.USAGE_MAP_READ) != 0 | - (usage & GpuBuffer.USAGE_MAP_WRITE) != 0 | - (usage & GpuBuffer.USAGE_HINT_CLIENT_STORAGE) != 0; + (usage & GpuBuffer.USAGE_MAP_WRITE) != 0 | + (usage & GpuBuffer.USAGE_HINT_CLIENT_STORAGE) != 0; - MemoryType memoryType = mappable ? MemoryTypes.HOST_MEM : MemoryTypes.GPU_MEM; + MemoryType memoryType = mappable ? MemoryTypes.HOST_MEM : MemoryTypes.GPU_MEM; this.buffer = new Buffer(vkUsage, memoryType); this.buffer.createBuffer(this.size()); } + public static int bufferUsageToGlEnum(int i) { + boolean stream = (i & 4) != 0; + // Draw + if ((i & 2) != 0) { + return stream ? 35040 : 35044; + } + // Read + else if ((i & 1) != 0) { + return stream ? 35041 : 35045; + } else { + return 35044; + } + } + @Override public boolean isClosed() { return this.closed; @@ -73,20 +87,6 @@ public Buffer getBuffer() { return buffer; } - public static int bufferUsageToGlEnum(int i) { - boolean stream = (i & 4) != 0; - // Draw - if ((i & 2) != 0) { - return stream ? 35040 : 35044; - } - // Read - else if ((i & 1) != 0) { - return stream ? 35041 : 35045; - } else { - return 35044; - } - } - @Environment(EnvType.CLIENT) public static class MappedView implements GpuBuffer.MappedView { private final int target; diff --git a/src/main/java/net/vulkanmod/render/engine/VkGpuDevice.java b/src/main/java/net/vulkanmod/render/engine/VkGpuDevice.java index 6c641decf..0c88bd4e4 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkGpuDevice.java +++ b/src/main/java/net/vulkanmod/render/engine/VkGpuDevice.java @@ -63,6 +63,22 @@ public VkGpuDevice(long l, int i, boolean bl, BiFunction= 1024; j >>= 1) { + GlStateManager._texImage2D(32868, 0, 6408, j, j, 0, 6408, 5121, null); + int k = GlStateManager._getTexLevelParameter(32868, 0, 4096); + if (k != 0) { + return j; + } + } + + int jx = Math.max(i, 1024); + LOGGER.info("Failed to determine maximum texture size by probing, trying GL_MAX_TEXTURE_SIZE = {}", jx); + return jx; + } + public VkDebugLabel debugLabels() { return this.debugLabels; } @@ -93,13 +109,13 @@ public GpuTexture createTexture(@Nullable String string, int usage, TextureForma int attachmentUsage = depthFormat ? VK10.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : VK10.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; VulkanImage texture = VulkanImage.builder(width, height) - .setName(string) - .setFormat(format) - .setArrayLayers(layers) - .setMipLevels(mipLevels) - .addUsage(attachmentUsage) - .setViewType(viewType) - .createVulkanImage(); + .setName(string) + .setFormat(format) + .setArrayLayers(layers) + .setMipLevels(mipLevels) + .addUsage(attachmentUsage) + .setViewType(viewType) + .createVulkanImage(); VkGlTexture vGlTexture = VkGlTexture.getTexture(id); vGlTexture.setVulkanImage(texture); @@ -176,7 +192,7 @@ public boolean isDebuggingEnabled() { @Override public String getRenderer() { - return "VulkanMod %s".formatted(Initializer.getVersion()) ; + return "VulkanMod %s".formatted(Initializer.getVersion()); } @Override @@ -194,22 +210,6 @@ public String getVersion() { return Vulkan.getDevice().vkVersion; } - private static int getMaxSupportedTextureSize() { - int i = GlStateManager._getInteger(3379); - - for (int j = Math.max(32768, i); j >= 1024; j >>= 1) { - GlStateManager._texImage2D(32868, 0, 6408, j, j, 0, 6408, 5121, null); - int k = GlStateManager._getTexLevelParameter(32868, 0, 4096); - if (k != 0) { - return j; - } - } - - int jx = Math.max(i, 1024); - LOGGER.info("Failed to determine maximum texture size by probing, trying GL_MAX_TEXTURE_SIZE = {}", jx); - return jx; - } - @Override public int getMaxTextureSize() { return this.maxSupportedTextureSize; @@ -383,16 +383,11 @@ public String toString() { } } - private static class VkRenderPipeline implements CompiledRenderPipeline { - final RenderPipeline renderPipeline; - - public VkRenderPipeline(RenderPipeline renderPipeline) { - this.renderPipeline = renderPipeline; - } + private record VkRenderPipeline(RenderPipeline renderPipeline) implements CompiledRenderPipeline { @Override - public boolean isValid() { - return true; + public boolean isValid() { + return true; + } } - } } diff --git a/src/main/java/net/vulkanmod/render/engine/VkGpuTexture.java b/src/main/java/net/vulkanmod/render/engine/VkGpuTexture.java index b5e5a5b65..e12cf45f2 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkGpuTexture.java +++ b/src/main/java/net/vulkanmod/render/engine/VkGpuTexture.java @@ -1,28 +1,27 @@ package net.vulkanmod.render.engine; -import com.mojang.blaze3d.opengl.GlConst; import com.mojang.blaze3d.opengl.GlStateManager; import com.mojang.blaze3d.opengl.GlTexture; import com.mojang.blaze3d.textures.AddressMode; import com.mojang.blaze3d.textures.FilterMode; import com.mojang.blaze3d.textures.GpuTexture; import com.mojang.blaze3d.textures.TextureFormat; -import it.unimi.dsi.fastutil.ints.*; +import it.unimi.dsi.fastutil.ints.Int2ReferenceMap; +import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.vulkanmod.gl.VkGlTexture; import net.vulkanmod.vulkan.texture.SamplerManager; import net.vulkanmod.vulkan.texture.VulkanImage; import org.jetbrains.annotations.Nullable; -import org.lwjgl.opengl.GL11; import org.lwjgl.vulkan.VK10; @Environment(EnvType.CLIENT) //public class VkGpuTexture extends GpuTexture { public class VkGpuTexture extends GlTexture { - protected VkGlTexture glTexture; protected final int id; private final Int2ReferenceMap fboCache = new Int2ReferenceOpenHashMap<>(); + protected VkGlTexture glTexture; protected boolean closed; protected boolean modesDirty = true; @@ -32,6 +31,44 @@ protected VkGpuTexture(int usage, String string, TextureFormat textureFormat, in this.glTexture = glTexture; } + public static TextureFormat textureFormat(int format) { + return switch (format) { + case VK10.VK_FORMAT_R8G8B8A8_UNORM, VK10.VK_FORMAT_B8G8R8A8_UNORM -> TextureFormat.RGBA8; + case VK10.VK_FORMAT_R8_UNORM -> TextureFormat.RED8; + case VK10.VK_FORMAT_D32_SFLOAT -> TextureFormat.DEPTH32; + default -> throw new IllegalStateException("Unexpected value: " + format); + }; + } + + public static int vkFormat(TextureFormat textureFormat) { + return switch (textureFormat) { + case RGBA8 -> VK10.VK_FORMAT_R8G8B8A8_UNORM; + case RED8 -> VK10.VK_FORMAT_R8_UNORM; + case RED8I -> VK10.VK_FORMAT_R8_SINT; + case DEPTH32 -> VK10.VK_FORMAT_D32_SFLOAT; + }; + } + +// public int getFbo(DirectStateAccess directStateAccess, @Nullable GpuTexture gpuTexture) { +// int i = gpuTexture == null ? 0 : ((VkGpuTexture)gpuTexture).id; +// return this.fboCache.computeIfAbsent(i, j -> { +// int k = directStateAccess.createFrameBufferObject(); +// directStateAccess.bindFrameBufferTextures(k, this.id, i, 0, 0); +// return k; +// }); +// } + + public static int vkImageViewType(int usage) { + int viewType; + if ((usage & GpuTexture.USAGE_CUBEMAP_COMPATIBLE) != 0) { + viewType = VK10.VK_IMAGE_VIEW_TYPE_CUBE; + } else { + viewType = VK10.VK_IMAGE_VIEW_TYPE_2D; + } + + return viewType; + } + @Override public void close() { if (!this.closed) { @@ -49,15 +86,6 @@ public boolean isClosed() { return this.closed; } -// public int getFbo(DirectStateAccess directStateAccess, @Nullable GpuTexture gpuTexture) { -// int i = gpuTexture == null ? 0 : ((VkGpuTexture)gpuTexture).id; -// return this.fboCache.computeIfAbsent(i, j -> { -// int k = directStateAccess.createFrameBufferObject(); -// directStateAccess.bindFrameBufferTextures(k, this.id, i, 0, 0); -// return k; -// }); -// } - public void flushModeChanges() { if (this.modesDirty) { // GlStateManager._texParameter(3553, 10242, GlConst.toGl(this.addressModeU)); @@ -116,42 +144,12 @@ public void setUseMipmaps(boolean bl) { } public VkFbo getFbo(@Nullable GpuTexture depthAttachment) { - int depthAttachmentId = depthAttachment == null ? 0 : ((VkGpuTexture)depthAttachment).id; + int depthAttachmentId = depthAttachment == null ? 0 : ((VkGpuTexture) depthAttachment).id; return this.fboCache.computeIfAbsent(depthAttachmentId, j -> new VkFbo(this, (VkGpuTexture) depthAttachment)); } public VulkanImage getVulkanImage() { return glTexture.getVulkanImage(); } - - public static TextureFormat textureFormat(int format) { - return switch (format) { - case VK10.VK_FORMAT_R8G8B8A8_UNORM, VK10.VK_FORMAT_B8G8R8A8_UNORM -> TextureFormat.RGBA8; - case VK10.VK_FORMAT_R8_UNORM -> TextureFormat.RED8; - case VK10.VK_FORMAT_D32_SFLOAT -> TextureFormat.DEPTH32; - default -> throw new IllegalStateException("Unexpected value: " + format); - }; - } - - public static int vkFormat(TextureFormat textureFormat) { - return switch (textureFormat) { - case RGBA8 -> VK10.VK_FORMAT_R8G8B8A8_UNORM; - case RED8 -> VK10.VK_FORMAT_R8_UNORM; - case RED8I -> VK10.VK_FORMAT_R8_SINT; - case DEPTH32 -> VK10.VK_FORMAT_D32_SFLOAT; - }; - } - - public static int vkImageViewType(int usage) { - int viewType; - if ((usage & GpuTexture.USAGE_CUBEMAP_COMPATIBLE) != 0) { - viewType = VK10.VK_IMAGE_VIEW_TYPE_CUBE; - } - else { - viewType = VK10.VK_IMAGE_VIEW_TYPE_2D; - } - - return viewType; - } } diff --git a/src/main/java/net/vulkanmod/render/engine/VkRenderPass.java b/src/main/java/net/vulkanmod/render/engine/VkRenderPass.java index 8d9c039bc..411ed5032 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkRenderPass.java +++ b/src/main/java/net/vulkanmod/render/engine/VkRenderPass.java @@ -5,40 +5,38 @@ import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.systems.RenderPass; import com.mojang.blaze3d.systems.ScissorState; -import com.mojang.blaze3d.textures.GpuTexture; import com.mojang.blaze3d.textures.GpuTextureView; import com.mojang.blaze3d.vertex.VertexFormat; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Supplier; - import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.SharedConstants; import net.vulkanmod.interfaces.shader.ExtendedRenderPipeline; import org.jetbrains.annotations.Nullable; -import org.joml.Matrix4f; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Supplier; @Environment(EnvType.CLIENT) public class VkRenderPass implements RenderPass { - protected static final int MAX_VERTEX_BUFFERS = 1; public static final boolean VALIDATION = SharedConstants.IS_RUNNING_IN_IDE; + protected static final int MAX_VERTEX_BUFFERS = 1; + protected final GpuBuffer[] vertexBuffers = new GpuBuffer[1]; + protected final HashMap uniforms = new HashMap<>(); + protected final HashMap samplers = new HashMap<>(); + protected final Set dirtyUniforms = new HashSet<>(); private final VkCommandEncoder encoder; private final boolean hasDepthTexture; - private boolean closed; + private final ScissorState scissorState = new ScissorState(); @Nullable protected RenderPipeline pipeline; - protected final GpuBuffer[] vertexBuffers = new GpuBuffer[1]; @Nullable protected GpuBuffer indexBuffer; protected VertexFormat.IndexType indexType = VertexFormat.IndexType.INT; - private final ScissorState scissorState = new ScissorState(); - protected final HashMap uniforms = new HashMap<>(); - protected final HashMap samplers = new HashMap<>(); - protected final Set dirtyUniforms = new HashSet<>(); protected int pushedDebugGroups; + private boolean closed; public VkRenderPass(VkCommandEncoder commandEncoder, boolean bl) { this.encoder = commandEncoder; @@ -71,20 +69,6 @@ public void popDebugGroup() { } } - @Override - public void setPipeline(RenderPipeline renderPipeline) { - if (this.pipeline == null || this.pipeline != renderPipeline) { - this.dirtyUniforms.addAll(this.uniforms.keySet()); - } - - - this.pipeline = renderPipeline; - - if (ExtendedRenderPipeline.of(renderPipeline).getPipeline() == null) { - this.encoder.getDevice().compilePipeline(renderPipeline); - } - } - @Override public void bindSampler(String string, @Nullable GpuTextureView gpuTextureView) { if (gpuTextureView == null) { @@ -143,7 +127,9 @@ public int getScissorHeight() { return this.scissorState.height(); } - public ScissorState getScissorState() { return this.scissorState; } + public ScissorState getScissorState() { + return this.scissorState; + } @Override public void setVertexBuffer(int i, GpuBuffer gpuBuffer) { @@ -208,5 +194,19 @@ public void close() { public @Nullable RenderPipeline getPipeline() { return pipeline; } + + @Override + public void setPipeline(RenderPipeline renderPipeline) { + if (this.pipeline == null || this.pipeline != renderPipeline) { + this.dirtyUniforms.addAll(this.uniforms.keySet()); + } + + + this.pipeline = renderPipeline; + + if (ExtendedRenderPipeline.of(renderPipeline).getPipeline() == null) { + this.encoder.getDevice().compilePipeline(renderPipeline); + } + } } diff --git a/src/main/java/net/vulkanmod/render/model/CubeModel.java b/src/main/java/net/vulkanmod/render/model/CubeModel.java index ef5bb5548..1439893a8 100644 --- a/src/main/java/net/vulkanmod/render/model/CubeModel.java +++ b/src/main/java/net/vulkanmod/render/model/CubeModel.java @@ -9,15 +9,14 @@ public class CubeModel { - private Polygon[] polygons; public float minX; public float minY; public float minZ; public float maxX; public float maxY; public float maxZ; - Vertex[] vertices; + private Polygon[] polygons; public void setVertices(int u, int v, float minX, float minY, float minZ, float dimX, float dimY, float dimZ, float growX, float growY, float growZ, boolean mirror, float uTexScale, float vTexScale, Set set) { this.minX = minX; @@ -44,24 +43,24 @@ public void setVertices(int u, int v, float minX, float minY, float minZ, float this.vertices = new Vertex[]{ new Vertex(minX, minY, minZ, 0.0F, 0.0F), - new Vertex(s, minY, minZ, 0.0F, 8.0F), - new Vertex(s, t, minZ, 8.0F, 8.0F), - new Vertex(minX, t, minZ, 8.0F, 0.0F), - new Vertex(minX, minY, u1, 0.0F, 0.0F), - new Vertex(s, minY, u1, 0.0F, 8.0F), - new Vertex(s, t, u1, 8.0F, 8.0F), - new Vertex(minX, t, u1, 8.0F, 0.0F) + new Vertex(s, minY, minZ, 0.0F, 8.0F), + new Vertex(s, t, minZ, 8.0F, 8.0F), + new Vertex(minX, t, minZ, 8.0F, 0.0F), + new Vertex(minX, minY, u1, 0.0F, 0.0F), + new Vertex(s, minY, u1, 0.0F, 8.0F), + new Vertex(s, t, u1, 8.0F, 8.0F), + new Vertex(minX, t, u1, 8.0F, 0.0F) }; - float w = (float)u; - float x = (float)u + dimZ; - float y = (float)u + dimZ + dimX; - float z = (float)u + dimZ + dimX + dimX; - float aa = (float)u + dimZ + dimX + dimZ; - float ab = (float)u + dimZ + dimX + dimZ + dimX; - float ac = (float)v; - float ad = (float)v + dimZ; - float ae = (float)v + dimZ + dimY; + float w = (float) u; + float x = (float) u + dimZ; + float y = (float) u + dimZ + dimX; + float z = (float) u + dimZ + dimX + dimX; + float aa = (float) u + dimZ + dimX + dimZ; + float ab = (float) u + dimZ + dimX + dimZ + dimX; + float ac = (float) v; + float ad = (float) v + dimZ; + float ae = (float) v + dimZ + dimY; Vertex vertex1 = this.vertices[0]; Vertex vertex2 = this.vertices[1]; 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 d87df233d..9316097c1 100644 --- a/src/main/java/net/vulkanmod/render/model/quad/ModelQuad.java +++ b/src/main/java/net/vulkanmod/render/model/quad/ModelQuad.java @@ -9,23 +9,24 @@ */ public class ModelQuad implements ModelQuadView { public static final int VERTEX_SIZE = 8; + private final int[] data = new int[4 * VERTEX_SIZE]; + Direction direction; + TextureAtlasSprite sprite; + private int flags; public static int vertexOffset(int vertexIndex) { return vertexIndex * VERTEX_SIZE; } - private final int[] data = new int[4 * VERTEX_SIZE]; - - Direction direction; - TextureAtlasSprite sprite; - - private int flags; - @Override public int getFlags() { return flags; } + public void setFlags(int f) { + this.flags = f; + } + @Override public float getX(int idx) { return Float.intBitsToFloat(this.data[vertexOffset(idx)]); @@ -104,10 +105,6 @@ public float setV(int idx, float f) { } - public void setFlags(int f) { - this.flags = f; - } - public void setSprite(TextureAtlasSprite sprite) { this.sprite = sprite; } 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 bb1dc0cca..41bd087c7 100644 --- a/src/main/java/net/vulkanmod/render/model/quad/ModelQuadFlags.java +++ b/src/main/java/net/vulkanmod/render/model/quad/ModelQuadFlags.java @@ -51,7 +51,7 @@ public static int getQuadFlags(ModelQuadView quad, Direction face) { case Z -> minX >= 0.0001f || minY >= 0.0001f || maxX <= 0.9999F || maxY <= 0.9999F; }; - boolean parallel = switch(face.getAxis()) { + boolean parallel = switch (face.getAxis()) { case X -> minX == maxX; case Y -> minY == maxY; case Z -> minZ == maxZ; diff --git a/src/main/java/net/vulkanmod/render/model/quad/QuadUtils.java b/src/main/java/net/vulkanmod/render/model/quad/QuadUtils.java index 9f7c7f1d7..f1500d1c4 100644 --- a/src/main/java/net/vulkanmod/render/model/quad/QuadUtils.java +++ b/src/main/java/net/vulkanmod/render/model/quad/QuadUtils.java @@ -10,9 +10,9 @@ public abstract class QuadUtils { public static int getIterationStartIdx(float[] aos, int[] lms) { final float ao00_11 = aos[0] + aos[2]; final float ao10_01 = aos[1] + aos[3]; - if(ao00_11 > ao10_01) { + if (ao00_11 > ao10_01) { return DEFAULT_START_IDX; - } else if(ao00_11 < ao10_01) { + } else if (ao00_11 < ao10_01) { return FLIPPED_START_IDX; } @@ -24,7 +24,7 @@ public static int getIterationStartIdx(float[] aos, int[] lms) { // return FLIPPED_START_IDX; // } - if(lm00_11 >= lm10_01) { + if (lm00_11 >= lm10_01) { return FLIPPED_START_IDX; } else { return DEFAULT_START_IDX; @@ -37,7 +37,7 @@ public static int getIterationStartIdx(float[] aos, int[] lms) { public static int getIterationStartIdx(float[] aos) { final float ao00_11 = aos[0] + aos[2]; final float ao10_01 = aos[1] + aos[3]; - if(ao00_11 >= ao10_01) { + if (ao00_11 >= ao10_01) { return DEFAULT_START_IDX; } else { return FLIPPED_START_IDX; diff --git a/src/main/java/net/vulkanmod/render/profiling/BuildTimeProfiler.java b/src/main/java/net/vulkanmod/render/profiling/BuildTimeProfiler.java index f93c28fb7..e7455a599 100644 --- a/src/main/java/net/vulkanmod/render/profiling/BuildTimeProfiler.java +++ b/src/main/java/net/vulkanmod/render/profiling/BuildTimeProfiler.java @@ -9,12 +9,12 @@ public abstract class BuildTimeProfiler { private static float deltaTime; public static void runBench(boolean building) { - if(bench) { + if (bench) { if (startTime == 0) { startTime = System.nanoTime(); } - if(!building) { + if (!building) { deltaTime = (System.nanoTime() - startTime) * 0.000001f; bench = false; startTime = 0; diff --git a/src/main/java/net/vulkanmod/render/profiling/Profiler.java b/src/main/java/net/vulkanmod/render/profiling/Profiler.java index ccfe5cb59..4287d36b5 100644 --- a/src/main/java/net/vulkanmod/render/profiling/Profiler.java +++ b/src/main/java/net/vulkanmod/render/profiling/Profiler.java @@ -16,41 +16,33 @@ public class Profiler { private static final float CONVERSION = NANOS_IN_MS; private static final float INV_CONVERSION = 1.0f / CONVERSION; private static final int SAMPLE_COUNT = 200; - - public static boolean ACTIVE = FORCE_ACTIVE; - private static final Profiler MAIN_PROFILER = new Profiler("Main"); - - public static Profiler getMainProfiler() { - return MAIN_PROFILER; - } - - public static void setActive(boolean b) { - if (!FORCE_ACTIVE) - ACTIVE = b; - - } - + public static boolean ACTIVE = FORCE_ACTIVE; private final String name; - LongArrayList startTimes = new LongArrayList(); ObjectArrayList nodeStack = new ObjectArrayList<>(); - ObjectArrayList nodes = new ObjectArrayList<>(); ObjectArrayList currentFrameNodes = new ObjectArrayList<>(); Object2ReferenceOpenHashMap nodeMap = new Object2ReferenceOpenHashMap<>(); - Node mainNode; Node selectedNode; Node currentNode; - ProfilerResults profilerResults = new ProfilerResults(); - public Profiler(String s) { this.name = s; this.currentNode = this.selectedNode = this.mainNode = new Node(s); } + public static Profiler getMainProfiler() { + return MAIN_PROFILER; + } + + public static void setActive(boolean b) { + if (!FORCE_ACTIVE) + ACTIVE = b; + + } + public void push(String s) { if (!(ACTIVE)) return; diff --git a/src/main/java/net/vulkanmod/render/shader/CustomRenderPipelines.java b/src/main/java/net/vulkanmod/render/shader/CustomRenderPipelines.java index 07ca57f3c..02ba082b1 100644 --- a/src/main/java/net/vulkanmod/render/shader/CustomRenderPipelines.java +++ b/src/main/java/net/vulkanmod/render/shader/CustomRenderPipelines.java @@ -15,12 +15,12 @@ public class CustomRenderPipelines { public static final List pipelines = new ArrayList<>(); public static final RenderPipeline.Snippet GUI_TRIANGLES_SNIPPET = RenderPipeline.builder(RenderPipelines.MATRICES_PROJECTION_SNIPPET) - .withVertexShader("core/gui") - .withFragmentShader("core/gui") - .withBlend(BlendFunction.TRANSLUCENT) - .withVertexFormat(DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.TRIANGLES) - .withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST) - .buildSnippet(); + .withVertexShader("core/gui") + .withFragmentShader("core/gui") + .withBlend(BlendFunction.TRANSLUCENT) + .withVertexFormat(DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.TRIANGLES) + .withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST) + .buildSnippet(); public static final RenderPipeline GUI_TRIANGLES = register(RenderPipeline.builder(GUI_TRIANGLES_SNIPPET).withLocation("pipeline/gui").build()); diff --git a/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java b/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java index 2c7bb5567..86cc2515c 100644 --- a/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java +++ b/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java @@ -10,23 +10,23 @@ import net.vulkanmod.vulkan.shader.SPIRVUtils; import org.apache.commons.io.IOUtils; -import java.io.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; 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; -import java.util.HashSet; -import java.util.Map; import java.util.Set; public abstract class ShaderLoadUtil { + public static final Set REMAPPED_SHADERS = Sets.newHashSet("core/screenquad.vsh", "core/rendertype_item_entity_translucent_cull.vsh"); private static final String RESOURCES_PATH = SPIRVUtils.class.getResource("/assets/vulkanmod").toExternalForm(); - public static final Set REMAPPED_SHADERS = Sets.newHashSet("core/screenquad.vsh","core/rendertype_item_entity_translucent_cull.vsh"); - 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; @@ -220,7 +220,7 @@ public static String removeNameSpace(String path) { public static String[] splitPath(String path) { int idx = path.lastIndexOf('/'); - return new String[] {path.substring(0, idx), path.substring(idx + 1)}; + return new String[]{path.substring(0, idx), path.substring(idx + 1)}; } public static InputStream getInputStream(String path) { diff --git a/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java b/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java index 60943f029..90cfc95f4 100644 --- a/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java +++ b/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java @@ -57,6 +57,32 @@ public CloudRenderer() { loadTexture(); } + 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.getPixelsABGR(); + + return new CloudGrid(pixels, width); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public void loadTexture() { this.cloudGrid = createCloudGrid(TEXTURE_LOCATION); } @@ -82,11 +108,9 @@ public void renderClouds(ClientLevel level, float ticks, float partialTicks, dou byte yState; if (centerY < -4.0f) { yState = Y_BELOW_CLOUDS; - } - else if (centerY > 0.0f) { + } else if (centerY > 0.0f) { yState = Y_ABOVE_CLOUDS; - } - else { + } else { yState = Y_INSIDE_CLOUDS; } @@ -214,25 +238,25 @@ private MeshData buildClouds(Tesselator tesselator, int centerCellX, int centerC if ((renderFaces & DIR_POS_Y_BIT) != 0 && cloudY <= 0.0f) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, upFaceBrightness); putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, color); - putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, color); - putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, color); } if ((renderFaces & DIR_NEG_Y_BIT) != 0 && cloudY >= -CELL_HEIGHT) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, downFaceBrightness); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); } if ((renderFaces & DIR_POS_X_BIT) != 0 && (x < 1.0f || insideClouds)) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, xDirBrightness); putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); - putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, color); } if ((renderFaces & DIR_NEG_X_BIT) != 0 && (x > -1.0f || insideClouds)) { @@ -245,24 +269,23 @@ private MeshData buildClouds(Tesselator tesselator, int centerCellX, int centerC if ((renderFaces & DIR_POS_Z_BIT) != 0 && (z < 1.0f || insideClouds)) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, zDirBrightness); - putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + CELL_WIDTH, color); } if ((renderFaces & DIR_NEG_Z_BIT) != 0 && (z > -1.0f || insideClouds)) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, zDirBrightness); putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); - putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, color); } } } - } - else { + } else { for (int cellX = -renderDistance; cellX < renderDistance; ++cellX) { for (int cellZ = -renderDistance; cellZ < renderDistance; ++cellZ) { @@ -275,9 +298,9 @@ private MeshData buildClouds(Tesselator tesselator, int centerCellX, int centerC if ((renderFaces & DIR_NEG_Y_BIT) != 0) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, upFaceBrightness); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); } @@ -288,32 +311,6 @@ private MeshData buildClouds(Tesselator tesselator, int centerCellX, int centerC 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.getPixelsABGR(); - - return new CloudGrid(pixels, width); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - static class CloudGrid { final int width; final int[] pixels; @@ -326,6 +323,10 @@ static class CloudGrid { this.renderFaces = computeRenderFaces(); } + private static boolean hasColor(int pixel) { + return ((pixel >> 24) & 0xFF) > 1; + } + byte[] computeRenderFaces() { byte[] renderFaces = new byte[pixels.length]; @@ -399,9 +400,5 @@ int getWrappedIdx(int x, int 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/SpriteUpdateUtil.java b/src/main/java/net/vulkanmod/render/texture/SpriteUpdateUtil.java index 82f0ceab2..7e3082cc1 100644 --- a/src/main/java/net/vulkanmod/render/texture/SpriteUpdateUtil.java +++ b/src/main/java/net/vulkanmod/render/texture/SpriteUpdateUtil.java @@ -9,8 +9,8 @@ public abstract class SpriteUpdateUtil { - private static boolean doUpload = true; private static final Set transitionedLayouts = new HashSet<>(); + private static boolean doUpload = true; public static void setDoUpload(boolean b) { doUpload = b; diff --git a/src/main/java/net/vulkanmod/render/util/DrawUtil.java b/src/main/java/net/vulkanmod/render/util/DrawUtil.java index b4e527eb8..46d6dfc65 100644 --- a/src/main/java/net/vulkanmod/render/util/DrawUtil.java +++ b/src/main/java/net/vulkanmod/render/util/DrawUtil.java @@ -1,12 +1,10 @@ package net.vulkanmod.render.util; -import com.mojang.blaze3d.ProjectionType; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.shader.GraphicsPipeline; -import net.vulkanmod.vulkan.shader.Pipeline; import net.vulkanmod.vulkan.texture.VTextureSelector; import net.vulkanmod.vulkan.texture.VulkanImage; import org.joml.Matrix4f; diff --git a/src/main/java/net/vulkanmod/render/util/SortUtil.java b/src/main/java/net/vulkanmod/render/util/SortUtil.java index ef524b6ce..08f6150b5 100644 --- a/src/main/java/net/vulkanmod/render/util/SortUtil.java +++ b/src/main/java/net/vulkanmod/render/util/SortUtil.java @@ -23,13 +23,12 @@ public static void mergeSort(int[] indices, float[] distances, int from, int to, if (Float.compare(distances[supp[mid]], distances[supp[mid - 1]]) <= 0) { System.arraycopy(supp, from, indices, from, len); - } - else { + } else { int i = from; int p = from; - for(int q = mid; i < to; ++i) { - if (q < to && (p >= mid || Float.compare(distances[supp[q]], distances[supp[p]]) > 0)) { + for (int q = mid; i < to; ++i) { + if (q < to && (p >= mid || Float.compare(distances[supp[q]], distances[supp[p]]) > 0)) { indices[i] = supp[q++]; } else { indices[i] = supp[p++]; @@ -68,33 +67,31 @@ public static void quickSort(int[] is, float[] distances, int from, int to) { swap(is, m, d); float mValue = distances[v]; - while(true) { + while (true) { - while(b < c) { - if(Float.compare(distances[is[b]], mValue) > 0) { - while(b < c) { - if(Float.compare(distances[is[c]], mValue) < 0) { + while (b < c) { + if (Float.compare(distances[is[b]], mValue) > 0) { + while (b < c) { + if (Float.compare(distances[is[c]], mValue) < 0) { swap(is, b, c); b++; c--; break; - } - else { + } else { c--; } } - } - else { + } else { b++; } } swap(is, d, b); - if(b - a > 1) + if (b - a > 1) quickSort(is, distances, a, b); - if(d - b > 1) + if (d - b > 1) quickSort(is, distances, b, d); return; @@ -106,7 +103,7 @@ public static void quickSort(int[] is, float[] distances, int from, int to) { private static void insertionSort(int[] is, float[] distances, int from, int to) { int i = from; - while(true) { + while (true) { ++i; if (i >= to) { return; @@ -115,7 +112,7 @@ private static void insertionSort(int[] is, float[] distances, int from, int to) int t = is[i]; int j = i; - for(int u = is[i - 1]; Float.compare(distances[u], distances[t]) < 0; u = is[j - 1]) { + for (int u = is[i - 1]; Float.compare(distances[u], distances[t]) < 0; u = is[j - 1]) { is[j] = u; if (from == j - 1) { --j; @@ -130,7 +127,7 @@ private static void insertionSort(int[] is, float[] distances, int from, int to) } public static void swap(int[] x, int a, int b, int n) { - for(int i = 0; i < n; ++b, ++i, ++a) { + for (int i = 0; i < n; ++b, ++i, ++a) { swap(x, a, b); } diff --git a/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java b/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java index 437345ff8..9d596da15 100644 --- a/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java +++ b/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java @@ -5,16 +5,16 @@ 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_POSITION = new VertexFormatElement(0, 0, VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.POSITION, 4); public static final VertexFormatElement ELEMENT_COLOR = new VertexFormatElement(1, 0, VertexFormatElement.Type.UINT, VertexFormatElement.Usage.COLOR, 1); public static final VertexFormatElement ELEMENT_UV0 = new VertexFormatElement(2, 0, VertexFormatElement.Type.USHORT, VertexFormatElement.Usage.UV, 2); public static final VertexFormat COMPRESSED_TERRAIN = VertexFormat.builder() - .add("Position", ELEMENT_POSITION) - .add("UV0", ELEMENT_UV0) - .add("Color", ELEMENT_COLOR) - .build(); + .add("Position", ELEMENT_POSITION) + .add("UV0", ELEMENT_UV0) + .add("Color", ELEMENT_COLOR) + .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 91c26a129..50cfcb523 100644 --- a/src/main/java/net/vulkanmod/render/vertex/QuadSorter.java +++ b/src/main/java/net/vulkanmod/render/vertex/QuadSorter.java @@ -55,10 +55,10 @@ public void setupQuadSortingPoints(long bufferPtr, int vertexCount, VertexFormat for (int m = 0; m < pointCount; ++m) { long ptr = bufferPtr + (long) m * quadStride; - short x0 = MemoryUtil.memGetShort(ptr + 0); + short x0 = MemoryUtil.memGetShort(ptr); short y0 = MemoryUtil.memGetShort(ptr + 2); short z0 = MemoryUtil.memGetShort(ptr + 4); - short x2 = MemoryUtil.memGetShort(ptr + offset + 0); + short x2 = MemoryUtil.memGetShort(ptr + offset); short y2 = MemoryUtil.memGetShort(ptr + offset + 2); short z2 = MemoryUtil.memGetShort(ptr + offset + 4); @@ -71,10 +71,10 @@ public void setupQuadSortingPoints(long bufferPtr, int vertexCount, VertexFormat for (int m = 0; m < pointCount; ++m) { long ptr = bufferPtr + (long) m * quadStride; - float x0 = MemoryUtil.memGetFloat(ptr + 0); + float x0 = MemoryUtil.memGetFloat(ptr); float y0 = MemoryUtil.memGetFloat(ptr + 4); float z0 = MemoryUtil.memGetFloat(ptr + 8); - float x2 = MemoryUtil.memGetFloat(ptr + offset + 0); + float x2 = MemoryUtil.memGetFloat(ptr + offset); float y2 = MemoryUtil.memGetFloat(ptr + offset + 4); float z2 = MemoryUtil.memGetFloat(ptr + offset + 8); @@ -111,12 +111,12 @@ public void putSortedQuadIndices(TerrainBufferBuilder bufferBuilder, VertexForma 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 + (0L), baseVertex); + MemoryUtil.memPutInt(ptr + ((long) size), 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); + MemoryUtil.memPutInt(ptr + (size * 5L), baseVertex); ptr += size * 6L; } @@ -143,12 +143,12 @@ public void putSortedQuadIndices(TerrainBuilder bufferBuilder, VertexFormat.Inde final int quadIndex = sortingPoints[i]; final int baseVertex = quadIndex * stride; - MemoryUtil.memPutInt(ptr + (size * 0L), baseVertex + 0); - MemoryUtil.memPutInt(ptr + (size * 1L), baseVertex + 1); + MemoryUtil.memPutInt(ptr + (0L), baseVertex); + MemoryUtil.memPutInt(ptr + ((long) size), 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); + MemoryUtil.memPutInt(ptr + (size * 5L), baseVertex); ptr += size * 6L; } diff --git a/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java b/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java index 9e8651dae..d25fce8fe 100644 --- a/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java @@ -11,18 +11,14 @@ public class TerrainBufferBuilder implements VertexConsumer { private static final Logger LOGGER = Initializer.LOGGER; private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false); - - private int capacity; - private int vertexSize; - protected long bufferPtr; - protected int nextElementByte; int vertices; + private int capacity; + private final int vertexSize; + private long elementPtr; - private long elementPtr; - - private VertexBuilder vertexBuilder; + private final VertexBuilder vertexBuilder; public TerrainBufferBuilder(int size, int vertexSize, VertexBuilder vertexBuilder) { this.bufferPtr = ALLOCATOR.malloc(size); @@ -88,54 +84,54 @@ public int getNextElementByte() { return nextElementByte; } - @Override - public VertexConsumer addVertex(float x, float y, float z) { - this.elementPtr = this.bufferPtr + this.nextElementByte; - this.endVertex(); + @Override + public VertexConsumer addVertex(float x, float y, float z) { + this.elementPtr = this.bufferPtr + this.nextElementByte; + this.endVertex(); - this.vertexBuilder.position(this.elementPtr, x, y, z); + this.vertexBuilder.position(this.elementPtr, x, y, z); - return this; - } + return this; + } - @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); + @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); - this.vertexBuilder.color(this.elementPtr, color); + this.vertexBuilder.color(this.elementPtr, color); - return this; - } + return this; + } - @Override - public VertexConsumer setUv(float u, float v) { - this.vertexBuilder.uv(this.elementPtr, u, v); + @Override + public VertexConsumer setUv(float u, float v) { + this.vertexBuilder.uv(this.elementPtr, u, v); - return this; - } + return this; + } - public VertexConsumer setLight(int i) { - this.vertexBuilder.light(this.elementPtr, i); + public VertexConsumer setLight(int i) { + this.vertexBuilder.light(this.elementPtr, i); - return this; - } + return this; + } - @Override - public VertexConsumer setNormal(float f, float g, float h) { - int packedNormal = I32_SNorm.packNormal(f, g, h); + @Override + public VertexConsumer setNormal(float f, float g, float h) { + int packedNormal = I32_SNorm.packNormal(f, g, h); - this.vertexBuilder.normal(this.elementPtr, packedNormal); + this.vertexBuilder.normal(this.elementPtr, packedNormal); - return this; - } + return this; + } - @Override - public VertexConsumer setUv1(int i, int j) { - return this; - } + @Override + public VertexConsumer setUv1(int i, int j) { + return this; + } - @Override - public VertexConsumer setUv2(int i, int j) { - return this; - } + @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 index f12c69a17..188604ca2 100644 --- a/src/main/java/net/vulkanmod/render/vertex/TerrainBuilder.java +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainBuilder.java @@ -13,25 +13,17 @@ public class TerrainBuilder { private static final Logger LOGGER = Initializer.LOGGER; private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false); - + private final VertexFormat format; + private final QuadSorter quadSorter = new QuadSorter(); + private final TerrainBufferBuilder[] bufferBuilders; protected long indexBufferPtr; - - private int indexBufferCapacity; protected long bufferPtr; - - private final VertexFormat format; - + protected VertexBuilder vertexBuilder; + private int indexBufferCapacity; 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); diff --git a/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java b/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java index 2c1281920..83c53854a 100644 --- a/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java @@ -38,12 +38,8 @@ public enum TerrainRenderType { this.alphaCutout = alphaCutout; } - public void setCutoutUniform() { - VRenderSystem.alphaCutout = this.alphaCutout; - } - public static TerrainRenderType get(RenderType renderType) { - return ((ExtendedRenderType)renderType).getTerrainRenderType(); + return ((ExtendedRenderType) renderType).getTerrainRenderType(); } public static TerrainRenderType get(ChunkSectionLayer layer) { @@ -95,4 +91,8 @@ public static void updateMapping() { public static TerrainRenderType getRemapped(TerrainRenderType renderType) { return remapper.apply(renderType); } + + public void setCutoutUniform() { + VRenderSystem.alphaCutout = this.alphaCutout; + } } diff --git a/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java b/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java index 5f6555459..4a8d0f0eb 100644 --- a/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java +++ b/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java @@ -21,7 +21,7 @@ class DefaultVertexBuilder implements VertexBuilder { private static final int VERTEX_SIZE = 32; public void vertex(long ptr, float x, float y, float z, int color, float u, float v, int light, int packedNormal) { - MemoryUtil.memPutFloat(ptr + 0, x); + MemoryUtil.memPutFloat(ptr, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); @@ -69,20 +69,18 @@ public int getStride() { } class CompressedVertexBuilder implements VertexBuilder { - 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; + private static final int VERTEX_SIZE = 16; 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); 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, sX); MemoryUtil.memPutShort(ptr + 2, sY); MemoryUtil.memPutShort(ptr + 4, sZ); @@ -101,7 +99,7 @@ public void position(long ptr, float x, float y, float z) { 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, sX); MemoryUtil.memPutShort(ptr + 2, sY); MemoryUtil.memPutShort(ptr + 4, sZ); } diff --git a/src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java b/src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java index fb8366991..e1e4923d2 100644 --- a/src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java +++ b/src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java @@ -8,22 +8,22 @@ public static int packNormal(float x, float y, float z) { y *= 127.0f; z *= 127.0f; - return ((int)x & 0xFF) | ((int)y & 0xFF) << 8| ((int)z & 0xFF) << 16; + return ((int) x & 0xFF) | ((int) y & 0xFF) << 8 | ((int) z & 0xFF) << 16; } public static int packNormal(int x, int y, int z) { - return (x & 0xFF) | (y & 0xFF) << 8| (z & 0xFF) << 16; + return (x & 0xFF) | (y & 0xFF) << 8 | (z & 0xFF) << 16; } public static float unpackX(int i) { - return (byte)(i & 0xFF) * NORM_INV; + return (byte) (i & 0xFF) * NORM_INV; } public static float unpackY(int i) { - return (byte)((i >> 8) & 0xFF) * NORM_INV; + return (byte) ((i >> 8) & 0xFF) * NORM_INV; } public static float unpackZ(int i) { - return (byte)((i >> 16) & 0xFF) * NORM_INV; + 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 fd2ae33f8..a0928c0a4 100644 --- a/src/main/java/net/vulkanmod/vulkan/Drawer.java +++ b/src/main/java/net/vulkanmod/vulkan/Drawer.java @@ -1,7 +1,8 @@ package net.vulkanmod.vulkan; import com.mojang.blaze3d.vertex.VertexFormat; -import net.vulkanmod.vulkan.memory.*; +import net.vulkanmod.vulkan.memory.MemoryManager; +import net.vulkanmod.vulkan.memory.MemoryTypes; import net.vulkanmod.vulkan.memory.buffer.Buffer; import net.vulkanmod.vulkan.memory.buffer.IndexBuffer; import net.vulkanmod.vulkan.memory.buffer.UniformBuffer; @@ -26,18 +27,15 @@ public class Drawer { private static final LongBuffer offsets = MemoryUtil.memAllocLong(1); private static final long pBuffers = MemoryUtil.memAddress0(buffers); private static final long pOffsets = MemoryUtil.memAddress0(offsets); - - 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 int framesNum; + private VertexBuffer[] vertexBuffers; + private IndexBuffer[] indexBuffers; private UniformBuffer[] uniformBuffers; private int currentFrame; @@ -106,8 +104,7 @@ public void draw(ByteBuffer vertexData, ByteBuffer indexData, VertexFormat.Mode int indexCount = vertexCount * 3 / 2; drawIndexed(vertexBuffer, indexBuffer, indexCount); - } - else { + } else { AutoIndexBuffer autoIndexBuffer = getAutoIndexBuffer(mode, vertexCount); if (autoIndexBuffer != null) { @@ -115,15 +112,14 @@ public void draw(ByteBuffer vertexData, ByteBuffer indexData, VertexFormat.Mode autoIndexBuffer.checkCapacity(indexCount); drawIndexed(vertexBuffer, autoIndexBuffer.getIndexBuffer(), indexCount); - } - else { + } else { draw(vertexBuffer, vertexCount); } } } public void drawIndexed(Buffer vertexBuffer, IndexBuffer indexBuffer, int indexCount) { - drawIndexed(vertexBuffer, indexBuffer, indexCount, indexBuffer.indexType.value); + drawIndexed(vertexBuffer, indexBuffer, indexCount, indexBuffer.indexType.value); } public void drawIndexed(Buffer vertexBuffer, Buffer indexBuffer, int indexCount, int indexType) { @@ -209,6 +205,6 @@ public AutoIndexBuffer getAutoIndexBuffer(VertexFormat.Mode mode, int vertexCoun 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 5e5a30f75..6576e8b00 100644 --- a/src/main/java/net/vulkanmod/vulkan/Renderer.java +++ b/src/main/java/net/vulkanmod/vulkan/Renderer.java @@ -40,7 +40,8 @@ import java.util.List; import java.util.Set; -import static net.vulkanmod.vulkan.Vulkan.*; +import static net.vulkanmod.vulkan.Vulkan.createStagingBuffers; +import static net.vulkanmod.vulkan.Vulkan.getCommandPool; import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; import static org.lwjgl.system.MemoryStack.stackPush; @@ -49,12 +50,38 @@ import static org.lwjgl.vulkan.VK10.*; public class Renderer { + public static boolean skipRendering = false; private static Renderer INSTANCE; - private static VkDevice device; - private static boolean swapChainUpdate = false; - public static boolean skipRendering = false; + private static int currentFrame = 0; + private static int imageIndex; + private static int lastReset = -1; + private final Set usedPipelines = new ObjectOpenHashSet<>(); + private final List onResizeCallbacks = new ObjectArrayList<>(); + MainPass mainPass; + private Pipeline boundPipeline; + private long boundPipelineHandle; + + private Drawer drawer; + + private SwapChain swapChain; + + private int framesNum; + private List commandBuffers; + private ArrayList imageAvailableSemaphores; + private ArrayList renderFinishedSemaphores; + private ArrayList inFlightFences; + private List transferCbs; + + private Framebuffer boundFramebuffer; + private RenderPass boundRenderPass; + private VkCommandBuffer currentCmdBuffer; + private boolean recordingCmds = false; + public Renderer() { + device = Vulkan.getVkDevice(); + framesNum = Initializer.CONFIG.frameQueueSize; + } public static void initRenderer() { INSTANCE = new Renderer(); @@ -77,44 +104,212 @@ public static int getCurrentImage() { return imageIndex; } - private final Set usedPipelines = new ObjectOpenHashSet<>(); - private Pipeline boundPipeline; - private long boundPipelineHandle; + public static void setLineWidth(float width) { + if (INSTANCE.boundFramebuffer == null) { + return; + } + vkCmdSetLineWidth(INSTANCE.currentCmdBuffer, width); + } - private Drawer drawer; + private static void resetDynamicState(VkCommandBuffer commandBuffer) { + vkCmdSetDepthBias(commandBuffer, 0.0F, 0.0F, 0.0F); - private SwapChain swapChain; + vkCmdSetLineWidth(commandBuffer, 1.0F); + } - private int framesNum; - private List commandBuffers; - private ArrayList imageAvailableSemaphores; - private ArrayList renderFinishedSemaphores; - private ArrayList inFlightFences; - private List transferCbs; + public static void setDepthBias(float constant, float slope) { + VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; - private Framebuffer boundFramebuffer; - private RenderPass boundRenderPass; + vkCmdSetDepthBias(commandBuffer, constant, 0.0f, slope); + } - private static int currentFrame = 0; - private static int imageIndex; - private static int lastReset = -1; - private VkCommandBuffer currentCmdBuffer; - private boolean recordingCmds = false; + public static void clearAttachments(int attachments) { + clearAttachments(INSTANCE.currentCmdBuffer, attachments); + } - MainPass mainPass; + public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments) { + Framebuffer framebuffer = Renderer.getInstance().boundFramebuffer; + if (framebuffer == null) + return; - private final List onResizeCallbacks = new ObjectArrayList<>(); + clearAttachments(commandBuffer, attachments, framebuffer.getWidth(), framebuffer.getHeight()); + } - public Renderer() { - device = Vulkan.getVkDevice(); - framesNum = Initializer.CONFIG.frameQueueSize; + public static void clearAttachments(int attachments, int width, int height) { + clearAttachments(INSTANCE.currentCmdBuffer, attachments, width, height); } - public static void setLineWidth(float width) { - if (INSTANCE.boundFramebuffer == null) { + public static void clearAttachments(int attachments, int x, int y, int width, int height) { + clearAttachments(INSTANCE.currentCmdBuffer, attachments, x, y, width, height); + } + + public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments, int width, int height) { + clearAttachments(commandBuffer, attachments, 0, 0, width, height); + } + + public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments, int x, int y, int width, int height) { + if (skipRendering) return; + + try (MemoryStack stack = stackPush()) { + //ClearValues have to be different for each attachment to clear, + //it seems it uses the same buffer: color and depth values override themselves + VkClearValue colorValue = VkClearValue.calloc(stack); + colorValue.color().float32(VRenderSystem.clearColor); + + VkClearValue depthValue = VkClearValue.calloc(stack); + depthValue.depthStencil().set(VRenderSystem.clearDepthValue, 0); //Use fast depth clears if possible + + int attachmentsCount = attachments == (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT) ? 2 : 1; + final VkClearAttachment.Buffer pAttachments = VkClearAttachment.malloc(attachmentsCount, stack); + switch (attachments) { + case GL_DEPTH_BUFFER_BIT -> { + + VkClearAttachment clearDepth = pAttachments.get(0); + clearDepth.aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); + clearDepth.colorAttachment(0); + clearDepth.clearValue(depthValue); + } + case GL_COLOR_BUFFER_BIT -> { + + VkClearAttachment clearColor = pAttachments.get(0); + clearColor.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); + clearColor.colorAttachment(0); + clearColor.clearValue(colorValue); + } + case GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT -> { + + VkClearAttachment clearColor = pAttachments.get(0); + clearColor.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); + clearColor.colorAttachment(0); + clearColor.clearValue(colorValue); + + VkClearAttachment clearDepth = pAttachments.get(1); + clearDepth.aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); + clearDepth.colorAttachment(0); + clearDepth.clearValue(depthValue); + } + default -> throw new RuntimeException("unexpected value"); + } + + //Rect to clear + VkRect2D renderArea = VkRect2D.malloc(stack); + renderArea.offset().set(x, y); + renderArea.extent().set(width, height); + + VkClearRect.Buffer pRect = VkClearRect.malloc(1, stack); + pRect.rect(renderArea); + pRect.baseArrayLayer(0); + pRect.layerCount(1); + + vkCmdClearAttachments(commandBuffer, pAttachments, pRect); + } + } + + public static void setInvertedViewport(int x, int y, int width, int 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) { + try (MemoryStack stack = stackPush()) { + setViewport(x, y, width, height, stack); + } + } + + public static void setViewport(int x, int y, int width, int height, MemoryStack stack) { + if (!INSTANCE.recordingCmds) + return; + + VkViewport.Buffer viewport = VkViewport.malloc(1, stack); + viewport.x(x); + viewport.y(height + y); + 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.recordingCmds || INSTANCE.boundFramebuffer == null) + return; + + try (MemoryStack stack = stackPush()) { + int framebufferHeight = INSTANCE.boundFramebuffer.getHeight(); + + x = Math.max(0, x); + + VkRect2D.Buffer scissor = VkRect2D.malloc(1, stack); + scissor.offset().set(x, framebufferHeight - (y + height)); + scissor.extent().set(width, height); + + vkCmdSetScissor(INSTANCE.currentCmdBuffer, 0, scissor); + } + } + + public static void resetScissor() { + if (INSTANCE.boundFramebuffer == null) + return; + + try (MemoryStack stack = stackPush()) { + VkRect2D.Buffer scissor = INSTANCE.boundFramebuffer.scissor(stack); + vkCmdSetScissor(INSTANCE.currentCmdBuffer, 0, scissor); } - vkCmdSetLineWidth(INSTANCE.currentCmdBuffer, width); + } + + public static void pushDebugSection(String s) { + if (Vulkan.ENABLE_VALIDATION_LAYERS) { + VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; + + try (MemoryStack stack = stackPush()) { + VkDebugUtilsLabelEXT markerInfo = VkDebugUtilsLabelEXT.calloc(stack); + markerInfo.sType(VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT); + ByteBuffer string = stack.UTF8(s); + markerInfo.pLabelName(string); + vkCmdBeginDebugUtilsLabelEXT(commandBuffer, markerInfo); + } + } + } + + public static void popDebugSection() { + if (Vulkan.ENABLE_VALIDATION_LAYERS) { + VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; + + vkCmdEndDebugUtilsLabelEXT(commandBuffer); + } + } + + public static void popPushDebugSection(String s) { + popDebugSection(); + pushDebugSection(s); + } + + public static int getFramesNum() { + return INSTANCE.framesNum; + } + + public static VkCommandBuffer getCommandBuffer() { + return INSTANCE.currentCmdBuffer; + } + + public static boolean isRecording() { + return INSTANCE.recordingCmds; + } + + public static void scheduleSwapChainUpdate() { + swapChainUpdate = true; } private void init() { @@ -196,8 +391,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); } @@ -271,7 +466,7 @@ public void beginFrame() { IntBuffer pImageIndex = stack.mallocInt(1); int vkResult = vkAcquireNextImageKHR(device, swapChain.getId(), VUtil.UINT64_MAX, - imageAvailableSemaphores.get(currentFrame), VK_NULL_HANDLE, pImageIndex); + imageAvailableSemaphores.get(currentFrame), VK_NULL_HANDLE, pImageIndex); if (vkResult == VK_SUBOPTIMAL_KHR || vkResult == VK_ERROR_OUT_OF_DATE_KHR || swapChainUpdate) { swapChainUpdate = true; @@ -488,9 +683,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().vkQueue(), info, inFlightFences.get(currentFrame)); vkWaitForFences(device, inFlightFences.get(currentFrame), true, -1); @@ -600,30 +795,30 @@ public Pipeline getBoundPipeline() { return boundPipeline; } - public void setBoundFramebuffer(Framebuffer framebuffer) { - this.boundFramebuffer = framebuffer; - } - public Framebuffer getBoundFramebuffer() { return boundFramebuffer; } - public void setBoundRenderPass(RenderPass boundRenderPass) { - this.boundRenderPass = boundRenderPass; + public void setBoundFramebuffer(Framebuffer framebuffer) { + this.boundFramebuffer = framebuffer; } public RenderPass getBoundRenderPass() { return boundRenderPass; } - public void setMainPass(MainPass mainPass) { - this.mainPass = mainPass; + public void setBoundRenderPass(RenderPass boundRenderPass) { + this.boundRenderPass = boundRenderPass; } public MainPass getMainPass() { return this.mainPass; } + public void setMainPass(MainPass mainPass) { + this.mainPass = mainPass; + } + public SwapChain getSwapChain() { return swapChain; } @@ -631,205 +826,4 @@ public SwapChain getSwapChain() { public CommandPool.CommandBuffer getTransferCb() { return transferCbs.get(currentFrame); } - - private static void resetDynamicState(VkCommandBuffer commandBuffer) { - vkCmdSetDepthBias(commandBuffer, 0.0F, 0.0F, 0.0F); - - vkCmdSetLineWidth(commandBuffer, 1.0F); - } - - public static void setDepthBias(float constant, float slope) { - VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; - - vkCmdSetDepthBias(commandBuffer, constant, 0.0f, slope); - } - - public static void clearAttachments(int attachments) { - clearAttachments(INSTANCE.currentCmdBuffer, attachments); - } - - public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments) { - Framebuffer framebuffer = Renderer.getInstance().boundFramebuffer; - if (framebuffer == null) - return; - - clearAttachments(commandBuffer, attachments, framebuffer.getWidth(), framebuffer.getHeight()); - } - - public static void clearAttachments(int attachments, int width, int height) { - clearAttachments(INSTANCE.currentCmdBuffer, attachments, width ,height); - } - - public static void clearAttachments(int attachments, int x, int y, int width, int height) { - clearAttachments(INSTANCE.currentCmdBuffer, attachments, x, y, width ,height); - } - - public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments, int width, int height) { - clearAttachments(commandBuffer, attachments, 0, 0, width, height); - } - - public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments, int x, int y, int width, int height) { - if (skipRendering) - return; - - try (MemoryStack stack = stackPush()) { - //ClearValues have to be different for each attachment to clear, - //it seems it uses the same buffer: color and depth values override themselves - VkClearValue colorValue = VkClearValue.calloc(stack); - colorValue.color().float32(VRenderSystem.clearColor); - - VkClearValue depthValue = VkClearValue.calloc(stack); - depthValue.depthStencil().set(VRenderSystem.clearDepthValue, 0); //Use fast depth clears if possible - - int attachmentsCount = attachments == (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT) ? 2 : 1; - final VkClearAttachment.Buffer pAttachments = VkClearAttachment.malloc(attachmentsCount, stack); - switch (attachments) { - case GL_DEPTH_BUFFER_BIT -> { - - VkClearAttachment clearDepth = pAttachments.get(0); - clearDepth.aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); - clearDepth.colorAttachment(0); - clearDepth.clearValue(depthValue); - } - case GL_COLOR_BUFFER_BIT -> { - - VkClearAttachment clearColor = pAttachments.get(0); - clearColor.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); - clearColor.colorAttachment(0); - clearColor.clearValue(colorValue); - } - case GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT -> { - - VkClearAttachment clearColor = pAttachments.get(0); - clearColor.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); - clearColor.colorAttachment(0); - clearColor.clearValue(colorValue); - - VkClearAttachment clearDepth = pAttachments.get(1); - clearDepth.aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); - clearDepth.colorAttachment(0); - clearDepth.clearValue(depthValue); - } - default -> throw new RuntimeException("unexpected value"); - } - - //Rect to clear - VkRect2D renderArea = VkRect2D.malloc(stack); - renderArea.offset().set(x, y); - renderArea.extent().set(width, height); - - VkClearRect.Buffer pRect = VkClearRect.malloc(1, stack); - pRect.rect(renderArea); - pRect.baseArrayLayer(0); - pRect.layerCount(1); - - vkCmdClearAttachments(commandBuffer, pAttachments, pRect); - } - } - - public static void setInvertedViewport(int x, int y, int width, int 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) { - try (MemoryStack stack = stackPush()) { - setViewport(x, y, width, height, stack); - } - } - - public static void setViewport(int x, int y, int width, int height, MemoryStack stack) { - if (!INSTANCE.recordingCmds) - return; - - VkViewport.Buffer viewport = VkViewport.malloc(1, stack); - viewport.x(x); - viewport.y(height + y); - 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.recordingCmds || INSTANCE.boundFramebuffer == null) - return; - - try (MemoryStack stack = stackPush()) { - int framebufferHeight = INSTANCE.boundFramebuffer.getHeight(); - - x = Math.max(0, x); - - VkRect2D.Buffer scissor = VkRect2D.malloc(1, stack); - scissor.offset().set(x, framebufferHeight - (y + height)); - scissor.extent().set(width, height); - - vkCmdSetScissor(INSTANCE.currentCmdBuffer, 0, scissor); - } - } - - public static void resetScissor() { - if (INSTANCE.boundFramebuffer == null) - return; - - try (MemoryStack stack = stackPush()) { - VkRect2D.Buffer scissor = INSTANCE.boundFramebuffer.scissor(stack); - vkCmdSetScissor(INSTANCE.currentCmdBuffer, 0, scissor); - } - } - - public static void pushDebugSection(String s) { - if (Vulkan.ENABLE_VALIDATION_LAYERS) { - VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; - - try (MemoryStack stack = stackPush()) { - VkDebugUtilsLabelEXT markerInfo = VkDebugUtilsLabelEXT.calloc(stack); - markerInfo.sType(VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT); - ByteBuffer string = stack.UTF8(s); - markerInfo.pLabelName(string); - vkCmdBeginDebugUtilsLabelEXT(commandBuffer, markerInfo); - } - } - } - - public static void popDebugSection() { - if (Vulkan.ENABLE_VALIDATION_LAYERS) { - VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; - - vkCmdEndDebugUtilsLabelEXT(commandBuffer); - } - } - - public static void popPushDebugSection(String s) { - popDebugSection(); - pushDebugSection(s); - } - - public static int getFramesNum() { - return INSTANCE.framesNum; - } - - public static VkCommandBuffer getCommandBuffer() { - return INSTANCE.currentCmdBuffer; - } - - public static boolean isRecording() { - return INSTANCE.recordingCmds; - } - - public static void scheduleSwapChainUpdate() { - swapChainUpdate = true; - } } diff --git a/src/main/java/net/vulkanmod/vulkan/Synchronization.java b/src/main/java/net/vulkanmod/vulkan/Synchronization.java index 609052db3..0c873ba7b 100644 --- a/src/main/java/net/vulkanmod/vulkan/Synchronization.java +++ b/src/main/java/net/vulkanmod/vulkan/Synchronization.java @@ -18,12 +18,23 @@ public class Synchronization { private final LongBuffer fences; private int idx = 0; - private ObjectArrayList commandBuffers = new ObjectArrayList<>(); + private final ObjectArrayList commandBuffers = new ObjectArrayList<>(); Synchronization(int allocSize) { this.fences = MemoryUtil.memAllocLong(allocSize); } + public static void waitFence(long fence) { + VkDevice device = Vulkan.getVkDevice(); + + vkWaitForFences(device, fence, true, VUtil.UINT64_MAX); + } + + public static boolean checkFenceStatus(long fence) { + VkDevice device = Vulkan.getVkDevice(); + return vkGetFenceStatus(device, fence) == VK_SUCCESS; + } + public synchronized void addCommandBuffer(CommandPool.CommandBuffer commandBuffer) { this.addFence(commandBuffer.getFence()); this.commandBuffers.add(commandBuffer); @@ -54,15 +65,4 @@ public synchronized void waitFences() { idx = 0; } - public static void waitFence(long fence) { - VkDevice device = Vulkan.getVkDevice(); - - vkWaitForFences(device, fence, true, VUtil.UINT64_MAX); - } - - public static boolean checkFenceStatus(long fence) { - VkDevice device = Vulkan.getVkDevice(); - return vkGetFenceStatus(device, fence) == VK_SUCCESS; - } - } diff --git a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java index fb1fe4468..486ad3210 100644 --- a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java +++ b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java @@ -2,7 +2,6 @@ import com.mojang.blaze3d.buffers.GpuBufferSlice; import com.mojang.blaze3d.platform.Window; - import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.fog.FogData; import net.vulkanmod.render.engine.VkGpuBuffer; @@ -15,50 +14,38 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.system.MemoryUtil; -import static org.lwjgl.vulkan.VK10.*; - import java.nio.ByteBuffer; import java.nio.FloatBuffer; +import static org.lwjgl.vulkan.VK10.*; + public abstract class VRenderSystem { private static final float DEFAULT_DEPTH_VALUE = 1.0f; - - private static long window; - public static boolean depthTest = true; public static boolean depthMask = true; public static int depthFun = 515; public static int topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; public static int polygonMode = VK_POLYGON_MODE_FILL; public static boolean canSetLineWidth = false; - public static int colorMask = PipelineState.ColorMask.getColorMask(true, true, true, true); - public static boolean cull = true; - public static boolean logicOp = false; public static int logicOpFun = 0; - public static float clearDepthValue = DEFAULT_DEPTH_VALUE; public static FloatBuffer clearColor = MemoryUtil.memCallocFloat(4); - public static MappedBuffer modelViewMatrix = new MappedBuffer(16 * 4); public static MappedBuffer projectionMatrix = new MappedBuffer(16 * 4); public static MappedBuffer TextureMatrix = new MappedBuffer(16 * 4); public static MappedBuffer MVP = new MappedBuffer(16 * 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); - public static MappedBuffer shaderColor = new MappedBuffer(4 * 4); public static MappedBuffer shaderFogColor = new MappedBuffer(4 * 4); public static FogData fogData; - public static MappedBuffer screenSize = new MappedBuffer(2 * 4); - public static float alphaCutout = 0.0f; - + private static long window; private static boolean depthBiasEnabled = false; private static float depthBiasConstant = 0.0f; private static float depthBiasSlope = 0.0f; @@ -122,14 +109,14 @@ public static void calculateMVP() { P.mul(MV).get(MVP.buffer); } - public static void setTextureMatrix(Matrix4f mat) { - mat.get(TextureMatrix.buffer.asFloatBuffer()); - } - public static MappedBuffer getTextureMatrix() { return TextureMatrix; } + public static void setTextureMatrix(Matrix4f mat) { + mat.get(TextureMatrix.buffer.asFloatBuffer()); + } + public static MappedBuffer getModelViewMatrix() { return modelViewMatrix; } @@ -193,7 +180,7 @@ public static void depthMask(boolean b) { public static void setPrimitiveTopologyGL(final int mode) { VRenderSystem.topology = switch (mode) { - case GL11.GL_LINES, GL11.GL_LINE_STRIP -> VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + case GL11.GL_LINES, GL11.GL_LINE_STRIP -> VK_PRIMITIVE_TOPOLOGY_LINE_LIST; case GL11.GL_TRIANGLE_FAN, GL11.GL_TRIANGLES, GL11.GL_TRIANGLE_STRIP -> VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; default -> throw new RuntimeException(String.format("Unknown GL primitive topology: %s", mode)); }; diff --git a/src/main/java/net/vulkanmod/vulkan/Vulkan.java b/src/main/java/net/vulkanmod/vulkan/Vulkan.java index f2f0a1646..627cf0c38 100644 --- a/src/main/java/net/vulkanmod/vulkan/Vulkan.java +++ b/src/main/java/net/vulkanmod/vulkan/Vulkan.java @@ -3,9 +3,9 @@ import net.vulkanmod.vulkan.device.Device; import net.vulkanmod.vulkan.device.DeviceManager; import net.vulkanmod.vulkan.framebuffer.SwapChain; -import net.vulkanmod.vulkan.memory.buffer.Buffer; import net.vulkanmod.vulkan.memory.MemoryManager; import net.vulkanmod.vulkan.memory.MemoryTypes; +import net.vulkanmod.vulkan.memory.buffer.Buffer; import net.vulkanmod.vulkan.memory.buffer.StagingBuffer; import net.vulkanmod.vulkan.queue.Queue; import net.vulkanmod.vulkan.shader.Pipeline; @@ -44,6 +44,18 @@ public class Vulkan { public static final boolean DYNAMIC_RENDERING = false; public static final Set VALIDATION_LAYERS; + public static final Set REQUIRED_EXTENSION = getRequiredExtensionSet(); + public static long window; + public static boolean use24BitsDepthFormat = true; + private static VkInstance instance; + private static long debugMessenger; + private static long surface; + private static long commandPool; + private static VkCommandBuffer immediateCmdBuffer; + private static long immediateFence; + private static long allocator; + private static StagingBuffer[] stagingBuffers; + private static int DEFAULT_DEPTH_FORMAT = 0; static { if (ENABLE_VALIDATION_LAYERS) { @@ -57,8 +69,6 @@ public class Vulkan { } } - public static final Set REQUIRED_EXTENSION = getRequiredExtensionSet(); - private static Set getRequiredExtensionSet() { ArrayList extensions = new ArrayList<>(List.of(VK_KHR_SWAPCHAIN_EXTENSION_NAME)); @@ -117,23 +127,6 @@ public static long getAllocator() { return allocator; } - public static long window; - - private static VkInstance instance; - private static long debugMessenger; - private static long surface; - - private static long commandPool; - private static VkCommandBuffer immediateCmdBuffer; - private static long immediateFence; - - private static long allocator; - - private static StagingBuffer[] stagingBuffers; - - public static boolean use24BitsDepthFormat = true; - private static int DEFAULT_DEPTH_FORMAT = 0; - public static void initVulkan(long window) { createInstance(); setupDebugMessenger(); diff --git a/src/main/java/net/vulkanmod/vulkan/device/Device.java b/src/main/java/net/vulkanmod/vulkan/device/Device.java index da850d3b9..9f2ae25db 100644 --- a/src/main/java/net/vulkanmod/vulkan/device/Device.java +++ b/src/main/java/net/vulkanmod/vulkan/device/Device.java @@ -1,10 +1,7 @@ package net.vulkanmod.vulkan.device; -import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.*; -import oshi.SystemInfo; -import oshi.hardware.CentralProcessor; import java.nio.IntBuffer; import java.util.HashSet; @@ -19,21 +16,18 @@ import static org.lwjgl.vulkan.VK11.vkGetPhysicalDeviceFeatures2; public class Device { - final VkPhysicalDevice physicalDevice; - final VkPhysicalDeviceProperties properties; - - private final int vendorId; public final String vendorIdString; public final String deviceName; public final String driverVersion; public final String vkVersion; - public final VkPhysicalDeviceFeatures2 availableFeatures; public final VkPhysicalDeviceVulkan11Features availableFeatures11; + final VkPhysicalDevice physicalDevice; + final VkPhysicalDeviceProperties properties; + private final int vendorId; // public final VkPhysicalDeviceVulkan13Features availableFeatures13; // public final boolean vulkan13Support; - private boolean drawIndirectSupported; public Device(VkPhysicalDevice device) { diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java index 8a2d5ad09..674c4431d 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java @@ -19,24 +19,21 @@ public class Framebuffer { public static final int DEFAULT_FORMAT = VK_FORMAT_R8G8B8A8_UNORM; // private long id; - + private final Reference2LongArrayMap renderpassToFramebufferMap = new Reference2LongArrayMap<>(); protected int format; protected int depthFormat; protected int width, height; protected boolean linearFiltering; protected boolean depthLinearFiltering; protected int attachmentCount; - + protected VulkanImage depthAttachment; boolean hasColorAttachment; boolean hasDepthAttachment; - private VulkanImage colorAttachment; - protected VulkanImage depthAttachment; - - private final Reference2LongArrayMap renderpassToFramebufferMap = new Reference2LongArrayMap<>(); //SwapChain - protected Framebuffer() {} + protected Framebuffer() { + } public Framebuffer(Builder builder) { this.format = builder.format; @@ -56,6 +53,14 @@ public Framebuffer(Builder builder) { } } + public static Builder builder(int width, int height, int colorAttachments, boolean hasDepthAttachment) { + return new Builder(width, height, colorAttachments, hasDepthAttachment); + } + + public static Builder builder(VulkanImage colorAttachment, VulkanImage depthAttachment) { + return new Builder(colorAttachment, depthAttachment); + } + public void createImages() { if (this.hasColorAttachment) { this.colorAttachment = VulkanImage.builder(this.width, this.height) @@ -207,14 +212,6 @@ public int getDepthFormat() { return this.depthFormat; } - public static Builder builder(int width, int height, int colorAttachments, boolean hasDepthAttachment) { - return new Builder(width, height, colorAttachments, hasDepthAttachment); - } - - public static Builder builder(VulkanImage colorAttachment, VulkanImage depthAttachment) { - return new Builder(colorAttachment, depthAttachment); - } - public static class Builder { final boolean createImages; final int width, height; @@ -223,7 +220,7 @@ public static class Builder { VulkanImage colorAttachment; VulkanImage depthAttachment; -// int colorAttachments; + // int colorAttachments; boolean hasColorAttachment; boolean hasDepthAttachment; diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java index 56300de44..a8a35cbdc 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java @@ -13,10 +13,9 @@ import static org.lwjgl.vulkan.VK10.*; public class RenderPass { + final int attachmentCount; Framebuffer framebuffer; long id; - - final int attachmentCount; AttachmentInfo colorAttachmentInfo; AttachmentInfo depthAttachmentInfo; @@ -39,6 +38,10 @@ public RenderPass(Framebuffer framebuffer, AttachmentInfo colorAttachmentInfo, A } + public static Builder builder(Framebuffer framebuffer) { + return new Builder(framebuffer); + } + private void createRenderPass() { try (MemoryStack stack = MemoryStack.stackPush()) { @@ -167,8 +170,7 @@ public void beginRenderPass(VkCommandBuffer commandBuffer, long framebufferId, M public void endRenderPass(VkCommandBuffer commandBuffer) { if (Vulkan.DYNAMIC_RENDERING) { KHRDynamicRendering.vkCmdEndRenderingKHR(commandBuffer); - } - else { + } else { vkCmdEndRenderPass(commandBuffer); if (colorAttachmentInfo != null) @@ -288,10 +290,6 @@ public enum Type { } } - public static Builder builder(Framebuffer framebuffer) { - return new Builder(framebuffer); - } - public static class Builder { Framebuffer framebuffer; AttachmentInfo colorAttachmentInfo; diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java index e760a72d6..016bc8e9f 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java @@ -33,11 +33,10 @@ public class SwapChain extends Framebuffer { private static final int defUncappedMode = checkPresentMode(VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR); private final Long2ReferenceOpenHashMap FBO_map = new Long2ReferenceOpenHashMap<>(); - + public boolean isBGRAformat; private long swapChainId = VK_NULL_HANDLE; private List swapChainImages; private VkExtent2D extent2D; - public boolean isBGRAformat; private boolean vsync = false; public SwapChain() { @@ -50,6 +49,43 @@ public SwapChain() { recreate(); } + private static VkExtent2D getExtent(VkSurfaceCapabilitiesKHR capabilities) { + + if (capabilities.currentExtent().width() != UINT32_MAX) { + return capabilities.currentExtent(); + } + + // Fallback + IntBuffer width = stackGet().ints(0); + IntBuffer height = stackGet().ints(0); + + glfwGetFramebufferSize(window, width, height); + + VkExtent2D actualExtent = VkExtent2D.mallocStack().set(width.get(0), height.get(0)); + + VkExtent2D minExtent = capabilities.minImageExtent(); + VkExtent2D maxExtent = capabilities.maxImageExtent(); + + actualExtent.width(MathUtil.clamp(minExtent.width(), maxExtent.width(), actualExtent.width())); + actualExtent.height(MathUtil.clamp(minExtent.height(), maxExtent.height(), actualExtent.height())); + + return actualExtent; + } + + private static int checkPresentMode(int... requestedModes) { + try (MemoryStack stack = MemoryStack.stackPush()) { + var a = DeviceManager.querySurfaceProperties(vkDevice.getPhysicalDevice(), stack).presentModes; + for (int dMode : requestedModes) { + for (int i = 0; i < a.capacity(); i++) { + if (a.get(i) == dMode) { + return dMode; + } + } + } + return VK_PRESENT_MODE_FIFO_KHR; // If None of the request modes exist/are supported by Driver + } + } + public void recreate() { if (this.depthAttachment != null) { this.depthAttachment.free(); @@ -285,43 +321,6 @@ private String getDisplayModeString(int requestedMode) { }; } - private static VkExtent2D getExtent(VkSurfaceCapabilitiesKHR capabilities) { - - if (capabilities.currentExtent().width() != UINT32_MAX) { - return capabilities.currentExtent(); - } - - // Fallback - IntBuffer width = stackGet().ints(0); - IntBuffer height = stackGet().ints(0); - - glfwGetFramebufferSize(window, width, height); - - VkExtent2D actualExtent = VkExtent2D.mallocStack().set(width.get(0), height.get(0)); - - VkExtent2D minExtent = capabilities.minImageExtent(); - VkExtent2D maxExtent = capabilities.maxImageExtent(); - - actualExtent.width(MathUtil.clamp(minExtent.width(), maxExtent.width(), actualExtent.width())); - actualExtent.height(MathUtil.clamp(minExtent.height(), maxExtent.height(), actualExtent.height())); - - return actualExtent; - } - - private static int checkPresentMode(int... requestedModes) { - try (MemoryStack stack = MemoryStack.stackPush()) { - var a = DeviceManager.querySurfaceProperties(vkDevice.getPhysicalDevice(), stack).presentModes; - for (int dMode : requestedModes) { - for (int i = 0; i < a.capacity(); i++) { - if (a.get(i) == dMode) { - return dMode; - } - } - } - return VK_PRESENT_MODE_FIFO_KHR; // If None of the request modes exist/are supported by Driver - } - } - public boolean isVsync() { return this.vsync; } diff --git a/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java b/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java index b52be1121..1d290e1e1 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java @@ -29,41 +29,23 @@ import static org.lwjgl.vulkan.VK10.*; public class MemoryManager { - private static final boolean DEBUG = false; public static final long BYTES_IN_MB = 1024 * 1024; - - private static MemoryManager INSTANCE; + private static final boolean DEBUG = false; private static final long ALLOCATOR = Vulkan.getAllocator(); - private static final Long2ReferenceOpenHashMap buffers = new Long2ReferenceOpenHashMap<>(); private static final Long2ReferenceOpenHashMap images = new Long2ReferenceOpenHashMap<>(); - static int Frames; - + private static MemoryManager INSTANCE; private static long deviceMemory = 0; private static long nativeMemory = 0; - - private int currentFrame = 0; - private final ObjectArrayList[] freeableBuffers = new ObjectArrayList[Frames]; private final ObjectArrayList[] freeableImages = new ObjectArrayList[Frames]; - private final ObjectArrayList[] frameOps = new ObjectArrayList[Frames]; private final ObjectArrayList>[] segmentsToFree = new ObjectArrayList[Frames]; - + private int currentFrame = 0; //debug private ObjectArrayList[] stackTraces; - public static MemoryManager getInstance() { - return INSTANCE; - } - - public static void createInstance(int frames) { - Frames = frames; - - INSTANCE = new MemoryManager(); - } - MemoryManager() { for (int i = 0; i < Frames; ++i) { this.freeableBuffers[i] = new ObjectArrayList<>(); @@ -81,6 +63,57 @@ public static void createInstance(int frames) { } } + public static MemoryManager getInstance() { + return INSTANCE; + } + + public static void createInstance(int frames) { + Frames = frames; + + INSTANCE = new MemoryManager(); + } + + public static void addImage(VulkanImage image) { + images.putIfAbsent(image.getId(), image); + + deviceMemory += image.size; + } + + public static void MapAndCopy(long allocation, Consumer consumer) { + try (MemoryStack stack = stackPush()) { + PointerBuffer data = stack.mallocPointer(1); + + vmaMapMemory(ALLOCATOR, allocation, data); + consumer.accept(data); + vmaUnmapMemory(ALLOCATOR, allocation); + } + } + + public static void freeBuffer(long buffer, long allocation) { + vmaDestroyBuffer(ALLOCATOR, buffer, allocation); + + buffers.remove(buffer); + } + + private static void freeBuffer(Buffer.BufferInfo bufferInfo) { + vmaDestroyBuffer(ALLOCATOR, bufferInfo.id(), bufferInfo.allocation()); + + if (bufferInfo.type() == MemoryType.Type.DEVICE_LOCAL) { + deviceMemory -= bufferInfo.bufferSize(); + } else { + nativeMemory -= bufferInfo.bufferSize(); + } + + buffers.remove(bufferInfo.id()); + } + + public static void freeImage(long imageId, long allocation) { + vmaDestroyImage(ALLOCATOR, imageId, allocation); + + VulkanImage image = images.remove(imageId); + deviceMemory -= image.size; + } + public synchronized void initFrame(int frame) { this.setCurrentFrame(frame); this.freeBuffers(frame); @@ -141,8 +174,7 @@ public synchronized void createBuffer(Buffer buffer, long size, int usage, int p if ((properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0) { deviceMemory += size; - } - else { + } else { nativeMemory += size; } @@ -186,22 +218,6 @@ public void createImage(int width, int height, int arrayLayers, int mipLevels, } } - public static void addImage(VulkanImage image) { - images.putIfAbsent(image.getId(), image); - - deviceMemory += image.size; - } - - public static void MapAndCopy(long allocation, Consumer consumer) { - try (MemoryStack stack = stackPush()) { - PointerBuffer data = stack.mallocPointer(1); - - vmaMapMemory(ALLOCATOR, allocation, data); - consumer.accept(data); - vmaUnmapMemory(ALLOCATOR, allocation); - } - } - public PointerBuffer Map(long allocation) { PointerBuffer data = MemoryUtil.memAllocPointer(1); @@ -210,32 +226,6 @@ public PointerBuffer Map(long allocation) { return data; } - public static void freeBuffer(long buffer, long allocation) { - vmaDestroyBuffer(ALLOCATOR, buffer, allocation); - - buffers.remove(buffer); - } - - private static void freeBuffer(Buffer.BufferInfo bufferInfo) { - vmaDestroyBuffer(ALLOCATOR, bufferInfo.id(), bufferInfo.allocation()); - - if (bufferInfo.type() == MemoryType.Type.DEVICE_LOCAL) { - deviceMemory -= bufferInfo.bufferSize(); - } - else { - nativeMemory -= bufferInfo.bufferSize(); - } - - buffers.remove(bufferInfo.id()); - } - - public static void freeImage(long imageId, long allocation) { - vmaDestroyImage(ALLOCATOR, imageId, allocation); - - VulkanImage image = images.remove(imageId); - deviceMemory -= image.size; - } - public synchronized void addToFreeable(Buffer buffer) { Buffer.BufferInfo bufferInfo = buffer.getBufferInfo(); diff --git a/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java b/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java index 15bf8d6df..d751e28c5 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java @@ -7,9 +7,9 @@ import java.nio.ByteBuffer; public abstract class MemoryType { - final Type type; public final VkMemoryType vkMemoryType; public final VkMemoryHeap vkMemoryHeap; + final Type type; MemoryType(Type type, VkMemoryType vkMemoryType, VkMemoryHeap vkMemoryHeap) { this.type = type; @@ -26,7 +26,7 @@ public abstract class MemoryType { public abstract boolean mappable(); public Type getType() { - return this.type; + return this.type; } public enum Type { diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java index ac8ac91e4..f13f2600c 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java @@ -68,6 +68,10 @@ public long getAllocation() { return allocation; } + public void setAllocation(long allocation) { + this.allocation = allocation; + } + public long getUsedBytes() { return usedBytes; } @@ -80,24 +84,20 @@ public long getId() { return id; } - public long getBufferSize() { - return bufferSize; + public void setId(long id) { + this.id = id; } - public long getDataPtr() { - return dataPtr; + public long getBufferSize() { + return bufferSize; } 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 long getDataPtr() { + return dataPtr; } public BufferInfo getBufferInfo() { diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java index 6b09cb0cb..b8ce2109f 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java @@ -3,7 +3,6 @@ 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; diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java index 03d764c5a..ecbec6252 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java @@ -10,7 +10,7 @@ import java.nio.ByteBuffer; import static org.lwjgl.system.libc.LibCString.nmemcpy; -import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK10.VK_BUFFER_USAGE_TRANSFER_SRC_BIT; public class StagingBuffer extends Buffer { private static final long DEFAULT_SIZE = 64 * 1024 * 1024; diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java index b9d102d18..12c50e5c8 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java @@ -9,15 +9,15 @@ public class UniformBuffer extends Buffer { private final static int MIN_OFFSET_ALIGNMENT = (int) DeviceManager.deviceProperties.limits().minUniformBufferOffsetAlignment(); - public static int getAlignedSize(int uploadSize) { - return align(uploadSize, MIN_OFFSET_ALIGNMENT); - } - public UniformBuffer(int size, MemoryType memoryType) { super(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memoryType); this.createBuffer(size); } + public static int getAlignedSize(int uploadSize) { + return align(uploadSize, MIN_OFFSET_ALIGNMENT); + } + public void checkCapacity(int size) { if (size > this.bufferSize - this.usedBytes) { resizeBuffer((this.bufferSize + size) * 2); diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java index 6fead50d2..45735b0c4 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java @@ -23,61 +23,6 @@ public AutoIndexBuffer(int vertexCount, DrawType type) { createIndexBuffer(vertexCount); } - private void createIndexBuffer(int vertexCount) { - this.vertexCount = vertexCount; - ByteBuffer buffer; - - 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 (indexType == IndexBuffer.IndexType.UINT16) - buffer = genQuadIndices(vertexCount); - else { - buffer = genIntQuadIndices(vertexCount); - } - } - case TRIANGLE_FAN -> buffer = genTriangleFanIndices(vertexCount); - case TRIANGLE_STRIP -> buffer = genTriangleStripIndices(vertexCount); - case LINES -> buffer = genLinesIndices(vertexCount); - case DEBUG_LINE_STRIP -> buffer = genDebugLineStripIndices(vertexCount); - default -> throw new IllegalArgumentException("Unsupported drawType: %s".formatted(this.drawType)); - } - - int size = buffer.capacity(); - this.indexBuffer = new IndexBuffer(size, MemoryTypes.GPU_MEM, indexType); - this.indexBuffer.copyBuffer(buffer, buffer.remaining()); - - MemoryUtil.memFree(buffer); - } - - public void checkCapacity(int vertexCount) { - if (vertexCount > this.vertexCount) { - int newVertexCount = Math.max(this.vertexCount * 2, vertexCount); - Initializer.LOGGER.info("Reallocating AutoIndexBuffer from {} to {}", this.vertexCount, newVertexCount); - - 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 -> { @@ -110,7 +55,7 @@ public static ByteBuffer genQuadIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount; i += 4) { - idxs.put(j + 0, (short) (i)); + idxs.put(j, (short) (i)); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); idxs.put(j + 3, (short) (i)); @@ -132,7 +77,7 @@ public static ByteBuffer genIntQuadIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount; i += 4) { - idxs.put(j + 0, (i)); + idxs.put(j, (i)); idxs.put(j + 1, (i + 1)); idxs.put(j + 2, (i + 2)); idxs.put(j + 3, (i)); @@ -154,7 +99,7 @@ public static ByteBuffer genLinesIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount; i += 4) { - idxs.put(j + 0, (short) (i)); + idxs.put(j, (short) (i)); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); idxs.put(j + 3, (short) (i + 3)); @@ -174,7 +119,7 @@ public static ByteBuffer genTriangleFanIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount - 2; ++i) { - idxs.put(j + 0, (short) 0); + idxs.put(j, (short) 0); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); @@ -192,7 +137,7 @@ public static ByteBuffer genTriangleStripIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount - 2; ++i) { - idxs.put(j + 0, (short) i); + idxs.put(j, (short) i); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); @@ -210,7 +155,7 @@ public static ByteBuffer genDebugLineStripIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount - 1; ++i) { - idxs.put(j + 0, (short) i); + idxs.put(j, (short) i); idxs.put(j + 1, (short) (i + 1)); j += 2; @@ -223,6 +168,61 @@ public static int roundUpToDivisible(int n, int d) { return ((n + d - 1) / d) * d; } + private void createIndexBuffer(int vertexCount) { + this.vertexCount = vertexCount; + ByteBuffer buffer; + + 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 (indexType == IndexBuffer.IndexType.UINT16) + buffer = genQuadIndices(vertexCount); + else { + buffer = genIntQuadIndices(vertexCount); + } + } + case TRIANGLE_FAN -> buffer = genTriangleFanIndices(vertexCount); + case TRIANGLE_STRIP -> buffer = genTriangleStripIndices(vertexCount); + case LINES -> buffer = genLinesIndices(vertexCount); + case DEBUG_LINE_STRIP -> buffer = genDebugLineStripIndices(vertexCount); + default -> throw new IllegalArgumentException("Unsupported drawType: %s".formatted(this.drawType)); + } + + int size = buffer.capacity(); + this.indexBuffer = new IndexBuffer(size, MemoryTypes.GPU_MEM, indexType); + this.indexBuffer.copyBuffer(buffer, buffer.remaining()); + + MemoryUtil.memFree(buffer); + } + + public void checkCapacity(int vertexCount) { + if (vertexCount > this.vertexCount) { + int newVertexCount = Math.max(this.vertexCount * 2, vertexCount); + Initializer.LOGGER.info("Reallocating AutoIndexBuffer from {} to {}", this.vertexCount, newVertexCount); + + 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 enum DrawType { QUADS(7), TRIANGLE_FAN(6), diff --git a/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java b/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java index 94801d758..a6479dedd 100644 --- a/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java +++ b/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java @@ -16,26 +16,18 @@ import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.VkCommandBuffer; import org.lwjgl.vulkan.VkRect2D; -import org.lwjgl.vulkan.VkViewport; import static org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; import static org.lwjgl.vulkan.VK10.*; public class DefaultMainPass implements MainPass { - public static DefaultMainPass create() { - return new DefaultMainPass(); - } - - private RenderTarget mainTarget; private final Framebuffer mainFramebuffer; - + private final RenderTarget mainTarget; private RenderPass mainRenderPass; private RenderPass auxRenderPass; - private GpuTexture[] colorAttachmentTextures; private GpuTextureView[] colorAttachmentTextureViews; - DefaultMainPass() { this.mainTarget = Minecraft.getInstance().getMainRenderTarget(); this.mainFramebuffer = Renderer.getInstance().getSwapChain(); @@ -44,6 +36,10 @@ public static DefaultMainPass create() { createSwapChainTextures(); } + public static DefaultMainPass create() { + return new DefaultMainPass(); + } + private void createRenderPasses() { RenderPass.Builder builder = RenderPass.builder(this.mainFramebuffer); builder.getColorAttachmentInfo().setFinalLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); diff --git a/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java b/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java index 63a843c58..3ff80f539 100644 --- a/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java +++ b/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java @@ -15,13 +15,17 @@ public interface MainPass { void onResize(); - default void mainTargetBindWrite() {} + default void mainTargetBindWrite() { + } - default void mainTargetUnbindWrite() {} + default void mainTargetUnbindWrite() { + } - default void rebindMainTarget() {} + default void rebindMainTarget() { + } - default void bindAsTexture() {} + default void bindAsTexture() { + } default GpuTexture getColorAttachment() { return null; diff --git a/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java b/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java index 8500e8da4..4130d74d8 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java @@ -14,10 +14,9 @@ import static org.lwjgl.vulkan.VK10.*; public class CommandPool { - long id; - private final List commandBuffers = new ObjectArrayList<>(); private final java.util.Queue availableCmdBuffers = new ArrayDeque<>(); + long id; CommandPool(int queueFamilyIndex) { this.createCommandPool(queueFamilyIndex); diff --git a/src/main/java/net/vulkanmod/vulkan/queue/GraphicsQueue.java b/src/main/java/net/vulkanmod/vulkan/queue/GraphicsQueue.java index e449f617b..f7f25a411 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/GraphicsQueue.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/GraphicsQueue.java @@ -1,13 +1,9 @@ package net.vulkanmod.vulkan.queue; import net.vulkanmod.vulkan.Synchronization; -import net.vulkanmod.vulkan.Vulkan; -import net.vulkanmod.vulkan.memory.MemoryManager; -import net.vulkanmod.vulkan.util.VUtil; import org.lwjgl.system.MemoryStack; -import org.lwjgl.vulkan.*; -import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK10.VK_NULL_HANDLE; public class GraphicsQueue extends Queue { public static GraphicsQueue INSTANCE; diff --git a/src/main/java/net/vulkanmod/vulkan/queue/Queue.java b/src/main/java/net/vulkanmod/vulkan/queue/Queue.java index 3e5b07fce..b45437c97 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/Queue.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/Queue.java @@ -25,15 +25,6 @@ public abstract class Queue { protected CommandPool commandPool; - public synchronized CommandPool.CommandBuffer beginCommands() { - try (MemoryStack stack = stackPush()) { - CommandPool.CommandBuffer commandBuffer = this.commandPool.getCommandBuffer(stack); - commandBuffer.begin(stack); - - return commandBuffer; - } - } - Queue(MemoryStack stack, int familyIndex) { this(stack, familyIndex, true); } @@ -47,35 +38,6 @@ public synchronized CommandPool.CommandBuffer beginCommands() { this.commandPool = new CommandPool(familyIndex); } - public synchronized long submitCommands(CommandPool.CommandBuffer commandBuffer) { - try (MemoryStack stack = stackPush()) { - return commandBuffer.submitCommands(stack, vkQueue, false); - } - } - - public VkQueue vkQueue() { - return this.vkQueue; - } - - public void cleanUp() { - if (commandPool != null) - commandPool.cleanUp(); - } - - public void waitIdle() { - vkQueueWaitIdle(vkQueue); - } - - public CommandPool getCommandPool() { - return commandPool; - } - - public enum Family { - Graphics, - Transfer, - Compute - } - public static QueueFamilyIndices getQueueFamilies() { if (device == null) device = Vulkan.getVkDevice(); @@ -191,6 +153,44 @@ public static QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) { } } + public synchronized CommandPool.CommandBuffer beginCommands() { + try (MemoryStack stack = stackPush()) { + CommandPool.CommandBuffer commandBuffer = this.commandPool.getCommandBuffer(stack); + commandBuffer.begin(stack); + + return commandBuffer; + } + } + + public synchronized long submitCommands(CommandPool.CommandBuffer commandBuffer) { + try (MemoryStack stack = stackPush()) { + return commandBuffer.submitCommands(stack, vkQueue, false); + } + } + + public VkQueue vkQueue() { + return this.vkQueue; + } + + public void cleanUp() { + if (commandPool != null) + commandPool.cleanUp(); + } + + public void waitIdle() { + vkQueueWaitIdle(vkQueue); + } + + public CommandPool getCommandPool() { + return commandPool; + } + + public enum Family { + Graphics, + Transfer, + Compute + } + public static class QueueFamilyIndices { public int graphicsFamily = VK_QUEUE_FAMILY_IGNORED; public int presentFamily = VK_QUEUE_FAMILY_IGNORED; diff --git a/src/main/java/net/vulkanmod/vulkan/queue/TransferQueue.java b/src/main/java/net/vulkanmod/vulkan/queue/TransferQueue.java index 4cd17c4d6..7f83744f2 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/TransferQueue.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/TransferQueue.java @@ -19,6 +19,19 @@ public TransferQueue(MemoryStack stack, int familyIndex) { super(stack, familyIndex); } + public static void uploadBufferCmd(VkCommandBuffer commandBuffer, long srcBuffer, long srcOffset, long dstBuffer, long dstOffset, long size) { + + try (MemoryStack stack = stackPush()) { + + VkBufferCopy.Buffer copyRegion = VkBufferCopy.calloc(1, stack); + copyRegion.size(size); + copyRegion.srcOffset(srcOffset); + copyRegion.dstOffset(dstOffset); + + vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, copyRegion); + } + } + public long copyBufferCmd(long srcBuffer, long srcOffset, long dstBuffer, long dstOffset, long size) { try (MemoryStack stack = stackPush()) { @@ -57,17 +70,4 @@ public void uploadBufferImmediate(long srcBuffer, long srcOffset, long dstBuffer } } - public static void uploadBufferCmd(VkCommandBuffer commandBuffer, long srcBuffer, long srcOffset, long dstBuffer, long dstOffset, long size) { - - try (MemoryStack stack = stackPush()) { - - VkBufferCopy.Buffer copyRegion = VkBufferCopy.calloc(1, stack); - copyRegion.size(size); - copyRegion.srcOffset(srcOffset); - copyRegion.dstOffset(dstOffset); - - vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, copyRegion); - } - } - } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/DescriptorSets.java b/src/main/java/net/vulkanmod/vulkan/shader/DescriptorSets.java index 3bfb14bca..1c35a2a0c 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/DescriptorSets.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/DescriptorSets.java @@ -18,22 +18,20 @@ import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.vulkan.VK10.*; -import static org.lwjgl.vulkan.VK10.vkDestroyDescriptorPool; public class DescriptorSets { private static final VkDevice DEVICE = Vulkan.getVkDevice(); private final Pipeline pipeline; + private final long[] boundUBs; + private final ImageDescriptor.State[] boundTextures; + private final IntBuffer dynamicOffsets; private int poolSize = 10; private long descriptorPool; private LongBuffer sets; private long currentSet; private int currentIdx = -1; - private final long[] boundUBs; - private final ImageDescriptor.State[] boundTextures; - private final IntBuffer dynamicOffsets; - DescriptorSets(Pipeline pipeline) { this.pipeline = pipeline; this.boundTextures = new ImageDescriptor.State[pipeline.imageDescriptors.size()]; @@ -55,7 +53,7 @@ protected void bindSets(VkCommandBuffer commandBuffer, UniformBuffer uniformBuff this.updateDescriptorSet(stack, uniformBuffer); vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipeline.pipelineLayout, - 0, stack.longs(currentSet), dynamicOffsets); + 0, stack.longs(currentSet), dynamicOffsets); } } @@ -68,8 +66,7 @@ private void updateUniforms(UniformBuffer globalUB) { if (useOwnUB) { BufferSlice bufferSlice = ubo.getBufferSlice(); offset = bufferSlice.getOffset(); - } - else { + } else { offset = (int) globalUB.getUsedBytes(); int alignedSize = UniformBuffer.getAlignedSize(ubo.getSize()); globalUB.checkCapacity(alignedSize); diff --git a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java index abf9e7e07..c8324cd36 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java @@ -52,6 +52,138 @@ public class GraphicsPipeline extends Pipeline { PIPELINES.add(this); } + private static VkVertexInputBindingDescription.Buffer getBindingDescription(VertexFormat vertexFormat) { + VkVertexInputBindingDescription.Buffer bindingDescription = VkVertexInputBindingDescription.calloc(1); + + bindingDescription.binding(0); + bindingDescription.stride(vertexFormat.getVertexSize()); + bindingDescription.inputRate(VK_VERTEX_INPUT_RATE_VERTEX); + + return bindingDescription; + } + + private static VkVertexInputAttributeDescription.Buffer getAttributeDescriptions(VertexFormat vertexFormat) { + List elements = vertexFormat.getElements(); + + int size = elements.size(); + + VkVertexInputAttributeDescription.Buffer attributeDescriptions = VkVertexInputAttributeDescription.calloc(size); + + int offset = 0; + + for (int i = 0; i < size; ++i) { + VkVertexInputAttributeDescription posDescription = attributeDescriptions.get(i); + posDescription.binding(0); + posDescription.location(i); + + VertexFormatElement formatElement = elements.get(i); + VertexFormatElement.Usage usage = formatElement.usage(); + VertexFormatElement.Type type = formatElement.type(); + int elementCount = formatElement.count(); + + switch (usage) { + case POSITION -> { + switch (type) { + case FLOAT -> { + posDescription.format(VK_FORMAT_R32G32B32_SFLOAT); + posDescription.offset(offset); + + offset += 12; + } + case SHORT -> { + posDescription.format(VK_FORMAT_R16G16B16A16_SINT); + posDescription.offset(offset); + + offset += 8; + } + case BYTE -> { + posDescription.format(VK_FORMAT_R8G8B8A8_SINT); + posDescription.offset(offset); + + offset += 4; + } + } + + } + + case COLOR -> { + switch (type) { + case UBYTE -> { + posDescription.format(VK_FORMAT_R8G8B8A8_UNORM); + posDescription.offset(offset); + + offset += 4; + } + case UINT -> { + posDescription.format(VK_FORMAT_R32_UINT); + posDescription.offset(offset); + + offset += 4; + } + } + } + + case UV -> { + switch (type) { + case FLOAT -> { + posDescription.format(VK_FORMAT_R32G32_SFLOAT); + posDescription.offset(offset); + + offset += 8; + } + case SHORT -> { + posDescription.format(VK_FORMAT_R16G16_SINT); + posDescription.offset(offset); + + offset += 4; + } + case USHORT -> { + posDescription.format(VK_FORMAT_R16G16_UINT); + posDescription.offset(offset); + + offset += 4; + } + case UINT -> { + posDescription.format(VK_FORMAT_R32_UINT); + posDescription.offset(offset); + + offset += 4; + } + } + } + + case NORMAL -> { + posDescription.format(VK_FORMAT_R8G8B8A8_SNORM); + posDescription.offset(offset); + + offset += 4; + } + + case GENERIC -> { + if (type == VertexFormatElement.Type.SHORT && elementCount == 1) { + posDescription.format(VK_FORMAT_R16_SINT); + posDescription.offset(offset); + + offset += 2; + } else if (type == VertexFormatElement.Type.INT && elementCount == 1) { + posDescription.format(VK_FORMAT_R32_SINT); + posDescription.offset(offset); + + offset += 4; + } else { + throw new RuntimeException(String.format("Unknown format: %s", usage)); + } + } + + default -> throw new RuntimeException(String.format("Unknown format: %s", usage)); + } + + posDescription.offset(((VertexFormatMixed) (vertexFormat)).getOffset(i)); + } + + return attributeDescriptions.rewind(); + } + public long getHandle(PipelineState state) { return graphicsPipelines.computeIfAbsent(state, this::createGraphicsPipeline); } @@ -150,8 +282,7 @@ private long createGraphicsPipeline(PipelineState state) { colorBlendAttachment.srcAlphaBlendFactor(PipelineState.BlendState.getSrcAlphaFactor(state.blendState_i)); colorBlendAttachment.dstAlphaBlendFactor(PipelineState.BlendState.getDstAlphaFactor(state.blendState_i)); colorBlendAttachment.alphaBlendOp(PipelineState.BlendState.blendOp(state.blendState_i)); - } - else { + } else { colorBlendAttachment.blendEnable(false); } @@ -170,9 +301,8 @@ private long createGraphicsPipeline(PipelineState state) { 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 { + VK_DYNAMIC_STATE_LINE_WIDTH)); + } else { dynamicStates.pDynamicStates( stack.ints(VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR)); } @@ -195,8 +325,7 @@ private long createGraphicsPipeline(PipelineState state) { if (!Vulkan.DYNAMIC_RENDERING) { pipelineInfo.renderPass(state.renderPass.getId()); pipelineInfo.subpass(0); - } - else { + } else { //dyn-rendering VkPipelineRenderingCreateInfoKHR renderingInfo = VkPipelineRenderingCreateInfoKHR.calloc(stack); renderingInfo.sType(KHRDynamicRendering.VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR); @@ -208,7 +337,7 @@ private long createGraphicsPipeline(PipelineState state) { LongBuffer pGraphicsPipeline = stack.mallocLong(1); Vulkan.checkResult(vkCreateGraphicsPipelines(DeviceManager.vkDevice, PIPELINE_CACHE, pipelineInfo, null, pGraphicsPipeline), - "Failed to create graphics pipeline " + this.name); + "Failed to create graphics pipeline " + this.name); return pGraphicsPipeline.get(0); } @@ -247,8 +376,7 @@ static class VertexInputDescription { if (vertexFormat != DefaultVertexFormat.EMPTY) { this.bindingDescriptions = getBindingDescription(vertexFormat); this.attributeDescriptions = getAttributeDescriptions(vertexFormat); - } - else { + } else { this.bindingDescriptions = null; this.attributeDescriptions = null; } @@ -261,138 +389,4 @@ void cleanUp() { } } } - - private static VkVertexInputBindingDescription.Buffer getBindingDescription(VertexFormat vertexFormat) { - VkVertexInputBindingDescription.Buffer bindingDescription = VkVertexInputBindingDescription.calloc(1); - - bindingDescription.binding(0); - bindingDescription.stride(vertexFormat.getVertexSize()); - bindingDescription.inputRate(VK_VERTEX_INPUT_RATE_VERTEX); - - return bindingDescription; - } - - private static VkVertexInputAttributeDescription.Buffer getAttributeDescriptions(VertexFormat vertexFormat) { - List elements = vertexFormat.getElements(); - - int size = elements.size(); - - VkVertexInputAttributeDescription.Buffer attributeDescriptions = VkVertexInputAttributeDescription.calloc(size); - - int offset = 0; - - for (int i = 0; i < size; ++i) { - VkVertexInputAttributeDescription posDescription = attributeDescriptions.get(i); - posDescription.binding(0); - posDescription.location(i); - - VertexFormatElement formatElement = elements.get(i); - VertexFormatElement.Usage usage = formatElement.usage(); - VertexFormatElement.Type type = formatElement.type(); - int elementCount = formatElement.count(); - - switch (usage) { - case POSITION -> { - switch (type) { - case FLOAT -> { - posDescription.format(VK_FORMAT_R32G32B32_SFLOAT); - posDescription.offset(offset); - - offset += 12; - } - case SHORT -> { - posDescription.format(VK_FORMAT_R16G16B16A16_SINT); - posDescription.offset(offset); - - offset += 8; - } - case BYTE -> { - posDescription.format(VK_FORMAT_R8G8B8A8_SINT); - posDescription.offset(offset); - - offset += 4; - } - } - - } - - case COLOR -> { - switch (type) { - case UBYTE -> { - posDescription.format(VK_FORMAT_R8G8B8A8_UNORM); - posDescription.offset(offset); - - offset += 4; - } - case UINT -> { - posDescription.format(VK_FORMAT_R32_UINT); - posDescription.offset(offset); - - offset += 4; - } - } - } - - case UV -> { - switch (type) { - case FLOAT -> { - posDescription.format(VK_FORMAT_R32G32_SFLOAT); - posDescription.offset(offset); - - offset += 8; - } - case SHORT -> { - posDescription.format(VK_FORMAT_R16G16_SINT); - posDescription.offset(offset); - - offset += 4; - } - case USHORT -> { - posDescription.format(VK_FORMAT_R16G16_UINT); - posDescription.offset(offset); - - offset += 4; - } - case UINT -> { - posDescription.format(VK_FORMAT_R32_UINT); - posDescription.offset(offset); - - offset += 4; - } - } - } - - case NORMAL -> { - posDescription.format(VK_FORMAT_R8G8B8A8_SNORM); - posDescription.offset(offset); - - offset += 4; - } - - case GENERIC -> { - if (type == VertexFormatElement.Type.SHORT && elementCount == 1) { - posDescription.format(VK_FORMAT_R16_SINT); - posDescription.offset(offset); - - offset += 2; - } - else if (type == VertexFormatElement.Type.INT && elementCount == 1) { - posDescription.format(VK_FORMAT_R32_SINT); - posDescription.offset(offset); - - offset += 4; - } - else { - throw new RuntimeException(String.format("Unknown format: %s", usage)); - } - } - - default -> throw new RuntimeException(String.format("Unknown format: %s", usage)); - } - - posDescription.offset(((VertexFormatMixed) (vertexFormat)).getOffset(i)); - } - - return attributeDescriptions.rewind(); - } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java index 2c70890fc..6b6f6eb81 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java @@ -39,9 +39,20 @@ public abstract class Pipeline { + protected static final List PIPELINES = new LinkedList<>(); private static final VkDevice DEVICE = Vulkan.getVkDevice(); protected static final long PIPELINE_CACHE = createPipelineCache(); - protected static final List PIPELINES = new LinkedList<>(); + public final String name; + protected long descriptorSetLayout; + protected long pipelineLayout; + protected DescriptorSets[] descriptorSets; + protected List buffers; + protected ManualUBO manualUBO; + protected List imageDescriptors; + protected PushConstants pushConstants; + public Pipeline(String name) { + this.name = name; + } private static long createPipelineCache() { try (MemoryStack stack = stackPush()) { @@ -70,19 +81,23 @@ public static void recreateDescriptorSets(int frames) { }); } - public final String name; + static long createShaderModule(ByteBuffer spirvCode) { - protected long descriptorSetLayout; - protected long pipelineLayout; + try (MemoryStack stack = stackPush()) { - protected DescriptorSets[] descriptorSets; - protected List buffers; - protected ManualUBO manualUBO; - protected List imageDescriptors; - protected PushConstants pushConstants; + VkShaderModuleCreateInfo createInfo = VkShaderModuleCreateInfo.calloc(stack); - public Pipeline(String name) { - this.name = name; + createInfo.sType(VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); + createInfo.pCode(spirvCode); + + LongBuffer pShaderModule = stack.mallocLong(1); + + if (vkCreateShaderModule(DEVICE, createInfo, null, pShaderModule) != VK_SUCCESS) { + throw new RuntimeException("Failed to create shader module"); + } + + return pShaderModule.get(0); + } } protected void createDescriptorSetLayout() { @@ -240,25 +255,6 @@ public void bindDescriptorSets(VkCommandBuffer commandBuffer, UniformBuffer unif this.descriptorSets[frame].bindSets(commandBuffer, uniformBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS); } - static long createShaderModule(ByteBuffer spirvCode) { - - try (MemoryStack stack = stackPush()) { - - VkShaderModuleCreateInfo createInfo = VkShaderModuleCreateInfo.calloc(stack); - - createInfo.sType(VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); - createInfo.pCode(spirvCode); - - LongBuffer pShaderModule = stack.mallocLong(1); - - if (vkCreateShaderModule(DEVICE, createInfo, null, pShaderModule) != VK_SUCCESS) { - throw new RuntimeException("Failed to create shader module"); - } - - return pShaderModule.get(0); - } - } - public static class Builder { final VertexFormat vertexFormat; final String shaderPath; @@ -288,6 +284,17 @@ public Builder() { this(null, null); } + public static int getStageFromString(String s) { + return switch (s) { + case "vertex" -> VK_SHADER_STAGE_VERTEX_BIT; + case "fragment" -> VK_SHADER_STAGE_FRAGMENT_BIT; + case "all" -> VK_SHADER_STAGE_ALL_GRAPHICS; + case "compute" -> VK_SHADER_STAGE_COMPUTE_BIT; + + default -> throw new RuntimeException("cannot identify type.."); + }; + } + public GraphicsPipeline createGraphicsPipeline() { Validate.isTrue(this.imageDescriptors != null && this.UBOs != null && this.vertShaderSPIRV != null && this.fragShaderSPIRV != null, @@ -383,8 +390,7 @@ private void parseUboNode(JsonElement jsonelement) { } uniformInfo.setBufferSupplier(uniformSupplier); - } - else { + } else { throw new IllegalStateException("No uniform supplier found for uniform: (%s:%s)".formatted(type2, name)); } } @@ -439,16 +445,5 @@ private void parsePushConstantNode(JsonArray jsonArray) { this.pushConstants = builder.buildPushConstant(); } - - public static int getStageFromString(String s) { - return switch (s) { - case "vertex" -> VK_SHADER_STAGE_VERTEX_BIT; - case "fragment" -> VK_SHADER_STAGE_FRAGMENT_BIT; - case "all" -> VK_SHADER_STAGE_ALL_GRAPHICS; - case "compute" -> VK_SHADER_STAGE_COMPUTE_BIT; - - default -> throw new RuntimeException("cannot identify type.."); - }; - } } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java b/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java index 1c7d0e5cd..c4d8129f9 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java @@ -16,6 +16,23 @@ public class PipelineState { public static final PipelineState DEFAULT = new PipelineState(getAssemblyRasterState(), getBlendState(), getDepthState(), getLogicOpState(), VRenderSystem.getColorMask(), null); public static PipelineState currentState = DEFAULT; + final RenderPass renderPass; + int assemblyRasterState; + int blendState_i; + int depthState_i; + int colorMask_i; + int logicOp_i; + + public PipelineState(int assemblyRasterState, int blendState, int depthState, int logicOp, int colorMask, + RenderPass renderPass) { + this.renderPass = renderPass; + + this.assemblyRasterState = assemblyRasterState; + this.blendState_i = blendState; + this.depthState_i = depthState; + this.colorMask_i = colorMask; + this.logicOp_i = logicOp; + } public static PipelineState getCurrentPipelineState(RenderPass renderPass) { int assemblyRasterState = getAssemblyRasterState(); @@ -59,31 +76,17 @@ public static int getLogicOpState() { return logicOpState; } - final RenderPass renderPass; - - int assemblyRasterState; - int blendState_i; - int depthState_i; - int colorMask_i; - int logicOp_i; - - public PipelineState(int assemblyRasterState, int blendState, int depthState, int logicOp, int colorMask, - RenderPass renderPass) { - this.renderPass = renderPass; - - this.assemblyRasterState = assemblyRasterState; - this.blendState_i = blendState; - this.depthState_i = depthState; - this.colorMask_i = colorMask; - this.logicOp_i = logicOp; + public static BlendInfo defaultBlendInfo() { + return new BlendInfo(true, VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD); } private boolean checkEquals(int assemblyRasterState, int blendState, int depthState, int logicOp, int colorMask, RenderPass renderPass) { return (blendState == this.blendState_i) && (depthState == this.depthState_i) - && renderPass == this.renderPass && logicOp == this.logicOp_i - && (assemblyRasterState == this.assemblyRasterState) - && colorMask == this.colorMask_i; + && renderPass == this.renderPass && logicOp == this.logicOp_i + && (assemblyRasterState == this.assemblyRasterState) + && colorMask == this.colorMask_i; } @Override @@ -95,9 +98,9 @@ public boolean equals(Object o) { PipelineState that = (PipelineState) o; return (blendState_i == that.blendState_i) && (depthState_i == that.depthState_i) - && this.renderPass == that.renderPass && logicOp_i == that.logicOp_i - && this.assemblyRasterState == that.assemblyRasterState - && this.colorMask_i == that.colorMask_i; + && this.renderPass == that.renderPass && logicOp_i == that.logicOp_i + && this.assemblyRasterState == that.assemblyRasterState + && this.colorMask_i == that.colorMask_i; } @Override @@ -105,11 +108,6 @@ public int hashCode() { return Objects.hash(blendState_i, depthState_i, logicOp_i, assemblyRasterState, colorMask_i, renderPass); } - public static BlendInfo defaultBlendInfo() { - return new BlendInfo(true, VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD); - } - public static class BlendInfo { public boolean enabled; public int srcRgbFactor; @@ -128,31 +126,6 @@ public BlendInfo(boolean enabled, int srcRgbFactor, int dstRgbFactor, int srcAlp this.blendOp = blendOp; } - /* gl to Vulkan conversion */ - public void setBlendFunction(int sourceFactor, int destFactor) { - this.srcRgbFactor = glToVulkanBlendFactor(sourceFactor); - this.srcAlphaFactor = glToVulkanBlendFactor(sourceFactor); - this.dstRgbFactor = glToVulkanBlendFactor(destFactor); - this.dstAlphaFactor = glToVulkanBlendFactor(destFactor); - } - - /* gl to Vulkan conversion */ - public void setBlendFuncSeparate(int srcRgb, int dstRgb, int srcAlpha, int dstAlpha) { - this.srcRgbFactor = glToVulkanBlendFactor(srcRgb); - this.srcAlphaFactor = glToVulkanBlendFactor(srcAlpha); - this.dstRgbFactor = glToVulkanBlendFactor(dstRgb); - this.dstAlphaFactor = glToVulkanBlendFactor(dstAlpha); - } - - public void setBlendOp(int i) { - this.blendOp = glToVulkanBlendOp(i); - } - - - public int createBlendState() { - return BlendState.getState(this); - } - private static int glToVulkanBlendOp(int value) { return switch (value) { case 0x8006 -> VK_BLEND_OP_ADD; @@ -201,6 +174,30 @@ private static int glToVulkanBlendFactor(int value) { // ZERO(0); }; } + + /* gl to Vulkan conversion */ + public void setBlendFunction(int sourceFactor, int destFactor) { + this.srcRgbFactor = glToVulkanBlendFactor(sourceFactor); + this.srcAlphaFactor = glToVulkanBlendFactor(sourceFactor); + this.dstRgbFactor = glToVulkanBlendFactor(destFactor); + this.dstAlphaFactor = glToVulkanBlendFactor(destFactor); + } + + /* gl to Vulkan conversion */ + public void setBlendFuncSeparate(int srcRgb, int dstRgb, int srcAlpha, int dstAlpha) { + this.srcRgbFactor = glToVulkanBlendFactor(srcRgb); + this.srcAlphaFactor = glToVulkanBlendFactor(srcAlpha); + this.dstRgbFactor = glToVulkanBlendFactor(dstRgb); + this.dstAlphaFactor = glToVulkanBlendFactor(dstAlpha); + } + + public void setBlendOp(int i) { + this.blendOp = glToVulkanBlendOp(i); + } + + public int createBlendState() { + return BlendState.getState(this); + } } public static class BlendState { @@ -327,9 +324,9 @@ public static abstract class ColorMask { public static int getColorMask(boolean r, boolean g, boolean b, boolean a) { return (r ? VK_COLOR_COMPONENT_R_BIT : 0) - | (g ? VK_COLOR_COMPONENT_G_BIT : 0) - | (b ? VK_COLOR_COMPONENT_B_BIT : 0) - | (a ? VK_COLOR_COMPONENT_A_BIT : 0); + | (g ? VK_COLOR_COMPONENT_G_BIT : 0) + | (b ? VK_COLOR_COMPONENT_B_BIT : 0) + | (a ? VK_COLOR_COMPONENT_A_BIT : 0); } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java b/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java index a45379fde..0dbe756fa 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java @@ -24,15 +24,12 @@ public class SPIRVUtils { private static final boolean DEBUG = true; private static final boolean OPTIMIZATIONS = false; - - private static long compiler; - private static long options; - //The dedicated Includer and Releaser Inner Classes used to Initialise #include Support for ShaderC private static final ShaderIncluder SHADER_INCLUDER = new ShaderIncluder(); private static final ShaderReleaser SHADER_RELEASER = new ShaderReleaser(); private static final long pUserData = 0; - + private static long compiler; + private static long options; private static ObjectArrayList includePaths; static { @@ -123,9 +120,9 @@ public long invoke(long user_data, long requested_source, int type, long request 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 e7e81619d..048e0d411 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/Uniforms.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/Uniforms.java @@ -3,7 +3,6 @@ import com.mojang.blaze3d.systems.RenderSystem; import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; import net.vulkanmod.vulkan.VRenderSystem; -import net.vulkanmod.vulkan.shader.layout.Uniform; import net.vulkanmod.vulkan.util.MappedBuffer; import java.util.function.Supplier; diff --git a/src/main/java/net/vulkanmod/vulkan/shader/converter/Attribute.java b/src/main/java/net/vulkanmod/vulkan/shader/converter/Attribute.java index 4bce3fb51..cab4742c2 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/converter/Attribute.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/converter/Attribute.java @@ -9,7 +9,8 @@ public class Attribute { public Attribute(String ioType, String type, String id) { switch (ioType) { - case "in", "out" -> {} + case "in", "out" -> { + } default -> throw new IllegalArgumentException(); } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/converter/GLSLParser.java b/src/main/java/net/vulkanmod/vulkan/shader/converter/GLSLParser.java index e3fae4055..4ef77c346 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/converter/GLSLParser.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/converter/GLSLParser.java @@ -15,31 +15,28 @@ * Simple parser used to convert GLSL shader code to make it Vulkan compatible */ public class GLSLParser { - private Lexer lexer; - private List tokens; - private int currentTokenIdx; - private Token currentToken; - - private Stage stage; State state = State.DEFAULT; - LinkedList vsStream = new LinkedList<>(); LinkedList fsStream = new LinkedList<>(); - int currentUniformLocation = 0; List uniformBlocks = new ArrayList<>(); Map uniformBlockMap = new HashMap<>(); List samplers = new ArrayList<>(); Map samplerMap = new HashMap<>(); - VertexFormat vertexFormat; int currentInAtt = 0, currentOutAtt = 0; ArrayList vertInAttributes = new ArrayList<>(); ArrayList vertOutAttributes = new ArrayList<>(); ArrayList fragInAttributes = new ArrayList<>(); ArrayList fragOutAttributes = new ArrayList<>(); + private Lexer lexer; + private List tokens; + private int currentTokenIdx; + private Token currentToken; + private Stage stage; - public GLSLParser() {} + public GLSLParser() { + } public void setVertexFormat(VertexFormat vertexFormat) { this.vertexFormat = vertexFormat; @@ -89,7 +86,7 @@ public void parse(Lexer lexer, Stage stage) { } } - private void parsePreprocessor() { + private void parsePreprocessor() { if (!currentToken.value.startsWith("#line")) { appendToken(currentToken); } @@ -130,8 +127,7 @@ private void parseSampler(Sampler.Type type) { if (next.type == Token.TokenType.SPACING) { if (Objects.equals(next.value, "\n")) { currentTokenIdx++; - } - else { + } else { int i = next.value.indexOf("\n"); if (i >= 0) { next.value = next.value.substring(i + 1); @@ -143,8 +139,7 @@ private void parseSampler(Sampler.Type type) { if (samplerMap.get(name) != null) { sampler = samplerMap.get(name); - } - else { + } else { sampler.setBinding(currentUniformLocation++); this.samplerMap.put(name, sampler); this.samplers.add(sampler); @@ -211,7 +206,8 @@ private void parseUniformBlock() { nextToken(true); switch (currentToken.type) { - case SEMICOLON -> {} + case SEMICOLON -> { + } case IDENTIFIER -> { ub.setAlias(currentToken.value); @@ -229,8 +225,7 @@ private void parseUniformBlock() { if (next.type == Token.TokenType.SPACING) { if (Objects.equals(next.value, "\n")) { currentTokenIdx++; - } - else { + } else { int i = next.value.indexOf("\n"); if (i >= 0) { next.value = next.value.substring(i + 1); @@ -240,8 +235,7 @@ private void parseUniformBlock() { if (uniformBlockMap.get(ub.name) != null) { ub = uniformBlockMap.get(ub.name); - } - else { + } else { ub.setBinding(this.currentUniformLocation++); this.uniformBlockMap.put(ub.name, ub); this.uniformBlocks.add(ub); @@ -276,8 +270,7 @@ private void parseAttribute() { if (next.type == Token.TokenType.SPACING) { if (Objects.equals(next.value, "\n")) { currentTokenIdx++; - } - else { + } else { int i = next.value.indexOf("\n"); if (i >= 0) { next.value = next.value.substring(i + 1); @@ -322,8 +315,7 @@ private void parseAttribute() { if (vertAttribute != null) { attribute.setLocation(vertAttribute.location); fragInAttributes.add(attribute); - } - else { + } else { return; } } @@ -428,7 +420,7 @@ public UBO[] createUBOs() { builder.addUniformInfo(uniformInfo); } - ubos[i] = builder.buildUBO(uniformBlock.name, uniformBlock.binding, VK11.VK_SHADER_STAGE_ALL); + ubos[i] = builder.buildUBO(uniformBlock.name, uniformBlock.binding, VK11.VK_SHADER_STAGE_ALL); ++i; } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/converter/Token.java b/src/main/java/net/vulkanmod/vulkan/shader/converter/Token.java index 560f9df07..ce1ba5859 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/converter/Token.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/converter/Token.java @@ -2,6 +2,21 @@ public class Token { + public final TokenType type; + public String value; + public Token(TokenType type, String value) { + this.type = type; + this.value = value; + } + + @Override + public String toString() { + return "Token{" + + "type=" + type + + ", value='" + value + '\'' + + '}'; + } + public enum TokenType { PREPROCESSOR, KEYWORD, @@ -30,20 +45,4 @@ public enum TokenType { EOF } - - public final TokenType type; - public String value; - - public Token(TokenType type, String value) { - this.type = type; - this.value = value; - } - - @Override - public String toString() { - return "Token{" + - "type=" + type + - ", value='" + value + '\'' + - '}'; - } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/Descriptor.java b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/Descriptor.java index 2685ccd0e..2a8fd774a 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/Descriptor.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/Descriptor.java @@ -2,9 +2,9 @@ public interface Descriptor { - int getBinding(); + int getBinding(); - int getType(); + int getType(); - int getStages(); + int getStages(); } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java index 0354402ac..9d73fcd06 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java @@ -7,12 +7,11 @@ public class ImageDescriptor implements Descriptor { - private final int descriptorType; - private final int binding; public final String qualifier; public final String name; public final int imageIdx; - + private final int descriptorType; + private final int binding; public boolean useSampler; public boolean isReadOnlyLayout; private int layout; @@ -58,23 +57,23 @@ public int getStages() { return VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT; } + public int getLayout() { + return layout; + } + public void setLayout(int layout) { this.layout = layout; this.isReadOnlyLayout = layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } - public int getLayout() { - return layout; + public int getMipLevel() { + return mipLevel; } public void setMipLevel(int mipLevel) { this.mipLevel = mipLevel; } - public int getMipLevel() { - return mipLevel; - } - public VulkanImage getImage() { return VTextureSelector.getImage(this.imageIdx); } 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 1229f1ada..af4f54aae 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java @@ -29,10 +29,10 @@ public UBO(String name, int binding, int stages, int size, List in @Override public String toString() { return "UBO{" + - "name='" + name + '\'' + - ", binding=" + binding + - ", useGlobalBuffer=" + useGlobalBuffer + - '}'; + "name='" + name + '\'' + + ", binding=" + binding + + ", useGlobalBuffer=" + useGlobalBuffer + + '}'; } public int getBinding() { diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat3.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat3.java index 82f067323..8ed9f6064 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat3.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat3.java @@ -12,7 +12,7 @@ public class Mat3 extends Uniform { void update(long ptr) { MappedBuffer src = values.get(); - MemoryUtil.memCopy(src.ptr + 0, ptr + this.offset + 0, 12); + MemoryUtil.memCopy(src.ptr, ptr + this.offset, 12); MemoryUtil.memCopy(src.ptr + 12, ptr + this.offset + 16, 12); MemoryUtil.memCopy(src.ptr + 24, ptr + this.offset + 32, 12); } 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 8c1509df1..118a773ed 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java @@ -8,10 +8,9 @@ public class Uniform { protected Supplier values; - - Info info; protected long offset; protected int size; + Info info; Uniform(Info info) { this.info = info; @@ -21,24 +20,6 @@ public class Uniform { this.setupSupplier(); } - protected void setupSupplier() { - this.values = this.info.bufferSupplier; - } - - public void setSupplier(Supplier supplier) { - this.values = supplier; - } - - public String getName() { - return this.info.name; - } - - void update(long ptr) { - MappedBuffer src = values.get(); - - MemoryUtil.memCopy(src.ptr, ptr + this.offset, this.size); - } - public static Uniform createField(Info info) { return switch (info.type) { case "mat4", "vec3", "vec4", "vec2" -> new Uniform(info); @@ -49,20 +30,6 @@ public static Uniform createField(Info info) { }; } - public int getOffset() { - return info.offset; - } - - 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); - } - //TODO public static Info createUniformInfo(String type, String name, int count) { return switch (type) { @@ -95,6 +62,40 @@ public static Info createUniformInfo(String type, String name) { }; } + protected void setupSupplier() { + this.values = this.info.bufferSupplier; + } + + public void setSupplier(Supplier supplier) { + this.values = supplier; + } + + public String getName() { + return this.info.name; + } + + void update(long ptr) { + MappedBuffer src = values.get(); + + MemoryUtil.memCopy(src.ptr, ptr + this.offset, this.size); + } + + public int getOffset() { + return info.offset; + } + + 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); + } + public static class Info { public final String type; public final String name; @@ -113,7 +114,9 @@ public static class Info { this.size = size; } - int getSizeBytes() { return 4 * this.size; } + int getSizeBytes() { + return 4 * this.size; + } int computeAlignmentOffset(int builderOffset) { return this.offset = builderOffset + ((align - (builderOffset % align)) % align); 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 700fd00bf..954934708 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.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; diff --git a/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java b/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java index 84a5665bc..6557b23cb 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java @@ -46,18 +46,18 @@ 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); + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + pStagingBuffer, pStagingAllocation); copyImageToBufferCmd(stack, commandBuffer.getHandle(), pStagingBuffer.get(0), image.getId(), 0, image.width, - image.height, 0, 0, 0, 0, 0); + 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)); } @@ -72,7 +72,7 @@ public static void copyImageToBuffer(VulkanImage image, Buffer buffer, int mipLe image.transitionImageLayout(stack, commandBuffer.getHandle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); copyImageToBufferCmd(stack, commandBuffer.getHandle(), buffer.getId(), image.getId(), mipLevel, width, - height, xOffset, yOffset, bufferOffset, bufferRowLength, bufferImageHeight); + height, xOffset, yOffset, bufferOffset, bufferRowLength, bufferImageHeight); image.transitionImageLayout(stack, commandBuffer.getHandle(), prevLayout); long fence = DeviceManager.getGraphicsQueue().submitCommands(commandBuffer); @@ -115,18 +115,18 @@ public static void blitFramebuffer(VulkanImage dstImage, int srcX0, int srcY0, i 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); + .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); + .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.getId(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, blit, VK_FILTER_LINEAR); dstImage.transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); @@ -166,7 +166,7 @@ public static void generateMipmaps(VulkanImage image) { barrier.dstAccessMask(VK_ACCESS_TRANSFER_READ_BIT); vkCmdPipelineBarrier(commandBuffer.getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, 0, null, null, barrier); + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, null, null, barrier); prevLevel = level - 1; @@ -174,18 +174,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); + .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); + image.getId(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, blit, VK_FILTER_LINEAR); } @@ -208,20 +208,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/SamplerManager.java b/src/main/java/net/vulkanmod/vulkan/texture/SamplerManager.java index f58fb4255..cfb05a4bf 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/SamplerManager.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/SamplerManager.java @@ -17,8 +17,13 @@ import static org.lwjgl.vulkan.VK12.VK_SAMPLER_REDUCTION_MODE_MIN; public abstract class SamplerManager { + public static final byte LINEAR_FILTERING_BIT = 0b1; + public static final byte CLAMP_BIT = 0b10; + public static final byte USE_MIPMAPS_BIT = 0b100; + public static final byte MIPMAP_LINEAR_FILTERING_BIT = 0b1000; + public static final byte REDUCTION_MIN_BIT = 0b10000; + public static final byte REDUCTION_MAX_BIT = 0b100000; static final float MIP_BIAS = -0.5f; - static final Short2LongMap SAMPLERS = new Short2LongOpenHashMap(); public static long getTextureSampler(byte maxLod, byte flags) { @@ -106,11 +111,4 @@ public static void cleanUp() { vkDestroySampler(DeviceManager.vkDevice, id, null); } } - - public static final byte LINEAR_FILTERING_BIT = 0b1; - public static final byte CLAMP_BIT = 0b10; - public static final byte USE_MIPMAPS_BIT = 0b100; - public static final byte MIPMAP_LINEAR_FILTERING_BIT = 0b1000; - public static final byte REDUCTION_MIN_BIT = 0b10000; - public static final byte REDUCTION_MAX_BIT = 0b100000; } diff --git a/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java b/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java index 58d1b31a7..59dfa793a 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java @@ -49,7 +49,7 @@ public static void uploadSubTexture(int mipLevel, int width, int height, int xOf int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, ByteBuffer buffer) { uploadSubTexture(mipLevel, 0, width, height, xOffset, yOffset, unpackSkipRows, unpackSkipPixels, unpackRowLength, - MemoryUtil.memAddress(buffer)); + MemoryUtil.memAddress(buffer)); } public static void uploadSubTexture(int mipLevel, int arrayLayer, int width, int height, int xOffset, int yOffset, @@ -61,7 +61,7 @@ public static void uploadSubTexture(int mipLevel, int arrayLayer, int width, int throw new NullPointerException("Texture is null at index: " + activeTexture); texture.uploadSubTextureAsync(mipLevel, arrayLayer, width, height, xOffset, yOffset, unpackSkipRows, unpackSkipPixels, - unpackRowLength, bufferPtr); + unpackRowLength, bufferPtr); } public static int getTextureIdx(String name) { diff --git a/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java b/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java index ab89a99d2..05408346f 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java @@ -24,10 +24,8 @@ import static org.lwjgl.vulkan.VK10.*; public class VulkanImage { - public static int DefaultFormat = VK_FORMAT_R8G8B8A8_UNORM; - private static final VkDevice DEVICE = Vulkan.getVkDevice(); - + public static int DefaultFormat = VK_FORMAT_R8G8B8A8_UNORM; public final String name; public final int format; public final int aspect; @@ -134,32 +132,6 @@ public static VulkanImage createWhiteTexture() { } } - private void createImage() { - try (MemoryStack stack = stackPush()) { - LongBuffer pTextureImage = stack.mallocLong(1); - PointerBuffer pAllocation = stack.pointers(0L); - - int flags = viewType == VK_IMAGE_VIEW_TYPE_CUBE ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0; - - MemoryManager.getInstance() - .createImage(width, height, arrayLayers, mipLevels, - format, VK_IMAGE_TILING_OPTIMAL, - usage, flags, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - pTextureImage, - pAllocation); - - id = pTextureImage.get(0); - allocation = pAllocation.get(0); - - MemoryManager.addImage(this); - - if (this.name != null) { - Vulkan.setDebugLabel(stack, VK_OBJECT_TYPE_IMAGE, pTextureImage.get(), this.name); - } - } - } - public static int getAspect(int format) { return switch (format) { case VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT -> @@ -208,111 +180,6 @@ public static long createImageView(long image, int viewType, int format, int asp } } - public void uploadSubTextureAsync(int mipLevel, - int width, int height, - int xOffset, int yOffset, - int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, - ByteBuffer buffer) - { - this.uploadSubTextureAsync(mipLevel, 0, width, height, - xOffset, yOffset, - unpackSkipRows, unpackSkipPixels, unpackRowLength, - MemoryUtil.memAddress(buffer)); - } - - public void uploadSubTextureAsync(int mipLevel, int arrayLayer, - int width, int height, - int xOffset, int yOffset, - int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, - ByteBuffer buffer) - { - this.uploadSubTextureAsync(mipLevel, arrayLayer, width, height, - xOffset, yOffset, - unpackSkipRows, unpackSkipPixels, unpackRowLength, - MemoryUtil.memAddress(buffer)); - } - - public void uploadSubTextureAsync(int mipLevel, int arrayLayer, - int width, int height, - int xOffset, int yOffset, - int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, - long srcPtr) - { - long uploadSize = (long) (unpackRowLength * height - unpackSkipPixels) * this.formatSize; - - 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(); - } - - srcPtr += ((long) unpackRowLength * unpackSkipRows + unpackSkipPixels) * this.formatSize; - - stagingBuffer.align(this.formatSize); - stagingBuffer.copyBuffer((int) uploadSize, srcPtr); - - long bufferId = stagingBuffer.getId(); - - VkCommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer().getHandle(); - try (MemoryStack stack = stackPush()) { - transferDstLayout(stack, commandBuffer); - - final int srcOffset = (int) (stagingBuffer.getOffset()); - - ImageUtil.copyBufferToImageCmd(stack, commandBuffer, bufferId, this.id, - arrayLayer, mipLevel, width, height, xOffset, yOffset, - srcOffset, unpackRowLength, height); - } - } - - private void transferDstLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { - transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - } - - public void readOnlyLayout() { - if (this.currentLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - return; - - try (MemoryStack stack = MemoryStack.stackPush()) { - if (Renderer.getInstance().getBoundRenderPass() != null) { - CommandPool.CommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer(); - VkCommandBuffer vkCommandBuffer = commandBuffer.getHandle(); - - readOnlyLayout(stack, vkCommandBuffer); - } - else { - readOnlyLayout(stack, Renderer.getCommandBuffer()); - } - } - } - - public void readOnlyLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { - transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - } - - public void updateTextureSampler(boolean blur, boolean clamp, boolean mipmaps) { - byte flags = blur ? LINEAR_FILTERING_BIT : 0; - flags |= clamp ? CLAMP_BIT : 0; - flags |= (byte) (mipmaps ? USE_MIPMAPS_BIT | MIPMAP_LINEAR_FILTERING_BIT : 0); - - this.updateTextureSampler(flags); - } - - public void updateTextureSampler(byte flags) { - updateTextureSampler(this.mipLevels - 1, flags); - } - - public void updateTextureSampler(int maxLod, byte flags) { - this.sampler = SamplerManager.getTextureSampler((byte) maxLod, flags); - } - - public void transitionImageLayout(MemoryStack stack, VkCommandBuffer commandBuffer, int newLayout) { - transitionImageLayout(stack, commandBuffer, this, newLayout); - } - public static void transitionImageLayout(MemoryStack stack, VkCommandBuffer commandBuffer, VulkanImage image, int newLayout) { if (image.currentLayout == newLayout) { // System.out.println("new layout is equal to current layout"); @@ -421,6 +288,137 @@ private static boolean hasStencilComponent(int format) { return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT; } + public static Builder builder(int width, int height) { + return new Builder(width, height); + } + + private void createImage() { + try (MemoryStack stack = stackPush()) { + LongBuffer pTextureImage = stack.mallocLong(1); + PointerBuffer pAllocation = stack.pointers(0L); + + int flags = viewType == VK_IMAGE_VIEW_TYPE_CUBE ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0; + + MemoryManager.getInstance() + .createImage(width, height, arrayLayers, mipLevels, + format, VK_IMAGE_TILING_OPTIMAL, + usage, flags, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + pTextureImage, + pAllocation); + + id = pTextureImage.get(0); + allocation = pAllocation.get(0); + + MemoryManager.addImage(this); + + if (this.name != null) { + Vulkan.setDebugLabel(stack, VK_OBJECT_TYPE_IMAGE, pTextureImage.get(), this.name); + } + } + } + + public void uploadSubTextureAsync(int mipLevel, + int width, int height, + int xOffset, int yOffset, + int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, + ByteBuffer buffer) { + this.uploadSubTextureAsync(mipLevel, 0, width, height, + xOffset, yOffset, + unpackSkipRows, unpackSkipPixels, unpackRowLength, + MemoryUtil.memAddress(buffer)); + } + + public void uploadSubTextureAsync(int mipLevel, int arrayLayer, + int width, int height, + int xOffset, int yOffset, + int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, + ByteBuffer buffer) { + this.uploadSubTextureAsync(mipLevel, arrayLayer, width, height, + xOffset, yOffset, + unpackSkipRows, unpackSkipPixels, unpackRowLength, + MemoryUtil.memAddress(buffer)); + } + + public void uploadSubTextureAsync(int mipLevel, int arrayLayer, + int width, int height, + int xOffset, int yOffset, + int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, + long srcPtr) { + long uploadSize = (long) ((long) unpackRowLength * height - unpackSkipPixels) * this.formatSize; + + 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(); + } + + srcPtr += ((long) unpackRowLength * unpackSkipRows + unpackSkipPixels) * this.formatSize; + + stagingBuffer.align(this.formatSize); + stagingBuffer.copyBuffer((int) uploadSize, srcPtr); + + long bufferId = stagingBuffer.getId(); + + VkCommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer().getHandle(); + try (MemoryStack stack = stackPush()) { + transferDstLayout(stack, commandBuffer); + + final int srcOffset = (int) (stagingBuffer.getOffset()); + + ImageUtil.copyBufferToImageCmd(stack, commandBuffer, bufferId, this.id, + arrayLayer, mipLevel, width, height, xOffset, yOffset, + srcOffset, unpackRowLength, height); + } + } + + private void transferDstLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { + transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + } + + public void readOnlyLayout() { + if (this.currentLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + return; + + try (MemoryStack stack = MemoryStack.stackPush()) { + if (Renderer.getInstance().getBoundRenderPass() != null) { + CommandPool.CommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer(); + VkCommandBuffer vkCommandBuffer = commandBuffer.getHandle(); + + readOnlyLayout(stack, vkCommandBuffer); + } else { + readOnlyLayout(stack, Renderer.getCommandBuffer()); + } + } + } + + public void readOnlyLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { + transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + } + + public void updateTextureSampler(boolean blur, boolean clamp, boolean mipmaps) { + byte flags = blur ? LINEAR_FILTERING_BIT : 0; + flags |= clamp ? CLAMP_BIT : 0; + flags |= (byte) (mipmaps ? USE_MIPMAPS_BIT | MIPMAP_LINEAR_FILTERING_BIT : 0); + + this.updateTextureSampler(flags); + } + + public void updateTextureSampler(byte flags) { + updateTextureSampler(this.mipLevels - 1, flags); + } + + public void updateTextureSampler(int maxLod, byte flags) { + this.sampler = SamplerManager.getTextureSampler((byte) maxLod, flags); + } + + public void transitionImageLayout(MemoryStack stack, VkCommandBuffer commandBuffer, int newLayout) { + transitionImageLayout(stack, commandBuffer, this, newLayout); + } + public void free() { MemoryManager.getInstance().addToFreeable(this); } @@ -472,10 +470,6 @@ public long getSampler() { return sampler; } - public static Builder builder(int width, int height) { - return new Builder(width, height); - } - public static class Builder { final int width; final int height; @@ -497,6 +491,18 @@ public Builder(int width, int height) { this.height = height; } + private static int formatSize(int format) { + return switch (format) { + case VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB, + VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, + 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; + }; + } + public Builder setName(String name) { this.name = name; return this; @@ -562,17 +568,5 @@ public VulkanImage createVulkanImage() { return VulkanImage.createTextureImage(this); } - - private static int formatSize(int format) { - return switch (format) { - case VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB, - VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, - 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; - }; - } } } diff --git a/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java b/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java index 0c2c0990b..5c44dfa8e 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java @@ -13,13 +13,61 @@ public static void useGammaCorrection(boolean b) { } public static int floatToInt(float f) { - return (int)(f * 255.0f) & 0xFF; + return (int) (f * 255.0f) & 0xFF; } public static float unpackColor(int c, int s) { return ((c >> s) & 0xFF) * COLOR_INV; } + public static int BGRAtoRGBA(int v) { + byte r = (byte) (v >> 16); + byte b = (byte) (v); + return r & 0xFF | (b << 16) & 0xFF0000 | v & 0xFF00FF00; + } + + public static float gamma(float f) { + return (float) Math.pow(f, 2.2); + } + + public static void setRGBA_Buffer(MappedBuffer buffer, float r, float g, float b, float a) { + colorConsumer.setRGBA_Buffer(buffer, r, g, b, a); + } + + public static void setRGBA_Buffer(FloatBuffer buffer, float r, float g, float b, float a) { + colorConsumer.setRGBA_Buffer(buffer, r, g, b, a); + } + + interface ColorConsumer { + + void setRGBA_Buffer(MappedBuffer buffer, float r, float g, float b, float a); + + void setRGBA_Buffer(FloatBuffer buffer, float r, float g, float b, float a); + + void setRGBA_Buffer(ByteBuffer buffer, float r, float g, float b, float a); + + default void putColor(MappedBuffer buffer, float r, float g, float b, float a) { + buffer.putFloat(0, r); + buffer.putFloat(4, g); + buffer.putFloat(8, b); + buffer.putFloat(12, a); + } + + default void putColor(FloatBuffer buffer, float r, float g, float b, float a) { + buffer.put(0, r); + buffer.put(1, g); + buffer.put(2, b); + buffer.put(3, a); + } + + default void putColor(ByteBuffer buffer, float r, float g, float b, float a) { + buffer.putFloat(0, r); + buffer.putFloat(4, g); + buffer.putFloat(8, b); + buffer.putFloat(12, a); + } + } + public static class ARGB { public static int pack(float r, float g, float b, float a) { int color = floatToInt(a) << 24 | floatToInt(r) << 16 | floatToInt(g) << 8 | floatToInt(b); @@ -86,52 +134,6 @@ public static int fromArgb32(int i) { } } - public static int BGRAtoRGBA(int v) { - byte r = (byte) (v >> 16); - byte b = (byte) (v); - return r & 0xFF | (b << 16) & 0xFF0000 | v & 0xFF00FF00; - } - - public static float gamma(float f) { - return (float) Math.pow(f, 2.2); - } - - public static void setRGBA_Buffer(MappedBuffer buffer, float r, float g, float b, float a) { - colorConsumer.setRGBA_Buffer(buffer, r, g, b, a); - } - - public static void setRGBA_Buffer(FloatBuffer buffer, float r, float g, float b, float a) { - colorConsumer.setRGBA_Buffer(buffer, r, g, b, a); - } - - interface ColorConsumer { - - void setRGBA_Buffer(MappedBuffer buffer, float r, float g, float b, float a); - void setRGBA_Buffer(FloatBuffer buffer, float r, float g, float b, float a); - void setRGBA_Buffer(ByteBuffer buffer, float r, float g, float b, float a); - - default void putColor(MappedBuffer buffer, float r, float g, float b, float a) { - buffer.putFloat(0, r); - buffer.putFloat(4, g); - buffer.putFloat(8, b); - buffer.putFloat(12, a); - } - - default void putColor(FloatBuffer buffer, float r, float g, float b, float a) { - buffer.put(0, r); - buffer.put(1, g); - buffer.put(2, b); - buffer.put(3, a); - } - - default void putColor(ByteBuffer buffer, float r, float g, float b, float a) { - buffer.putFloat(0, r); - buffer.putFloat(4, g); - buffer.putFloat(8, b); - buffer.putFloat(12, a); - } - } - public static class DefaultColorConsumer implements ColorConsumer { @Override diff --git a/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java b/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java index fd2a9ece0..b2e7ccd19 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java @@ -1,6 +1,5 @@ package net.vulkanmod.vulkan.util; -import com.mojang.blaze3d.systems.RenderSystem; import net.vulkanmod.render.PipelineManager; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; diff --git a/src/main/java/net/vulkanmod/vulkan/util/MappedBuffer.java b/src/main/java/net/vulkanmod/vulkan/util/MappedBuffer.java index 67b0f246f..130d3a9eb 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/MappedBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/util/MappedBuffer.java @@ -9,9 +9,6 @@ public class MappedBuffer { public final ByteBuffer buffer; public final long ptr; - public static MappedBuffer createFromBuffer(ByteBuffer buffer) { - return new MappedBuffer(buffer, MemoryUtil.memAddress0(buffer)); - } MappedBuffer(ByteBuffer buffer, long ptr) { this.buffer = buffer; this.ptr = ptr; @@ -22,6 +19,10 @@ public MappedBuffer(int size) { this.ptr = MemoryUtil.memAddress0(this.buffer); } + public static MappedBuffer createFromBuffer(ByteBuffer buffer) { + return new MappedBuffer(buffer, MemoryUtil.memAddress0(buffer)); + } + public void putFloat(int idx, float f) { VUtil.UNSAFE.putFloat(ptr + idx, f); } diff --git a/src/main/java/net/vulkanmod/vulkan/util/Pair.java b/src/main/java/net/vulkanmod/vulkan/util/Pair.java index 3b05f1425..d8c300b99 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/Pair.java +++ b/src/main/java/net/vulkanmod/vulkan/util/Pair.java @@ -1,6 +1,6 @@ package net.vulkanmod.vulkan.util; -public class Pair { +public class Pair { public A first; public B second; From 9007677ee20554f331f64203e6e1945154fd1368 Mon Sep 17 00:00:00 2001 From: Temo Tskipuri Date: Thu, 27 Nov 2025 00:39:35 +0400 Subject: [PATCH 5/5] Reverted unwanted changes --- src/main/java/net/vulkanmod/Initializer.java | 61 +- .../java/net/vulkanmod/config/Config.java | 54 +- .../net/vulkanmod/config/gui/GuiElement.java | 17 +- .../vulkanmod/config/gui/VOptionScreen.java | 9 +- .../config/gui/render/GuiRenderer.java | 3 +- .../config/gui/render/PolygonRenderState.java | 24 +- .../gui/widget/CyclingOptionWidget.java | 24 +- .../config/gui/widget/OptionWidget.java | 14 +- .../config/gui/widget/RangeOptionWidget.java | 9 +- .../config/gui/widget/SwitchOptionWidget.java | 10 +- .../config/gui/widget/VAbstractWidget.java | 8 +- .../config/gui/widget/VButtonWidget.java | 5 +- .../config/option/CyclingOption.java | 16 +- .../net/vulkanmod/config/option/Option.java | 24 +- .../net/vulkanmod/config/option/Options.java | 274 ++++---- .../config/video/VideoModeManager.java | 9 +- .../vulkanmod/config/video/VideoModeSet.java | 14 +- src/main/java/net/vulkanmod/gl/GlUtil.java | 53 +- .../java/net/vulkanmod/gl/VkGlBuffer.java | 18 +- .../net/vulkanmod/gl/VkGlFramebuffer.java | 34 +- .../java/net/vulkanmod/gl/VkGlProgram.java | 15 +- .../net/vulkanmod/gl/VkGlRenderbuffer.java | 32 +- .../java/net/vulkanmod/gl/VkGlShader.java | 22 +- .../java/net/vulkanmod/gl/VkGlTexture.java | 60 +- .../interfaces/ExtendedVertexBuilder.java | 3 +- .../shader/ExtendedRenderPipeline.java | 8 +- .../mixin/chunk/ClientChunkCacheM.java | 2 + .../vulkanmod/mixin/chunk/DirectionMixin.java | 8 +- .../vulkanmod/mixin/chunk/FrustumMixin.java | 20 +- .../mixin/chunk/LevelRendererMixin.java | 26 +- .../chunk/SectionBufferBuilderPoolM.java | 8 +- .../mixin/chunk/SectionRenderDispatcherM.java | 4 +- .../net/vulkanmod/mixin/chunk/ViewAreaM.java | 16 +- .../mixin/chunk/VisibilitySetMixin.java | 4 +- .../mixin/compatibility/PostPassM.java | 31 +- .../mixin/compatibility/gl/GL11M.java | 3 +- .../mixin/compatibility/gl/GL14M.java | 1 + .../mixin/debug/DebugEntryMemoryM.java | 4 +- .../mixin/debug/DebugScreenEntriesM.java | 2 +- .../mixin/debug/KeyboardHandlerM.java | 6 +- .../debug/crash_report/SystemReportM.java | 10 +- .../net/vulkanmod/mixin/matrix/Matrix4fM.java | 19 +- .../mixin/profiling/GameLoadTimeEventM.java | 18 +- .../vulkanmod/mixin/profiling/GuiMixin.java | 5 +- .../mixin/profiling/KeyboardHandlerM.java | 3 +- .../mixin/profiling/LevelRendererMixin.java | 4 +- .../mixin/render/CompositeRenderTypeM.java | 41 +- .../mixin/render/GlStateManagerM.java | 18 +- .../mixin/render/GuiRendererMixin.java | 14 +- .../mixin/render/MinecraftMixin.java | 17 +- .../mixin/render/RenderSystemMixin.java | 21 +- .../mixin/render/biome/BiomeManagerM.java | 4 +- .../mixin/render/block/BakedQuadM.java | 24 +- .../mixin/render/clouds/LevelRendererM.java | 23 +- .../mixin/render/color/BlockColorsM.java | 20 +- .../mixin/render/entity/EntityRendererM.java | 8 +- .../mixin/render/entity/LevelRendererM.java | 28 +- .../render/entity/model/ModelPartCubeM.java | 3 +- .../mixin/render/entity/model/ModelPartM.java | 34 +- .../mixin/render/frame/MinecraftMixin.java | 3 +- .../frapi/BatchingRenderCommandQueueM.java | 7 +- .../frapi/BlockRenderDispatcherAccessor.java | 5 +- .../render/frapi/ItemFeatureRendererM.java | 8 +- .../render/frapi/ItemRendererAccessor.java | 8 +- .../frapi/OrderedRenderCommandQueueImplM.java | 2 + .../render/particle/QuadParticleGroupM.java | 10 +- .../particle/QuadParticleRenderStateM.java | 8 +- .../mixin/render/shader/RenderPipelineM.java | 18 +- .../mixin/render/shader/ShaderManagerM.java | 1 + .../render/target/RenderTargetMixin.java | 26 +- .../mixin/render/vertex/BufferBuilderM.java | 39 +- .../render/vertex/VertexFormatMixin.java | 3 + .../mixin/screen/OptionsScreenM.java | 8 +- .../mixin/texture/mip/MipmapGeneratorM.java | 40 +- .../mixin/texture/update/MLightTexture.java | 87 +-- .../mixin/texture/update/MSpriteContents.java | 13 +- .../mixin/texture/update/MTextureManager.java | 4 +- .../vulkanmod/mixin/util/ScreenshotMixin.java | 6 +- .../vertex/SpriteCoordinateExpanderM.java | 4 +- .../mixin/vertex/VertexMultiConsumersM.java | 34 +- .../mixin/voxel/VoxelShapeMixin.java | 12 +- .../mixin/wayland/InputConstantsM.java | 2 +- .../mixin/wayland/MinecraftMixin.java | 19 +- .../vulkanmod/mixin/window/WindowMixin.java | 85 +-- .../net/vulkanmod/render/PipelineManager.java | 10 +- src/main/java/net/vulkanmod/render/VBO.java | 11 +- .../net/vulkanmod/render/chunk/ChunkArea.java | 19 +- .../render/chunk/ChunkAreaManager.java | 14 +- .../render/chunk/ChunkStatusMap.java | 12 +- .../vulkanmod/render/chunk/RenderSection.java | 71 +- .../vulkanmod/render/chunk/SectionGrid.java | 18 +- .../vulkanmod/render/chunk/WorldRenderer.java | 135 ++-- .../render/chunk/buffer/AreaBuffer.java | 33 +- .../render/chunk/buffer/DrawBuffers.java | 24 +- .../chunk/buffer/DrawParametersBuffer.java | 6 +- .../render/chunk/buffer/UploadManager.java | 8 +- .../render/chunk/build/RenderRegion.java | 12 +- .../render/chunk/build/UploadBuffer.java | 7 +- .../render/chunk/build/biome/BiomeData.java | 77 ++- .../chunk/build/color/BlockColorRegistry.java | 18 +- .../render/chunk/build/color/BoxBlur.java | 2 +- .../render/chunk/build/color/TintCache.java | 3 +- .../chunk/build/frapi/VulkanModRenderer.java | 76 +-- .../AccessBatchingRenderCommandQueue.java | 2 +- .../accessor/AccessChunkRendererRegion.java | 4 +- .../accessor/AccessLayerRenderState.java | 2 +- .../accessor/AccessRenderCommandQueue.java | 3 +- .../chunk/build/frapi/helper/ColorHelper.java | 169 +++-- .../build/frapi/helper/GeometryHelper.java | 418 ++++++------ .../build/frapi/helper/NormalHelper.java | 330 ++++----- .../build/frapi/helper/TextureHelper.java | 161 ++--- .../build/frapi/mesh/EncodingFormat.java | 371 +++++----- .../chunk/build/frapi/mesh/MeshImpl.java | 155 +++-- .../build/frapi/mesh/MutableMeshImpl.java | 26 +- .../build/frapi/mesh/MutableQuadViewImpl.java | 598 ++++++++-------- .../chunk/build/frapi/mesh/QuadViewImpl.java | 645 +++++++++--------- .../render/AbstractBlockRenderContext.java | 392 +++++------ .../frapi/render/AbstractRenderContext.java | 85 ++- .../frapi/render/BlockRenderContext.java | 95 +-- .../build/frapi/render/ItemRenderContext.java | 162 ++--- .../build/frapi/render/MeshItemCommand.java | 7 +- .../render/SimpleBlockRenderContext.java | 2 + .../chunk/build/light/LightPipeline.java | 15 +- .../build/light/data/LightDataAccess.java | 169 ++--- .../build/light/flat/FlatLightPipeline.java | 6 +- .../chunk/build/light/smooth/AoFaceData.java | 120 ++-- .../build/light/smooth/AoNeighborInfo.java | 136 ++-- .../light/smooth/NewSmoothLightPipeline.java | 50 +- .../light/smooth/SmoothLightPipeline.java | 66 +- .../build/light/smooth/SubBlockAoFace.java | 30 +- .../chunk/build/renderer/BlockRenderer.java | 17 +- .../build/renderer/DefaultFluidRenderers.java | 14 +- .../chunk/build/renderer/FluidRenderer.java | 33 +- .../render/chunk/build/task/BuildTask.java | 4 +- .../render/chunk/build/task/ChunkTask.java | 18 +- .../chunk/build/task/CompileResult.java | 6 +- .../chunk/build/task/CompiledSection.java | 5 +- .../chunk/build/task/TaskDispatcher.java | 45 +- .../chunk/build/thread/BuilderResources.java | 7 +- .../chunk/build/thread/ThreadBuilderPack.java | 17 +- .../render/chunk/frustum/VFrustum.java | 5 +- .../render/chunk/graph/SectionGraph.java | 59 +- .../render/chunk/util/CircularIntList.java | 9 +- .../render/chunk/util/ResettableQueue.java | 4 +- .../render/chunk/util/SimpleDirection.java | 12 +- .../render/chunk/util/StaticQueue.java | 6 +- .../net/vulkanmod/render/chunk/util/Util.java | 3 + .../vulkanmod/render/engine/EGlProgram.java | 6 +- .../render/engine/VkCommandEncoder.java | 211 +++--- .../vulkanmod/render/engine/VkDebugLabel.java | 16 +- .../net/vulkanmod/render/engine/VkFbo.java | 4 + .../vulkanmod/render/engine/VkGpuBuffer.java | 44 +- .../vulkanmod/render/engine/VkGpuDevice.java | 61 +- .../vulkanmod/render/engine/VkGpuTexture.java | 86 +-- .../vulkanmod/render/engine/VkRenderPass.java | 60 +- .../net/vulkanmod/render/model/CubeModel.java | 35 +- .../render/model/quad/ModelQuad.java | 19 +- .../render/model/quad/ModelQuadFlags.java | 2 +- .../render/model/quad/QuadUtils.java | 8 +- .../render/profiling/BuildTimeProfiler.java | 4 +- .../vulkanmod/render/profiling/Profiler.java | 30 +- .../render/shader/CustomRenderPipelines.java | 12 +- .../render/shader/ShaderLoadUtil.java | 12 +- .../vulkanmod/render/sky/CloudRenderer.java | 105 +-- .../render/texture/SpriteUpdateUtil.java | 2 +- .../net/vulkanmod/render/util/DrawUtil.java | 2 + .../net/vulkanmod/render/util/SortUtil.java | 33 +- .../render/vertex/CustomVertexFormat.java | 10 +- .../vulkanmod/render/vertex/QuadSorter.java | 20 +- .../render/vertex/TerrainBufferBuilder.java | 84 +-- .../render/vertex/TerrainBuilder.java | 18 +- .../render/vertex/TerrainRenderType.java | 10 +- .../render/vertex/VertexBuilder.java | 10 +- .../render/vertex/format/I32_SNorm.java | 10 +- .../java/net/vulkanmod/vulkan/Drawer.java | 22 +- .../java/net/vulkanmod/vulkan/Renderer.java | 484 ++++++------- .../net/vulkanmod/vulkan/Synchronization.java | 24 +- .../net/vulkanmod/vulkan/VRenderSystem.java | 29 +- .../java/net/vulkanmod/vulkan/Vulkan.java | 33 +- .../net/vulkanmod/vulkan/device/Device.java | 12 +- .../vulkan/framebuffer/Framebuffer.java | 29 +- .../vulkan/framebuffer/RenderPass.java | 14 +- .../vulkan/framebuffer/SwapChain.java | 77 +-- .../vulkan/memory/MemoryManager.java | 120 ++-- .../vulkanmod/vulkan/memory/MemoryType.java | 4 +- .../vulkan/memory/buffer/Buffer.java | 20 +- .../vulkan/memory/buffer/IndirectBuffer.java | 1 + .../vulkan/memory/buffer/StagingBuffer.java | 2 +- .../vulkan/memory/buffer/UniformBuffer.java | 8 +- .../memory/buffer/index/AutoIndexBuffer.java | 122 ++-- .../vulkan/pass/DefaultMainPass.java | 14 +- .../net/vulkanmod/vulkan/pass/MainPass.java | 12 +- .../vulkanmod/vulkan/queue/CommandPool.java | 3 +- .../vulkanmod/vulkan/queue/GraphicsQueue.java | 6 +- .../net/vulkanmod/vulkan/queue/Queue.java | 76 +-- .../vulkanmod/vulkan/queue/TransferQueue.java | 26 +- .../vulkan/shader/DescriptorSets.java | 13 +- .../vulkan/shader/GraphicsPipeline.java | 282 ++++---- .../net/vulkanmod/vulkan/shader/Pipeline.java | 81 +-- .../vulkan/shader/PipelineState.java | 109 +-- .../vulkanmod/vulkan/shader/SPIRVUtils.java | 13 +- .../net/vulkanmod/vulkan/shader/Uniforms.java | 1 + .../vulkan/shader/converter/Attribute.java | 3 +- .../vulkan/shader/converter/GLSLParser.java | 42 +- .../vulkan/shader/converter/Token.java | 31 +- .../vulkan/shader/descriptor/Descriptor.java | 6 +- .../shader/descriptor/ImageDescriptor.java | 17 +- .../vulkan/shader/descriptor/UBO.java | 8 +- .../vulkanmod/vulkan/shader/layout/Mat3.java | 2 +- .../vulkan/shader/layout/Uniform.java | 73 +- .../vulkanmod/vulkan/shader/layout/Vec1i.java | 2 + .../vulkanmod/vulkan/texture/ImageUtil.java | 52 +- .../vulkan/texture/SamplerManager.java | 14 +- .../vulkan/texture/VTextureSelector.java | 4 +- .../vulkanmod/vulkan/texture/VulkanImage.java | 294 ++++---- .../net/vulkanmod/vulkan/util/ColorUtil.java | 96 ++- .../net/vulkanmod/vulkan/util/DrawUtil.java | 1 + .../vulkanmod/vulkan/util/MappedBuffer.java | 7 +- .../java/net/vulkanmod/vulkan/util/Pair.java | 2 +- 219 files changed, 5080 insertions(+), 4885 deletions(-) diff --git a/src/main/java/net/vulkanmod/Initializer.java b/src/main/java/net/vulkanmod/Initializer.java index ba64d44a0..198d7153a 100644 --- a/src/main/java/net/vulkanmod/Initializer.java +++ b/src/main/java/net/vulkanmod/Initializer.java @@ -13,45 +13,46 @@ import java.nio.file.Path; public class Initializer implements ClientModInitializer { - public static final Logger LOGGER = LogManager.getLogger("VulkanMod"); - public static Config CONFIG; - private static String VERSION; + public static final Logger LOGGER = LogManager.getLogger("VulkanMod"); - private static Config loadConfig(Path path) { - Config config = Config.load(path); + private static String VERSION; + public static Config CONFIG; - if (config == null) { - config = new Config(); - config.write(); - } + @Override + public void onInitializeClient() { - return config; - } + VERSION = FabricLoader.getInstance() + .getModContainer("vulkanmod") + .get() + .getMetadata() + .getVersion().getFriendlyString(); - public static String getVersion() { - return VERSION; - } + LOGGER.info("== VulkanMod =="); - @Override - public void onInitializeClient() { + Platform.init(); + VideoModeManager.init(); - VERSION = FabricLoader.getInstance() - .getModContainer("vulkanmod") - .get() - .getMetadata() - .getVersion().getFriendlyString(); + var configPath = FabricLoader.getInstance() + .getConfigDir() + .resolve("vulkanmod_settings.json"); - LOGGER.info("== VulkanMod =="); + CONFIG = loadConfig(configPath); - Platform.init(); - VideoModeManager.init(); + Renderer.register(VulkanModRenderer.INSTANCE); + } - var configPath = FabricLoader.getInstance() - .getConfigDir() - .resolve("vulkanmod_settings.json"); + private static Config loadConfig(Path path) { + Config config = Config.load(path); - CONFIG = loadConfig(configPath); + if(config == null) { + config = new Config(); + config.write(); + } - Renderer.register(VulkanModRenderer.INSTANCE); - } + return config; + } + + public static String getVersion() { + return VERSION; + } } diff --git a/src/main/java/net/vulkanmod/config/Config.java b/src/main/java/net/vulkanmod/config/Config.java index 89598c07f..e2bebdb7f 100644 --- a/src/main/java/net/vulkanmod/config/Config.java +++ b/src/main/java/net/vulkanmod/config/Config.java @@ -13,44 +13,26 @@ import java.util.Collections; public class Config { - private static final Gson GSON = new GsonBuilder() - .setPrettyPrinting() - .excludeFieldsWithModifiers(Modifier.PRIVATE) - .create(); - private static Path CONFIG_PATH; public VideoModeSet.VideoMode videoMode = VideoModeManager.getFirstAvailable().getVideoMode(); public int windowMode = 0; + public int advCulling = 2; public boolean indirectDraw = true; + public boolean uniqueOpaqueLayer = true; public boolean entityCulling = true; public int device = -1; + public int ambientOcclusion = 1; public int frameQueueSize = 2; public int builderThreads = 0; + public boolean backFaceCulling = true; public boolean textureAnimations = true; - public static Config load(Path path) { - Config config; - Config.CONFIG_PATH = path; - - if (Files.exists(path)) { - try (FileReader fileReader = new FileReader(path.toFile())) { - config = GSON.fromJson(fileReader, Config.class); - } catch (IOException exception) { - throw new RuntimeException(exception.getMessage()); - } - } else { - config = null; - } - - return config; - } - public void write() { - if (!Files.exists(CONFIG_PATH.getParent())) { + if(!Files.exists(CONFIG_PATH.getParent())) { try { Files.createDirectories(CONFIG_PATH); } catch (IOException e) { @@ -64,4 +46,30 @@ public void write() { e.printStackTrace(); } } + + private static Path CONFIG_PATH; + + private static final Gson GSON = new GsonBuilder() + .setPrettyPrinting() + .excludeFieldsWithModifiers(Modifier.PRIVATE) + .create(); + + public static Config load(Path path) { + Config config; + Config.CONFIG_PATH = path; + + if (Files.exists(path)) { + try (FileReader fileReader = new FileReader(path.toFile())) { + config = GSON.fromJson(fileReader, Config.class); + } + catch (IOException exception) { + throw new RuntimeException(exception.getMessage()); + } + } + else { + config = null; + } + + return config; + } } diff --git a/src/main/java/net/vulkanmod/config/gui/GuiElement.java b/src/main/java/net/vulkanmod/config/gui/GuiElement.java index 88cf40ce5..04b85d2a1 100644 --- a/src/main/java/net/vulkanmod/config/gui/GuiElement.java +++ b/src/main/java/net/vulkanmod/config/gui/GuiElement.java @@ -7,14 +7,16 @@ import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.navigation.FocusNavigationEvent; import net.minecraft.client.gui.navigation.ScreenRectangle; +import net.minecraft.client.input.MouseButtonEvent; import org.jetbrains.annotations.Nullable; public abstract class GuiElement implements GuiEventListener, NarratableEntry { - public int x; - public int y; protected int width; protected int height; + public int x; + public int y; + protected boolean hovered; protected long hoverStartTime; protected int hoverTime; @@ -74,7 +76,8 @@ public void updateState(double mX, double mY) { public float getHoverMultiplier(float time) { if (this.hovered) { return Math.min(((this.hoverTime) / time), 1.0f); - } else { + } + else { int delta = (int) (Util.getMillis() - this.hoverStopTime); return Math.max(1.0f - (delta / time), 0.0f); } @@ -104,13 +107,13 @@ public ScreenRectangle getRectangle() { } @Override - public boolean isFocused() { - return false; + public void setFocused(boolean bl) { + } @Override - public void setFocused(boolean bl) { - + public boolean isFocused() { + return false; } @Override diff --git a/src/main/java/net/vulkanmod/config/gui/VOptionScreen.java b/src/main/java/net/vulkanmod/config/gui/VOptionScreen.java index eb2ea5b37..fcf879d71 100644 --- a/src/main/java/net/vulkanmod/config/gui/VOptionScreen.java +++ b/src/main/java/net/vulkanmod/config/gui/VOptionScreen.java @@ -30,16 +30,21 @@ public class VOptionScreen extends Screen { private final Screen parent; private final List optionPages; - private final List pageButtons = Lists.newArrayList(); - private final List buttons = Lists.newArrayList(); + private int currentListIdx = 0; + private int tooltipX; private int tooltipY; private int tooltipWidth; + private VButtonWidget supportButton; + private VButtonWidget doneButton; private VButtonWidget applyButton; + private final List pageButtons = Lists.newArrayList(); + private final List buttons = Lists.newArrayList(); + public VOptionScreen(Component title, Screen parent) { super(title); this.parent = parent; diff --git a/src/main/java/net/vulkanmod/config/gui/render/GuiRenderer.java b/src/main/java/net/vulkanmod/config/gui/render/GuiRenderer.java index 93d54a515..e268dab92 100644 --- a/src/main/java/net/vulkanmod/config/gui/render/GuiRenderer.java +++ b/src/main/java/net/vulkanmod/config/gui/render/GuiRenderer.java @@ -1,8 +1,7 @@ package net.vulkanmod.config.gui.render; import com.mojang.blaze3d.pipeline.RenderPipeline; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.*; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; diff --git a/src/main/java/net/vulkanmod/config/gui/render/PolygonRenderState.java b/src/main/java/net/vulkanmod/config/gui/render/PolygonRenderState.java index b3a509aaf..ff4b2b03d 100644 --- a/src/main/java/net/vulkanmod/config/gui/render/PolygonRenderState.java +++ b/src/main/java/net/vulkanmod/config/gui/render/PolygonRenderState.java @@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable; import org.joml.Matrix3x2f; -public record PolygonRenderState( +public record PolygonRenderState ( RenderPipeline pipeline, TextureSetup textureSetup, Matrix3x2f pose, @@ -27,7 +27,17 @@ public PolygonRenderState( @Nullable ScreenRectangle screenRectangle ) { this(renderPipeline, textureSetup, pose, vertices, color, screenRectangle, - getBounds(vertices, pose, screenRectangle)); + getBounds(vertices, pose, screenRectangle)); + } + + @Override + public void buildVertices(VertexConsumer vertexConsumer) { + for (float[] vertex : vertices) { + float x = vertex[0]; + float y = vertex[1]; + vertexConsumer.addVertexWith2DPose(this.pose(), x, y) + .setColor(this.col); + } } @Nullable @@ -59,15 +69,5 @@ private static ScreenRectangle getBounds(float[][] vertices, Matrix3x2f matrix3x ScreenRectangle screenRectangle2 = new ScreenRectangle((int) x0, (int) y0, (int) (x1 - x0), (int) (y1 - y0)).transformMaxBounds(matrix3x2f); return screenRectangle != null ? screenRectangle.intersection(screenRectangle2) : screenRectangle2; } - - @Override - public void buildVertices(VertexConsumer vertexConsumer) { - for (float[] vertex : vertices) { - float x = vertex[0]; - float y = vertex[1]; - vertexConsumer.addVertexWith2DPose(this.pose(), x, y) - .setColor(this.col); - } - } } diff --git a/src/main/java/net/vulkanmod/config/gui/widget/CyclingOptionWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/CyclingOptionWidget.java index fb6c51a67..6ec5157d2 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/CyclingOptionWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/CyclingOptionWidget.java @@ -10,8 +10,8 @@ import net.vulkanmod.vulkan.util.ColorUtil; public class CyclingOptionWidget extends OptionWidget> { - private final Button leftButton; - private final Button rightButton; + private Button leftButton; + private Button rightButton; private boolean focused; @@ -72,7 +72,8 @@ public void renderBars() { public void onClick(double mouseX, double mouseY) { if (leftButton.isHovered(mouseX, mouseY)) { option.prevValue(); - } else if (rightButton.isHovered(mouseX, mouseY)) { + } + else if (rightButton.isHovered(mouseX, mouseY)) { option.nextValue(); } } @@ -88,13 +89,13 @@ protected void onDrag(double mouseX, double mouseY, double deltaX, double deltaY } @Override - public boolean isFocused() { - return this.focused; + public void setFocused(boolean bl) { + this.focused = bl; } @Override - public void setFocused(boolean bl) { - this.focused = bl; + public boolean isFocused() { + return this.focused; } class Button { @@ -128,9 +129,11 @@ void renderButton(double mouseX, double mouseY) { int color; if (this.isHovered(mouseX, mouseY) && this.active) { color = HOVERED_COLOR; - } else if (this.active) { + } + else if (this.active) { color = ACTIVE_COLOR; - } else { + } + else { color = INACTIVE_COLOR; } @@ -146,7 +149,8 @@ void renderButton(double mouseX, double mouseY) { {xC + w, yC + h}, {xC + w, yC - h}, }; - } else { + } + else { vertices = new float[][]{ {xC + w, yC}, {xC - w, yC - h}, diff --git a/src/main/java/net/vulkanmod/config/gui/widget/OptionWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/OptionWidget.java index 59e2b37be..b3ee79345 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/OptionWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/OptionWidget.java @@ -16,9 +16,9 @@ public abstract class OptionWidget> extends VAbstractWidget implements NarratableEntry { - private final Component name; public int controlX; public int controlWidth; + private final Component name; protected Component displayedValue; protected boolean controlHovered; @@ -137,21 +137,21 @@ public boolean mouseReleased(MouseButtonEvent event) { @Override public boolean isMouseOver(double mouseX, double mouseY) { - return this.active && this.visible && mouseX >= (double) this.x && mouseY >= (double) this.y && mouseX < (double) (this.x + this.width) && mouseY < (double) (this.y + this.height); + return this.active && this.visible && mouseX >= (double)this.x && mouseY >= (double)this.y && mouseX < (double)(this.x + this.width) && mouseY < (double)(this.y + this.height); } @Override - public boolean isFocused() { - return this.focused; + public void setFocused(boolean bl) { + this.focused = bl; } @Override - public void setFocused(boolean bl) { - this.focused = bl; + public boolean isFocused() { + return this.focused; } protected boolean clicked(double mouseX, double mouseY) { - return this.active && this.visible && mouseX >= (double) this.controlX && mouseY >= (double) this.y && mouseX < (double) (this.x + this.width) && mouseY < (double) (this.y + this.height); + return this.active && this.visible && mouseX >= (double)this.controlX && mouseY >= (double)this.y && mouseX < (double)(this.x + this.width) && mouseY < (double)(this.y + this.height); } public Component getName() { diff --git a/src/main/java/net/vulkanmod/config/gui/widget/RangeOptionWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/RangeOptionWidget.java index 8dea9fa93..277386177 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/RangeOptionWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/RangeOptionWidget.java @@ -8,6 +8,7 @@ import net.minecraft.util.Mth; import net.vulkanmod.config.gui.render.GuiRenderer; import net.vulkanmod.config.option.RangeOption; +import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.util.ColorUtil; import org.lwjgl.glfw.GLFW; @@ -81,13 +82,13 @@ public boolean keyPressed(KeyEvent event) { } @Override - public boolean isFocused() { - return this.focused; + public void setFocused(boolean bl) { + this.focused = bl; } @Override - public void setFocused(boolean bl) { - this.focused = bl; + public boolean isFocused() { + return this.focused; } private void setValueFromMouse(double mouseX) { diff --git a/src/main/java/net/vulkanmod/config/gui/widget/SwitchOptionWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/SwitchOptionWidget.java index 7c81fd31b..f4b0b5f9f 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/SwitchOptionWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/SwitchOptionWidget.java @@ -41,7 +41,7 @@ protected void renderControls(double mouseX, double mouseY) { } color = ColorUtil.ARGB.pack(0.6f, 0.6f, 0.6f, 1.0f); - GuiRenderer.renderBoxBorder(x0, y0, halfWidth * 2, height, 1, color); + GuiRenderer.renderBoxBorder(x0, y0, halfWidth * 2, height, 1, color); color = this.active ? 0xFFFFFFFF : 0xFFA0A0A0; Font textRenderer = Minecraft.getInstance().font; @@ -77,13 +77,13 @@ protected void updateDisplayedValue() { } @Override - public boolean isFocused() { - return this.focused; + public void setFocused(boolean bl) { + this.focused = bl; } @Override - public void setFocused(boolean bl) { - this.focused = bl; + public boolean isFocused() { + return this.focused; } } diff --git a/src/main/java/net/vulkanmod/config/gui/widget/VAbstractWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/VAbstractWidget.java index 8eb82d9b1..0a76bd6ff 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/VAbstractWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/VAbstractWidget.java @@ -75,10 +75,10 @@ public boolean mouseClicked(MouseButtonEvent event, boolean bl) { protected boolean clicked(double mX, double mY) { return this.active && this.visible - && mX >= (double) this.getX() - && mY >= (double) this.getY() - && mX < (double) (this.getX() + this.getWidth()) - && mY < (double) (this.getY() + this.getHeight()); + && mX >= (double)this.getX() + && mY >= (double)this.getY() + && mX < (double)(this.getX() + this.getWidth()) + && mY < (double)(this.getY() + this.getHeight()); } @Override diff --git a/src/main/java/net/vulkanmod/config/gui/widget/VButtonWidget.java b/src/main/java/net/vulkanmod/config/gui/widget/VButtonWidget.java index 5c268c6dc..3055259d6 100644 --- a/src/main/java/net/vulkanmod/config/gui/widget/VButtonWidget.java +++ b/src/main/java/net/vulkanmod/config/gui/widget/VButtonWidget.java @@ -5,6 +5,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.util.Mth; import net.vulkanmod.config.gui.render.GuiRenderer; +import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.util.ColorUtil; import java.util.function.Consumer; @@ -40,12 +41,12 @@ public void renderWidget(double mouseX, double mouseY) { GuiRenderer.drawCenteredString(textRenderer, this.message, this.x + this.width / 2, this.y + (this.height - 8) / 2, j | Mth.ceil(this.alpha * 255.0f) << 24); - if (this.selected) { + if(this.selected) { color = ColorUtil.ARGB.pack(0.3f, 0.0f, 0.0f, 1.0f); GuiRenderer.fillBox(this.x, this.y, (int) 1.5f, this.height, color); color = ColorUtil.ARGB.pack(0.3f, 0.0f, 0.0f, 0.2f); - GuiRenderer.fillBox(this.x, this.y, this.width, this.height, color); + GuiRenderer.fillBox(this.x, this.y, this.width, this.height, color); } } diff --git a/src/main/java/net/vulkanmod/config/option/CyclingOption.java b/src/main/java/net/vulkanmod/config/option/CyclingOption.java index a8ec440bd..d6080f7fd 100644 --- a/src/main/java/net/vulkanmod/config/option/CyclingOption.java +++ b/src/main/java/net/vulkanmod/config/option/CyclingOption.java @@ -32,24 +32,26 @@ public void updateOption(E[] values, Consumer setter, Supplier getter) { this.index = ArrayUtils.indexOf(this.values, this.getNewValue()); } - public int index() { - return this.index; + public int index() { return this.index; } + + public void setValues(E[] values) { + this.values = values; } public void prevValue() { - if (this.index > 0) + if(this.index > 0) this.index--; this.updateValue(); } public void nextValue() { - if (this.index < values.length - 1) + if(this.index < values.length - 1) this.index++; this.updateValue(); } private void updateValue() { - if (this.index >= 0 && this.index < this.values.length) { + if(this.index >= 0 && this.index < this.values.length) { this.newValue = values[this.index]; if (onChange != null) @@ -73,8 +75,4 @@ private int findNewValueIndex() { public E[] getValues() { return values; } - - public void setValues(E[] values) { - this.values = values; - } } diff --git a/src/main/java/net/vulkanmod/config/option/Option.java b/src/main/java/net/vulkanmod/config/option/Option.java index 8d24507ce..a1425ccf8 100644 --- a/src/main/java/net/vulkanmod/config/option/Option.java +++ b/src/main/java/net/vulkanmod/config/option/Option.java @@ -64,6 +64,13 @@ public Option setActive(boolean active) { public abstract OptionWidget createOptionWidget(int x, int y, int width, int height); + public void setNewValue(T t) { + this.newValue = t; + + if (onChange != null) + onChange.run(); + } + public Component getName() { return this.name; } @@ -77,7 +84,7 @@ public boolean isChanged() { } public void apply() { - if (!isChanged()) + if(!isChanged()) return; onApply.accept(this.newValue); @@ -88,23 +95,16 @@ public T getNewValue() { return this.newValue; } - public void setNewValue(T t) { - this.newValue = t; - - if (onChange != null) - onChange.run(); - } - public Component getDisplayedValue() { return this.translator.apply(this.newValue); } - public Component getTooltip() { - return this.tooltip; - } - public Option setTooltip(Component text) { this.tooltip = text; return this; } + + public Component getTooltip() { + return this.tooltip; + } } diff --git a/src/main/java/net/vulkanmod/config/option/Options.java b/src/main/java/net/vulkanmod/config/option/Options.java index 751ccfe6e..560e6d2c9 100644 --- a/src/main/java/net/vulkanmod/config/option/Options.java +++ b/src/main/java/net/vulkanmod/config/option/Options.java @@ -85,7 +85,7 @@ public static OptionBlock[] getVideoOpts() { value -> { boolean exclusiveFullscreen = value == WindowMode.EXCLUSIVE_FULLSCREEN; minecraftOptions.fullscreen() - .set(exclusiveFullscreen); + .set(exclusiveFullscreen); config.windowMode = value.mode; fullscreenDirty = true; @@ -93,63 +93,63 @@ public static OptionBlock[] getVideoOpts() { () -> 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 ? - Component.translatable( - "options.framerateLimit.max") - .getString() : - String.valueOf(value)), - value -> { - minecraftOptions.framerateLimit().set(value); - minecraft.getFramerateLimitTracker().setFramerateLimit(value); - }, - () -> minecraftOptions.framerateLimit().get()), + 10, 260, 10, + value -> Component.nullToEmpty(value == 260 ? + Component.translatable( + "options.framerateLimit.max") + .getString() : + String.valueOf(value)), + value -> { + minecraftOptions.framerateLimit().set(value); + minecraft.getFramerateLimitTracker().setFramerateLimit(value); + }, + () -> minecraftOptions.framerateLimit().get()), new SwitchOption(Component.translatable("options.vsync"), - value -> { - minecraftOptions.enableVsync().set(value); - window.updateVsync(value); - }, - () -> minecraftOptions.enableVsync().get()), + value -> { + minecraftOptions.enableVsync().set(value); + window.updateVsync(value); + }, + () -> minecraftOptions.enableVsync().get()), new CyclingOption<>(Component.translatable("options.inactivityFpsLimit"), - InactivityFpsLimit.values(), - value -> minecraftOptions.inactivityFpsLimit().set(value), - () -> minecraftOptions.inactivityFpsLimit().get()) + InactivityFpsLimit.values(), + value -> minecraftOptions.inactivityFpsLimit().set(value), + () -> minecraftOptions.inactivityFpsLimit().get()) .setTranslator(inactivityFpsLimit -> Component.translatable(inactivityFpsLimit.getKey())) }), new OptionBlock("", new Option[]{ new RangeOption(Component.translatable("options.guiScale"), - 0, window.calculateScale(0, minecraft.isEnforceUnicode()), 1, - value -> Component.translatable((value == 0) - ? "options.guiScale.auto" - : String.valueOf(value)), - value -> { - minecraftOptions.guiScale().set(value); - minecraft.resizeDisplay(); - }, - () -> (minecraftOptions.guiScale().get())), + 0, window.calculateScale(0, minecraft.isEnforceUnicode()), 1, + value -> Component.translatable((value == 0) + ? "options.guiScale.auto" + : String.valueOf(value)), + value -> { + minecraftOptions.guiScale().set(value); + minecraft.resizeDisplay(); + }, + () -> (minecraftOptions.guiScale().get())), new RangeOption(Component.translatable("options.gamma"), - 0, 100, 1, - value -> Component.translatable(switch (value) { - case 0 -> "options.gamma.min"; - case 50 -> "options.gamma.default"; - case 100 -> "options.gamma.max"; - default -> String.valueOf(value); - }), - value -> minecraftOptions.gamma().set(value * 0.01), - () -> (int) (minecraftOptions.gamma().get() * 100.0)), + 0, 100, 1, + value -> Component.translatable(switch (value) { + case 0 -> "options.gamma.min"; + case 50 -> "options.gamma.default"; + case 100 -> "options.gamma.max"; + default -> String.valueOf(value); + }), + value -> minecraftOptions.gamma().set(value * 0.01), + () -> (int) (minecraftOptions.gamma().get() * 100.0)), }), new OptionBlock("", new Option[]{ new SwitchOption(Component.translatable("options.viewBobbing"), - (value) -> minecraftOptions.bobView().set(value), - () -> minecraftOptions.bobView().get()), + (value) -> minecraftOptions.bobView().set(value), + () -> minecraftOptions.bobView().get()), new CyclingOption<>(Component.translatable("options.attackIndicator"), - AttackIndicatorStatus.values(), - value -> minecraftOptions.attackIndicator().set(value), - () -> minecraftOptions.attackIndicator().get()) + AttackIndicatorStatus.values(), + value -> minecraftOptions.attackIndicator().set(value), + () -> minecraftOptions.attackIndicator().get()) .setTranslator(value -> Component.translatable(value.getKey())), new SwitchOption(Component.translatable("options.autosaveIndicator"), - value -> minecraftOptions.showAutosaveIndicator().set(value), - () -> minecraftOptions.showAutosaveIndicator().get()), + value -> minecraftOptions.showAutosaveIndicator().set(value), + () -> minecraftOptions.showAutosaveIndicator().get()), }) }; } @@ -158,52 +158,52 @@ public static OptionBlock[] getGraphicsOpts() { return new OptionBlock[]{ new OptionBlock("", new Option[]{ new RangeOption(Component.translatable("options.renderDistance"), - 2, 32, 1, - (value) -> minecraftOptions.renderDistance().set(value), - () -> minecraftOptions.renderDistance().get()), + 2, 32, 1, + (value) -> minecraftOptions.renderDistance().set(value), + () -> minecraftOptions.renderDistance().get()), new RangeOption(Component.translatable("options.simulationDistance"), - 5, 32, 1, - (value) -> minecraftOptions.simulationDistance().set(value), - () -> minecraftOptions.simulationDistance().get()), + 5, 32, 1, + (value) -> minecraftOptions.simulationDistance().set(value), + () -> minecraftOptions.simulationDistance().get()), new CyclingOption<>(Component.translatable("options.prioritizeChunkUpdates"), - PrioritizeChunkUpdates.values(), - value -> minecraftOptions.prioritizeChunkUpdates().set(value), - () -> minecraftOptions.prioritizeChunkUpdates().get()) + PrioritizeChunkUpdates.values(), + value -> minecraftOptions.prioritizeChunkUpdates().set(value), + () -> minecraftOptions.prioritizeChunkUpdates().get()) .setTranslator(value -> Component.translatable(value.getKey())), }), new OptionBlock("", new Option[]{ new CyclingOption<>(Component.translatable("options.graphics"), - new GraphicsStatus[]{GraphicsStatus.FAST, GraphicsStatus.FANCY}, - value -> minecraftOptions.graphicsMode().set(value), - () -> minecraftOptions.graphicsMode().get()) + new GraphicsStatus[]{GraphicsStatus.FAST, GraphicsStatus.FANCY}, + value -> minecraftOptions.graphicsMode().set(value), + () -> minecraftOptions.graphicsMode().get()) .setTranslator(graphicsMode -> Component.translatable(graphicsMode.getKey())), new CyclingOption<>(Component.translatable("options.particles"), - new ParticleStatus[]{ParticleStatus.MINIMAL, ParticleStatus.DECREASED, ParticleStatus.ALL}, - value -> minecraftOptions.particles().set(value), - () -> minecraftOptions.particles().get()) + new ParticleStatus[]{ParticleStatus.MINIMAL, ParticleStatus.DECREASED, ParticleStatus.ALL}, + value -> minecraftOptions.particles().set(value), + () -> minecraftOptions.particles().get()) .setTranslator(particlesMode -> Component.translatable(particlesMode.getKey())), new CyclingOption<>(Component.translatable("options.renderClouds"), - CloudStatus.values(), - value -> minecraftOptions.cloudStatus().set(value), - () -> minecraftOptions.cloudStatus().get()) + CloudStatus.values(), + value -> minecraftOptions.cloudStatus().set(value), + () -> minecraftOptions.cloudStatus().get()) .setTranslator(value -> Component.translatable(value.getKey())), new RangeOption(Component.translatable("options.renderCloudsDistance"), - 2, 128, 1, - (value) -> minecraftOptions.cloudRange().set(value), - () -> minecraftOptions.cloudRange().get()), + 2, 128, 1, + (value) -> minecraftOptions.cloudRange().set(value), + () -> minecraftOptions.cloudRange().get()), new CyclingOption<>(Component.translatable("options.ao"), - new Integer[]{LightMode.FLAT, LightMode.SMOOTH, LightMode.SUB_BLOCK}, - (value) -> { - if (value > LightMode.FLAT) - minecraftOptions.ambientOcclusion().set(true); - else - minecraftOptions.ambientOcclusion().set(false); + new Integer[]{LightMode.FLAT, LightMode.SMOOTH, LightMode.SUB_BLOCK}, + (value) -> { + if (value > LightMode.FLAT) + minecraftOptions.ambientOcclusion().set(true); + else + minecraftOptions.ambientOcclusion().set(false); - config.ambientOcclusion = value; + config.ambientOcclusion = value; - minecraft.levelRenderer.allChanged(); - }, - () -> config.ambientOcclusion) + minecraft.levelRenderer.allChanged(); + }, + () -> config.ambientOcclusion) .setTranslator(value -> Component.translatable(switch (value) { case LightMode.FLAT -> "options.off"; case LightMode.SMOOTH -> "options.on"; @@ -212,33 +212,33 @@ public static OptionBlock[] getGraphicsOpts() { })) .setTooltip(Component.translatable("vulkanmod.options.ao.subBlock.tooltip")), new RangeOption(Component.translatable("options.biomeBlendRadius"), - 0, 7, 1, - value -> { - int v = value * 2 + 1; - return Component.nullToEmpty("%d x %d".formatted(v, v)); - }, - (value) -> { - minecraftOptions.biomeBlendRadius().set(value); - minecraft.levelRenderer.allChanged(); - }, - () -> minecraftOptions.biomeBlendRadius().get()), + 0, 7, 1, + value -> { + int v = value * 2 + 1; + return Component.nullToEmpty("%d x %d".formatted(v, v)); + }, + (value) -> { + minecraftOptions.biomeBlendRadius().set(value); + minecraft.levelRenderer.allChanged(); + }, + () -> minecraftOptions.biomeBlendRadius().get()), }), new OptionBlock("", new Option[]{ new SwitchOption(Component.translatable("options.entityShadows"), - value -> minecraftOptions.entityShadows().set(value), - () -> minecraftOptions.entityShadows().get()), + value -> minecraftOptions.entityShadows().set(value), + () -> minecraftOptions.entityShadows().get()), new RangeOption(Component.translatable("options.entityDistanceScaling"), - 50, 500, 25, - value -> minecraftOptions.entityDistanceScaling().set(value * 0.01), - () -> minecraftOptions.entityDistanceScaling().get().intValue() * 100), + 50, 500, 25, + value -> minecraftOptions.entityDistanceScaling().set(value * 0.01), + () -> minecraftOptions.entityDistanceScaling().get().intValue() * 100), new CyclingOption<>(Component.translatable("options.mipmapLevels"), - new Integer[]{0, 1, 2, 3, 4}, - value -> { - minecraftOptions.mipmapLevels().set(value); - minecraft.updateMaxMipLevel(value); - minecraft.delayTextureReload(); - }, - () -> minecraftOptions.mipmapLevels().get()) + new Integer[]{0, 1, 2, 3, 4}, + value -> { + minecraftOptions.mipmapLevels().set(value); + minecraft.updateMaxMipLevel(value); + minecraft.delayTextureReload(); + }, + () -> minecraftOptions.mipmapLevels().get()) .setTranslator(value -> Component.nullToEmpty(value.toString())) }) }; @@ -248,9 +248,9 @@ public static OptionBlock[] getOptimizationOpts() { return new OptionBlock[]{ new OptionBlock("", new Option[]{ new CyclingOption<>(Component.translatable("vulkanmod.options.advCulling"), - new Integer[]{1, 2, 3, 10}, - value -> config.advCulling = value, - () -> config.advCulling) + new Integer[]{1, 2, 3, 10}, + value -> config.advCulling = value, + () -> config.advCulling) .setTranslator(value -> Component.translatable(switch (value) { case 1 -> "vulkanmod.options.advCulling.aggressive"; case 2 -> "vulkanmod.options.advCulling.normal"; @@ -260,27 +260,27 @@ public static OptionBlock[] getOptimizationOpts() { })) .setTooltip(Component.translatable("vulkanmod.options.advCulling.tooltip")), new SwitchOption(Component.translatable("vulkanmod.options.entityCulling"), - value -> config.entityCulling = value, - () -> config.entityCulling) + value -> config.entityCulling = value, + () -> config.entityCulling) .setTooltip(Component.translatable("vulkanmod.options.entityCulling.tooltip")), new SwitchOption(Component.translatable("vulkanmod.options.uniqueOpaqueLayer"), - value -> { - config.uniqueOpaqueLayer = value; - TerrainRenderType.updateMapping(); - minecraft.levelRenderer.allChanged(); - }, - () -> config.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) + 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) + value -> config.indirectDraw = value, + () -> config.indirectDraw) .setTooltip(Component.translatable("vulkanmod.options.indirectDraw.tooltip")), }) }; @@ -291,12 +291,12 @@ public static OptionBlock[] getOtherOpts() { return new OptionBlock[]{ new OptionBlock("", new Option[]{ new RangeOption(Component.translatable("vulkanmod.options.builderThreads"), - 0, (Runtime.getRuntime().availableProcessors() - 1), 1, - value -> { - config.builderThreads = value; - WorldRenderer.getInstance().getTaskDispatcher().createThreads(value); - }, - () -> config.builderThreads) + 0, (Runtime.getRuntime().availableProcessors() - 1), 1, + value -> { + config.builderThreads = value; + WorldRenderer.getInstance().getTaskDispatcher().createThreads(value); + }, + () -> config.builderThreads) .setTranslator(value -> { if (value == 0) return Component.translatable("vulkanmod.options.builderThreads.auto"); @@ -304,27 +304,27 @@ public static OptionBlock[] getOtherOpts() { return Component.nullToEmpty(String.valueOf(value)); }), new RangeOption(Component.translatable("vulkanmod.options.frameQueue"), - 2, 5, 1, - value -> { - config.frameQueueSize = value; - Renderer.scheduleSwapChainUpdate(); - }, () -> config.frameQueueSize) + 2, 5, 1, + value -> { + config.frameQueueSize = value; + Renderer.scheduleSwapChainUpdate(); + }, () -> config.frameQueueSize) .setTooltip(Component.translatable("vulkanmod.options.frameQueue.tooltip")), new SwitchOption(Component.translatable("vulkanmod.options.textureAnimations"), - value -> { - config.textureAnimations = value; - }, - () -> config.textureAnimations), + value -> { + config.textureAnimations = value; + }, + () -> config.textureAnimations), }), new OptionBlock("", new Option[]{ new CyclingOption<>(Component.translatable("vulkanmod.options.deviceSelector"), - IntStream.range(-1, DeviceManager.suitableDevices.size()).boxed() - .toArray(Integer[]::new), - value -> config.device = value, - () -> config.device) + IntStream.range(-1, DeviceManager.suitableDevices.size()).boxed() + .toArray(Integer[]::new), + value -> config.device = value, + () -> config.device) .setTranslator(value -> Component.translatable((value == -1) - ? "vulkanmod.options.deviceSelector.auto" - : DeviceManager.suitableDevices.get( + ? "vulkanmod.options.deviceSelector.auto" + : DeviceManager.suitableDevices.get( value).deviceName) ) .setTooltip(Component.nullToEmpty("%s: %s".formatted( diff --git a/src/main/java/net/vulkanmod/config/video/VideoModeManager.java b/src/main/java/net/vulkanmod/config/video/VideoModeManager.java index 7e28e0b48..985455a63 100644 --- a/src/main/java/net/vulkanmod/config/video/VideoModeManager.java +++ b/src/main/java/net/vulkanmod/config/video/VideoModeManager.java @@ -7,13 +7,14 @@ import java.util.ArrayList; import java.util.List; -import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor; +import static org.lwjgl.glfw.GLFW.*; public abstract class VideoModeManager { - public static VideoModeSet.VideoMode selectedVideoMode; private static VideoModeSet.VideoMode osVideoMode; private static VideoModeSet[] videoModeSets; + public static VideoModeSet.VideoMode selectedVideoMode; + public static void init() { long monitor = glfwGetPrimaryMonitor(); osVideoMode = getCurrentVideoMode(monitor); @@ -29,7 +30,7 @@ public static VideoModeSet[] getVideoResolutions() { } public static VideoModeSet getFirstAvailable() { - if (videoModeSets != null) + if(videoModeSets != null) return videoModeSets[videoModeSets.length - 1]; else return VideoModeSet.getDummy(); @@ -39,7 +40,7 @@ public static VideoModeSet.VideoMode getOsVideoMode() { return osVideoMode; } - public static VideoModeSet.VideoMode getCurrentVideoMode(long monitor) { + public static VideoModeSet.VideoMode getCurrentVideoMode(long monitor){ GLFWVidMode vidMode = GLFW.glfwGetVideoMode(monitor); if (vidMode == null) diff --git a/src/main/java/net/vulkanmod/config/video/VideoModeSet.java b/src/main/java/net/vulkanmod/config/video/VideoModeSet.java index a49246981..e4fb34fac 100644 --- a/src/main/java/net/vulkanmod/config/video/VideoModeSet.java +++ b/src/main/java/net/vulkanmod/config/video/VideoModeSet.java @@ -10,18 +10,18 @@ public class VideoModeSet { public final int bitDepth; List refreshRates = new ObjectArrayList<>(); - public VideoModeSet(int width, int height, int bitDepth) { - this.width = width; - this.height = height; - this.bitDepth = bitDepth; - } - public static VideoModeSet getDummy() { var set = new VideoModeSet(-1, -1, -1); set.addRefreshRate(-1); return set; } + public VideoModeSet(int width, int height, int bitDepth) { + this.width = width; + this.height = height; + this.bitDepth = bitDepth; + } + public int getRefreshRate() { return this.refreshRates.get(0); } @@ -90,6 +90,6 @@ public String toString() { "refreshRate=" + refreshRate + ']'; } - } + } } diff --git a/src/main/java/net/vulkanmod/gl/GlUtil.java b/src/main/java/net/vulkanmod/gl/GlUtil.java index 2112a01a2..fe8edea75 100644 --- a/src/main/java/net/vulkanmod/gl/GlUtil.java +++ b/src/main/java/net/vulkanmod/gl/GlUtil.java @@ -29,7 +29,7 @@ public static ByteBuffer RGBtoRGBA_buffer(ByteBuffer in) { ByteBuffer out = MemoryUtil.memAlloc(outSize); int j = 0; - for (int i = 0; i < outSize; i += 4, j += 3) { + for (int i = 0; i < outSize; i+=4, j+=3) { out.put(i, in.get(j)); out.put(i + 1, in.get(j + 1)); out.put(i + 2, in.get(j + 2)); @@ -50,7 +50,7 @@ public static ByteBuffer BGRAtoRGBA_buffer(ByteBuffer in) { long srcPtr = MemoryUtil.memAddress0(in); // TODO write in place (don't free the returned buffer in that case) - for (int i = 0; i < outSize; i += 4) { + for (int i = 0; i < outSize ; i += 4) { int color = MemoryUtil.memGetInt(srcPtr + i); color = (color << 24) & 0xFF000000 | (color >> 8) & 0xFFFFFF; @@ -63,29 +63,34 @@ public static ByteBuffer BGRAtoRGBA_buffer(ByteBuffer in) { public static int vulkanFormat(int glFormat, int type) { return switch (glFormat) { - case GL11.GL_RGBA, GL30.GL_RGBA8 -> switch (type) { - case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; - case GL11.GL_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; - case GL30.GL_UNSIGNED_INT_8_8_8_8, GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> VK_FORMAT_R8G8B8A8_UNORM; - default -> throw new IllegalStateException("Unexpected type: " + type); - }; - case GL30.GL_BGRA -> switch (type) { - case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_B8G8R8A8_UNORM; - case GL11.GL_BYTE -> VK_FORMAT_B8G8R8A8_UNORM; - case GL30.GL_UNSIGNED_INT_8_8_8_8, GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> VK_FORMAT_B8G8R8A8_UNORM; - default -> throw new IllegalStateException("Unexpected type: " + type); - }; - case GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> switch (type) { - case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UINT; - case GL11.GL_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; - default -> throw new IllegalStateException("Unexpected type: " + type); - }; - case GL11.GL_RED -> switch (type) { - case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8_UNORM; - default -> throw new IllegalStateException("Unexpected type: " + type); - }; + case GL11.GL_RGBA, GL30.GL_RGBA8 -> + switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; + case GL11.GL_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; + case GL30.GL_UNSIGNED_INT_8_8_8_8, GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> VK_FORMAT_R8G8B8A8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; + case GL30.GL_BGRA -> + switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_B8G8R8A8_UNORM; + case GL11.GL_BYTE -> VK_FORMAT_B8G8R8A8_UNORM; + case GL30.GL_UNSIGNED_INT_8_8_8_8, GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> VK_FORMAT_B8G8R8A8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; + case GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> + switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UINT; + case GL11.GL_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; + case GL11.GL_RED -> + switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; case GL11.GL_DEPTH_COMPONENT, GL30.GL_DEPTH_COMPONENT32, - GL30.GL_DEPTH_COMPONENT32F, GL30.GL_DEPTH_COMPONENT24 -> Vulkan.getDefaultDepthFormat(); + GL30.GL_DEPTH_COMPONENT32F, GL30.GL_DEPTH_COMPONENT24 -> + Vulkan.getDefaultDepthFormat(); default -> throw new IllegalStateException("Unexpected format: " + glFormat); }; diff --git a/src/main/java/net/vulkanmod/gl/VkGlBuffer.java b/src/main/java/net/vulkanmod/gl/VkGlBuffer.java index 846ba19a0..1a2d6b4d5 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlBuffer.java +++ b/src/main/java/net/vulkanmod/gl/VkGlBuffer.java @@ -10,21 +10,14 @@ // TODO: Implement missing features. // This class is only used to emulate a CPU buffer for texture copying purposes public class VkGlBuffer { - private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int ID_COUNTER = 1; + private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int boundId = 0; private static VkGlBuffer boundBuffer; private static VkGlBuffer arrayBufferBound; private static VkGlBuffer pixelPackBufferBound; private static VkGlBuffer pixelUnpackBufferBound; - int id; - int target; - ByteBuffer data; - - public VkGlBuffer(int id) { - this.id = id; - } public static int glGenBuffers() { int id = ID_COUNTER; @@ -112,6 +105,15 @@ private static void checkTarget(int target) { throw new IllegalArgumentException("target %d not supported".formatted(target)); } + int id; + int target; + + ByteBuffer data; + + public VkGlBuffer(int id) { + this.id = id; + } + private void allocate(int size) { if (this.data != null) this.freeData(); diff --git a/src/main/java/net/vulkanmod/gl/VkGlFramebuffer.java b/src/main/java/net/vulkanmod/gl/VkGlFramebuffer.java index 87a301539..fffacde97 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlFramebuffer.java +++ b/src/main/java/net/vulkanmod/gl/VkGlFramebuffer.java @@ -14,20 +14,11 @@ import static org.lwjgl.vulkan.VK11.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; public class VkGlFramebuffer { - private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int idCounter = 1; + + private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static VkGlFramebuffer boundFramebuffer; private static VkGlFramebuffer readFramebuffer; - public final int id; - Framebuffer framebuffer; - RenderPass renderPass; - VulkanImage colorAttachment; - VulkanImage depthAttachment; - boolean needsUpdate; - - VkGlFramebuffer(int i) { - this.id = i; - } public static void resetBoundFramebuffer() { boundFramebuffer = null; @@ -152,6 +143,19 @@ public static VkGlFramebuffer getFramebuffer(int id) { return map.get(id); } + public final int id; + Framebuffer framebuffer; + RenderPass renderPass; + + VulkanImage colorAttachment; + VulkanImage depthAttachment; + + boolean needsUpdate; + + VkGlFramebuffer(int i) { + this.id = i; + } + boolean beginRendering() { return Renderer.getInstance().beginRendering(this.renderPass, this.framebuffer); } @@ -210,16 +214,16 @@ public void create() { VulkanImage depthImage = this.depthAttachment; this.framebuffer = Framebuffer.builder(this.colorAttachment, depthImage) - .build(); + .build(); RenderPass.Builder builder = RenderPass.builder(this.framebuffer); builder.getColorAttachmentInfo() - .setLoadOp(VK_ATTACHMENT_LOAD_OP_LOAD) - .setFinalLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + .setLoadOp(VK_ATTACHMENT_LOAD_OP_LOAD) + .setFinalLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); if (hasDepthImage) { builder.getDepthAttachmentInfo() - .setOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); + .setOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); } this.renderPass = builder.build(); diff --git a/src/main/java/net/vulkanmod/gl/VkGlProgram.java b/src/main/java/net/vulkanmod/gl/VkGlProgram.java index 38fe4829b..2cce606f2 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlProgram.java +++ b/src/main/java/net/vulkanmod/gl/VkGlProgram.java @@ -4,16 +4,10 @@ import net.vulkanmod.vulkan.shader.Pipeline; public class VkGlProgram { - private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int ID_COUNTER = 1; + private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int boundProgramId = 0; private static VkGlProgram boundProgram; - int id; - Pipeline pipeline; - - VkGlProgram(int i) { - this.id = i; - } public static VkGlProgram getBoundProgram() { return boundProgram; @@ -44,6 +38,13 @@ public static void glUseProgram(int id) { } + int id; + Pipeline pipeline; + + VkGlProgram(int i) { + this.id = i; + } + public void bindPipeline(Pipeline pipeline) { this.pipeline = pipeline; } diff --git a/src/main/java/net/vulkanmod/gl/VkGlRenderbuffer.java b/src/main/java/net/vulkanmod/gl/VkGlRenderbuffer.java index 453996896..e811144a2 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlRenderbuffer.java +++ b/src/main/java/net/vulkanmod/gl/VkGlRenderbuffer.java @@ -14,21 +14,10 @@ import static org.lwjgl.vulkan.VK10.*; public class VkGlRenderbuffer { - private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int ID_COUNTER = 1; + private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int boundId = 0; private static VkGlRenderbuffer bound; - final int id; - VulkanImage vulkanImage; - int internalFormat; - boolean needsUpdate = false; - int maxLevel = 0; - int maxLod = 0; - int minFilter, magFilter = GL11.GL_LINEAR; - - public VkGlRenderbuffer(int id) { - this.id = id; - } public static int genId() { int id = ID_COUNTER; @@ -76,10 +65,8 @@ public static void texParameteri(int target, int pName, int param) { switch (pName) { case GL30.GL_TEXTURE_MAX_LEVEL -> bound.setMaxLevel(param); case GL30.GL_TEXTURE_MAX_LOD -> bound.setMaxLod(param); - case GL30.GL_TEXTURE_MIN_LOD -> { - } - case GL30.GL_TEXTURE_LOD_BIAS -> { - } + case GL30.GL_TEXTURE_MIN_LOD -> {} + case GL30.GL_TEXTURE_LOD_BIAS -> {} case GL11.GL_TEXTURE_MAG_FILTER -> bound.setMagFilter(param); case GL11.GL_TEXTURE_MIN_FILTER -> bound.setMinFilter(param); @@ -121,6 +108,19 @@ public static VkGlRenderbuffer getBound() { return bound; } + final int id; + VulkanImage vulkanImage; + int internalFormat; + + boolean needsUpdate = false; + int maxLevel = 0; + int maxLod = 0; + int minFilter, magFilter = GL11.GL_LINEAR; + + public VkGlRenderbuffer(int id) { + this.id = id; + } + void allocateIfNeeded(int width, int height, int format) { int vkFormat = GlUtil.vulkanFormat(format); diff --git a/src/main/java/net/vulkanmod/gl/VkGlShader.java b/src/main/java/net/vulkanmod/gl/VkGlShader.java index 374a278e2..95b70bff0 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlShader.java +++ b/src/main/java/net/vulkanmod/gl/VkGlShader.java @@ -3,17 +3,9 @@ import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; public class VkGlShader { - private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int ID_COUNTER = 1; - private static final int boundTextureId = 0; - final int id; - final int type; - String source; - - VkGlShader(int id, int type) { - this.id = id; - this.type = type; - } + private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); + private static int boundTextureId = 0; public static int glCreateShader(int type) { int id = ID_COUNTER++; @@ -40,4 +32,14 @@ public static int glGetShaderi(int i, int j) { return 0; } + final int id; + final int type; + + String source; + + VkGlShader(int id, int type) { + this.id = id; + this.type = type; + } + } diff --git a/src/main/java/net/vulkanmod/gl/VkGlTexture.java b/src/main/java/net/vulkanmod/gl/VkGlTexture.java index fc7a7646e..8d39e536e 100644 --- a/src/main/java/net/vulkanmod/gl/VkGlTexture.java +++ b/src/main/java/net/vulkanmod/gl/VkGlTexture.java @@ -17,8 +17,8 @@ import static org.lwjgl.vulkan.VK10.*; public class VkGlTexture { - private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int ID_COUNTER = 1; + private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int boundTextureId = 0; private static VkGlTexture boundTexture; private static int activeTexture = 0; @@ -26,19 +26,6 @@ public class VkGlTexture { private static int unpackRowLength; private static int unpackSkipRows; private static int unpackSkipPixels; - public final int id; - VulkanImage vulkanImage; - int width, height; - int vkFormat; - boolean needsUpdate = false; - int maxLevel = 0; - int maxLod = 0; - int minFilter, magFilter = GL11.GL_LINEAR; - boolean clamp = true; - - public VkGlTexture(int id) { - this.id = id; - } public static void bindIdToImage(int id, VulkanImage vulkanImage) { VkGlTexture texture = map.get(id); @@ -117,7 +104,10 @@ public static void texImage2D(int target, int level, int internalFormat, int wid } private static boolean checkParams(int level, int width, int height) { - return width == 0 || height == 0; + if (width == 0 || height == 0) + return true; + + return false; } public static void texSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int type, long pixels) { @@ -153,7 +143,7 @@ private static ByteBuffer getByteBuffer(int width, int height, long pixels) { return src; } - public static void texSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int type, @Nullable ByteBuffer pixels) { + public static void texSubImage2D(int target, int level, int xOffset, int yOffset, int width , int height, int format, int type, @Nullable ByteBuffer pixels) { if (width == 0 || height == 0) return; @@ -185,18 +175,15 @@ public static void texParameteri(int target, int pName, int param) { switch (pName) { case GL30.GL_TEXTURE_MAX_LEVEL -> boundTexture.setMaxLevel(param); case GL30.GL_TEXTURE_MAX_LOD -> boundTexture.setMaxLod(param); - case GL30.GL_TEXTURE_MIN_LOD -> { - } - case GL30.GL_TEXTURE_LOD_BIAS -> { - } + case GL30.GL_TEXTURE_MIN_LOD -> {} + case GL30.GL_TEXTURE_LOD_BIAS -> {} case GL11.GL_TEXTURE_MAG_FILTER -> boundTexture.setMagFilter(param); case GL11.GL_TEXTURE_MIN_FILTER -> boundTexture.setMinFilter(param); case GL11.GL_TEXTURE_WRAP_S, GL11.GL_TEXTURE_WRAP_T -> boundTexture.setClamp(param); - default -> { - } + default -> {} } //TODO @@ -283,6 +270,23 @@ public static VkGlTexture getBoundTexture() { return boundTexture; } + public final int id; + VulkanImage vulkanImage; + + int width, height; + int vkFormat; + + boolean needsUpdate = false; + int maxLevel = 0; + int maxLod = 0; + int minFilter, magFilter = GL11.GL_LINEAR; + + boolean clamp = true; + + public VkGlTexture(int id) { + this.id = id; + } + void updateParams(int level, int width, int height, int internalFormat, int type) { if (level > this.maxLevel) { this.maxLevel = level; @@ -321,7 +325,8 @@ void allocateImage(int width, int height, int vkFormat) { 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) .setName(String.format("GlTexture %d", this.id)) .setMipLevels(maxLevel + 1) @@ -340,8 +345,7 @@ void updateSampler() { samplerFlags |= magFilter == GL11.GL_LINEAR ? SamplerManager.LINEAR_FILTERING_BIT : 0; samplerFlags |= switch (minFilter) { - case GL11.GL_LINEAR_MIPMAP_LINEAR -> - SamplerManager.USE_MIPMAPS_BIT | SamplerManager.MIPMAP_LINEAR_FILTERING_BIT; + case GL11.GL_LINEAR_MIPMAP_LINEAR -> SamplerManager.USE_MIPMAPS_BIT | SamplerManager.MIPMAP_LINEAR_FILTERING_BIT; case GL11.GL_NEAREST_MIPMAP_NEAREST -> SamplerManager.USE_MIPMAPS_BIT; default -> 0; }; @@ -418,7 +422,11 @@ void setMinFilter(int v) { } void setClamp(int v) { - this.clamp = v == GL30.GL_CLAMP_TO_EDGE; + if (v == GL30.GL_CLAMP_TO_EDGE) { + this.clamp = true; + } else { + this.clamp = false; + } updateSampler(); } diff --git a/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java b/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java index bb74ff830..441fe41b3 100644 --- a/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java +++ b/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java @@ -19,6 +19,5 @@ default boolean canUseFastVertex() { void vertex(float x, float y, float z, int packedColor, float u, float v, int overlay, int light, int packedNormal); // Used for particles - default void vertex(float x, float y, float z, float u, float v, int packedColor, int light) { - } + default void vertex(float x, float y, float z, float u, float v, int packedColor, int light) {} } diff --git a/src/main/java/net/vulkanmod/interfaces/shader/ExtendedRenderPipeline.java b/src/main/java/net/vulkanmod/interfaces/shader/ExtendedRenderPipeline.java index 4f763d34a..dc927f0f0 100644 --- a/src/main/java/net/vulkanmod/interfaces/shader/ExtendedRenderPipeline.java +++ b/src/main/java/net/vulkanmod/interfaces/shader/ExtendedRenderPipeline.java @@ -11,11 +11,11 @@ static ExtendedRenderPipeline of(RenderPipeline renderPipeline) { return (ExtendedRenderPipeline) renderPipeline; } - Pipeline getPipeline(); - void setPipeline(GraphicsPipeline pipeline); - EGlProgram getProgram(); - void setProgram(EGlProgram program); + + Pipeline getPipeline(); + + EGlProgram getProgram(); } diff --git a/src/main/java/net/vulkanmod/mixin/chunk/ClientChunkCacheM.java b/src/main/java/net/vulkanmod/mixin/chunk/ClientChunkCacheM.java index 08ca14556..0f5e9d392 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/ClientChunkCacheM.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/ClientChunkCacheM.java @@ -1,12 +1,14 @@ package net.vulkanmod.mixin.chunk; import net.minecraft.client.multiplayer.ClientChunkCache; +import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.levelgen.Heightmap; import net.vulkanmod.render.chunk.ChunkStatusMap; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/net/vulkanmod/mixin/chunk/DirectionMixin.java b/src/main/java/net/vulkanmod/mixin/chunk/DirectionMixin.java index 76e6c4794..81b0248d3 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/DirectionMixin.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/DirectionMixin.java @@ -9,13 +9,9 @@ @Mixin(Direction.class) public class DirectionMixin { - @Shadow - @Final - private static Direction[] BY_3D_DATA; + @Shadow @Final private static Direction[] BY_3D_DATA; - @Shadow - @Final - private int oppositeIndex; + @Shadow @Final private int oppositeIndex; /** * @author diff --git a/src/main/java/net/vulkanmod/mixin/chunk/FrustumMixin.java b/src/main/java/net/vulkanmod/mixin/chunk/FrustumMixin.java index a8d2e81c5..7fdfcc70e 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/FrustumMixin.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/FrustumMixin.java @@ -16,19 +16,13 @@ @Mixin(Frustum.class) public class FrustumMixin implements FrustumMixed { - @Unique - private final VFrustum vFrustum = new VFrustum(); - @Shadow - private double camX; - @Shadow - private double camY; - @Shadow - private double camZ; - @Shadow - @Final - private Matrix4f matrix; - @Shadow - private Vector4f viewVector; + @Shadow private double camX; + @Shadow private double camY; + @Shadow private double camZ; + @Shadow @Final private Matrix4f matrix; + @Shadow private Vector4f viewVector; + + @Unique private final VFrustum vFrustum = new VFrustum(); @Inject(method = "calculateFrustum", at = @At("HEAD")) private void calculateFrustum(Matrix4f modelView, Matrix4f projection, CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java b/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java index acc21dc78..c4471218b 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java @@ -8,10 +8,7 @@ import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.RenderBuffers; -import net.minecraft.client.renderer.SubmitNodeStorage; +import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher; import net.minecraft.client.renderer.chunk.ChunkSectionLayerGroup; import net.minecraft.client.renderer.chunk.ChunkSectionsToRender; @@ -22,6 +19,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.BlockDestructionProgress; import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.phys.Vec3; import net.vulkanmod.render.chunk.WorldRenderer; import net.vulkanmod.render.profiling.Profiler; import net.vulkanmod.render.vertex.TerrainRenderType; @@ -38,15 +36,12 @@ @Mixin(LevelRenderer.class) public abstract class LevelRendererMixin { - @Unique - double camX, camY, camZ; - @Unique - Matrix4f modelView, projection; - @Shadow - @Final - private Long2ObjectMap> destructionProgress; - @Unique - private WorldRenderer worldRenderer; + @Shadow @Final private Long2ObjectMap> destructionProgress; + + @Unique private WorldRenderer worldRenderer; + + @Unique double camX, camY, camZ; + @Unique Matrix4f modelView, projection; @Inject(method = "", at = @At("RETURN")) private void init(Minecraft minecraft, EntityRenderDispatcher entityRenderDispatcher, @@ -76,7 +71,7 @@ private void onExtractVisibleBlockEntities(Camera camera, float partialTick, Lev @Inject(method = "submitBlockEntities", at = @At(value = "RETURN"), cancellable = true) private void onSubmitBlockEntities(PoseStack poseStack, LevelRenderState levelRenderState, - SubmitNodeStorage submitNodeStorage, CallbackInfo ci) { + SubmitNodeStorage submitNodeStorage, CallbackInfo ci) { this.worldRenderer.renderBlockEntities(poseStack, levelRenderState, submitNodeStorage, this.destructionProgress); ci.cancel(); @@ -127,7 +122,8 @@ private void renderSectionLayer(ChunkSectionsToRender instance, ChunkSectionLaye this.worldRenderer.renderSectionLayer(TerrainRenderType.SOLID, camX, camY, camZ, modelView, projection); this.worldRenderer.renderSectionLayer(TerrainRenderType.CUTOUT, camX, camY, camZ, modelView, projection); this.worldRenderer.renderSectionLayer(TerrainRenderType.CUTOUT_MIPPED, camX, camY, camZ, modelView, projection); - } else if (chunkSectionLayerGroup == ChunkSectionLayerGroup.TRANSLUCENT) { + } + else if (chunkSectionLayerGroup == ChunkSectionLayerGroup.TRANSLUCENT) { Profiler profiler = Profiler.getMainProfiler(); profiler.pop(); profiler.push("Translucent_terrain"); diff --git a/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java b/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java index 516cc77d8..18e653849 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/SectionBufferBuilderPoolM.java @@ -8,8 +8,8 @@ @Mixin(SectionBufferBuilderPool.class) public class SectionBufferBuilderPoolM { - @ModifyVariable(method = "allocate", at = @At("STORE"), ordinal = 1) - private static int skipAllocation(int value) { - return 0; - } + @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/chunk/SectionRenderDispatcherM.java b/src/main/java/net/vulkanmod/mixin/chunk/SectionRenderDispatcherM.java index 4b77e59ee..35a1bafc7 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/SectionRenderDispatcherM.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/SectionRenderDispatcherM.java @@ -2,11 +2,13 @@ import net.minecraft.client.renderer.chunk.SectionRenderDispatcher; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(SectionRenderDispatcher.class) public class SectionRenderDispatcherM { - // TODO + // TODO // @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/thread/ProcessorMailbox;tell(Ljava/lang/Object;)V")) // private void redirectTask(ProcessorMailbox instance, Object object) {} } diff --git a/src/main/java/net/vulkanmod/mixin/chunk/ViewAreaM.java b/src/main/java/net/vulkanmod/mixin/chunk/ViewAreaM.java index 3536c5d40..ef958df3f 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/ViewAreaM.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/ViewAreaM.java @@ -11,15 +11,13 @@ @Mixin(ViewArea.class) public abstract class ViewAreaM { - @Shadow - public SectionRenderDispatcher.RenderSection[] sections; + @Shadow public SectionRenderDispatcher.RenderSection[] sections; - @Shadow - protected abstract void setViewDistance(int i); + @Shadow protected abstract void setViewDistance(int i); - @Inject(method = "createSections", at = @At("HEAD")) - private void skipAllocation(SectionRenderDispatcher sectionRenderDispatcher, CallbackInfo ci) { - // It's not possible to completely skip allocation since it would cause an error if repositionCamera is called - this.setViewDistance(0); - } + @Inject(method = "createSections", at = @At("HEAD")) + private void skipAllocation(SectionRenderDispatcher sectionRenderDispatcher, CallbackInfo ci) { + // It's not possible to completely skip allocation since it would cause an error if repositionCamera is called + this.setViewDistance(0); + } } diff --git a/src/main/java/net/vulkanmod/mixin/chunk/VisibilitySetMixin.java b/src/main/java/net/vulkanmod/mixin/chunk/VisibilitySetMixin.java index 3b4b9a0fa..824abb3ba 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/VisibilitySetMixin.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/VisibilitySetMixin.java @@ -9,7 +9,7 @@ @Mixin(VisibilitySet.class) public class VisibilitySetMixin implements VisibilitySetExtended { - // private int vis2 = 0; +// private int vis2 = 0; private long vis = 0; /** @@ -29,7 +29,7 @@ public void set(Direction dir1, Direction dir2, boolean p_112989_) { */ @Overwrite public void setAll(boolean bl) { - if (bl) this.vis = 0xFFFFFFFFFFFFFFFFL; + if(bl) this.vis = 0xFFFFFFFFFFFFFFFFL; } /** diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java b/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java index 082c23011..99580bb1d 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java @@ -13,11 +13,12 @@ import com.mojang.blaze3d.systems.RenderPass; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.textures.GpuTextureView; +import com.mojang.blaze3d.vertex.*; import com.mojang.datafixers.util.Pair; import net.minecraft.client.renderer.MappableRingBuffer; import net.minecraft.client.renderer.PostPass; import net.minecraft.resources.ResourceLocation; -import net.vulkanmod.render.engine.VkGpuTexture; +import net.vulkanmod.render.engine.*; import net.vulkanmod.vulkan.Renderer; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -31,24 +32,12 @@ @Mixin(PostPass.class) public abstract class PostPassM { - @Shadow - @Final - private String name; - @Shadow - @Final - private List inputs; - @Shadow - @Final - private ResourceLocation outputTargetId; - @Shadow - @Final - private RenderPipeline pipeline; - @Shadow - @Final - private MappableRingBuffer infoUbo; - @Shadow - @Final - private Map customUniforms; + @Shadow @Final private String name; + @Shadow @Final private List inputs; + @Shadow @Final private ResourceLocation outputTargetId; + @Shadow @Final private RenderPipeline pipeline; + @Shadow @Final private MappableRingBuffer infoUbo; + @Shadow @Final private Map customUniforms; /** * @author @@ -62,7 +51,7 @@ public void addToFrame(FrameGraphBuilder frameGraphBuilder, Map resourceHandle = map.computeIfPresent( + ResourceHandle resourceHandle = (ResourceHandle)map.computeIfPresent( this.outputTargetId, (resourceLocation, resourceHandlex) -> framePass.readsAndWrites(resourceHandlex) ); if (resourceHandle == null) { @@ -104,7 +93,7 @@ public void addToFrame(FrameGraphBuilder frameGraphBuilder, Map entry : this.customUniforms.entrySet()) { - renderPass.setUniform(entry.getKey(), entry.getValue()); + renderPass.setUniform((String)entry.getKey(), (GpuBuffer)entry.getValue()); } for (Pair pair2 : list) { 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 0f42fe99e..7793470bf 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java @@ -3,13 +3,13 @@ import net.vulkanmod.gl.VkGlTexture; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; -import org.jetbrains.annotations.Nullable; import org.lwjgl.opengl.GL11; import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.NativeType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; +import org.jetbrains.annotations.Nullable; import java.nio.ByteBuffer; import java.nio.IntBuffer; @@ -315,6 +315,7 @@ public static void glBlendFunc(@NativeType("GLenum") int sfactor, @NativeType("G } + /** * @author * @reason diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL14M.java b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL14M.java index b43a1b5d8..6d6781524 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL14M.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL14M.java @@ -2,6 +2,7 @@ import net.vulkanmod.vulkan.VRenderSystem; import org.lwjgl.opengl.GL14; +import org.lwjgl.opengl.GL14C; import org.lwjgl.system.NativeType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; diff --git a/src/main/java/net/vulkanmod/mixin/debug/DebugEntryMemoryM.java b/src/main/java/net/vulkanmod/mixin/debug/DebugEntryMemoryM.java index 2ccf53e76..cd6e90fd6 100644 --- a/src/main/java/net/vulkanmod/mixin/debug/DebugEntryMemoryM.java +++ b/src/main/java/net/vulkanmod/mixin/debug/DebugEntryMemoryM.java @@ -19,9 +19,7 @@ @Mixin(DebugEntryMemory.class) public abstract class DebugEntryMemoryM { - @Shadow - @Final - private static ResourceLocation GROUP; + @Shadow @Final private static ResourceLocation GROUP; @Shadow protected static long bytesToMegabytes(long l) { diff --git a/src/main/java/net/vulkanmod/mixin/debug/DebugScreenEntriesM.java b/src/main/java/net/vulkanmod/mixin/debug/DebugScreenEntriesM.java index ca8a193b9..1f0843edd 100644 --- a/src/main/java/net/vulkanmod/mixin/debug/DebugScreenEntriesM.java +++ b/src/main/java/net/vulkanmod/mixin/debug/DebugScreenEntriesM.java @@ -20,6 +20,6 @@ public static ResourceLocation register(ResourceLocation resourceLocation, Debug @Inject(method = "", at = @At("RETURN")) private static void addEntry(CallbackInfo ci) { - register(ResourceLocation.fromNamespaceAndPath("vkmod", "stats"), new DebugEntryMemoryStats()); + register(ResourceLocation.fromNamespaceAndPath("vkmod","stats"), new DebugEntryMemoryStats()); } } diff --git a/src/main/java/net/vulkanmod/mixin/debug/KeyboardHandlerM.java b/src/main/java/net/vulkanmod/mixin/debug/KeyboardHandlerM.java index 6a9ed9a7f..e01a76c91 100644 --- a/src/main/java/net/vulkanmod/mixin/debug/KeyboardHandlerM.java +++ b/src/main/java/net/vulkanmod/mixin/debug/KeyboardHandlerM.java @@ -13,11 +13,9 @@ @Mixin(KeyboardHandler.class) public abstract class KeyboardHandlerM { - @Shadow - private boolean handledDebugKey; + @Shadow protected abstract boolean handleChunkDebugKeys(KeyEvent keyEvent); - @Shadow - protected abstract boolean handleChunkDebugKeys(KeyEvent keyEvent); + @Shadow private boolean handledDebugKey; @Inject(method = "keyPress", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/KeyMapping;set(Lcom/mojang/blaze3d/platform/InputConstants$Key;Z)V", ordinal = 1)) private void chunkDebug(long l, int i, KeyEvent keyEvent, CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/debug/crash_report/SystemReportM.java b/src/main/java/net/vulkanmod/mixin/debug/crash_report/SystemReportM.java index 7a2d36f2c..621a389a7 100644 --- a/src/main/java/net/vulkanmod/mixin/debug/crash_report/SystemReportM.java +++ b/src/main/java/net/vulkanmod/mixin/debug/crash_report/SystemReportM.java @@ -10,9 +10,9 @@ @Mixin(SystemReport.class) public class SystemReportM { - @Inject(method = "appendToCrashReportString", at = @At("RETURN")) - private void addVulkanDevicesInfo(StringBuilder stringBuilder, CallbackInfo ci) { - stringBuilder.append("\n\n -- VulkanMod Device Report --"); - stringBuilder.append(DeviceManager.getAvailableDevicesInfo()); - } + @Inject(method = "appendToCrashReportString", at = @At("RETURN")) + private void addVulkanDevicesInfo(StringBuilder stringBuilder, CallbackInfo ci) { + stringBuilder.append("\n\n -- VulkanMod Device Report --"); + stringBuilder.append(DeviceManager.getAvailableDevicesInfo()); + } } diff --git a/src/main/java/net/vulkanmod/mixin/matrix/Matrix4fM.java b/src/main/java/net/vulkanmod/mixin/matrix/Matrix4fM.java index d2189832a..d39d9647b 100644 --- a/src/main/java/net/vulkanmod/mixin/matrix/Matrix4fM.java +++ b/src/main/java/net/vulkanmod/mixin/matrix/Matrix4fM.java @@ -8,17 +8,10 @@ @Mixin(Matrix4f.class) public abstract class Matrix4fM { - @Shadow - public abstract Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne); - - @Shadow - public abstract Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne); - - @Shadow - public abstract Matrix4f setPerspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne); - - @Shadow - public abstract Matrix4f setOrtho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne); + @Shadow public abstract Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne); + @Shadow public abstract Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne); + @Shadow public abstract Matrix4f setPerspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne); + @Shadow public abstract Matrix4f setOrtho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne); /** * @author @@ -27,7 +20,7 @@ public abstract class Matrix4fM { @Overwrite(remap = false) public Matrix4f setOrtho(float left, float right, float bottom, float top, float zNear, float zFar) { this.setOrtho(left, right, bottom, top, zNear, zFar, true); - return (Matrix4f) (Object) this; + return (Matrix4f)(Object)this; } /** @@ -55,6 +48,6 @@ public Matrix4f perspective(float fovy, float aspect, float zNear, float zFar) { @Overwrite(remap = false) public Matrix4f setPerspective(float fovy, float aspect, float zNear, float zFar) { this.setPerspective(fovy, aspect, zNear, zFar, true); - return (Matrix4f) (Object) this; + return (Matrix4f)(Object)this; } } diff --git a/src/main/java/net/vulkanmod/mixin/profiling/GameLoadTimeEventM.java b/src/main/java/net/vulkanmod/mixin/profiling/GameLoadTimeEventM.java index fd02ace35..985d36d76 100644 --- a/src/main/java/net/vulkanmod/mixin/profiling/GameLoadTimeEventM.java +++ b/src/main/java/net/vulkanmod/mixin/profiling/GameLoadTimeEventM.java @@ -5,6 +5,7 @@ import net.minecraft.client.telemetry.TelemetryEventSender; import net.minecraft.client.telemetry.TelemetryEventType; import net.minecraft.client.telemetry.TelemetryProperty; +import net.minecraft.client.telemetry.TelemetryPropertyMap; import net.minecraft.client.telemetry.events.GameLoadTimesEvent; import org.slf4j.Logger; import org.spongepowered.asm.mixin.Final; @@ -18,14 +19,11 @@ @Mixin(GameLoadTimesEvent.class) public class GameLoadTimeEventM { - @Shadow - @Final - private static Logger LOGGER; - @Shadow - @Final - private Map, Stopwatch> measurements; - @Shadow - private OptionalLong bootstrapTime; + @Shadow @Final private Map, Stopwatch> measurements; + + @Shadow @Final private static Logger LOGGER; + + @Shadow private OptionalLong bootstrapTime; public void send(TelemetryEventSender telemetryEventSender) { Map measurements = new Reference2ReferenceOpenHashMap<>(); @@ -36,7 +34,7 @@ public void send(TelemetryEventSender telemetryEventSender) { (telemetryProperty, stopwatch) -> { if (!stopwatch.isRunning()) { long l = stopwatch.elapsed(TimeUnit.MILLISECONDS); - measurements.put(telemetryProperty, new GameLoadTimesEvent.Measurement((int) l)); + measurements.put(telemetryProperty, new GameLoadTimesEvent.Measurement((int)l)); } else { LOGGER.warn( "Measurement {} was discarded since it was still ongoing when the event {} was sent.", @@ -46,7 +44,7 @@ public void send(TelemetryEventSender telemetryEventSender) { } } ); - this.bootstrapTime.ifPresent(l -> measurements.put(TelemetryProperty.LOAD_TIME_BOOTSTRAP_MS, new GameLoadTimesEvent.Measurement((int) l))); + this.bootstrapTime.ifPresent(l -> measurements.put(TelemetryProperty.LOAD_TIME_BOOTSTRAP_MS, new GameLoadTimesEvent.Measurement((int)l))); this.measurements.clear(); } diff --git a/src/main/java/net/vulkanmod/mixin/profiling/GuiMixin.java b/src/main/java/net/vulkanmod/mixin/profiling/GuiMixin.java index 8802bc485..26563f60a 100644 --- a/src/main/java/net/vulkanmod/mixin/profiling/GuiMixin.java +++ b/src/main/java/net/vulkanmod/mixin/profiling/GuiMixin.java @@ -5,6 +5,7 @@ import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.DebugScreenOverlay; +import net.minecraft.client.renderer.entity.ItemRenderer; import net.vulkanmod.render.profiling.ProfilerOverlay; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -16,9 +17,7 @@ @Mixin(Gui.class) public class GuiMixin { - @Shadow - @Final - private DebugScreenOverlay debugOverlay; + @Shadow @Final private DebugScreenOverlay debugOverlay; @Inject(method = "", at = @At("RETURN")) private void createProfilerOverlay(Minecraft minecraft, CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/profiling/KeyboardHandlerM.java b/src/main/java/net/vulkanmod/mixin/profiling/KeyboardHandlerM.java index 7cd882964..467ec1a73 100644 --- a/src/main/java/net/vulkanmod/mixin/profiling/KeyboardHandlerM.java +++ b/src/main/java/net/vulkanmod/mixin/profiling/KeyboardHandlerM.java @@ -24,7 +24,8 @@ private void injOverlayToggle(long l, int i, KeyEvent keyEvent, CallbackInfo ci) case GLFW.GLFW_KEY_F8 -> ProfilerOverlay.toggle(); case GLFW.GLFW_KEY_F10 -> BuildTimeProfiler.startBench(); } - } else if (ProfilerOverlay.shouldRender) { + } + else if (ProfilerOverlay.shouldRender) { ProfilerOverlay.onKeyPress(keyEvent.key()); } } diff --git a/src/main/java/net/vulkanmod/mixin/profiling/LevelRendererMixin.java b/src/main/java/net/vulkanmod/mixin/profiling/LevelRendererMixin.java index 3cbdf3cec..b0061a261 100644 --- a/src/main/java/net/vulkanmod/mixin/profiling/LevelRendererMixin.java +++ b/src/main/java/net/vulkanmod/mixin/profiling/LevelRendererMixin.java @@ -2,7 +2,9 @@ import com.mojang.blaze3d.buffers.GpuBufferSlice; import com.mojang.blaze3d.resource.ResourceHandle; +import net.minecraft.client.Camera; import net.minecraft.client.CloudStatus; +import net.minecraft.client.DeltaTracker; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.client.renderer.state.LevelRenderState; @@ -47,7 +49,7 @@ private void popProfiler3(GpuBufferSlice gpuBufferSlice, ResourceHandle resource @Inject(method = "method_62214", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/renderer/LevelRenderer;submitEntities(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/state/LevelRenderState;Lnet/minecraft/client/renderer/SubmitNodeCollector;)V")) + target = "Lnet/minecraft/client/renderer/LevelRenderer;submitEntities(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/state/LevelRenderState;Lnet/minecraft/client/renderer/SubmitNodeCollector;)V")) private void profilerTerrain2(GpuBufferSlice gpuBufferSlice, LevelRenderState levelRenderState, ProfilerFiller profilerFiller, Matrix4f matrix4f, ResourceHandle resourceHandle, ResourceHandle resourceHandle2, boolean bl, Frustum frustum, diff --git a/src/main/java/net/vulkanmod/mixin/render/CompositeRenderTypeM.java b/src/main/java/net/vulkanmod/mixin/render/CompositeRenderTypeM.java index 5efcee406..c701142d7 100644 --- a/src/main/java/net/vulkanmod/mixin/render/CompositeRenderTypeM.java +++ b/src/main/java/net/vulkanmod/mixin/render/CompositeRenderTypeM.java @@ -11,9 +11,7 @@ import com.mojang.blaze3d.vertex.MeshData; import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.renderer.RenderType; -import net.vulkanmod.render.engine.VkCommandEncoder; -import net.vulkanmod.render.engine.VkGpuTexture; -import net.vulkanmod.render.engine.VkRenderPass; +import net.vulkanmod.render.engine.*; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.texture.VTextureSelector; import org.joml.Vector3f; @@ -29,30 +27,25 @@ @Mixin(RenderType.CompositeRenderType.class) public abstract class CompositeRenderTypeM { - @Shadow - @Final - private RenderType.CompositeState state; - @Shadow - @Final - private RenderPipeline renderPipeline; + @Shadow @Final private RenderType.CompositeState state; + @Shadow @Final private RenderPipeline renderPipeline; // TODO - /** * @author * @reason */ @Overwrite public void draw(MeshData meshData) { - ((RenderType.CompositeRenderType) (Object) (this)).setupRenderState(); + ((RenderType.CompositeRenderType)(Object)(this)).setupRenderState(); GpuBufferSlice gpuBufferSlice = RenderSystem.getDynamicUniforms() - .writeTransform( - RenderSystem.getModelViewMatrix(), - new Vector4f(1.0F, 1.0F, 1.0F, 1.0F), - new Vector3f(), - RenderSystem.getTextureMatrix(), - RenderSystem.getShaderLineWidth() - ); + .writeTransform( + RenderSystem.getModelViewMatrix(), + new Vector4f(1.0F, 1.0F, 1.0F, 1.0F), + new Vector3f(), + RenderSystem.getTextureMatrix(), + RenderSystem.getShaderLineWidth() + ); MeshData var3 = meshData; try { @@ -68,7 +61,7 @@ public void draw(MeshData meshData) { indexType = meshData.drawState().indexType(); } - RenderTarget renderTarget = ((CompositeStateAccessor) (Object) this.state).getOutputState().getRenderTarget(); + RenderTarget renderTarget = ((CompositeStateAccessor)(Object)this.state).getOutputState().getRenderTarget(); GpuTextureView gpuTextureView = RenderSystem.outputColorTextureOverride != null ? RenderSystem.outputColorTextureOverride : renderTarget.getColorTextureView(); @@ -77,10 +70,10 @@ public void draw(MeshData meshData) { : null; try (RenderPass renderPass = RenderSystem.getDevice() - .createCommandEncoder() - .createRenderPass(() -> "Immediate draw for " + - ((RenderType.CompositeRenderType) (Object) (this)).getName(), - gpuTextureView, OptionalInt.empty(), gpuTextureView2, OptionalDouble.empty())) { + .createCommandEncoder() + .createRenderPass(() -> "Immediate draw for " + + ((RenderType.CompositeRenderType) (Object) (this)).getName(), + gpuTextureView, OptionalInt.empty(), gpuTextureView2, OptionalDouble.empty())) { renderPass.setPipeline(this.renderPipeline); ScissorState scissorState = RenderSystem.getScissorStateForRenderTypeDraws(); if (scissorState.enabled()) { @@ -124,7 +117,7 @@ public void draw(MeshData meshData) { meshData.close(); } - ((RenderType.CompositeRenderType) (Object) (this)).clearRenderState(); + ((RenderType.CompositeRenderType)(Object)(this)).clearRenderState(); } } diff --git a/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java b/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java index bfc2f4e57..3f17f536e 100644 --- a/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java +++ b/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java @@ -3,31 +3,25 @@ import com.mojang.blaze3d.opengl.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.jtracy.Plot; -import net.vulkanmod.gl.VkGlBuffer; -import net.vulkanmod.gl.VkGlFramebuffer; -import net.vulkanmod.gl.VkGlShader; -import net.vulkanmod.gl.VkGlTexture; +import net.vulkanmod.gl.*; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; import org.jetbrains.annotations.Nullable; 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.At; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.Shadow; import java.nio.ByteBuffer; @Mixin(GlStateManager.class) public class GlStateManagerM { - @Shadow - @Final - private static Plot PLOT_BUFFERS; + @Shadow @Final private static Plot PLOT_BUFFERS; - @Shadow - private static int numBuffers; + @Shadow private static int numBuffers; /** * @author @@ -77,8 +71,7 @@ public static void _disableScissorTest() { * @author */ @Overwrite(remap = false) - public static void _enableScissorTest() { - } + public static void _enableScissorTest() {} /** * @author @@ -113,7 +106,6 @@ public static void _scissorBox(int x, int y, int width, int height) { } //TODO - /** * @author */ diff --git a/src/main/java/net/vulkanmod/mixin/render/GuiRendererMixin.java b/src/main/java/net/vulkanmod/mixin/render/GuiRendererMixin.java index 3c0893a88..09e25216e 100644 --- a/src/main/java/net/vulkanmod/mixin/render/GuiRendererMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/GuiRendererMixin.java @@ -22,17 +22,14 @@ @Mixin(GuiRenderer.class) public abstract class GuiRendererMixin { - @Shadow - @Final - private GuiRenderState renderState; - @Shadow - private @Nullable GpuTextureView itemsAtlasView; + @Shadow @Final private GuiRenderState renderState; + @Shadow private @Nullable GpuTextureView itemsAtlasView; @Overwrite private void submitBlitFromItemAtlas(GuiItemRenderState guiItemRenderState, float u, float v, int size, int atlasSize) { v = 1.0f - v; - float u1 = u + (float) size / atlasSize; - float v1 = v + (float) (size) / atlasSize; + float u1 = u + (float)size / atlasSize; + float v1 = v + (float)(size) / atlasSize; this.renderState .submitBlitToCurrentLayer( new BlitRenderState( @@ -68,7 +65,8 @@ private void useVertexCount(RenderPass renderPass, int baseVertex, int firstInde if (vkRenderPass.getPipeline().getVertexFormatMode() != VertexFormat.Mode.TRIANGLES) { int vertexCount = indexCount * 2 / 3; renderPass.drawIndexed(baseVertex, 0, vertexCount, 1); - } else { + } + else { renderPass.drawIndexed(baseVertex, 0, indexCount, 1); } } diff --git a/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java b/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java index 8f0e8a988..d39d1cd18 100644 --- a/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java @@ -1,5 +1,7 @@ package net.vulkanmod.mixin.render; +import com.mojang.blaze3d.pipeline.RenderTarget; +import com.mojang.blaze3d.systems.TimerQuery; import net.minecraft.client.GraphicsStatus; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; @@ -17,16 +19,16 @@ 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; + @Mixin(Minecraft.class) public class MinecraftMixin { - @Shadow - public boolean noRender; - @Shadow - @Final - public Options options; + @Shadow public boolean noRender; + @Shadow @Final public Options options; @Inject(method = "", at = @At(value = "RETURN")) private void forceGraphicsMode(GameConfig gameConfig, CallbackInfo ci) { @@ -39,7 +41,7 @@ private void forceGraphicsMode(GameConfig gameConfig, CallbackInfo ci) { } @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, int i, ProfilerFiller profilerFiller, int j) { int n = Math.min(10, i) - 1; boolean doUpload = j == n; @@ -64,7 +66,6 @@ public void onResolutionChanged(CallbackInfo ci) { // 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 949e37fe4..74ef4eb5b 100644 --- a/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.shaders.ShaderType; import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.*; import net.minecraft.client.renderer.DynamicUniforms; import net.minecraft.resources.ResourceLocation; import net.vulkanmod.render.engine.VkGpuDevice; @@ -16,26 +17,20 @@ import java.util.function.BiFunction; -import static com.mojang.blaze3d.systems.RenderSystem.getDevice; +import static com.mojang.blaze3d.systems.RenderSystem.*; @Mixin(RenderSystem.class) public abstract class RenderSystemMixin { - @Shadow - private static Matrix4f textureMatrix; - @Shadow - private static @Nullable Thread renderThread; + @Shadow private static Matrix4f textureMatrix; + @Shadow private static @Nullable Thread renderThread; - @Shadow - private static @Nullable GpuDevice DEVICE; - @Shadow - private static @Nullable DynamicUniforms dynamicUniforms; + @Shadow private static @Nullable GpuDevice DEVICE; + @Shadow private static @Nullable DynamicUniforms dynamicUniforms; - @Shadow - private static String apiDescription; + @Shadow private static String apiDescription; @Shadow - public static void assertOnRenderThread() { - } + public static void assertOnRenderThread() {} @Overwrite(remap = false) public static void initRenderer(long l, int i, boolean bl, BiFunction shaderSource, boolean bl2) { diff --git a/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java b/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java index 4b9d386a0..7ec047b32 100644 --- a/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java +++ b/src/main/java/net/vulkanmod/mixin/render/biome/BiomeManagerM.java @@ -9,9 +9,7 @@ @Mixin(BiomeManager.class) public class BiomeManagerM implements BiomeManagerExtended { - @Shadow - @Final - private long biomeZoomSeed; + @Shadow @Final private long biomeZoomSeed; @Override public long getBiomeZoomSeed() { 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 de26a6b26..2d07ba780 100644 --- a/src/main/java/net/vulkanmod/mixin/render/block/BakedQuadM.java +++ b/src/main/java/net/vulkanmod/mixin/render/block/BakedQuadM.java @@ -5,8 +5,8 @@ import net.minecraft.core.Direction; import net.vulkanmod.render.chunk.build.frapi.helper.NormalHelper; import net.vulkanmod.render.chunk.cull.QuadFacing; -import net.vulkanmod.render.model.quad.ModelQuadFlags; 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; import org.spongepowered.asm.mixin.Shadow; @@ -19,24 +19,14 @@ @Mixin(BakedQuad.class) public class BakedQuadM implements ModelQuadView { - @Shadow - @Final - protected int[] vertices; - @Shadow - @Final - protected Direction direction; - @Shadow - @Final - protected int tintIndex; + @Shadow @Final protected int[] vertices; + @Shadow @Final protected Direction direction; + @Shadow @Final protected int tintIndex; private int flags; private int normal; private QuadFacing facing; - private static int vertexOffset(int vertexIndex) { - return vertexIndex * VERTEX_SIZE; - } - @Inject(method = "", at = @At("RETURN")) private void onInit(int[] vertices, int tintIndex, Direction face, TextureAtlasSprite textureAtlasSprite, boolean shade, int lightEmission, CallbackInfo ci) { this.flags = ModelQuadFlags.getQuadFlags(this, face); @@ -53,7 +43,7 @@ public int getFlags() { @Override public float getX(int idx) { - return Float.intBitsToFloat(this.vertices[vertexOffset(idx)]); + return Float.intBitsToFloat(this.vertices[vertexOffset(idx) + 0]); } @Override @@ -110,4 +100,8 @@ public int getNormal() { public boolean isTinted() { return this.tintIndex != -1; } + + private static int vertexOffset(int vertexIndex) { + return vertexIndex * VERTEX_SIZE; + } } diff --git a/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java b/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java index 5c68b3c16..10231841c 100644 --- a/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java +++ b/src/main/java/net/vulkanmod/mixin/render/clouds/LevelRendererM.java @@ -4,17 +4,13 @@ import com.mojang.blaze3d.framegraph.FramePass; import net.minecraft.client.CloudStatus; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.LevelTargetBundle; +import net.minecraft.client.renderer.*; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.world.phys.Vec3; import net.vulkanmod.render.profiling.Profiler; import net.vulkanmod.render.sky.CloudRenderer; import org.jetbrains.annotations.Nullable; -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.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -22,16 +18,11 @@ @Mixin(LevelRenderer.class) public abstract class LevelRendererM { - @Shadow - private int ticks; - @Shadow - private @Nullable ClientLevel level; - @Shadow - @Final - private LevelTargetBundle targets; + @Shadow private int ticks; + @Shadow private @Nullable ClientLevel level; + @Shadow @Final private LevelTargetBundle targets; - @Unique - private CloudRenderer cloudRenderer; + @Unique private CloudRenderer cloudRenderer; @Inject(method = "addCloudsPass", at = @At("HEAD"), cancellable = true) public void addCloudsPass(FrameGraphBuilder frameGraphBuilder, CloudStatus cloudStatus, Vec3 camPos, float partialTicks, int i, float g, CallbackInfo ci) { @@ -51,7 +42,7 @@ public void addCloudsPass(FrameGraphBuilder frameGraphBuilder, CloudStatus cloud profiler.push("Clouds"); this.cloudRenderer.renderClouds(this.level, this.ticks, partialTicks, - camPos.x(), camPos.y(), camPos.z()); + camPos.x(), camPos.y(), camPos.z()); profiler.pop(); }); diff --git a/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java b/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java index cdae4133b..b3480e5c9 100644 --- a/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java +++ b/src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java @@ -14,16 +14,16 @@ @Mixin(BlockColors.class) public class BlockColorsM implements BlockColorsExtended { - @Unique - private final BlockColorRegistry colorResolvers = new BlockColorRegistry(); + @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); - } + @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; - } + @Override + public BlockColorRegistry getColorResolverMap() { + return this.colorResolvers; + } } diff --git a/src/main/java/net/vulkanmod/mixin/render/entity/EntityRendererM.java b/src/main/java/net/vulkanmod/mixin/render/entity/EntityRendererM.java index 6f7f733a6..c8503bc8d 100644 --- a/src/main/java/net/vulkanmod/mixin/render/entity/EntityRendererM.java +++ b/src/main/java/net/vulkanmod/mixin/render/entity/EntityRendererM.java @@ -33,22 +33,22 @@ public class EntityRendererM { // //// WorldRenderer.getInstance().getSectionGrid().getSectionAtBlockPos((int) entity.getX(), (int) entity.getY(), (int) entity.getZ()); // WorldRenderer worldRenderer = WorldRenderer.getInstance(); - - /// / return (worldRenderer.getLastFrame() == worldRenderer.getSectionGrid().getSectionAtBlockPos(entity.getBlockX(), entity.getBlockY(), entity.getBlockZ()).getLastFrame()); +//// return (worldRenderer.getLastFrame() == worldRenderer.getSectionGrid().getSectionAtBlockPos(entity.getBlockX(), entity.getBlockY(), entity.getBlockZ()).getLastFrame()); // // return frustum.isVisible(aABB); // } // } + @Redirect(method = "shouldRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/culling/Frustum;isVisible(Lnet/minecraft/world/phys/AABB;)Z")) private boolean isVisible(Frustum frustum, AABB aABB) { - if (Initializer.CONFIG.entityCulling) { + if(Initializer.CONFIG.entityCulling) { WorldRenderer worldRenderer = WorldRenderer.getInstance(); Vec3 pos = aABB.getCenter(); RenderSection section = worldRenderer.getSectionGrid().getSectionAtBlockPos((int) pos.x(), (int) pos.y(), (int) pos.z()); - if (section == null) + if(section == null) return frustum.isVisible(aABB); return worldRenderer.getLastFrame() == section.getLastFrame(); diff --git a/src/main/java/net/vulkanmod/mixin/render/entity/LevelRendererM.java b/src/main/java/net/vulkanmod/mixin/render/entity/LevelRendererM.java index 79d8c13c5..2fda4e46d 100644 --- a/src/main/java/net/vulkanmod/mixin/render/entity/LevelRendererM.java +++ b/src/main/java/net/vulkanmod/mixin/render/entity/LevelRendererM.java @@ -1,7 +1,33 @@ package net.vulkanmod.mixin.render.entity; +import com.mojang.blaze3d.buffers.GpuBufferSlice; +import com.mojang.blaze3d.resource.GraphicsResourceAllocator; +import com.mojang.blaze3d.vertex.PoseStack; +import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.client.Camera; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; -import org.spongepowered.asm.mixin.Mixin; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.EntityRenderDispatcher; +import net.minecraft.util.Mth; +import net.minecraft.world.TickRateManager; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; +import net.vulkanmod.Initializer; +import net.vulkanmod.render.chunk.WorldRenderer; +import org.joml.Matrix4f; +import org.joml.Vector4f; +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; + +import java.util.List; +import java.util.Map; @Mixin(LevelRenderer.class) public class LevelRendererM { diff --git a/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartCubeM.java b/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartCubeM.java index b6fc47ec7..a8be49c77 100644 --- a/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartCubeM.java +++ b/src/main/java/net/vulkanmod/mixin/render/entity/model/ModelPartCubeM.java @@ -14,8 +14,7 @@ @Mixin(ModelPart.Cube.class) public class ModelPartCubeM implements ModelPartCubeMixed { - @Unique - CubeModel cube; + @Unique CubeModel cube; @Inject(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/client/model/geom/ModelPart$Cube;polygons:[Lnet/minecraft/client/model/geom/ModelPart$Polygon;", 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 c8a7a27d0..514dc0681 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 @@ -11,10 +11,7 @@ import org.joml.Matrix3f; import org.joml.Matrix4f; import org.joml.Vector3f; -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.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -23,11 +20,9 @@ @Mixin(ModelPart.class) public abstract class ModelPartM { - @Unique - Vector3f normal = new Vector3f(); - @Shadow - @Final - private List cubes; + @Shadow @Final private List cubes; + + @Unique Vector3f normal = new Vector3f(); @Inject(method = "compile", at = @At("HEAD"), cancellable = true) private void injCompile(PoseStack.Pose pose, VertexConsumer vertexConsumer, int light, int overlay, int color, CallbackInfo ci) { @@ -48,7 +43,7 @@ public void renderCubes(PoseStack.Pose pose, VertexConsumer vertexConsumer, int color = ColorUtil.RGBA.fromArgb32(color); for (ModelPart.Cube cube : this.cubes) { - ModelPartCubeMixed cubeMixed = (ModelPartCubeMixed) (cube); + ModelPartCubeMixed cubeMixed = (ModelPartCubeMixed)(cube); CubeModel cubeModel = cubeMixed.getCubeModel(); CubeModel.Polygon[] polygons = cubeModel.getPolygons(); @@ -66,15 +61,16 @@ public void renderCubes(PoseStack.Pose pose, VertexConsumer vertexConsumer, int for (CubeModel.Vertex vertex : vertices) { Vector3f pos = vertex.pos(); vertexBuilder.vertex(pos.x(), pos.y(), pos.z(), - color, - vertex.u(), vertex.v(), - overlay, light, packedNormal); + color, + vertex.u(), vertex.v(), + overlay, light, packedNormal); } } } - } else { + } + else { for (ModelPart.Cube cube : this.cubes) { - ModelPartCubeMixed cubeMixed = (ModelPartCubeMixed) (cube); + ModelPartCubeMixed cubeMixed = (ModelPartCubeMixed)(cube); CubeModel cubeModel = cubeMixed.getCubeModel(); CubeModel.Polygon[] polygons = cubeModel.getPolygons(); @@ -90,10 +86,10 @@ public void renderCubes(PoseStack.Pose pose, VertexConsumer vertexConsumer, int for (CubeModel.Vertex vertex : vertices) { Vector3f pos = vertex.pos(); vertexConsumer.addVertex(pos.x(), pos.y(), pos.z(), - color, - vertex.u(), vertex.v(), - overlay, light, - normal.x(), normal.y(), normal.z()); + color, + vertex.u(), vertex.v(), + overlay, light, + normal.x(), normal.y(), normal.z()); } } } diff --git a/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java b/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java index f8ae6ccad..1298815bf 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/frame/MinecraftMixin.java @@ -16,8 +16,7 @@ @Mixin(Minecraft.class) public class MinecraftMixin { - @Shadow - public boolean noRender; + @Shadow public boolean noRender; @Inject(method = "runTick", at = @At(value = "HEAD")) private void preFrameOps(boolean bl, CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/BatchingRenderCommandQueueM.java b/src/main/java/net/vulkanmod/mixin/render/frapi/BatchingRenderCommandQueueM.java index a6a88a227..84906672a 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frapi/BatchingRenderCommandQueueM.java +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/BatchingRenderCommandQueueM.java @@ -23,10 +23,9 @@ @Mixin(SubmitNodeCollection.class) abstract class BatchingRenderCommandQueueM implements OrderedSubmitNodeCollector, AccessRenderCommandQueue, AccessBatchingRenderCommandQueue { - @Unique - private final List meshItemCommands = new ArrayList<>(); - @Shadow - private boolean wasUsed; + @Shadow private boolean wasUsed; + + @Unique private final List meshItemCommands = new ArrayList<>(); @Inject(method = "clear()V", at = @At("RETURN")) public void clear(CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/BlockRenderDispatcherAccessor.java b/src/main/java/net/vulkanmod/mixin/render/frapi/BlockRenderDispatcherAccessor.java index 393ff845c..3ded98367 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frapi/BlockRenderDispatcherAccessor.java +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/BlockRenderDispatcherAccessor.java @@ -1,12 +1,13 @@ package net.vulkanmod.mixin.render.frapi; -import net.minecraft.client.color.block.BlockColors; +import java.util.function.Supplier; + import net.minecraft.client.renderer.SpecialBlockModelRenderer; import net.minecraft.client.renderer.block.BlockRenderDispatcher; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; -import java.util.function.Supplier; +import net.minecraft.client.color.block.BlockColors; @Mixin(BlockRenderDispatcher.class) public interface BlockRenderDispatcherAccessor { diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/ItemFeatureRendererM.java b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemFeatureRendererM.java index 67804236d..778b5c308 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frapi/ItemFeatureRendererM.java +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemFeatureRendererM.java @@ -20,11 +20,9 @@ @Mixin(ItemFeatureRenderer.class) public class ItemFeatureRendererM { - @Unique - private final ItemRenderContext itemRenderContext = new ItemRenderContext(); - @Shadow - @Final - private PoseStack poseStack; + @Shadow @Final private PoseStack poseStack; + + @Unique private final ItemRenderContext itemRenderContext = new ItemRenderContext(); @Inject(method = "render", at = @At("RETURN")) private void onReturnRender(SubmitNodeCollection queue, MultiBufferSource.BufferSource vertexConsumers, OutlineBufferSource outlineVertexConsumers, CallbackInfo ci) { diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java index 52e73376e..06ca19723 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/ItemRendererAccessor.java @@ -10,8 +10,8 @@ @Mixin(ItemRenderer.class) public interface ItemRendererAccessor { - @Invoker("getSpecialFoilBuffer") - static VertexConsumer getSpecialFoilBuffer(MultiBufferSource provider, RenderType layer, PoseStack.Pose entry) { - throw new AssertionError(); - } + @Invoker("getSpecialFoilBuffer") + static VertexConsumer getSpecialFoilBuffer(MultiBufferSource provider, RenderType layer, PoseStack.Pose entry) { + throw new AssertionError(); + } } diff --git a/src/main/java/net/vulkanmod/mixin/render/frapi/OrderedRenderCommandQueueImplM.java b/src/main/java/net/vulkanmod/mixin/render/frapi/OrderedRenderCommandQueueImplM.java index 43bf4f017..17a372de2 100644 --- a/src/main/java/net/vulkanmod/mixin/render/frapi/OrderedRenderCommandQueueImplM.java +++ b/src/main/java/net/vulkanmod/mixin/render/frapi/OrderedRenderCommandQueueImplM.java @@ -18,10 +18,12 @@ import com.mojang.blaze3d.vertex.PoseStack; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshView; + import net.minecraft.client.renderer.OrderedSubmitNodeCollector; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.SubmitNodeStorage; + import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.world.item.ItemDisplayContext; diff --git a/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleGroupM.java b/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleGroupM.java index 359564186..807c85b93 100644 --- a/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleGroupM.java +++ b/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleGroupM.java @@ -12,14 +12,14 @@ @Mixin(QuadParticleGroup.class) public class QuadParticleGroupM { + @Redirect(method = "extractRenderState", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/culling/Frustum;pointInFrustum(DDD)Z")) + private boolean particleWithinSections(Frustum instance, double x, double y, double z) { + return !cull(WorldRenderer.getInstance(), x, y, z) && instance.pointInFrustum(x,y, z); + } + @Unique private static 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(); } - - @Redirect(method = "extractRenderState", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/culling/Frustum;pointInFrustum(DDD)Z")) - private boolean particleWithinSections(Frustum instance, double x, double y, double z) { - return !cull(WorldRenderer.getInstance(), x, y, z) && instance.pointInFrustum(x, y, z); - } } diff --git a/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleRenderStateM.java b/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleRenderStateM.java index 4789f23e7..b893f0835 100644 --- a/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleRenderStateM.java +++ b/src/main/java/net/vulkanmod/mixin/render/particle/QuadParticleRenderStateM.java @@ -13,10 +13,8 @@ @Mixin(QuadParticleRenderState.class) public class QuadParticleRenderStateM { - @Unique - private final Quaternionf quaternionf = new Quaternionf(); - @Unique - private final Vector3f vector3f = new Vector3f(); + @Unique private final Quaternionf quaternionf = new Quaternionf(); + @Unique private final Vector3f vector3f = new Vector3f(); @Overwrite public void renderRotatedQuad( @@ -24,7 +22,7 @@ public void renderRotatedQuad( ) { quaternionf.set(xr, yr, zr, wr); - ExtendedVertexBuilder vertexBuilder = (ExtendedVertexBuilder) vertexConsumer; + ExtendedVertexBuilder vertexBuilder = (ExtendedVertexBuilder)vertexConsumer; color = ColorUtil.BGRAtoRGBA(color); diff --git a/src/main/java/net/vulkanmod/mixin/render/shader/RenderPipelineM.java b/src/main/java/net/vulkanmod/mixin/render/shader/RenderPipelineM.java index ace6fa23f..465ae4a92 100644 --- a/src/main/java/net/vulkanmod/mixin/render/shader/RenderPipelineM.java +++ b/src/main/java/net/vulkanmod/mixin/render/shader/RenderPipelineM.java @@ -10,14 +10,12 @@ @Mixin(RenderPipeline.class) public abstract class RenderPipelineM implements ExtendedRenderPipeline { - @Unique - GraphicsPipeline pipeline; - @Unique - EGlProgram eGlProgram; + @Unique GraphicsPipeline pipeline; + @Unique EGlProgram eGlProgram; @Override - public EGlProgram getProgram() { - return this.eGlProgram; + public void setPipeline(GraphicsPipeline pipeline) { + this.pipeline = pipeline; } @Override @@ -26,12 +24,12 @@ public void setProgram(EGlProgram program) { } @Override - public Pipeline getPipeline() { - return this.pipeline; + public EGlProgram getProgram() { + return this.eGlProgram; } @Override - public void setPipeline(GraphicsPipeline pipeline) { - this.pipeline = pipeline; + public Pipeline getPipeline() { + return this.pipeline; } } diff --git a/src/main/java/net/vulkanmod/mixin/render/shader/ShaderManagerM.java b/src/main/java/net/vulkanmod/mixin/render/shader/ShaderManagerM.java index a576ba4a3..4294266e7 100644 --- a/src/main/java/net/vulkanmod/mixin/render/shader/ShaderManagerM.java +++ b/src/main/java/net/vulkanmod/mixin/render/shader/ShaderManagerM.java @@ -5,6 +5,7 @@ import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.client.renderer.ShaderManager; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.util.profiling.ProfilerFiller; 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 e5cea046c..310d64158 100644 --- a/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java @@ -9,29 +9,19 @@ import net.vulkanmod.render.engine.VkFbo; import net.vulkanmod.render.engine.VkGpuTexture; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.*; import java.util.OptionalInt; @Mixin(RenderTarget.class) public abstract class RenderTargetMixin { - @Shadow - public int width; - @Shadow - public int height; + @Shadow public int width; + @Shadow public int height; - @Shadow - @Nullable - protected GpuTexture colorTexture; - @Shadow - @Nullable - protected GpuTexture depthTexture; - @Shadow - @Nullable - protected GpuTextureView colorTextureView; + @Shadow @Nullable protected GpuTexture colorTexture; + @Shadow @Nullable protected GpuTexture depthTexture; + @Shadow @Nullable protected GpuTextureView colorTextureView; @Overwrite public void blitAndBlendToTexture(GpuTextureView gpuTextureView) { @@ -43,8 +33,8 @@ public void blitAndBlendToTexture(GpuTextureView gpuTextureView) { } try (RenderPass renderPass = RenderSystem.getDevice() - .createCommandEncoder() - .createRenderPass(() -> "Blit render target", gpuTextureView, OptionalInt.empty())) { + .createCommandEncoder() + .createRenderPass(() -> "Blit render target", gpuTextureView, OptionalInt.empty())) { renderPass.setPipeline(RenderPipelines.ENTITY_OUTLINE_BLIT); RenderSystem.bindDefaultUniforms(renderPass); renderPass.bindSampler("InSampler", this.colorTextureView); 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 d822a321e..9bb93a893 100644 --- a/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java +++ b/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java @@ -16,30 +16,24 @@ public abstract class BufferBuilderM implements VertexConsumer, ExtendedVertexBuilder { - @Shadow - private boolean fastFormat; - @Shadow - private boolean fullFormat; - @Shadow - private VertexFormat format; - @Shadow - private int elementsToFill; - @Shadow - @Final - private int initialElementsToFill; - private long ptr; + @Shadow private boolean fastFormat; + @Shadow private boolean fullFormat; + @Shadow private VertexFormat format; + + @Shadow protected abstract long beginVertex(); + + @Shadow private int elementsToFill; + @Shadow @Final private int initialElementsToFill; - @Shadow - protected abstract long beginVertex(); + @Shadow protected abstract long beginElement(VertexFormatElement vertexFormatElement); - @Shadow - protected abstract long beginElement(VertexFormatElement vertexFormatElement); + private long ptr; public void vertex(float x, float y, float z, int packedColor, float u, float v, int overlay, int light, int packedNormal) { this.ptr = this.beginVertex(); if (this.format == DefaultVertexFormat.NEW_ENTITY) { - MemoryUtil.memPutFloat(ptr, x); + MemoryUtil.memPutFloat(ptr + 0, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); @@ -53,7 +47,8 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, MemoryUtil.memPutInt(ptr + 28, light); MemoryUtil.memPutInt(ptr + 32, packedNormal); - } else { + } + else { this.elementsToFill = this.initialElementsToFill; this.position(x, y, z); @@ -71,7 +66,7 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, public void vertex(float x, float y, float z, float u, float v, int packedColor, int light) { this.ptr = this.beginVertex(); - MemoryUtil.memPutFloat(ptr, x); + MemoryUtil.memPutFloat(ptr + 0, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); @@ -84,7 +79,7 @@ public void vertex(float x, float y, float z, float u, float v, int packedColor, } public void position(float x, float y, float z) { - MemoryUtil.memPutFloat(ptr, x); + MemoryUtil.memPutFloat(ptr + 0, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); } @@ -132,7 +127,7 @@ public void fastNormal(int packedNormal) { public void addVertex(float x, float y, float z, int color, float u, float v, int overlay, int light, float normalX, float normalY, float normalZ) { if (this.fastFormat) { long ptr = this.beginVertex(); - MemoryUtil.memPutFloat(ptr, x); + MemoryUtil.memPutFloat(ptr + 0, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); @@ -171,7 +166,7 @@ private void putQuadData(PoseStack.Pose matrixEntry, BakedQuad quad, float[] bri Vec3i vec3i = quad.direction().getUnitVec3i(); Matrix4f matrix4f = matrixEntry.pose(); - boolean trustedNormals = ((PoseAccessor) (Object) matrixEntry).trustedNormals(); + 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) { diff --git a/src/main/java/net/vulkanmod/mixin/render/vertex/VertexFormatMixin.java b/src/main/java/net/vulkanmod/mixin/render/vertex/VertexFormatMixin.java index 197bac277..0fef9b2e9 100644 --- a/src/main/java/net/vulkanmod/mixin/render/vertex/VertexFormatMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/vertex/VertexFormatMixin.java @@ -1,11 +1,14 @@ package net.vulkanmod.mixin.render.vertex; +import com.google.common.collect.ImmutableMap; import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormatElement; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.vulkanmod.interfaces.VertexFormatMixed; +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; diff --git a/src/main/java/net/vulkanmod/mixin/screen/OptionsScreenM.java b/src/main/java/net/vulkanmod/mixin/screen/OptionsScreenM.java index 5294a8857..e3f20791b 100644 --- a/src/main/java/net/vulkanmod/mixin/screen/OptionsScreenM.java +++ b/src/main/java/net/vulkanmod/mixin/screen/OptionsScreenM.java @@ -15,13 +15,9 @@ @Mixin(OptionsScreen.class) public class OptionsScreenM extends Screen { - @Shadow - @Final - private Screen lastScreen; + @Shadow @Final private Screen lastScreen; - @Shadow - @Final - private Options options; + @Shadow @Final private Options options; protected OptionsScreenM(Component title) { super(title); diff --git a/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java b/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java index e50c18d24..6f47b9740 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java +++ b/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java @@ -1,8 +1,10 @@ package net.vulkanmod.mixin.texture.mip; import com.mojang.blaze3d.platform.NativeImage; +import net.minecraft.Util; import net.minecraft.client.renderer.texture.MipmapGenerator; import net.vulkanmod.mixin.texture.image.NativeImageAccessor; +import org.lwjgl.opengl.GL30; import org.lwjgl.system.MemoryUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -31,7 +33,7 @@ public static NativeImage[] generateMipLevels(NativeImage[] nativeImages, int i) NativeImage[] nativeImages2 = new NativeImage[i + 1]; nativeImages2[0] = nativeImages[0]; - long srcPtr = ((NativeImageAccessor) (Object) nativeImages2[0]).getPixels(); + long srcPtr = ((NativeImageAccessor)(Object)nativeImages2[0]).getPixels(); boolean bl = hasTransparentPixel(srcPtr, nativeImages2[0].getWidth(), nativeImages2[0].getHeight()); if (bl) { @@ -57,7 +59,7 @@ public static NativeImage[] generateMipLevels(NativeImage[] nativeImages, int i) } - for (int j = 1; j <= i; ++j) { + for(int j = 1; j <= i; ++j) { if (j < nativeImages.length) { nativeImages2[j] = nativeImages[j]; } else { @@ -66,16 +68,16 @@ public static NativeImage[] generateMipLevels(NativeImage[] nativeImages, int i) int width = nativeImage2.getWidth(); int height = nativeImage2.getHeight(); - srcPtr = ((NativeImageAccessor) (Object) nativeImage).getPixels(); - long dstPtr = ((NativeImageAccessor) (Object) nativeImage2).getPixels(); + srcPtr = ((NativeImageAccessor)(Object)nativeImage).getPixels(); + long dstPtr = ((NativeImageAccessor)(Object)nativeImage2).getPixels(); final int width2 = width * 2; - for (int m = 0; m < width; ++m) { - for (int n = 0; n < height; ++n) { - int p0 = MemoryUtil.memGetInt(srcPtr + ((m * 2L) + ((n * 2L) * width2)) * 4L); - int p1 = MemoryUtil.memGetInt(srcPtr + ((m * 2L + 1) + ((n * 2L) * width2)) * 4L); - int p2 = MemoryUtil.memGetInt(srcPtr + ((m * 2L) + ((n * 2L + 1) * width2)) * 4L); - int p3 = MemoryUtil.memGetInt(srcPtr + ((m * 2L + 1) + ((n * 2L + 1) * width2)) * 4L); + for(int m = 0; m < width; ++m) { + for(int n = 0; n < height; ++n) { + int p0 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 0) + ((n * 2 + 0) * width2)) * 4L); + int p1 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 1) + ((n * 2 + 0) * width2)) * 4L); + int p2 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 0) + ((n * 2 + 1) * width2)) * 4L); + int p3 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 1) + ((n * 2 + 1) * width2)) * 4L); int outColor = blend(p0, p1, p2, p3); MemoryUtil.memPutInt(dstPtr + (m + (long) n * width) * 4L, outColor); @@ -91,9 +93,9 @@ public static NativeImage[] generateMipLevels(NativeImage[] nativeImages, int i) } private static boolean hasTransparentPixel(long ptr, int width, int height) { - for (int i = 0; i < width; ++i) { - for (int j = 0; j < height; ++j) { - if (getPixelA(MemoryUtil.memGetInt(ptr + (i + (long) j * width) * 4L)) == 0) { + for(int i = 0; i < width; ++i) { + for(int j = 0; j < height; ++j) { + if (getPixelA(MemoryUtil.memGetInt(ptr + (i + j * width) * 4L)) == 0) { return true; } } @@ -120,8 +122,8 @@ private static int gammaBlend(int i, int j, int k, int l, int m) { float g = getPow22(j >> m); float h = getPow22(k >> m); float n = getPow22(l >> m); - float o = (float) ((double) ((float) Math.pow((double) (f + g + h + n) * 0.25, 0.45454545454545453))); - return (int) ((double) o * 255.0); + float o = (float)((double)((float)Math.pow((double)(f + g + h + n) * 0.25, 0.45454545454545453))); + return (int)((double)o * 255.0); } private static int getPixelA(int rgba) { @@ -135,10 +137,10 @@ private static int calculateAverage(NativeImage nativeImage) { final int[] values = new int[width * height]; int count = 0; - long srcPtr = ((NativeImageAccessor) (Object) nativeImage).getPixels(); + long srcPtr = ((NativeImageAccessor)(Object)nativeImage).getPixels(); - for (int i = 0; i < width; ++i) { - for (int j = 0; j < height; ++j) { + for(int i = 0; i < width; ++i) { + for(int j = 0; j < height; ++j) { // int value = nativeImage.getPixelRGBA(i, j); int value = MemoryUtil.memGetInt(srcPtr + (i + (long) j * width) * 4L); if (((value >> 24) & 0xFF) > 0) { @@ -157,7 +159,7 @@ private static int calculateAverage(NativeImage nativeImage) { sumB += (values[i] >> 16) & 0xFF; } - if (count == 0) + if(count == 0) return 0; sumR /= count; diff --git a/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java b/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java index f586e8a47..6cd861797 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java +++ b/src/main/java/net/vulkanmod/mixin/texture/update/MLightTexture.java @@ -1,44 +1,47 @@ package net.vulkanmod.mixin.texture.update; import com.mojang.blaze3d.platform.NativeImage; +import com.mojang.blaze3d.systems.CommandEncoder; +import com.mojang.blaze3d.systems.GpuDevice; +import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.textures.GpuTextureView; 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.util.profiling.Profiler; +import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.LivingEntity; +import net.vulkanmod.gl.VkGlTexture; +import net.vulkanmod.mixin.texture.image.NativeImageAccessor; +import net.vulkanmod.render.engine.VkGpuTexture; +import net.vulkanmod.render.texture.ImageUploadHelper; +import net.vulkanmod.vulkan.queue.CommandPool; import org.joml.Vector3f; -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.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 { - @Unique - private static final Vector3f END_FLASH_SKY_LIGHT_COLOR = new Vector3f(0.9F, 0.5F, 1.0F); + @Unique private static final Vector3f END_FLASH_SKY_LIGHT_COLOR = new Vector3f(0.9F, 0.5F, 1.0F); - @Shadow - @Final - private Minecraft minecraft; - @Shadow - @Final - private GameRenderer renderer; + @Shadow @Final private Minecraft minecraft; + @Shadow @Final private GameRenderer renderer; - @Shadow - private boolean updateLightTexture; - @Shadow - private float blockLightRedFlicker; + @Shadow private boolean updateLightTexture; + @Shadow private float blockLightRedFlicker; - @Unique - private DynamicTexture lightTexture; - @Unique - private GpuTextureView textureView; - @Unique - private NativeImage lightPixels; + @Unique private DynamicTexture lightTexture; + @Unique private GpuTextureView textureView; + @Unique private NativeImage lightPixels; private Vector3f[] tempVecs; @@ -116,25 +119,7 @@ public class MLightTexture { // // float gamma = this.minecraft.options.gamma().get().floatValue(); // float darkenWorldAmount = this.renderer.getDarkenWorldAmount(partialTicks); - - @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 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); - } - - /// / boolean forceBrightLightmap = clientLevel.effects().forceBrightLightmap(); +//// boolean forceBrightLightmap = clientLevel.effects().forceBrightLightmap(); // float ambientLight = clientLevel.dimensionType().ambientLight(); // // Vector3f vector3f2; @@ -222,6 +207,7 @@ private static float getBrightness(float ambientLight, int i) { // // ci.cancel(); // } + @Unique private float getDarknessGamma(float f) { MobEffectInstance mobEffectInstance = this.minecraft.player.getEffect(MobEffects.DARKNESS); @@ -231,7 +217,17 @@ private float getDarknessGamma(float f) { @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); + 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 @@ -241,4 +237,11 @@ private float notGamma(float f) { 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 index f16b927b6..f61bf5539 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/update/MSpriteContents.java +++ b/src/main/java/net/vulkanmod/mixin/texture/update/MSpriteContents.java @@ -14,13 +14,9 @@ @Mixin(SpriteContents.Ticker.class) public class MSpriteContents { - @Shadow - int subFrame; - @Shadow - int frame; - @Shadow - @Final - SpriteContents.AnimatedTexture animationInfo; + @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, GpuTexture gpuTexture, CallbackInfo ci) { @@ -34,7 +30,8 @@ private void checkUpload(int i, int j, GpuTexture gpuTexture, CallbackInfo ci) { } ci.cancel(); - } else { + } + else { SpriteUpdateUtil.addTransitionedLayout(VTextureSelector.getBoundTexture()); } } diff --git a/src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java b/src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java index cb6296b76..595ca054c 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java +++ b/src/main/java/net/vulkanmod/mixin/texture/update/MTextureManager.java @@ -15,9 +15,7 @@ @Mixin(TextureManager.class) public abstract class MTextureManager { - @Shadow - @Final - private Set tickableTextures; + @Shadow @Final private Set tickableTextures; /** * @author diff --git a/src/main/java/net/vulkanmod/mixin/util/ScreenshotMixin.java b/src/main/java/net/vulkanmod/mixin/util/ScreenshotMixin.java index 28474e2d1..04075bab5 100644 --- a/src/main/java/net/vulkanmod/mixin/util/ScreenshotMixin.java +++ b/src/main/java/net/vulkanmod/mixin/util/ScreenshotMixin.java @@ -35,15 +35,15 @@ public static void takeScreenshot(RenderTarget renderTarget, int mipLevel, Consu int pixelSize = TextureFormat.RGBA8.pixelSize(); GpuBuffer gpuBuffer = RenderSystem.getDevice() - .createBuffer(() -> "Screenshot buffer", 9, width * height * pixelSize); + .createBuffer(() -> "Screenshot buffer", 9, width * height * pixelSize); CommandEncoder commandEncoder = RenderSystem.getDevice().createCommandEncoder(); RenderSystem.getDevice().createCommandEncoder().copyTextureToBuffer(gpuTexture, gpuBuffer, 0, () -> { try (GpuBuffer.MappedView readView = commandEncoder.mapBuffer(gpuBuffer, true, false)) { NativeImage nativeImage = new NativeImage(width, height, false); var colorAttachment = ((VkGpuTexture) Renderer.getInstance() - .getMainPass() - .getColorAttachment()); + .getMainPass() + .getColorAttachment()); boolean isBgraFormat = (colorAttachment.getVulkanImage().format == VK10.VK_FORMAT_B8G8R8A8_UNORM); int size = mipLevel * mipLevel; diff --git a/src/main/java/net/vulkanmod/mixin/vertex/SpriteCoordinateExpanderM.java b/src/main/java/net/vulkanmod/mixin/vertex/SpriteCoordinateExpanderM.java index 5ff63fd3c..c27452a11 100644 --- a/src/main/java/net/vulkanmod/mixin/vertex/SpriteCoordinateExpanderM.java +++ b/src/main/java/net/vulkanmod/mixin/vertex/SpriteCoordinateExpanderM.java @@ -15,9 +15,7 @@ //TODO move @Mixin(SpriteCoordinateExpander.class) public class SpriteCoordinateExpanderM implements ExtendedVertexBuilder { - @Shadow - @Final - private TextureAtlasSprite sprite; + @Shadow @Final private TextureAtlasSprite sprite; @Unique private ExtendedVertexBuilder extDelegate; diff --git a/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java b/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java index bdef849b6..6a23dcf26 100644 --- a/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java +++ b/src/main/java/net/vulkanmod/mixin/vertex/VertexMultiConsumersM.java @@ -22,12 +22,8 @@ public class VertexMultiConsumersM { @Mixin(targets = "com/mojang/blaze3d/vertex/VertexMultiConsumer$Double") public static class DoubleM implements ExtendedVertexBuilder { - @Shadow - @Final - private VertexConsumer first; - @Shadow - @Final - private VertexConsumer second; + @Shadow @Final private VertexConsumer first; + @Shadow @Final private VertexConsumer second; @Unique private ExtendedVertexBuilder firstExt; @@ -62,9 +58,7 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, @Mixin(targets = "com/mojang/blaze3d/vertex/VertexMultiConsumer$Multiple") public static class MultipleM implements ExtendedVertexBuilder { - @Shadow - @Final - private VertexConsumer[] delegates; + @Shadow @Final private VertexConsumer[] delegates; @Unique private boolean canUseFastVertex = false; @@ -98,24 +92,16 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, @Mixin(SheetedDecalTextureGenerator.class) public static abstract class SheetDecalM implements ExtendedVertexBuilder { - @Shadow - @Final - private VertexConsumer delegate; - @Shadow - @Final - private Matrix3f normalInversePose; - @Shadow - @Final - private Matrix4f cameraInversePose; - @Shadow - @Final - private float textureScale; + @Shadow @Final private VertexConsumer delegate; + @Shadow @Final private Matrix3f normalInversePose; + @Shadow @Final private Matrix4f cameraInversePose; + @Shadow @Final private float textureScale; @Unique private boolean canUseFastVertex = false; - private final Vector3f normal = new Vector3f(); - private final Vector4f position = new Vector4f(); + private Vector3f normal = new Vector3f(); + private Vector4f position = new Vector4f(); @Override public boolean canUseFastVertex() { @@ -134,7 +120,7 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, float nz = I32_SNorm.unpackZ(packedNormal); normal.set(nx, ny, nz); - position.set(x, y, z, 1.0f); + position.set(x, y , z, 1.0f); this.normalInversePose.transform(normal); Direction direction = Direction.getApproximateNearest(normal.x(), normal.y(), normal.z()); diff --git a/src/main/java/net/vulkanmod/mixin/voxel/VoxelShapeMixin.java b/src/main/java/net/vulkanmod/mixin/voxel/VoxelShapeMixin.java index a749071a3..5331d81c7 100644 --- a/src/main/java/net/vulkanmod/mixin/voxel/VoxelShapeMixin.java +++ b/src/main/java/net/vulkanmod/mixin/voxel/VoxelShapeMixin.java @@ -1,8 +1,6 @@ package net.vulkanmod.mixin.voxel; -import net.minecraft.world.phys.shapes.CubeVoxelShape; -import net.minecraft.world.phys.shapes.DiscreteVoxelShape; -import net.minecraft.world.phys.shapes.VoxelShape; +import net.minecraft.world.phys.shapes.*; import net.vulkanmod.interfaces.VoxelShapeExtended; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -13,9 +11,7 @@ @Mixin(VoxelShape.class) public class VoxelShapeMixin implements VoxelShapeExtended { - @Shadow - @Final - protected DiscreteVoxelShape shape; + @Shadow @Final protected DiscreteVoxelShape shape; int co; @@ -26,8 +22,8 @@ private void initCornerOcclusion(DiscreteVoxelShape discreteVoxelShape, Callback // TODO: lithium subclasses // lithium is using its own classes for simple cube shapes - VoxelShape shape = (VoxelShape) ((Object) this); - if (!(shape instanceof CubeVoxelShape) || disShape == null) { + VoxelShape shape = (VoxelShape)((Object)this); + if(!(shape instanceof CubeVoxelShape) || disShape == null) { this.co = 0; return; } diff --git a/src/main/java/net/vulkanmod/mixin/wayland/InputConstantsM.java b/src/main/java/net/vulkanmod/mixin/wayland/InputConstantsM.java index f86c7c34a..7c4ee506c 100644 --- a/src/main/java/net/vulkanmod/mixin/wayland/InputConstantsM.java +++ b/src/main/java/net/vulkanmod/mixin/wayland/InputConstantsM.java @@ -2,7 +2,7 @@ import com.mojang.blaze3d.platform.InputConstants; import net.vulkanmod.config.Platform; -import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.*; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; diff --git a/src/main/java/net/vulkanmod/mixin/wayland/MinecraftMixin.java b/src/main/java/net/vulkanmod/mixin/wayland/MinecraftMixin.java index c6cd0f544..19d93d508 100644 --- a/src/main/java/net/vulkanmod/mixin/wayland/MinecraftMixin.java +++ b/src/main/java/net/vulkanmod/mixin/wayland/MinecraftMixin.java @@ -8,6 +8,7 @@ import net.minecraft.server.packs.PackResources; import net.minecraft.server.packs.VanillaPackResources; import net.vulkanmod.config.Platform; +import net.vulkanmod.config.video.VideoModeManager; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -19,23 +20,19 @@ @Mixin(Minecraft.class) public class MinecraftMixin { - @Shadow - @Final - public Options options; - @Shadow - @Final - private Window window; - @Shadow - @Final - private VanillaPackResources vanillaPackResources; + @Shadow @Final private Window window; + @Shadow @Final public Options options; + + @Shadow @Final private VanillaPackResources vanillaPackResources; /** * @author * @reason Only KWin supports setting the Icon on Wayland AFAIK */ - @Redirect(method = "", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/Window;setIcon(Lnet/minecraft/server/packs/PackResources;Lcom/mojang/blaze3d/platform/IconSet;)V")) + @Redirect(method="", at=@At(value="INVOKE", target="Lcom/mojang/blaze3d/platform/Window;setIcon(Lnet/minecraft/server/packs/PackResources;Lcom/mojang/blaze3d/platform/IconSet;)V")) private void bypassWaylandIcon(Window instance, PackResources packResources, IconSet iconSet) throws IOException { - if (!Platform.isWayLand()) { + if (!Platform.isWayLand()) + { this.window.setIcon(this.vanillaPackResources, SharedConstants.getCurrentVersion().stable() ? IconSet.RELEASE : IconSet.SNAPSHOT); } } diff --git a/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java b/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java index 02a62e9be..4827f9043 100644 --- a/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java +++ b/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java @@ -1,16 +1,13 @@ package net.vulkanmod.mixin.window; import com.mojang.blaze3d.TracyFrameCapture; -import com.mojang.blaze3d.platform.DisplayData; -import com.mojang.blaze3d.platform.ScreenManager; -import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.platform.WindowEventHandler; +import com.mojang.blaze3d.platform.*; import com.mojang.blaze3d.systems.RenderSystem; import net.vulkanmod.Initializer; import net.vulkanmod.config.Config; import net.vulkanmod.config.Platform; -import net.vulkanmod.config.option.Options; 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; @@ -32,51 +29,33 @@ @Mixin(Window.class) public abstract class WindowMixin { - @Shadow - @Final - private static Logger LOGGER; - @Final - @Shadow - private long handle; - @Shadow - private boolean vsync; - @Shadow - private boolean fullscreen; - @Shadow - private int windowedX; - @Shadow - private int windowedY; - @Shadow - private int windowedWidth; - @Shadow - private int windowedHeight; - @Shadow - private int x; - @Shadow - private int y; - @Shadow - private int width; - @Shadow - private int height; - - @Shadow - private int framebufferWidth; - @Shadow - private int framebufferHeight; - private boolean wasOnFullscreen = false; + @Final @Shadow private long handle; + + @Shadow private boolean vsync; + @Shadow private boolean fullscreen; + + @Shadow @Final private static Logger LOGGER; + + @Shadow private int windowedX; + @Shadow private int windowedY; + @Shadow private int windowedWidth; + @Shadow private int windowedHeight; + @Shadow private int x; + @Shadow private int y; + @Shadow private int width; + @Shadow private int height; - @Shadow - public abstract int getWidth(); + @Shadow private int framebufferWidth; + @Shadow private int framebufferHeight; - @Shadow - public abstract int getHeight(); + @Shadow public abstract int getWidth(); - @Shadow - protected abstract void updateFullscreen(boolean bl, @Nullable TracyFrameCapture tracyFrameCapture); + @Shadow public abstract int getHeight(); + + @Shadow protected abstract void updateFullscreen(boolean bl, @Nullable TracyFrameCapture tracyFrameCapture); @Redirect(method = "", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwWindowHint(II)V")) - private void redirect(int hint, int value) { - } + private void redirect(int hint, int value) { } @Inject(method = "", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwCreateWindow(IILjava/lang/CharSequence;JJ)J")) private void vulkanHint(WindowEventHandler windowEventHandler, ScreenManager screenManager, DisplayData displayData, String string, String string2, CallbackInfo ci) { @@ -115,7 +94,7 @@ public void toggleFullScreen() { */ @Overwrite public void updateDisplay(@Nullable TracyFrameCapture tracyFrameCapture) { - RenderSystem.flipFrame((Window) ((Object) this), tracyFrameCapture); + RenderSystem.flipFrame((Window) ((Object)this), tracyFrameCapture); if (Options.fullscreenDirty) { Options.fullscreenDirty = false; @@ -123,6 +102,8 @@ public void updateDisplay(@Nullable TracyFrameCapture tracyFrameCapture) { } } + private boolean wasOnFullscreen = false; + /** * @author */ @@ -140,11 +121,12 @@ private void setMode() { if (set != null) { supported = set.hasRefreshRate(videoMode.refreshRate); - } else { + } + else { supported = false; } - if (!supported) { + if(!supported) { LOGGER.error("Resolution not supported, using first available as fallback"); videoMode = VideoModeManager.getFirstAvailable().getVideoMode(); } @@ -164,7 +146,8 @@ private void setMode() { this.wasOnFullscreen = true; } - } else if (config.windowMode == WindowMode.WINDOWED_FULLSCREEN.mode) { + } + else if (config.windowMode == WindowMode.WINDOWED_FULLSCREEN.mode) { VideoModeSet.VideoMode videoMode = VideoModeManager.getOsVideoMode(); if (!this.wasOnFullscreen) { @@ -206,7 +189,7 @@ private void onFramebufferResize(long window, int width, int height) { int prevWidth = this.getWidth(); int prevHeight = this.getHeight(); - if (width > 0 && height > 0) { + if(width > 0 && height > 0) { this.framebufferWidth = width; this.framebufferHeight = height; // if (this.framebufferWidth != prevWidth || this.framebufferHeight != prevHeight) { @@ -228,7 +211,7 @@ private void onResize(long window, int width, int height) { this.width = width; this.height = height; - if (width > 0 && height > 0) + if(width > 0 && height > 0) Renderer.scheduleSwapChainUpdate(); } diff --git a/src/main/java/net/vulkanmod/render/PipelineManager.java b/src/main/java/net/vulkanmod/render/PipelineManager.java index 928782453..9368e5ad1 100644 --- a/src/main/java/net/vulkanmod/render/PipelineManager.java +++ b/src/main/java/net/vulkanmod/render/PipelineManager.java @@ -15,15 +15,17 @@ public abstract class PipelineManager { public static VertexFormat terrainVertexFormat; - static GraphicsPipeline - terrainShader, terrainShaderEarlyZ, - fastBlitPipeline, cloudsPipeline; - private static Function shaderGetter; public static void setTerrainVertexFormat(VertexFormat format) { terrainVertexFormat = format; } + static GraphicsPipeline + terrainShader, terrainShaderEarlyZ, + fastBlitPipeline, cloudsPipeline; + + private static Function shaderGetter; + public static void init() { setTerrainVertexFormat(CustomVertexFormat.COMPRESSED_TERRAIN); createBasicPipelines(); diff --git a/src/main/java/net/vulkanmod/render/VBO.java b/src/main/java/net/vulkanmod/render/VBO.java index c6a9cce0b..e3c4153ec 100644 --- a/src/main/java/net/vulkanmod/render/VBO.java +++ b/src/main/java/net/vulkanmod/render/VBO.java @@ -3,8 +3,7 @@ import com.mojang.blaze3d.vertex.MeshData; import com.mojang.blaze3d.vertex.VertexFormat; import net.vulkanmod.vulkan.Renderer; -import net.vulkanmod.vulkan.memory.MemoryType; -import net.vulkanmod.vulkan.memory.MemoryTypes; +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; @@ -25,7 +24,7 @@ public class VBO { private int vertexCount; public VBO(boolean useGpuMem) { - this.memoryType = useGpuMem ? MemoryTypes.GPU_MEM : MemoryTypes.HOST_MEM; + this.memoryType = useGpuMem ? MemoryTypes.GPU_MEM : MemoryTypes.HOST_MEM; } public void upload(MeshData meshData) { @@ -90,7 +89,8 @@ public void uploadIndexBuffer(ByteBuffer data) { } this.autoIndexed = true; - } else { + } + else { if (this.indexBuffer != null && !this.autoIndexed) { this.indexBuffer.scheduleFree(); } @@ -115,7 +115,8 @@ public void draw() { if (this.indexBuffer != null) { Renderer.getDrawer().drawIndexed(this.vertexBuffer, this.indexBuffer, this.indexCount); - } else { + } + else { Renderer.getDrawer().draw(this.vertexBuffer, this.vertexCount); } } diff --git a/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java b/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java index 4c30c3394..85400a8f1 100644 --- a/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java +++ b/src/main/java/net/vulkanmod/render/chunk/ChunkArea.java @@ -11,13 +11,15 @@ public class ChunkArea { public final int index; - //Help JIT optimisations by hardcoding the queue size to the max possible ChunkArea limit - public final StaticQueue sectionQueue = new StaticQueue<>(512); final DrawBuffers drawBuffers; final Vector3i position; final byte[] frustumBuffer = new byte[64]; + int sectionsContained = 0; + //Help JIT optimisations by hardcoding the queue size to the max possible ChunkArea limit + public final StaticQueue sectionQueue = new StaticQueue<>(512); + public ChunkArea(int i, Vector3i origin, int minHeight) { this.index = i; this.position = origin; @@ -27,17 +29,17 @@ public ChunkArea(int i, Vector3i origin, int minHeight) { public void updateFrustum(VFrustum frustum) { //TODO: maybe move to an aux class int frustumResult = frustum.cubeInFrustum(this.position.x(), this.position.y(), this.position.z(), - this.position.x() + (8 << 4), this.position.y() + (8 << 4), this.position.z() + (8 << 4)); + this.position.x() + (8 << 4) , this.position.y() + (8 << 4), this.position.z() + (8 << 4)); //Inner cubes if (frustumResult == FrustumIntersection.INTERSECT) { int width = 8 << 4; int l = width >> 1; - for (int x1 = 0; x1 < 2; x1++) { + for(int x1 = 0; x1 < 2; x1++) { float xMin = this.position.x() + (x1 * l); float xMax = xMin + l; - for (int y1 = 0; y1 < 2; y1++) { + for(int y1 = 0; y1 < 2; y1++) { float yMin = this.position.y() + (y1 * l); float yMax = yMin + l; for (int z1 = 0; z1 < 2; z1++) { @@ -45,7 +47,7 @@ public void updateFrustum(VFrustum frustum) { float zMax = zMin + l; frustumResult = frustum.cubeInFrustum(xMin, yMin, zMin, - xMax, yMax, zMax); + xMax , yMax, zMax); int beginIdx = (x1 << 5) + (y1 << 4) + (z1 << 3); if (frustumResult == FrustumIntersection.INTERSECT) { @@ -70,10 +72,11 @@ public void updateFrustum(VFrustum frustum) { } } - } else { + } + else { int end = beginIdx + 8; - for (int i = beginIdx; i < end; ++i) { + for(int i = beginIdx; i < end; ++i) { this.frustumBuffer[i] = (byte) frustumResult; } } diff --git a/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java b/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java index daed29320..4b79212b6 100644 --- a/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java +++ b/src/main/java/net/vulkanmod/render/chunk/ChunkAreaManager.java @@ -15,21 +15,25 @@ public class ChunkAreaManager { public static final int AREA_SIZE = WIDTH * WIDTH * HEIGHT; public static final int AREA_SH_XZ = Util.flooredLog(WIDTH); - public static final int BLOCK_TO_AREA_SH_XZ = AREA_SH_XZ + SEC_SH; public static final int AREA_SH_Y = Util.flooredLog(HEIGHT); - public static final int BLOCK_TO_AREA_SH_Y = AREA_SH_Y + SEC_SH; + public static final int SEC_SH = 4; + public static final int BLOCK_TO_AREA_SH_XZ = AREA_SH_XZ + SEC_SH; + public static final int BLOCK_TO_AREA_SH_Y = AREA_SH_Y + SEC_SH; + public final int size; final int sectionGridWidth; final int xzSize; final int ySize; final int minHeight; final ChunkArea[] chunkAreasArr; + + int prevX; + int prevZ; + private final CircularIntList xList; private final CircularIntList zList; private final CircularIntList.RangeIterator xComplIterator; - int prevX; - int prevZ; public ChunkAreaManager(int width, int height, int minHeight) { this.minHeight = minHeight; @@ -242,7 +246,7 @@ public String[] getStats() { vbUsed /= div; ibSize /= div; ibUsed /= div; - frag /= 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/ChunkStatusMap.java b/src/main/java/net/vulkanmod/render/chunk/ChunkStatusMap.java index 0a4b5da2b..56e2206d5 100644 --- a/src/main/java/net/vulkanmod/render/chunk/ChunkStatusMap.java +++ b/src/main/java/net/vulkanmod/render/chunk/ChunkStatusMap.java @@ -11,6 +11,11 @@ public class ChunkStatusMap { public static final byte ALL_FLAGS = CHUNK_READY | NEIGHBOURS_READY; public static ChunkStatusMap INSTANCE; + + public static void createInstance(int renderDistance) { + INSTANCE = new ChunkStatusMap(renderDistance); + } + private final Long2ByteOpenHashMap map; public ChunkStatusMap(int renderDistance) { @@ -19,10 +24,6 @@ public ChunkStatusMap(int renderDistance) { map.defaultReturnValue((byte) 0); } - public static void createInstance(int renderDistance) { - INSTANCE = new ChunkStatusMap(renderDistance); - } - public void updateDistance(int renderDistance) { int diameter = renderDistance * 2 + 1; this.map.ensureCapacity(diameter * diameter); @@ -54,7 +55,8 @@ public void updateNeighbours(int x, int z) { for (int z1 = z - 1; z1 <= z + 1; ++z1) { if (checkNeighbours(x1, z1)) { map.put(ChunkPos.asLong(x1, z1), ALL_FLAGS); - } else { + } + else { long l = ChunkPos.asLong(x1, z1); byte current = map.get(l); diff --git a/src/main/java/net/vulkanmod/render/chunk/RenderSection.java b/src/main/java/net/vulkanmod/render/chunk/RenderSection.java index 97b4588af..0ec0365c5 100644 --- a/src/main/java/net/vulkanmod/render/chunk/RenderSection.java +++ b/src/main/java/net/vulkanmod/render/chunk/RenderSection.java @@ -2,6 +2,7 @@ import com.google.common.collect.Sets; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +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; @@ -9,7 +10,11 @@ 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.task.*; +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; @@ -19,29 +24,35 @@ import java.util.Set; public class RenderSection { - private final CompileStatus compileStatus = new CompileStatus(); + private ChunkArea chunkArea; public byte frustumIndex; public short lastFrame = -1; + private short lastFrame2 = -1; public short inAreaIndex; + public byte adjDirs; public RenderSection adjDown, adjUp, adjNorth, adjSouth, adjWest, adjEast; + + private final CompileStatus compileStatus = new CompileStatus(); + + private boolean dirty = true; + private boolean playerChanged; + private boolean completelyEmpty = true; + private boolean containsBlockEntities = false; + public long visibility; + public int xOffset, yOffset, zOffset; + // Graph-info public byte mainDir; public byte directions; public byte sourceDirs; public byte steps; public byte directionChanges; - private ChunkArea chunkArea; - private short lastFrame2 = -1; - private boolean dirty = true; - private boolean playerChanged; - private boolean completelyEmpty = true; - private boolean containsBlockEntities = false; public RenderSection(int index, int x, int y, int z) { this.xOffset = x; @@ -263,12 +274,6 @@ public boolean isDirty() { return this.dirty; } - public void setDirty(boolean playerChanged) { - this.playerChanged = playerChanged || this.dirty && this.playerChanged; - this.dirty = true; - WorldRenderer.getInstance().scheduleGraphUpdate(); - } - public boolean isDirtyFromPlayer() { return this.dirty && this.playerChanged; } @@ -301,28 +306,32 @@ public void resetDrawParameters(TerrainRenderType renderType) { } } - public ChunkArea getChunkArea() { - return this.chunkArea; - } - public void setChunkArea(ChunkArea chunkArea) { this.chunkArea = chunkArea; this.frustumIndex = chunkArea.getFrustumIndex(xOffset, yOffset, zOffset); } - public CompiledSection getCompiledSection() { - return compileStatus.compiledSection; + public ChunkArea getChunkArea() { + return this.chunkArea; } - public void setCompiledSection(CompiledSection compiledSection) { - this.compileStatus.compiledSection = compiledSection; + public CompiledSection getCompiledSection() { + return compileStatus.compiledSection; } public boolean isCompiled() { return this.compileStatus.compiledSection != CompiledSection.UNCOMPILED; } + public void setVisibility(long visibility) { + this.visibility = visibility; + } + + public void setCompletelyEmpty(boolean b) { + this.completelyEmpty = b; + } + public void setContainsBlockEntities(boolean b) { this.containsBlockEntities = b; } @@ -339,18 +348,10 @@ public long getVisibility() { return visibility; } - public void setVisibility(long visibility) { - this.visibility = visibility; - } - public boolean isCompletelyEmpty() { return this.completelyEmpty; } - public void setCompletelyEmpty(boolean b) { - this.completelyEmpty = b; - } - public boolean containsBlockEntities() { return this.containsBlockEntities; } @@ -395,6 +396,16 @@ private void resetDrawParameters() { } } + public void setDirty(boolean playerChanged) { + this.playerChanged = playerChanged || this.dirty && this.playerChanged; + this.dirty = true; + WorldRenderer.getInstance().scheduleGraphUpdate(); + } + + public void setCompiledSection(CompiledSection compiledSection) { + this.compileStatus.compiledSection = compiledSection; + } + public boolean setLastFrame(short i) { boolean alreadySet = i == this.lastFrame; if (!alreadySet) diff --git a/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java b/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java index ca94a788f..f7075774a 100644 --- a/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java +++ b/src/main/java/net/vulkanmod/render/chunk/SectionGrid.java @@ -15,16 +15,18 @@ public class SectionGrid { protected final Level level; - final ChunkAreaManager chunkAreaManager; - private final CircularIntList xList; - private final CircularIntList zList; - private final CircularIntList.RangeIterator xComplIterator; - public RenderSection[] sections; protected int gridHeight; protected int gridWidth; + public RenderSection[] sections; + final ChunkAreaManager chunkAreaManager; + 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); @@ -145,7 +147,7 @@ public void repositionCamera(double x, double z) { for (int yRel = 0; yRel < this.gridHeight; ++yRel) { moveSection(xRelativeIndex, yRel, zRelativeIndex, x1, z1, - xList, zList, xRangeIterator.getCurrentIndex(), zIterator.getCurrentIndex()); + xList, zList, xRangeIterator.getCurrentIndex(), zIterator.getCurrentIndex()); } } } @@ -164,7 +166,7 @@ public void repositionCamera(double x, double z) { for (int yRel = 0; yRel < this.gridHeight; ++yRel) { moveSection(xRelativeIndex, yRel, zRelativeIndex, x1, z1, - xList, zList, xComplIterator.getCurrentIndex(), zRangeIterator.getCurrentIndex()); + xList, zList, xComplIterator.getCurrentIndex(), zRangeIterator.getCurrentIndex()); } } } @@ -186,7 +188,7 @@ private void moveSection(int xRelativeIndex, int yRel, int zRelativeIndex, renderSection.setOrigin(x1, y1, z1); this.setNeighbours(renderSection, xList, zList, xCurrentIdx, zCurrentIdx, - xRelativeIndex, yRel, zRelativeIndex); + xRelativeIndex, yRel, zRelativeIndex); ChunkArea oldArea = renderSection.getChunkArea(); diff --git a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java index 095b97372..6bbffe097 100644 --- a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java @@ -34,18 +34,18 @@ import net.vulkanmod.render.PipelineManager; import net.vulkanmod.render.chunk.buffer.DrawBuffers; import net.vulkanmod.render.chunk.build.RenderRegionBuilder; -import net.vulkanmod.render.chunk.build.task.ChunkTask; 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; import net.vulkanmod.render.profiling.Profiler; import net.vulkanmod.render.vertex.TerrainRenderType; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; -import net.vulkanmod.vulkan.memory.MemoryTypes; 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; import org.jetbrains.annotations.Nullable; @@ -56,19 +56,30 @@ public class WorldRenderer { private static WorldRenderer INSTANCE; + + public static WorldRenderer init(EntityRenderDispatcher entityRenderDispatcher, + BlockEntityRenderDispatcher blockEntityRenderDispatcher, + RenderBuffers renderBuffers, + LevelRenderState levelRenderState, + FeatureRenderDispatcher featureRenderDispatcher) { + if (INSTANCE != null) { + return INSTANCE; + } + else { + return INSTANCE = new WorldRenderer(entityRenderDispatcher, blockEntityRenderDispatcher, renderBuffers, levelRenderState, featureRenderDispatcher); + } + } + private final Minecraft minecraft; + private ClientLevel level; + private int renderDistance; private final RenderBuffers renderBuffers; + private final EntityRenderDispatcher entityRenderDispatcher; private final BlockEntityRenderDispatcher blockEntityRenderDispatcher; private final LevelRenderState levelRenderState; private final FeatureRenderDispatcher featureRenderDispatcher; - private final Set globalBlockEntities = Sets.newHashSet(); - private final TaskDispatcher taskDispatcher; - private final List onAllChangedCallbacks = new ObjectArrayList<>(); - public RenderRegionBuilder renderRegionCache; - IndirectBuffer[] indirectBuffers; - private ClientLevel level; - private int renderDistance; + private float partialTick; private Vec3 cameraPos; private int lastCameraSectionX; @@ -79,18 +90,32 @@ public class WorldRenderer { private float lastCameraZ; private float lastCamRotX; private float lastCamRotY; + private SectionGrid sectionGrid; + private SectionGraph sectionGraph; private boolean graphNeedsUpdate; + + private final Set globalBlockEntities = Sets.newHashSet(); + + private final TaskDispatcher taskDispatcher; + private double xTransparentOld; private double yTransparentOld; private double zTransparentOld; + IndirectBuffer[] indirectBuffers; + + public RenderRegionBuilder renderRegionCache; + + private final List onAllChangedCallbacks = new ObjectArrayList<>(); + private WorldRenderer(EntityRenderDispatcher entityRenderDispatcher, BlockEntityRenderDispatcher blockEntityRenderDispatcher, RenderBuffers renderBuffers, LevelRenderState levelRenderState, - FeatureRenderDispatcher featureRenderDispatcher) { + FeatureRenderDispatcher featureRenderDispatcher) + { this.minecraft = Minecraft.getInstance(); this.renderBuffers = renderBuffers; this.entityRenderDispatcher = entityRenderDispatcher; @@ -111,56 +136,6 @@ private WorldRenderer(EntityRenderDispatcher entityRenderDispatcher, }); } - public static WorldRenderer init(EntityRenderDispatcher entityRenderDispatcher, - BlockEntityRenderDispatcher blockEntityRenderDispatcher, - RenderBuffers renderBuffers, - LevelRenderState levelRenderState, - FeatureRenderDispatcher featureRenderDispatcher) { - if (INSTANCE != null) { - return INSTANCE; - } else { - return INSTANCE = new WorldRenderer(entityRenderDispatcher, blockEntityRenderDispatcher, renderBuffers, levelRenderState, featureRenderDispatcher); - } - } - - public static WorldRenderer getInstance() { - return INSTANCE; - } - - public static ClientLevel getLevel() { - return INSTANCE.level; - } - - public void setLevel(@Nullable ClientLevel level) { - this.lastCameraX = Float.MIN_VALUE; - this.lastCameraY = Float.MIN_VALUE; - this.lastCameraZ = Float.MIN_VALUE; - this.lastCameraSectionX = Integer.MIN_VALUE; - this.lastCameraSectionY = Integer.MIN_VALUE; - this.lastCameraSectionZ = Integer.MIN_VALUE; - -// this.entityRenderDispatcher.setLevel(level); - this.level = level; - ChunkStatusMap.createInstance(renderDistance); - if (level != null) { - this.allChanged(); - } else { - if (this.sectionGrid != null) { - this.sectionGrid.freeAllBuffers(); - this.sectionGrid = null; - } - - this.taskDispatcher.stopThreads(); - - this.graphNeedsUpdate = true; - } - - } - - public static Vec3 getCameraPos() { - return INSTANCE.cameraPos; - } - private void allocateIndirectBuffers() { if (this.indirectBuffers != null) Arrays.stream(this.indirectBuffers).forEach(Buffer::scheduleFree); @@ -300,6 +275,32 @@ public void allChanged() { } } + public void setLevel(@Nullable ClientLevel level) { + this.lastCameraX = Float.MIN_VALUE; + this.lastCameraY = Float.MIN_VALUE; + this.lastCameraZ = Float.MIN_VALUE; + this.lastCameraSectionX = Integer.MIN_VALUE; + this.lastCameraSectionY = Integer.MIN_VALUE; + this.lastCameraSectionZ = Integer.MIN_VALUE; + +// this.entityRenderDispatcher.setLevel(level); + this.level = level; + ChunkStatusMap.createInstance(renderDistance); + if (level != null) { + this.allChanged(); + } else { + if (this.sectionGrid != null) { + this.sectionGrid.freeAllBuffers(); + this.sectionGrid = null; + } + + this.taskDispatcher.stopThreads(); + + this.graphNeedsUpdate = true; + } + + } + public void addOnAllChangedCallback(Runnable runnable) { this.onAllChangedCallbacks.add(runnable); } @@ -442,7 +443,7 @@ public void renderBlockEntities(PoseStack poseStack, LevelRenderState levelRende poseStack.pushPose(); poseStack.translate(blockPos.getX() - camX, blockPos.getY() - camY, blockPos.getZ() - camZ); crumblingOverlay = new ModelFeatureRenderer.CrumblingOverlay(sortedSet.last() - .getProgress(), poseStack.last()); + .getProgress(), poseStack.last()); poseStack.popPose(); } else { crumblingOverlay = null; @@ -537,4 +538,16 @@ public void cleanUp() { Arrays.stream(indirectBuffers).forEach(Buffer::scheduleFree); } + public static WorldRenderer getInstance() { + return INSTANCE; + } + + public static ClientLevel getLevel() { + return INSTANCE.level; + } + + public static Vec3 getCameraPos() { + return INSTANCE.cameraPos; + } + } 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 e2df45537..c2c02db66 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/AreaBuffer.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/AreaBuffer.java @@ -3,9 +3,7 @@ import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; import net.vulkanmod.Initializer; import net.vulkanmod.render.chunk.util.Util; -import net.vulkanmod.vulkan.memory.MemoryManager; -import net.vulkanmod.vulkan.memory.MemoryType; -import net.vulkanmod.vulkan.memory.MemoryTypes; +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; @@ -25,9 +23,11 @@ public class AreaBuffer { private final Int2ReferenceOpenHashMap usedSegments = new Int2ReferenceOpenHashMap<>(); Segment first, last; + + private Buffer buffer; + int size, used = 0; int segments = 0; - private Buffer buffer; public AreaBuffer(Usage usage, int elementCount, int elementSize) { this.usage = usage.usage; @@ -140,7 +140,8 @@ public Segment reallocate(int uploadSize) { if (last.isFree()) { last.size += increment; - } else { + } + else { int offset = last.offset + last.size; Segment segment = new Segment(offset, newSize - offset); segments++; @@ -348,17 +349,6 @@ public int getUsed() { return used; } - public enum Usage { - VERTEX(0), - INDEX(1); - - final int usage; - - Usage(int i) { - usage = i; - } - } - public static class Segment { int offset, size; boolean free = true; @@ -394,4 +384,15 @@ public void bindNext(Segment s) { } + public enum Usage { + VERTEX(0), + INDEX(1); + + final int usage; + + Usage(int i) { + usage = i; + } + } + } 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 eb005c518..24f3c9550 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/DrawBuffers.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/DrawBuffers.java @@ -26,19 +26,22 @@ public class DrawBuffers { public static final int VERTEX_SIZE = PipelineManager.terrainVertexFormat.getVertexSize(); public static final int INDEX_SIZE = Short.BYTES; - // TODO: refactor - public static final float POS_OFFSET = PipelineManager.terrainVertexFormat == CustomVertexFormat.COMPRESSED_TERRAIN ? 4.0f : 0.0f; + private static final int CMD_STRIDE = 32; + private static final long cmdBufferPtr = MemoryUtil.nmemAlignedAlloc(CMD_STRIDE, (long) ChunkAreaManager.AREA_SIZE * QuadFacing.COUNT * CMD_STRIDE); - final int[] sectionIndices = new int[512]; - final int[] masks = new int[512]; + private final int index; private final Vector3i origin; private final int minHeight; - private final EnumMap vertexBuffers = new EnumMap<>(TerrainRenderType.class); + + private boolean allocated = false; AreaBuffer indexBuffer; + private final EnumMap vertexBuffers = new EnumMap<>(TerrainRenderType.class); + long drawParamsPtr; - private boolean allocated = false; + 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) { @@ -137,6 +140,9 @@ private int encodeSectionOffset(int xOffset, int yOffset, int zOffset) { return yOffset1 << 16 | zOffset1 << 8 | xOffset1; } + // TODO: refactor + 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); float yOffset = (float) ((this.origin.y) + POS_OFFSET - camY); @@ -212,7 +218,8 @@ public void buildDrawBatchesIndirect(Vec3 cameraPos, IndirectBuffer indirectBuff } } - } else { + } + else { for (var iterator = queue.iterator(isTranslucent); iterator.hasNext(); ) { final RenderSection section = iterator.next(); @@ -310,7 +317,8 @@ public void buildDrawBatchesDirect(Vec3 cameraPos, StaticQueue qu } } - } else { + } + else { final int facing = 6; final long facingOffset = facing * DrawParametersBuffer.STRIDE; drawParamsBasePtr += facingOffset; diff --git a/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java b/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java index b741a9493..f26c2420d 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/DrawParametersBuffer.java @@ -6,11 +6,13 @@ import org.lwjgl.system.MemoryUtil; public abstract class DrawParametersBuffer { - public static final long STRIDE = 16; 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; @@ -30,7 +32,7 @@ public static void freeBuffer(long ptr) { } public static long getParamsPtr(long basePtr, int section, int renderType, int facing) { - return basePtr + ((((long) renderType * SECTIONS + section) * FACINGS) + facing) * STRIDE; + return basePtr + (((renderType * SECTIONS + section) * FACINGS) + facing) * STRIDE; } public static void resetParameters(long ptr) { 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 fb032396c..5ab8bee72 100644 --- a/src/main/java/net/vulkanmod/render/chunk/buffer/UploadManager.java +++ b/src/main/java/net/vulkanmod/render/chunk/buffer/UploadManager.java @@ -20,14 +20,16 @@ public class UploadManager { public static UploadManager INSTANCE; - Queue queue = DeviceManager.getTransferQueue(); - CommandPool.CommandBuffer commandBuffer; - LongOpenHashSet dstBuffers = new LongOpenHashSet(); public static void createInstance() { INSTANCE = new UploadManager(); } + Queue queue = DeviceManager.getTransferQueue(); + CommandPool.CommandBuffer commandBuffer; + + LongOpenHashSet dstBuffers = new LongOpenHashSet(); + public void submitUploads() { if (this.commandBuffer == null) return; 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 83433271f..f9402f0ce 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/RenderRegion.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/RenderRegion.java @@ -44,10 +44,13 @@ public class RenderRegion implements BlockAndTintGetter { private final PalettedContainer[] blockDataContainers; private final BlockState[] blockData; private final DataLayer[][] lightData; + + private BiomeData biomeData; + private TintCache tintCache; + private final Map blockEntityMap; + private final Function blockStateGetter; - private final BiomeData biomeData; - private TintCache tintCache; RenderRegion(Level level, int x, int y, int z, PalettedContainer[] blockData, DataLayer[][] lightData, BiomeData biomeData, Map blockEntityMap) { @@ -101,7 +104,7 @@ 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); } } @@ -233,7 +236,8 @@ public BlockState debugBlockState(BlockPos blockPos) { BlockState blockState = null; if (y == 60) { blockState = Blocks.BARRIER.defaultBlockState(); - } else if (y == 70) { + } + else if (y == 70) { blockState = DebugLevelSource.getBlockStateFor(x, z); } 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 571d23d38..3254b19c4 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/UploadBuffer.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/UploadBuffer.java @@ -2,6 +2,7 @@ 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; @@ -29,13 +30,15 @@ public UploadBuffer(TerrainBuilder terrainBuilder, TerrainBuilder.DrawState draw this.vertexBuffers[i] = BufferUtil.clone(bufferBuilder.getBuffer()); } } - } else { + } + else { this.vertexBuffers = null; } if (!drawState.sequentialIndex()) { this.indexBuffer = BufferUtil.clone(terrainBuilder.getIndexBuffer()); - } else { + } + else { this.indexBuffer = null; } } 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 index 07b8712cf..fe701cbe6 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/biome/BiomeData.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/biome/BiomeData.java @@ -14,8 +14,10 @@ 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; - private final long biomeZoomSeed; + Biome[] biomes = new Biome[SIZE]; + private final long biomeZoomSeed; + int secX, secY, secZ; // Cached cell offsets @@ -28,42 +30,11 @@ public BiomeData(long biomeZoomSeed, int secX, int secY, int secZ) { this.secZ = secZ; } - 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; - } - public void getBiomeData(Level level, LevelChunkSection chunkSection, int secX, int secY, int secZ) { Biome defaultValue = level.registryAccess() - .lookupOrThrow(Registries.BIOME) - .getOrThrow(Biomes.PLAINS) - .value(); + .lookupOrThrow(Registries.BIOME) + .getOrThrow(Biomes.PLAINS) + .value(); int baseIdx = getRelativeSectionIdx(secX, secY, secZ); @@ -75,8 +46,9 @@ public void getBiomeData(Level level, LevelChunkSection chunkSection, int secX, if (chunkSection != null) { biomes[idx] = chunkSection.getNoiseBiome(x, y, z) - .value(); - } else { + .value(); + } + else { biomes[idx] = defaultValue; } @@ -147,4 +119,35 @@ private Vector3f getOffset(int baseIndex, int cellX, int cellY, int 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 index a4fcdb56e..b8ec0ca39 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/color/BlockColorRegistry.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/color/BlockColorRegistry.java @@ -6,16 +6,16 @@ public class BlockColorRegistry { - private final Reference2ReferenceOpenHashMap map = new Reference2ReferenceOpenHashMap<>(); + private final Reference2ReferenceOpenHashMap map = new Reference2ReferenceOpenHashMap<>(); - public void register(BlockColor blockColor, Block... blocks) { - for (Block block : blocks) { - this.map.put(block, blockColor); - } - } + 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); - } + public BlockColor getBlockColor(Block block) { + return this.map.get(block); + } } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java b/src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java index 4360d9780..f86333de7 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/color/BoxBlur.java @@ -16,7 +16,7 @@ public static void horizontalBlur(int[] src, int[] dst, int y0, int width, int f int r = 0, g = 0, b = 0; //init accumulator - for (int x = 0; x < x0 + 1 + filterRadius; ++x) { + for(int x = 0; x < x0 + 1 + filterRadius; ++x) { color = src[getIdx(x, y, totalWidth)]; r += unpackR(color); g += unpackG(color); 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 index 320c57fbd..e31cc965e 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/color/TintCache.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/color/TintCache.java @@ -62,7 +62,8 @@ public void init(BiomeData biomeData, int blendRadius, int secX, int secY, int s } this.temp = new int[size]; - } else { + } + else { for (Layer[] layers : layers.values()) { for (Layer layer : layers) { layer.invalidate(); 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 index 668215602..eea26fc79 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/VulkanModRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/VulkanModRenderer.java @@ -1,7 +1,6 @@ package net.vulkanmod.render.chunk.build.frapi; import com.mojang.blaze3d.vertex.PoseStack; -import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableMesh; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.render.BlockVertexConsumerProvider; @@ -14,6 +13,8 @@ import net.minecraft.client.renderer.block.model.BlockStateModel; import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.core.BlockPos; + +import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.RenderShape; @@ -28,49 +29,48 @@ * Fabric renderer implementation. */ public class VulkanModRenderer implements Renderer { - public static final VulkanModRenderer INSTANCE = new VulkanModRenderer(); + public static final VulkanModRenderer INSTANCE = new VulkanModRenderer(); - private VulkanModRenderer() { - } + private VulkanModRenderer() {} - @Override - public MutableMesh mutableMesh() { - return new MutableMeshImpl(); - } + @Override + public MutableMesh mutableMesh() { + return new MutableMeshImpl(); + } - @Override - public void render(ModelBlockRenderer modelBlockRenderer, BlockAndTintGetter blockAndTintGetter, - BlockStateModel blockStateModel, BlockState blockState, BlockPos blockPos, PoseStack poseStack, - BlockVertexConsumerProvider blockVertexConsumerProvider, boolean cull, long seed, int overlay) { - BlockRenderContext.POOL.get().render(blockAndTintGetter, blockStateModel, blockState, blockPos, poseStack, blockVertexConsumerProvider, cull, seed, overlay); - } + @Override + public void render(ModelBlockRenderer modelBlockRenderer, BlockAndTintGetter blockAndTintGetter, + BlockStateModel blockStateModel, BlockState blockState, BlockPos blockPos, PoseStack poseStack, + BlockVertexConsumerProvider blockVertexConsumerProvider, boolean cull, long seed, int overlay) { + BlockRenderContext.POOL.get().render(blockAndTintGetter, blockStateModel, blockState, blockPos, poseStack, blockVertexConsumerProvider, cull, seed, overlay); + } - @Override - public void render(PoseStack.Pose pose, BlockVertexConsumerProvider blockVertexConsumerProvider, BlockStateModel blockStateModel, - float v, float v1, float v2, int i, int i1, BlockAndTintGetter blockAndTintGetter, - BlockPos blockPos, BlockState blockState) { - SimpleBlockRenderContext.POOL.get().bufferModel(pose, blockVertexConsumerProvider, blockStateModel, v, v1, v2, i, i1, blockAndTintGetter, blockPos, blockState); - } + @Override + public void render(PoseStack.Pose pose, BlockVertexConsumerProvider blockVertexConsumerProvider, BlockStateModel blockStateModel, + float v, float v1, float v2, int i, int i1, BlockAndTintGetter blockAndTintGetter, + BlockPos blockPos, BlockState blockState) { + SimpleBlockRenderContext.POOL.get().bufferModel(pose, blockVertexConsumerProvider, blockStateModel, v, v1, v2, i, i1, blockAndTintGetter, blockPos, blockState); + } - @Override - public void renderBlockAsEntity(BlockRenderDispatcher blockRenderDispatcher, BlockState blockState, - PoseStack poseStack, MultiBufferSource multiBufferSource, int light, int overlay, - BlockAndTintGetter blockAndTintGetter, BlockPos pos) { - RenderShape blockRenderType = blockState.getRenderShape(); + @Override + public void renderBlockAsEntity(BlockRenderDispatcher blockRenderDispatcher, BlockState blockState, + PoseStack poseStack, MultiBufferSource multiBufferSource, int light, int overlay, + BlockAndTintGetter blockAndTintGetter, BlockPos pos) { + RenderShape blockRenderType = blockState.getRenderShape(); - if (blockRenderType != RenderShape.INVISIBLE) { - BlockStateModel model = blockRenderDispatcher.getBlockModel(blockState); - int tint = ((BlockRenderDispatcherAccessor) blockRenderDispatcher).getBlockColors().getColor(blockState, null, null, 0); - float red = (tint >> 16 & 255) / 255.0F; - float green = (tint >> 8 & 255) / 255.0F; - float blue = (tint & 255) / 255.0F; - FabricBlockModelRenderer.render(poseStack.last(), layer -> multiBufferSource.getBuffer(RenderLayerHelper.getEntityBlockLayer(layer)), model, red, green, blue, light, overlay, blockAndTintGetter, pos, blockState); + if (blockRenderType != RenderShape.INVISIBLE) { + BlockStateModel model = blockRenderDispatcher.getBlockModel(blockState); + int tint = ((BlockRenderDispatcherAccessor) blockRenderDispatcher).getBlockColors().getColor(blockState, null, null, 0); + float red = (tint >> 16 & 255) / 255.0F; + float green = (tint >> 8 & 255) / 255.0F; + float blue = (tint & 255) / 255.0F; + FabricBlockModelRenderer.render(poseStack.last(), layer -> multiBufferSource.getBuffer(RenderLayerHelper.getEntityBlockLayer(layer)), model, red, green, blue, light, overlay, blockAndTintGetter, pos, blockState); ((BlockRenderDispatcherAccessor) blockRenderDispatcher).getBlockEntityModelsGetter().get().renderByBlock(blockState.getBlock(), ItemDisplayContext.NONE, poseStack, Minecraft.getInstance().gameRenderer.getSubmitNodeStorage(), light, overlay, 0); - } - } + } + } - @Override - public QuadEmitter getLayerRenderStateEmitter(ItemStackRenderState.LayerRenderState layer) { - return ((AccessLayerRenderState) layer).getMutableMesh().emitter(); - } + @Override + public QuadEmitter getLayerRenderStateEmitter(ItemStackRenderState.LayerRenderState layer) { + return ((AccessLayerRenderState) layer).getMutableMesh().emitter(); + } } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessBatchingRenderCommandQueue.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessBatchingRenderCommandQueue.java index eed65f1b7..aa1b3f992 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessBatchingRenderCommandQueue.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessBatchingRenderCommandQueue.java @@ -6,5 +6,5 @@ import java.util.List; public interface AccessBatchingRenderCommandQueue { - List getMeshItemCommands(); + List getMeshItemCommands(); } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessChunkRendererRegion.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessChunkRendererRegion.java index 1dbf93086..a24048ae3 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessChunkRendererRegion.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessChunkRendererRegion.java @@ -23,7 +23,7 @@ * chunk rebuild, thus avoiding repeated thread-local lookups. */ public interface AccessChunkRendererRegion { - TerrainRenderContext fabric_getRenderer(); + TerrainRenderContext fabric_getRenderer(); - void fabric_setRenderer(TerrainRenderContext renderer); + void fabric_setRenderer(TerrainRenderContext renderer); } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessLayerRenderState.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessLayerRenderState.java index 870439ba5..f2d56f756 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessLayerRenderState.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessLayerRenderState.java @@ -20,5 +20,5 @@ import net.vulkanmod.render.chunk.build.frapi.mesh.MutableMeshImpl; public interface AccessLayerRenderState { - MutableMeshImpl getMutableMesh(); + MutableMeshImpl getMutableMesh(); } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessRenderCommandQueue.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessRenderCommandQueue.java index fc60db25a..5d958f088 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessRenderCommandQueue.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/accessor/AccessRenderCommandQueue.java @@ -7,8 +7,9 @@ import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.world.item.ItemDisplayContext; + import java.util.List; public interface AccessRenderCommandQueue { - void submitItem(PoseStack matrices, ItemDisplayContext displayContext, int light, int overlay, int outlineColors, int[] tintLayers, List quads, RenderType renderLayer, ItemStackRenderState.FoilType glintType, MeshView mesh); + void submitItem(PoseStack matrices, ItemDisplayContext displayContext, int light, int overlay, int outlineColors, int[] tintLayers, List quads, RenderType renderLayer, ItemStackRenderState.FoilType glintType, MeshView mesh); } 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 index 0af344de7..80003422e 100644 --- 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 @@ -24,60 +24,55 @@ * designed to be usable without the default renderer. */ public abstract class ColorHelper { - private static final boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - - private ColorHelper() { - } - - /** - * Component-wise max. - */ - public static int maxLight(int l0, int l1) { - if (l0 == 0) return l1; - if (l1 == 0) return l0; - - return Math.max(l0 & 0xFFFF, l1 & 0xFFFF) | Math.max(l0 & 0xFFFF0000, l1 & 0xFFFF0000); - } - - /** - * 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); - } + private ColorHelper() { } + + private static final boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + + /** + * Component-wise max. + */ + public static int maxLight(int l0, int l1) { + if (l0 == 0) return l1; + if (l1 == 0) return l0; + + return Math.max(l0 & 0xFFFF, l1 & 0xFFFF) | Math.max(l0 & 0xFFFF0000, l1 & 0xFFFF0000); + } + + /** 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) @@ -95,37 +90,37 @@ Vanilla color format (big endian): RGBA (0xRRGGBBAA) 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); - } - } + /** + * 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 index 2c32042df..fc68442cd 100644 --- 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 @@ -16,6 +16,8 @@ package net.vulkanmod.render.chunk.build.frapi.helper; +import static net.minecraft.util.Mth.equal; + import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.core.Direction; @@ -23,221 +25,215 @@ import net.minecraft.core.Direction.AxisDirection; import org.joml.Vector3fc; -import static net.minecraft.util.Mth.equal; - /** * 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 { - /** - * 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; - private GeometryHelper() { - } - - /** - * 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 Vector3fc 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(Vector3fc 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; - } + 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 Vector3fc 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(Vector3fc 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 index 46246fb83..8b8ebb1b0 100644 --- 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 @@ -16,14 +16,14 @@ package net.vulkanmod.render.chunk.build.frapi.helper; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; -import net.minecraft.core.Direction; -import net.minecraft.core.Vec3i; -import net.minecraft.util.Mth; 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. @@ -31,165 +31,165 @@ * designed to be usable without the default renderer. */ public abstract class NormalHelper { - private static final float PACK = 127.0f; - private static final float UNPACK = 1.0f / PACK; - private NormalHelper() { - } - - /** - * 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.getUnitVec3i(); - 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.getUnitVec3i(); - - 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)); - } + 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.getUnitVec3i(); + 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.getUnitVec3i(); + + 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 index 902b94747..bc622cd92 100644 --- 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 @@ -26,84 +26,85 @@ * itself to implement automatic block-breaking models for enhanced models. */ public class TextureHelper { - private static final float NORMALIZER = 1f / 16f; - 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)); - } - - private TextureHelper() { - } - - /** - * 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); - } - } - - private static void applyModifier(MutableQuadView quad, VertexModifier modifier) { - for (int i = 0; i < 4; i++) { - modifier.apply(quad, i); - } - } - - @FunctionalInterface - private interface VertexModifier { - void apply(MutableQuadView quad, int vertexIndex); - } + 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/mesh/EncodingFormat.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/EncodingFormat.java index 1c1039d37..a0de50146 100644 --- 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 @@ -19,17 +19,17 @@ import com.google.common.base.Preconditions; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.ShadeMode; -import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; import net.fabricmc.fabric.api.util.TriState; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.client.renderer.item.ItemStackRenderState; -import net.minecraft.core.Direction; -import net.minecraft.util.Mth; -import net.vulkanmod.render.chunk.build.frapi.helper.GeometryHelper; import org.apache.commons.lang3.ArrayUtils; 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.minecraft.core.Direction; +import net.minecraft.util.Mth; /** * Holds all the array offsets and bit-wise encoders/decoders for @@ -37,182 +37,187 @@ * All of this is implementation-specific - that's why it isn't a "helper" class. */ public final class EncodingFormat { - public static final int HEADER_STRIDE = 4; - 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 int HEADER_BITS = 0; - static final int HEADER_FACE_NORMAL = 1; - static final int HEADER_TINT_INDEX = 2; - static final int HEADER_TAG = 3; - 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; - 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_OFFSET = CULL_BIT_OFFSET + CULL_BIT_LENGTH; - private static final int CULL_MASK = bitMask(CULL_BIT_LENGTH, CULL_BIT_OFFSET); - private static final @Nullable ChunkSectionLayer[] NULLABLE_BLOCK_RENDER_LAYERS = ArrayUtils.add(ChunkSectionLayer.values(), null); - private static final int NULLABLE_BLOCK_RENDER_LAYER_COUNT = NULLABLE_BLOCK_RENDER_LAYERS.length; - private static final int NULL_RENDER_LAYER_INDEX = NULLABLE_BLOCK_RENDER_LAYER_COUNT - 1; - private static final int RENDER_LAYER_BIT_LENGTH = Mth.ceillog2(NULLABLE_BLOCK_RENDER_LAYER_COUNT); - private static final TriState[] TRI_STATES = TriState.values(); - private static final int TRI_STATE_COUNT = TRI_STATES.length; - private static final int AO_BIT_LENGTH = Mth.ceillog2(TRI_STATE_COUNT); - private static final @Nullable ItemStackRenderState.FoilType[] NULLABLE_GLINTS = ArrayUtils.add(ItemStackRenderState.FoilType.values(), null); - private static final int NULLABLE_GLINT_COUNT = NULLABLE_GLINTS.length; - private static final int NULL_GLINT_INDEX = NULLABLE_GLINT_COUNT - 1; - private static final int GLINT_BIT_LENGTH = Mth.ceillog2(NULLABLE_GLINT_COUNT); - private static final ShadeMode[] SHADE_MODES = ShadeMode.values(); - private static final int SHADE_MODE_COUNT = SHADE_MODES.length; - private static final int SHADE_MODE_BIT_LENGTH = Mth.ceillog2(SHADE_MODE_COUNT); - private static final int LIGHT_BIT_LENGTH = Mth.ceillog2(DIRECTION_COUNT); - 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 RENDER_LAYER_BIT_OFFSET = GEOMETRY_BIT_OFFSET + GEOMETRY_BIT_LENGTH; - private static final int EMISSIVE_BIT_OFFSET = RENDER_LAYER_BIT_OFFSET + RENDER_LAYER_BIT_LENGTH; - private static final int DIFFUSE_BIT_OFFSET = EMISSIVE_BIT_OFFSET + EMISSIVE_BIT_LENGTH; - private static final int AO_BIT_OFFSET = DIFFUSE_BIT_OFFSET + DIFFUSE_BIT_LENGTH; - private static final int GLINT_BIT_OFFSET = AO_BIT_OFFSET + AO_BIT_LENGTH; - private static final int SHADE_MODE_BIT_OFFSET = GLINT_BIT_OFFSET + GLINT_BIT_LENGTH; - private static final int TOTAL_BIT_LENGTH = SHADE_MODE_BIT_OFFSET + SHADE_MODE_BIT_LENGTH; - private static final int SHADE_MODE_MASK = bitMask(SHADE_MODE_BIT_LENGTH, SHADE_MODE_BIT_OFFSET); - private static final int GLINT_MASK = bitMask(GLINT_BIT_LENGTH, GLINT_BIT_OFFSET); - private static final int AO_MASK = bitMask(AO_BIT_LENGTH, AO_BIT_OFFSET); - private static final int DIFFUSE_MASK = bitMask(DIFFUSE_BIT_LENGTH, DIFFUSE_BIT_OFFSET); - private static final int EMISSIVE_MASK = bitMask(EMISSIVE_BIT_LENGTH, EMISSIVE_BIT_OFFSET); - private static final int RENDER_LAYER_MASK = bitMask(RENDER_LAYER_BIT_LENGTH, RENDER_LAYER_BIT_OFFSET); - private static final int GEOMETRY_MASK = bitMask(GEOMETRY_BIT_LENGTH, GEOMETRY_BIT_OFFSET); - private static final int NORMALS_MASK = bitMask(NORMALS_BIT_LENGTH, NORMALS_BIT_OFFSET); - private static final int LIGHT_MASK = bitMask(LIGHT_BIT_LENGTH, LIGHT_BIT_OFFSET); - private static final int NORMALS_BIT_LENGTH = 4; - private static final int GEOMETRY_BIT_LENGTH = GeometryHelper.FLAG_BIT_COUNT; - private static final int EMISSIVE_BIT_LENGTH = 1; - private static final int DIFFUSE_BIT_LENGTH = 1; - private static final int CULL_BIT_OFFSET = 0; - - static { - final VertexFormat format = DefaultVertexFormat.BLOCK; - VERTEX_X = HEADER_STRIDE; - 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); - } - - static { - Preconditions.checkArgument(TOTAL_BIT_LENGTH <= 32, "Indigo header encoding bit count (%s) exceeds integer bit length)", TOTAL_STRIDE); - } - - private EncodingFormat() { - } - - private 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); - } - - @Nullable - static ChunkSectionLayer renderLayer(int bits) { - return NULLABLE_BLOCK_RENDER_LAYERS[(bits & RENDER_LAYER_MASK) >>> RENDER_LAYER_BIT_OFFSET]; - } - - static int renderLayer(int bits, @Nullable ChunkSectionLayer renderLayer) { - int index = renderLayer == null ? NULL_RENDER_LAYER_INDEX : renderLayer.ordinal(); - return (bits & ~RENDER_LAYER_MASK) | (index << RENDER_LAYER_BIT_OFFSET); - } - - static boolean emissive(int bits) { - return (bits & EMISSIVE_MASK) != 0; - } - - static int emissive(int bits, boolean emissive) { - return emissive ? (bits | EMISSIVE_MASK) : (bits & ~EMISSIVE_MASK); - } - - static boolean diffuseShade(int bits) { - return (bits & DIFFUSE_MASK) != 0; - } - - static int diffuseShade(int bits, boolean shade) { - return shade ? (bits | DIFFUSE_MASK) : (bits & ~DIFFUSE_MASK); - } - - static TriState ambientOcclusion(int bits) { - return TRI_STATES[(bits & AO_MASK) >>> AO_BIT_OFFSET]; - } - - static int ambientOcclusion(int bits, TriState ao) { - return (bits & ~AO_MASK) | (ao.ordinal() << AO_BIT_OFFSET); - } - - @Nullable - static ItemStackRenderState.FoilType glint(int bits) { - return NULLABLE_GLINTS[(bits & GLINT_MASK) >>> GLINT_BIT_OFFSET]; - } - - static int glint(int bits, @Nullable ItemStackRenderState.FoilType glint) { - int index = glint == null ? NULL_GLINT_INDEX : glint.ordinal(); - return (bits & ~GLINT_MASK) | (index << GLINT_BIT_OFFSET); - } - - static ShadeMode shadeMode(int bits) { - return SHADE_MODES[(bits & SHADE_MODE_MASK) >>> SHADE_MODE_BIT_OFFSET]; - } - - static int shadeMode(int bits, ShadeMode mode) { - return (bits & ~SHADE_MODE_MASK) | (mode.ordinal() << SHADE_MODE_BIT_OFFSET); - } + private EncodingFormat() { } + + static final int HEADER_BITS = 0; + static final int HEADER_FACE_NORMAL = 1; + static final int HEADER_TINT_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); + } + + private static final int DIRECTION_COUNT = Direction.values().length; + private static final int NULLABLE_DIRECTION_COUNT = DIRECTION_COUNT + 1; + + private static final @Nullable ChunkSectionLayer[] NULLABLE_BLOCK_RENDER_LAYERS = ArrayUtils.add(ChunkSectionLayer.values(), null); + private static final int NULLABLE_BLOCK_RENDER_LAYER_COUNT = NULLABLE_BLOCK_RENDER_LAYERS.length; + private static final TriState[] TRI_STATES = TriState.values(); + private static final int TRI_STATE_COUNT = TRI_STATES.length; + private static final @Nullable ItemStackRenderState.FoilType[] NULLABLE_GLINTS = ArrayUtils.add(ItemStackRenderState.FoilType.values(), null); + private static final int NULLABLE_GLINT_COUNT = NULLABLE_GLINTS.length; + private static final ShadeMode[] SHADE_MODES = ShadeMode.values(); + private static final int SHADE_MODE_COUNT = SHADE_MODES.length; + + private static final int NULL_RENDER_LAYER_INDEX = NULLABLE_BLOCK_RENDER_LAYER_COUNT - 1; + private static final int NULL_GLINT_INDEX = NULLABLE_GLINT_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 RENDER_LAYER_BIT_LENGTH = Mth.ceillog2(NULLABLE_BLOCK_RENDER_LAYER_COUNT); + private static final int EMISSIVE_BIT_LENGTH = 1; + private static final int DIFFUSE_BIT_LENGTH = 1; + private static final int AO_BIT_LENGTH = Mth.ceillog2(TRI_STATE_COUNT); + private static final int GLINT_BIT_LENGTH = Mth.ceillog2(NULLABLE_GLINT_COUNT); + private static final int SHADE_MODE_BIT_LENGTH = Mth.ceillog2(SHADE_MODE_COUNT); + + 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 RENDER_LAYER_BIT_OFFSET = GEOMETRY_BIT_OFFSET + GEOMETRY_BIT_LENGTH; + private static final int EMISSIVE_BIT_OFFSET = RENDER_LAYER_BIT_OFFSET + RENDER_LAYER_BIT_LENGTH; + private static final int DIFFUSE_BIT_OFFSET = EMISSIVE_BIT_OFFSET + EMISSIVE_BIT_LENGTH; + private static final int AO_BIT_OFFSET = DIFFUSE_BIT_OFFSET + DIFFUSE_BIT_LENGTH; + private static final int GLINT_BIT_OFFSET = AO_BIT_OFFSET + AO_BIT_LENGTH; + private static final int SHADE_MODE_BIT_OFFSET = GLINT_BIT_OFFSET + GLINT_BIT_LENGTH; + private static final int TOTAL_BIT_LENGTH = SHADE_MODE_BIT_OFFSET + SHADE_MODE_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 RENDER_LAYER_MASK = bitMask(RENDER_LAYER_BIT_LENGTH, RENDER_LAYER_BIT_OFFSET); + private static final int EMISSIVE_MASK = bitMask(EMISSIVE_BIT_LENGTH, EMISSIVE_BIT_OFFSET); + private static final int DIFFUSE_MASK = bitMask(DIFFUSE_BIT_LENGTH, DIFFUSE_BIT_OFFSET); + private static final int AO_MASK = bitMask(AO_BIT_LENGTH, AO_BIT_OFFSET); + private static final int GLINT_MASK = bitMask(GLINT_BIT_LENGTH, GLINT_BIT_OFFSET); + private static final int SHADE_MODE_MASK = bitMask(SHADE_MODE_BIT_LENGTH, SHADE_MODE_BIT_OFFSET); + + static { + Preconditions.checkArgument(TOTAL_BIT_LENGTH <= 32, "Indigo header encoding bit count (%s) exceeds integer bit length)", TOTAL_STRIDE); + } + + private 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); + } + + @Nullable + static ChunkSectionLayer renderLayer(int bits) { + return NULLABLE_BLOCK_RENDER_LAYERS[(bits & RENDER_LAYER_MASK) >>> RENDER_LAYER_BIT_OFFSET]; + } + + static int renderLayer(int bits, @Nullable ChunkSectionLayer renderLayer) { + int index = renderLayer == null ? NULL_RENDER_LAYER_INDEX : renderLayer.ordinal(); + return (bits & ~RENDER_LAYER_MASK) | (index << RENDER_LAYER_BIT_OFFSET); + } + + static boolean emissive(int bits) { + return (bits & EMISSIVE_MASK) != 0; + } + + static int emissive(int bits, boolean emissive) { + return emissive ? (bits | EMISSIVE_MASK) : (bits & ~EMISSIVE_MASK); + } + + static boolean diffuseShade(int bits) { + return (bits & DIFFUSE_MASK) != 0; + } + + static int diffuseShade(int bits, boolean shade) { + return shade ? (bits | DIFFUSE_MASK) : (bits & ~DIFFUSE_MASK); + } + + static TriState ambientOcclusion(int bits) { + return TRI_STATES[(bits & AO_MASK) >>> AO_BIT_OFFSET]; + } + + static int ambientOcclusion(int bits, TriState ao) { + return (bits & ~AO_MASK) | (ao.ordinal() << AO_BIT_OFFSET); + } + + @Nullable + static ItemStackRenderState.FoilType glint(int bits) { + return NULLABLE_GLINTS[(bits & GLINT_MASK) >>> GLINT_BIT_OFFSET]; + } + + static int glint(int bits, @Nullable ItemStackRenderState.FoilType glint) { + int index = glint == null ? NULL_GLINT_INDEX : glint.ordinal(); + return (bits & ~GLINT_MASK) | (index << GLINT_BIT_OFFSET); + } + + static ShadeMode shadeMode(int bits) { + return SHADE_MODES[(bits & SHADE_MODE_MASK) >>> SHADE_MODE_BIT_OFFSET]; + } + + static int shadeMode(int bits, ShadeMode mode) { + return (bits & ~SHADE_MODE_MASK) | (mode.ordinal() << SHADE_MODE_BIT_OFFSET); + } } 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 index ca5a9e520..834f867b8 100644 --- 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 @@ -16,88 +16,87 @@ package net.vulkanmod.render.chunk.build.frapi.mesh; +import java.util.function.Consumer; + import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.jetbrains.annotations.Range; + 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; -import org.jetbrains.annotations.Range; - -import java.util.function.Consumer; public class MeshImpl implements Mesh { - /** - * Used to satisfy external calls to {@link #forEach(Consumer)}. - */ - private static final ThreadLocal> CURSOR_POOLS = ThreadLocal.withInitial(ObjectArrayList::new); - - int[] data; - int limit; - - MeshImpl(int[] data) { - this.data = data; - limit = data.length; - } - - MeshImpl() { - } - - @Override - @Range(from = 0, to = Integer.MAX_VALUE) - public int size() { - return limit / EncodingFormat.TOTAL_STRIDE; - } - - @Override - public void forEach(Consumer action) { - ObjectArrayList pool = CURSOR_POOLS.get(); - QuadViewImpl cursor; - - if (pool.isEmpty()) { - cursor = new QuadViewImpl(); - } else { - cursor = pool.pop(); - } - - forEach(action, cursor); - - pool.push(cursor); - } - - /** - * The renderer can call this with its own cursor to avoid the performance hit of a - * thread-local lookup or to use a mutable cursor. - */ - void forEach(Consumer action, C cursor) { - final int limit = this.limit; - int index = 0; - cursor.data = data; - - while (index < limit) { - cursor.baseIndex = index; - cursor.load(); - action.accept(cursor); - index += EncodingFormat.TOTAL_STRIDE; - } - - cursor.data = null; - } - - // TODO: This could be optimized by checking if the emitter is that of a MutableMeshImpl and if - // it has no transforms, in which case the entire data array can be copied in bulk. - @Override - public void outputTo(QuadEmitter emitter) { - MutableQuadViewImpl e = (MutableQuadViewImpl) emitter; - final int[] data = this.data; - final int limit = this.limit; - int index = 0; - - while (index < limit) { - System.arraycopy(data, index, e.data, e.baseIndex, EncodingFormat.TOTAL_STRIDE); - e.load(); - e.transformAndEmit(); - index += EncodingFormat.TOTAL_STRIDE; - } - - e.clear(); - } + /** Used to satisfy external calls to {@link #forEach(Consumer)}. */ + private static final ThreadLocal> CURSOR_POOLS = ThreadLocal.withInitial(ObjectArrayList::new); + + int[] data; + int limit; + + MeshImpl(int[] data) { + this.data = data; + limit = data.length; + } + + MeshImpl() { + } + + @Override + @Range(from = 0, to = Integer.MAX_VALUE) + public int size() { + return limit / EncodingFormat.TOTAL_STRIDE; + } + + @Override + public void forEach(Consumer action) { + ObjectArrayList pool = CURSOR_POOLS.get(); + QuadViewImpl cursor; + + if (pool.isEmpty()) { + cursor = new QuadViewImpl(); + } else { + cursor = pool.pop(); + } + + forEach(action, cursor); + + pool.push(cursor); + } + + /** + * The renderer can call this with its own cursor to avoid the performance hit of a + * thread-local lookup or to use a mutable cursor. + */ + void forEach(Consumer action, C cursor) { + final int limit = this.limit; + int index = 0; + cursor.data = data; + + while (index < limit) { + cursor.baseIndex = index; + cursor.load(); + action.accept(cursor); + index += EncodingFormat.TOTAL_STRIDE; + } + + cursor.data = null; + } + + // TODO: This could be optimized by checking if the emitter is that of a MutableMeshImpl and if + // it has no transforms, in which case the entire data array can be copied in bulk. + @Override + public void outputTo(QuadEmitter emitter) { + MutableQuadViewImpl e = (MutableQuadViewImpl) emitter; + final int[] data = this.data; + final int limit = this.limit; + int index = 0; + + while (index < limit) { + System.arraycopy(data, index, e.data, e.baseIndex, EncodingFormat.TOTAL_STRIDE); + e.load(); + e.transformAndEmit(); + index += EncodingFormat.TOTAL_STRIDE; + } + + e.clear(); + } } \ No newline at end of file diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableMeshImpl.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableMeshImpl.java index 32c492279..79ab94df6 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableMeshImpl.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/mesh/MutableMeshImpl.java @@ -16,13 +16,13 @@ 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.MutableMesh; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; -import java.util.function.Consumer; - /** * Our implementation of {@link MutableMesh}, mainly used for optimized mesh creation. * Not much to it - mainly it just needs to grow the int[] array as quads are appended @@ -31,15 +31,7 @@ * The one interesting bit is in {@link #emitter}. */ public class MutableMeshImpl extends MeshImpl implements MutableMesh { - public MutableMeshImpl() { - data = new int[8 * EncodingFormat.TOTAL_STRIDE]; - limit = 0; - - ensureCapacity(EncodingFormat.TOTAL_STRIDE); - emitter.data = data; - emitter.baseIndex = limit; - emitter.clear(); - } private final MutableQuadViewImpl emitter = new MutableQuadViewImpl() { + private final MutableQuadViewImpl emitter = new MutableQuadViewImpl() { @Override protected void emitDirectly() { // Necessary because the validity of geometry is not encoded; reading mesh data always @@ -52,6 +44,16 @@ protected void emitDirectly() { } }; + public MutableMeshImpl() { + data = new int[8 * EncodingFormat.TOTAL_STRIDE]; + limit = 0; + + ensureCapacity(EncodingFormat.TOTAL_STRIDE); + emitter.data = data; + emitter.baseIndex = limit; + emitter.clear(); + } + private void ensureCapacity(int stride) { if (stride > data.length - limit) { final int[] bigger = new int[data.length * 2]; @@ -88,6 +90,4 @@ public void clear() { emitter.baseIndex = limit; emitter.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 index 0dbf73398..215db6398 100644 --- 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 @@ -17,22 +17,22 @@ package net.vulkanmod.render.chunk.build.frapi.mesh; import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadTransform; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.ShadeMode; import net.fabricmc.fabric.api.util.TriState; import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.core.Direction; +import net.vulkanmod.render.model.quad.ModelQuadView; +import org.jetbrains.annotations.Nullable; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadTransform; +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.model.quad.ModelQuadView; -import org.jetbrains.annotations.Nullable; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.core.Direction; import java.util.Objects; @@ -49,301 +49,301 @@ * numbers. It also allows for a consistent interface for those transformations. */ public abstract class MutableQuadViewImpl extends QuadViewImpl implements QuadEmitter { - private static final QuadTransform NO_TRANSFORM = q -> true; - - private static final int[] DEFAULT_QUAD_DATA = new int[EncodingFormat.TOTAL_STRIDE]; - - static { - MutableQuadViewImpl quad = new MutableQuadViewImpl() { - @Override - protected void emitDirectly() { - // This quad won't be emitted. It's only used to configure the default quad data. - } - }; - - // Start with all zeroes - quad.data = DEFAULT_QUAD_DATA; - // Apply non-zero defaults - quad.color(-1, -1, -1, -1); - quad.cullFace(null); - quad.renderLayer(null); - quad.diffuseShade(true); - quad.ambientOcclusion(TriState.DEFAULT); - quad.glint(null); - quad.tintIndex(-1); - quad.tintIndex(-1); - } - - 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; - }; - protected boolean hasTransform = false; - private QuadTransform activeTransform = NO_TRANSFORM; - - public final void clear() { - System.arraycopy(DEFAULT_QUAD_DATA, 0, data, baseIndex, EncodingFormat.TOTAL_STRIDE); - isGeometryInvalid = true; - nominalFace = null; - } - - @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 nominalFace(@Nullable Direction face) { - nominalFace = face; - return this; - } - - @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 MutableQuadViewImpl renderLayer(@Nullable ChunkSectionLayer renderLayer) { - data[baseIndex + HEADER_BITS] = EncodingFormat.renderLayer(data[baseIndex + HEADER_BITS], renderLayer); - return this; - } - - @Override - public MutableQuadViewImpl emissive(boolean emissive) { - data[baseIndex + HEADER_BITS] = EncodingFormat.emissive(data[baseIndex + HEADER_BITS], emissive); - return this; - } - - @Override - public MutableQuadViewImpl diffuseShade(boolean shade) { - data[baseIndex + HEADER_BITS] = EncodingFormat.diffuseShade(data[baseIndex + HEADER_BITS], shade); - return this; - } - - @Override - public MutableQuadViewImpl ambientOcclusion(TriState ao) { - Objects.requireNonNull(ao, "ambient occlusion TriState may not be null"); - data[baseIndex + HEADER_BITS] = EncodingFormat.ambientOcclusion(data[baseIndex + HEADER_BITS], ao); - return this; - } - - @Override - public MutableQuadViewImpl glint(@Nullable ItemStackRenderState.FoilType glint) { - data[baseIndex + HEADER_BITS] = EncodingFormat.glint(data[baseIndex + HEADER_BITS], glint); - return this; - } - - @Override - public MutableQuadViewImpl shadeMode(ShadeMode mode) { - Objects.requireNonNull(mode, "ShadeMode may not be null"); - data[baseIndex + HEADER_BITS] = EncodingFormat.shadeMode(data[baseIndex + HEADER_BITS], mode); - return this; - } - - @Override - public final MutableQuadViewImpl tintIndex(int tintIndex) { - data[baseIndex + HEADER_TINT_INDEX] = tintIndex; - 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; - System.arraycopy(q.data, q.baseIndex, data, baseIndex, EncodingFormat.TOTAL_STRIDE); - nominalFace = q.nominalFace; - isGeometryInvalid = q.isGeometryInvalid; - - if (!isGeometryInvalid) { - faceNormal.set(q.faceNormal); - } - - 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 normalFlags = 0; - int colorIndex = baseIndex + VERTEX_COLOR; - int normalIndex = baseIndex + VERTEX_NORMAL; - - for (int i = 0; i < 4; i++) { - data[colorIndex] = ColorHelper.fromVanillaColor(data[colorIndex]); - - // Set normal flag if normal is not zero, ignoring W component - if ((data[normalIndex] & 0xFFFFFF) != 0) { - normalFlags |= 1 << i; - } - - colorIndex += VERTEX_STRIDE; - normalIndex += VERTEX_STRIDE; - } - - normalFlags(normalFlags); - return this; - } - - @Override - public final MutableQuadViewImpl fromBakedQuad(BakedQuad quad) { - fromVanilla(quad.vertices(), 0); + private static final QuadTransform NO_TRANSFORM = q -> true; + + private static final int[] DEFAULT_QUAD_DATA = new int[EncodingFormat.TOTAL_STRIDE]; + + static { + MutableQuadViewImpl quad = new MutableQuadViewImpl() { + @Override + protected void emitDirectly() { + // This quad won't be emitted. It's only used to configure the default quad data. + } + }; + + // Start with all zeroes + quad.data = DEFAULT_QUAD_DATA; + // Apply non-zero defaults + quad.color(-1, -1, -1, -1); + quad.cullFace(null); + quad.renderLayer(null); + quad.diffuseShade(true); + quad.ambientOcclusion(TriState.DEFAULT); + quad.glint(null); + quad.tintIndex(-1); + quad.tintIndex(-1); + } + + protected boolean hasTransform = false; + 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; + }; + + public final void clear() { + System.arraycopy(DEFAULT_QUAD_DATA, 0, data, baseIndex, EncodingFormat.TOTAL_STRIDE); + isGeometryInvalid = true; + nominalFace = null; + } + + @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 nominalFace(@Nullable Direction face) { + nominalFace = face; + return this; + } + + @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 MutableQuadViewImpl renderLayer(@Nullable ChunkSectionLayer renderLayer) { + data[baseIndex + HEADER_BITS] = EncodingFormat.renderLayer(data[baseIndex + HEADER_BITS], renderLayer); + return this; + } + + @Override + public MutableQuadViewImpl emissive(boolean emissive) { + data[baseIndex + HEADER_BITS] = EncodingFormat.emissive(data[baseIndex + HEADER_BITS], emissive); + return this; + } + + @Override + public MutableQuadViewImpl diffuseShade(boolean shade) { + data[baseIndex + HEADER_BITS] = EncodingFormat.diffuseShade(data[baseIndex + HEADER_BITS], shade); + return this; + } + + @Override + public MutableQuadViewImpl ambientOcclusion(TriState ao) { + Objects.requireNonNull(ao, "ambient occlusion TriState may not be null"); + data[baseIndex + HEADER_BITS] = EncodingFormat.ambientOcclusion(data[baseIndex + HEADER_BITS], ao); + return this; + } + + @Override + public MutableQuadViewImpl glint(@Nullable ItemStackRenderState.FoilType glint) { + data[baseIndex + HEADER_BITS] = EncodingFormat.glint(data[baseIndex + HEADER_BITS], glint); + return this; + } + + @Override + public MutableQuadViewImpl shadeMode(ShadeMode mode) { + Objects.requireNonNull(mode, "ShadeMode may not be null"); + data[baseIndex + HEADER_BITS] = EncodingFormat.shadeMode(data[baseIndex + HEADER_BITS], mode); + return this; + } + + @Override + public final MutableQuadViewImpl tintIndex(int tintIndex) { + data[baseIndex + HEADER_TINT_INDEX] = tintIndex; + 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; + System.arraycopy(q.data, q.baseIndex, data, baseIndex, EncodingFormat.TOTAL_STRIDE); + nominalFace = q.nominalFace; + isGeometryInvalid = q.isGeometryInvalid; + + if (!isGeometryInvalid) { + faceNormal.set(q.faceNormal); + } + + 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 normalFlags = 0; + int colorIndex = baseIndex + VERTEX_COLOR; + int normalIndex = baseIndex + VERTEX_NORMAL; + + for (int i = 0; i < 4; i++) { + data[colorIndex] = ColorHelper.fromVanillaColor(data[colorIndex]); + + // Set normal flag if normal is not zero, ignoring W component + if ((data[normalIndex] & 0xFFFFFF) != 0) { + normalFlags |= 1 << i; + } + + colorIndex += VERTEX_STRIDE; + normalIndex += VERTEX_STRIDE; + } + + normalFlags(normalFlags); + return this; + } + + @Override + public final MutableQuadViewImpl fromBakedQuad(BakedQuad quad) { + fromVanilla(quad.vertices(), 0); // data[baseIndex + HEADER_BITS] = EncodingFormat.cullFace(0, cullFace); - nominalFace(quad.direction()); - diffuseShade(quad.shade()); - tintIndex(quad.tintIndex()); + nominalFace(quad.direction()); + diffuseShade(quad.shade()); + tintIndex(quad.tintIndex()); // tag(0); - // Copy data from BakedQuad instead of calculating properties + // Copy data from BakedQuad instead of calculating properties ModelQuadView quadView = (ModelQuadView) (Object) 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; - - int lightEmission = quad.lightEmission(); - - if (lightEmission > 0) { - for (int i = 0; i < 4; i++) { - lightmap(i, LightTexture.lightCoordsWithEmission(lightmap(i), lightEmission)); - } - } - - return this; - } - - @Override - public void pushTransform(QuadTransform transform) { - if (transform == null) { - throw new NullPointerException("QuadTransform cannot be null!"); - } - - transformStack.push(transform); - hasTransform = true; - - 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; - hasTransform = false; - } else if (transformStack.size() == 1) { - activeTransform = transformStack.get(0); - } - } - - /** - * Emit the quad without applying transforms and without clearing the underlying data. - * Geometry is not guaranteed to be valid when called, but can be computed by calling {@link #computeGeometry()}. - */ - protected abstract void emitDirectly(); - - /** - * Apply transforms and then if transforms return true, emit the quad without clearing the underlying data. - */ - public final void transformAndEmit() { - if (activeTransform.transform(this)) { - emitDirectly(); - } - } - - @Override - public final MutableQuadViewImpl emit() { - transformAndEmit(); - clear(); - return this; - } + 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; + + int lightEmission = quad.lightEmission(); + + if (lightEmission > 0) { + for (int i = 0; i < 4; i++) { + lightmap(i, LightTexture.lightCoordsWithEmission(lightmap(i), lightEmission)); + } + } + + return this; + } + + @Override + public void pushTransform(QuadTransform transform) { + if (transform == null) { + throw new NullPointerException("QuadTransform cannot be null!"); + } + + transformStack.push(transform); + hasTransform = true; + + 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; + hasTransform = false; + } else if (transformStack.size() == 1) { + activeTransform = transformStack.get(0); + } + } + + /** + * Emit the quad without applying transforms and without clearing the underlying data. + * Geometry is not guaranteed to be valid when called, but can be computed by calling {@link #computeGeometry()}. + */ + protected abstract void emitDirectly(); + + /** + * Apply transforms and then if transforms return true, emit the quad without clearing the underlying data. + */ + public final void transformAndEmit() { + if (activeTransform.transform(this)) { + emitDirectly(); + } + } + + @Override + public final MutableQuadViewImpl emit() { + transformAndEmit(); + clear(); + return this; + } } \ No newline at end of file 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 index f6203f5c0..723e80792 100644 --- 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 @@ -16,15 +16,26 @@ package net.vulkanmod.render.chunk.build.frapi.mesh; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.HEADER_BITS; +import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.HEADER_TINT_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.fabricmc.fabric.api.renderer.v1.mesh.ShadeMode; import net.fabricmc.fabric.api.util.TriState; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.client.renderer.item.ItemStackRenderState; -import net.minecraft.core.Direction; -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.cull.QuadFacing; import net.vulkanmod.render.model.quad.ModelQuadFlags; import net.vulkanmod.render.model.quad.ModelQuadView; @@ -32,326 +43,318 @@ import org.jetbrains.annotations.Nullable; import org.joml.Vector2f; import org.joml.Vector3f; - -import static net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat.*; +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.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 { - protected final Vector3f faceNormal = new Vector3f(); - @Nullable - protected Direction nominalFace; - /** - * True when face normal, light face, or geometry flags may not match geometry. - */ - protected boolean isGeometryInvalid = true; - /** - * 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]); - } - - @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 final int normalFlags() { - return EncodingFormat.normalFlags(data[baseIndex + HEADER_BITS]); - } - - @Override - public final boolean hasNormal(int vertexIndex) { - return (normalFlags() & (1 << vertexIndex)) != 0; - } - - /** - * True if any vertex normal has been set. - */ - public final boolean hasVertexNormals() { - return normalFlags() != 0; - } - - /** - * True if all vertex normals have been set. - */ - public final boolean hasAllVertexNormals() { - return (normalFlags() & 0b1111) == 0b1111; - } - - protected final int normalIndex(int vertexIndex) { - return baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_NORMAL; - } - - @Override - public final float normalX(int vertexIndex) { - return hasNormal(vertexIndex) ? NormalHelper.unpackNormalX(data[normalIndex(vertexIndex)]) : Float.NaN; - } - - @Override - public final float normalY(int vertexIndex) { - return hasNormal(vertexIndex) ? NormalHelper.unpackNormalY(data[normalIndex(vertexIndex)]) : Float.NaN; - } - - @Override - public final float normalZ(int vertexIndex) { - return hasNormal(vertexIndex) ? NormalHelper.unpackNormalZ(data[normalIndex(vertexIndex)]) : Float.NaN; - } - - @Override - @Nullable - public final 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 - @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 - @Nullable - public final Direction cullFace() { - return EncodingFormat.cullFace(data[baseIndex + HEADER_BITS]); - } - - @Override - @Nullable - public ChunkSectionLayer renderLayer() { - return EncodingFormat.renderLayer(data[baseIndex + HEADER_BITS]); - } - - @Override - public boolean emissive() { - return EncodingFormat.emissive(data[baseIndex + HEADER_BITS]); - } - - @Override - public boolean diffuseShade() { - return EncodingFormat.diffuseShade(data[baseIndex + HEADER_BITS]); - } - - @Override - public TriState ambientOcclusion() { - return EncodingFormat.ambientOcclusion(data[baseIndex + HEADER_BITS]); - } - - @Override - @Nullable - public ItemStackRenderState.FoilType glint() { - return EncodingFormat.glint(data[baseIndex + HEADER_BITS]); - } - - @Override - public ShadeMode shadeMode() { - return EncodingFormat.shadeMode(data[baseIndex + HEADER_BITS]); - } - - @Override - public final int tintIndex() { - return data[baseIndex + HEADER_TINT_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); - - int colorIndex = targetIndex + VERTEX_COLOR - HEADER_STRIDE; - - 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.tintIndex(); - } - - @Override - public Direction getFacingDirection() { - return this.lightFace(); - } - - @Override - public int getNormal() { - return packedFaceNormal(); - } - - @Override - public QuadFacing getQuadFacing() { - return this.facing; - } + @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]); + } + + @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 final int normalFlags() { + return EncodingFormat.normalFlags(data[baseIndex + HEADER_BITS]); + } + + @Override + public final boolean hasNormal(int vertexIndex) { + return (normalFlags() & (1 << vertexIndex)) != 0; + } + + /** True if any vertex normal has been set. */ + public final boolean hasVertexNormals() { + return normalFlags() != 0; + } + + /** True if all vertex normals have been set. */ + public final boolean hasAllVertexNormals() { + return (normalFlags() & 0b1111) == 0b1111; + } + + protected final int normalIndex(int vertexIndex) { + return baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_NORMAL; + } + + @Override + public final float normalX(int vertexIndex) { + return hasNormal(vertexIndex) ? NormalHelper.unpackNormalX(data[normalIndex(vertexIndex)]) : Float.NaN; + } + + @Override + public final float normalY(int vertexIndex) { + return hasNormal(vertexIndex) ? NormalHelper.unpackNormalY(data[normalIndex(vertexIndex)]) : Float.NaN; + } + + @Override + public final float normalZ(int vertexIndex) { + return hasNormal(vertexIndex) ? NormalHelper.unpackNormalZ(data[normalIndex(vertexIndex)]) : Float.NaN; + } + + @Override + @Nullable + public final 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 + @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 + @Nullable + public final Direction cullFace() { + return EncodingFormat.cullFace(data[baseIndex + HEADER_BITS]); + } + + @Override + @Nullable + public ChunkSectionLayer renderLayer() { + return EncodingFormat.renderLayer(data[baseIndex + HEADER_BITS]); + } + + @Override + public boolean emissive() { + return EncodingFormat.emissive(data[baseIndex + HEADER_BITS]); + } + + @Override + public boolean diffuseShade() { + return EncodingFormat.diffuseShade(data[baseIndex + HEADER_BITS]); + } + + @Override + public TriState ambientOcclusion() { + return EncodingFormat.ambientOcclusion(data[baseIndex + HEADER_BITS]); + } + + @Override + @Nullable + public ItemStackRenderState.FoilType glint() { + return EncodingFormat.glint(data[baseIndex + HEADER_BITS]); + } + + @Override + public ShadeMode shadeMode() { + return EncodingFormat.shadeMode(data[baseIndex + HEADER_BITS]); + } + + @Override + public final int tintIndex() { + return data[baseIndex + HEADER_TINT_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); + + int colorIndex = targetIndex + VERTEX_COLOR - HEADER_STRIDE; + + 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.tintIndex(); + } + + @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 index dd0cce20a..9750c2f47 100644 --- 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 @@ -9,65 +9,49 @@ import net.minecraft.client.color.block.BlockColor; import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.renderer.ItemBlockRenderTypes; -import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BlockModelPart; import net.minecraft.client.renderer.block.model.BlockStateModel; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.state.BlockState; 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.frapi.VulkanModRenderer; -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.vulkanmod.render.chunk.build.light.LightPipeline; import net.vulkanmod.render.chunk.build.light.data.QuadLightData; import org.jetbrains.annotations.Nullable; +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.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.state.BlockState; import java.util.List; import java.util.function.Predicate; import java.util.function.Supplier; public abstract class AbstractBlockRenderContext extends AbstractRenderContext { - private static final Renderer RENDERER = VulkanModRenderer.INSTANCE; - - protected final BlockColorRegistry blockColorRegistry; - protected final Object2ByteLinkedOpenHashMap occlusionCache = new Object2ByteLinkedOpenHashMap<>(2048, 0.25F) { - protected void rehash(int i) { - } - }; - protected final QuadLightData quadLightData = new QuadLightData(); - protected BlockState blockState; - protected BlockPos blockPos; - protected BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos(); - protected ChunkSectionLayer defaultLayer; - protected BlockAndTintGetter renderRegion; - protected LightPipeline smoothLightPipeline; - protected LightPipeline flatLightPipeline; - protected boolean useAO; - protected boolean defaultAO; - protected RandomSource random; - protected boolean enableCulling = true; - protected int cullCompletionFlags; - protected int cullResultFlags; - private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { - { - data = new int[EncodingFormat.TOTAL_STRIDE]; - clear(); - } - - @Override - public void emitDirectly() { - renderQuad(this); - } + private static final Renderer RENDERER = VulkanModRenderer.INSTANCE; + + protected final BlockColorRegistry blockColorRegistry; + + private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { + { + data = new int[EncodingFormat.TOTAL_STRIDE]; + clear(); + } + + @Override + public void emitDirectly() { + renderQuad(this); + } // @Override // public void emitBlockQuads(QuadEmitter emitter, BakedModel model, BlockState state, @@ -78,210 +62,234 @@ public void emitDirectly() { // AbstractBlockRenderContext.this.emitVanillaBlockQuads(model, state, randomSupplier, cullTest); // } // } - }; + }; + + protected BlockState blockState; + protected BlockPos blockPos; + protected BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos(); + protected ChunkSectionLayer defaultLayer; + + protected BlockAndTintGetter renderRegion; - protected AbstractBlockRenderContext() { - this.occlusionCache.defaultReturnValue((byte) 127); + protected final Object2ByteLinkedOpenHashMap occlusionCache = new Object2ByteLinkedOpenHashMap<>(2048, 0.25F) { + protected void rehash(int i) { + } + }; - BlockColors blockColors = Minecraft.getInstance().getBlockColors(); - this.blockColorRegistry = BlockColorsExtended.from(blockColors).getColorResolverMap(); - } + protected final QuadLightData quadLightData = new QuadLightData(); + protected LightPipeline smoothLightPipeline; + protected LightPipeline flatLightPipeline; - protected void setupLightPipelines(LightPipeline flatLightPipeline, LightPipeline smoothLightPipeline) { - this.flatLightPipeline = flatLightPipeline; - this.smoothLightPipeline = smoothLightPipeline; - } + protected boolean useAO; + protected boolean defaultAO; - public void prepareForWorld(BlockAndTintGetter blockView, boolean enableCulling) { - this.renderRegion = blockView; - this.enableCulling = enableCulling; - } + protected RandomSource random; - public void prepareForBlock(BlockState blockState, BlockPos blockPos, boolean modelAo) { - this.blockPos = blockPos; - this.blockState = blockState; - this.defaultLayer = ItemBlockRenderTypes.getChunkRenderType(blockState); + protected boolean enableCulling = true; + protected int cullCompletionFlags; + protected int cullResultFlags; - this.useAO = Minecraft.useAmbientOcclusion(); - this.defaultAO = this.useAO && modelAo && blockState.getLightEmission() == 0; + protected AbstractBlockRenderContext() { + this.occlusionCache.defaultReturnValue((byte) 127); - this.cullCompletionFlags = 0; - this.cullResultFlags = 0; - } + BlockColors blockColors = Minecraft.getInstance().getBlockColors(); + this.blockColorRegistry = BlockColorsExtended.from(blockColors).getColorResolverMap(); + } - public boolean isFaceCulled(@Nullable Direction face) { - return !this.shouldRenderFace(face); - } + protected void setupLightPipelines(LightPipeline flatLightPipeline, LightPipeline smoothLightPipeline) { + this.flatLightPipeline = flatLightPipeline; + this.smoothLightPipeline = smoothLightPipeline; + } - public boolean shouldRenderFace(Direction face) { - if (face == null || !enableCulling) { - return true; - } + public void prepareForWorld(BlockAndTintGetter blockView, boolean enableCulling) { + this.renderRegion = blockView; + this.enableCulling = enableCulling; + } - final int mask = 1 << face.get3DDataValue(); + public void prepareForBlock(BlockState blockState, BlockPos blockPos, boolean modelAo) { + this.blockPos = blockPos; + this.blockState = blockState; + this.defaultLayer = ItemBlockRenderTypes.getChunkRenderType(blockState); - if ((cullCompletionFlags & mask) == 0) { - cullCompletionFlags |= mask; + this.useAO = Minecraft.useAmbientOcclusion(); + this.defaultAO = this.useAO && modelAo && blockState.getLightEmission() == 0; - if (this.faceNotOccluded(blockState, face)) { - cullResultFlags |= mask; - return true; - } else { - return false; - } - } else { - return (cullResultFlags & mask) != 0; - } - } + this.cullCompletionFlags = 0; + this.cullResultFlags = 0; + } - public boolean faceNotOccluded(BlockState blockState, Direction face) { - BlockGetter blockGetter = this.renderRegion; + public boolean isFaceCulled(@Nullable Direction face) { + return !this.shouldRenderFace(face); + } - BlockPos adjPos = tempPos.setWithOffset(blockPos, face); - BlockState adjBlockState = blockGetter.getBlockState(adjPos); + public boolean shouldRenderFace(Direction face) { + if (face == null || !enableCulling) { + return true; + } - if (blockState.skipRendering(adjBlockState, face)) { - return false; - } + final int mask = 1 << face.get3DDataValue(); - if (adjBlockState.canOcclude()) { - VoxelShape shape = blockState.getFaceOcclusionShape(face); + if ((cullCompletionFlags & mask) == 0) { + cullCompletionFlags |= mask; - if (shape.isEmpty()) - return true; + if (this.faceNotOccluded(blockState, face)) { + cullResultFlags |= mask; + return true; + } else { + return false; + } + } else { + return (cullResultFlags & mask) != 0; + } + } - VoxelShape adjShape = adjBlockState.getFaceOcclusionShape(face.getOpposite()); + public boolean faceNotOccluded(BlockState blockState, Direction face) { + BlockGetter blockGetter = this.renderRegion; - if (adjShape.isEmpty()) - return true; + BlockPos adjPos = tempPos.setWithOffset(blockPos, face); + BlockState adjBlockState = blockGetter.getBlockState(adjPos); - if (shape == Shapes.block() && adjShape == Shapes.block()) { - return false; - } + if (blockState.skipRendering(adjBlockState, face)) { + return false; + } - ShapePairKey blockStatePairKey = new ShapePairKey(shape, adjShape); + if (adjBlockState.canOcclude()) { + VoxelShape shape = blockState.getFaceOcclusionShape(face); - byte b = occlusionCache.getAndMoveToFirst(blockStatePairKey); - if (b != 127) { - return b != 0; - } else { - boolean bl = Shapes.joinIsNotEmpty(shape, adjShape, BooleanOp.ONLY_FIRST); + if (shape.isEmpty()) + return true; - if (occlusionCache.size() == 2048) { - occlusionCache.removeLastByte(); - } + VoxelShape adjShape = adjBlockState.getFaceOcclusionShape(face.getOpposite()); - occlusionCache.putAndMoveToFirst(blockStatePairKey, (byte) (bl ? 1 : 0)); - return bl; - } - } + if (adjShape.isEmpty()) + return true; - return true; - } + if (shape == Shapes.block() && adjShape == Shapes.block()) { + return false; + } - public QuadEmitter getEmitter() { - editorQuad.clear(); - return editorQuad; - } + ShapePairKey blockStatePairKey = new ShapePairKey(shape, adjShape); - @Override - protected void bufferQuad(MutableQuadViewImpl quadView) { - this.renderQuad(quadView); - } + byte b = occlusionCache.getAndMoveToFirst(blockStatePairKey); + if (b != 127) { + return b != 0; + } else { + boolean bl = Shapes.joinIsNotEmpty(shape, adjShape, BooleanOp.ONLY_FIRST); - protected abstract VertexConsumer getVertexConsumer(ChunkSectionLayer layer); + if (occlusionCache.size() == 2048) { + occlusionCache.removeLastByte(); + } - private void renderQuad(MutableQuadViewImpl quad) { - if (isFaceCulled(quad.cullFace())) { - return; - } + occlusionCache.putAndMoveToFirst(blockStatePairKey, (byte) (bl ? 1 : 0)); + return bl; + } + } - endRenderQuad(quad); - } + return true; + } - protected void endRenderQuad(MutableQuadViewImpl quad) { - } + public QuadEmitter getEmitter() { + editorQuad.clear(); + return editorQuad; + } - /** - * handles block color, common to all renders. - */ - protected void tintQuad(MutableQuadViewImpl quad) { - int tintIndex = quad.tintIndex(); + @Override + protected void bufferQuad(MutableQuadViewImpl quadView) { + this.renderQuad(quadView); + } - if (tintIndex != -1) { - final int blockColor = getBlockColor(this.renderRegion, tintIndex); + protected abstract VertexConsumer getVertexConsumer(ChunkSectionLayer layer); - for (int i = 0; i < 4; i++) { - quad.color(i, ColorHelper.multiplyColor(blockColor, quad.color(i))); - } - } - } + private void renderQuad(MutableQuadViewImpl quad) { + if (isFaceCulled(quad.cullFace())) { + return; + } - private int getBlockColor(BlockAndTintGetter region, int colorIndex) { - BlockColor blockColor = this.blockColorRegistry.getBlockColor(this.blockState.getBlock()); + endRenderQuad(quad); + } - int color = blockColor != null ? blockColor.getColor(blockState, region, blockPos, colorIndex) : -1; - return 0xFF000000 | color; - } + protected void endRenderQuad(MutableQuadViewImpl quad) {} - protected void shadeQuad(MutableQuadViewImpl quad, LightPipeline lightPipeline, boolean emissive, boolean vanillaShade) { - QuadLightData data = this.quadLightData; + /** handles block color, common to all renders. */ + protected void tintQuad(MutableQuadViewImpl quad) { + int tintIndex = quad.tintIndex(); - // TODO: enhanced AO - lightPipeline.calculate(quad, this.blockPos, data, quad.cullFace(), quad.lightFace(), quad.diffuseShade()); + if (tintIndex != -1) { + final int blockColor = getBlockColor(this.renderRegion, tintIndex); - if (emissive) { - for (int i = 0; i < 4; i++) { - quad.color(i, ColorHelper.multiplyRGB(quad.color(i), data.br[i])); + 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.diffuseShade()); + + 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); - data.lm[i] = LightTexture.FULL_BRIGHT; - } - } else { - for (int i = 0; i < 4; i++) { - quad.color(i, ColorHelper.multiplyRGB(quad.color(i), data.br[i])); + data.lm[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])); - data.lm[i] = ColorHelper.maxBrightness(quad.lightmap(i), data.lm[i]); - } - } - } + data.lm[i] = ColorHelper.maxBrightness(quad.lightmap(i), data.lm[i]); + } + } + } - public ChunkSectionLayer effectiveRenderLayer(@Nullable ChunkSectionLayer quadRenderLayer) { - return quadRenderLayer == null ? defaultLayer : quadRenderLayer; - } + public ChunkSectionLayer effectiveRenderLayer(@Nullable ChunkSectionLayer quadRenderLayer) { + return quadRenderLayer == null ? defaultLayer : quadRenderLayer; + } - public void emitVanillaBlockQuads(BlockStateModel model, @Nullable BlockState state, Supplier randomSupplier, Predicate cullTest) { - MutableQuadViewImpl quad = this.editorQuad; + public void emitVanillaBlockQuads(BlockStateModel model, @Nullable BlockState state, Supplier randomSupplier, Predicate cullTest) { + MutableQuadViewImpl quad = this.editorQuad; // final RenderMaterial defaultMaterial = state.getLightEmission() == 0 ? STANDARD_MATERIAL : NO_AO_MATERIAL; - for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) { - final Direction cullFace = ModelHelper.faceFromIndex(i); + for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) { + final Direction cullFace = ModelHelper.faceFromIndex(i); + + if (cullTest.test(cullFace)) { + // Skip entire quad list if possible. + continue; + } - if (cullTest.test(cullFace)) { - // Skip entire quad list if possible. - continue; - } + final List parts = ((BlockStateModel) this).collectParts(random); + final int partCount = parts.size(); - final List parts = ((BlockStateModel) this).collectParts(random); - final int partCount = parts.size(); + for (int j = 0; j < partCount; j++) { + parts.get(j).emitQuads(quad, cullTest); + } + } - for (int j = 0; j < partCount; j++) { - parts.get(j).emitQuads(quad, cullTest); - } - } + } - } + // TODO move elsewhere + record ShapePairKey(VoxelShape first, VoxelShape second) { + public boolean equals(Object object) { + if (object instanceof ShapePairKey shapePairKey && this.first == shapePairKey.first && this.second == shapePairKey.second) { + return true; + } - // TODO move elsewhere - record ShapePairKey(VoxelShape first, VoxelShape second) { - public boolean equals(Object object) { - return object instanceof ShapePairKey( - VoxelShape first1, VoxelShape second1 - ) && this.first == first1 && this.second == second1; - } + return false; + } - public int hashCode() { - return System.identityHashCode(this.first) * 31 + System.identityHashCode(this.second); - } - } + public int hashCode() { + return System.identityHashCode(this.first) * 31 + System.identityHashCode(this.second); + } + } } 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 index 126e0641e..d98321876 100644 --- 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 @@ -21,63 +21,62 @@ import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.vulkanmod.render.chunk.build.frapi.mesh.EncodingFormat; import net.vulkanmod.render.chunk.build.frapi.mesh.MutableQuadViewImpl; +import org.joml.Matrix3f; import org.joml.Matrix4f; import org.joml.Vector3f; import org.joml.Vector4f; public abstract class AbstractRenderContext { - private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { - { - data = new int[EncodingFormat.TOTAL_STRIDE]; - clear(); - } + private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { + { + data = new int[EncodingFormat.TOTAL_STRIDE]; + clear(); + } - @Override - protected void emitDirectly() { - bufferQuad(this); - } - }; + @Override + protected void emitDirectly() { + bufferQuad(this); + } + }; - private final Vector4f posVec = new Vector4f(); - private final Vector3f normalVec = new Vector3f(); + private final Vector4f posVec = new Vector4f(); + private final Vector3f normalVec = new Vector3f(); - protected PoseStack.Pose matrices; - protected int overlay; + protected PoseStack.Pose matrices; + protected int overlay; - protected QuadEmitter getEmitter() { - editorQuad.clear(); - return editorQuad; - } + protected QuadEmitter getEmitter() { + editorQuad.clear(); + return editorQuad; + } - protected abstract void bufferQuad(MutableQuadViewImpl quadView); + protected abstract void bufferQuad(MutableQuadViewImpl quadView); - /** - * 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 PoseStack.Pose matrices = this.matrices; - final Matrix4f posMatrix = matrices.pose(); - final boolean useNormals = quad.hasVertexNormals(); + /** 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 PoseStack.Pose matrices = this.matrices; + final Matrix4f posMatrix = matrices.pose(); + final boolean useNormals = quad.hasVertexNormals(); - if (useNormals) { - quad.populateMissingNormals(); - } else { - matrices.transformNormal(quad.faceNormal(), normalVec); - } + if (useNormals) { + quad.populateMissingNormals(); + } else { + matrices.transformNormal(quad.faceNormal(), normalVec); + } - for (int i = 0; i < 4; i++) { - posVec.set(quad.x(i), quad.y(i), quad.z(i), 1.0f); - posVec.mul(posMatrix); + for (int i = 0; i < 4; i++) { + posVec.set(quad.x(i), quad.y(i), quad.z(i), 1.0f); + posVec.mul(posMatrix); - if (useNormals) { - quad.copyNormal(i, normalVec); - matrices.transformNormal(normalVec, normalVec); - } + if (useNormals) { + quad.copyNormal(i, normalVec); + matrices.transformNormal(normalVec, normalVec); + } - vertexConsumer.addVertex(posVec.x(), posVec.y(), posVec.z(), quad.color(i), quad.u(i), quad.v(i), overlay, quad.lightmap(i), normalVec.x(), normalVec.y(), normalVec.z()); - } - } + vertexConsumer.addVertex(posVec.x(), posVec.y(), posVec.z(), quad.color(i), quad.u(i), quad.v(i), overlay, quad.lightmap(i), normalVec.x(), normalVec.y(), normalVec.z()); + } + } } \ No newline at end of file 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 index a63ec22ba..872671b4b 100644 --- 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 @@ -26,73 +26,76 @@ * Context for non-terrain block rendering. */ public class BlockRenderContext extends AbstractBlockRenderContext { - public static final ThreadLocal POOL = ThreadLocal.withInitial(BlockRenderContext::new); - private final ArrayLightDataCache lightDataCache = new ArrayLightDataCache(); - private BlockVertexConsumerProvider vertexConsumers; + public static final ThreadLocal POOL = ThreadLocal.withInitial(BlockRenderContext::new); + + private BlockVertexConsumerProvider vertexConsumers; private ChunkSectionLayer defaultRenderLayer; - public BlockRenderContext() { - LightPipeline flatLightPipeline = new FlatLightPipeline(this.lightDataCache); + 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); - } + LightPipeline smoothLightPipeline; + if (Initializer.CONFIG.ambientOcclusion == LightMode.SUB_BLOCK) { + smoothLightPipeline = new NewSmoothLightPipeline(lightDataCache); + } + else { + smoothLightPipeline = new SmoothLightPipeline(lightDataCache); + } - this.setupLightPipelines(flatLightPipeline, smoothLightPipeline); + this.setupLightPipelines(flatLightPipeline, smoothLightPipeline); - random = RandomSource.create(); + random = RandomSource.create(); } - public void render(BlockAndTintGetter blockView, BlockStateModel model, BlockState state, BlockPos pos, PoseStack matrixStack, BlockVertexConsumerProvider buffers, boolean cull, long seed, int overlay) { - Vec3 offset = state.getOffset(pos); - matrixStack.translate(offset.x, offset.y, offset.z); + public void render(BlockAndTintGetter blockView, BlockStateModel model, BlockState state, BlockPos pos, PoseStack matrixStack, BlockVertexConsumerProvider buffers, boolean cull, long seed, int overlay) { + Vec3 offset = state.getOffset(pos); + matrixStack.translate(offset.x, offset.y, offset.z); - this.blockPos = pos; - this.vertexConsumers = buffers; + this.blockPos = pos; + this.vertexConsumers = buffers; this.defaultRenderLayer = ItemBlockRenderTypes.getChunkRenderType(state); - this.matrices = matrixStack.last(); - this.overlay = overlay; - this.random.setSeed(seed); + this.matrices = matrixStack.last(); + this.overlay = overlay; + this.random.setSeed(seed); - this.lightDataCache.reset(blockView, pos); + this.lightDataCache.reset(blockView, pos); - this.prepareForWorld(blockView, cull); - this.prepareForBlock(state, pos, state.getLightEmission() == 0); + this.prepareForWorld(blockView, cull); + this.prepareForBlock(state, pos, state.getLightEmission() == 0); - model.emitQuads(getEmitter(), blockView, pos, state, random, this::isFaceCulled); + model.emitQuads(getEmitter(), blockView, pos, state, random, this::isFaceCulled); - this.vertexConsumers = null; - } + this.vertexConsumers = null; + } - @Override - protected VertexConsumer getVertexConsumer(ChunkSectionLayer layer) { - return vertexConsumers.getBuffer(layer); - } + @Override + protected VertexConsumer getVertexConsumer(ChunkSectionLayer layer) { + return vertexConsumers.getBuffer(layer); + } - protected void endRenderQuad(MutableQuadViewImpl quad) { - final TriState aoMode = quad.ambientOcclusion(); - final boolean ao = this.useAO && (aoMode == TriState.TRUE || (aoMode == TriState.DEFAULT && this.defaultAO)); - final boolean emissive = quad.emissive(); - final boolean vanillaShade = quad.shadeMode() == ShadeMode.VANILLA; + protected void endRenderQuad(MutableQuadViewImpl quad) { + final TriState aoMode = quad.ambientOcclusion(); + final boolean ao = this.useAO && (aoMode == TriState.TRUE || (aoMode == TriState.DEFAULT && this.defaultAO)); + final boolean emissive = quad.emissive(); + final boolean vanillaShade = quad.shadeMode() == ShadeMode.VANILLA; final ChunkSectionLayer quadRenderLayer = quad.renderLayer(); final ChunkSectionLayer renderLayer = quadRenderLayer == null ? defaultRenderLayer : quadRenderLayer; - final VertexConsumer vertexConsumer = getVertexConsumer(renderLayer); + final VertexConsumer vertexConsumer = getVertexConsumer(renderLayer); - LightPipeline lightPipeline = ao ? this.smoothLightPipeline : this.flatLightPipeline; + LightPipeline lightPipeline = ao ? this.smoothLightPipeline : this.flatLightPipeline; - tintQuad(quad); - shadeQuad(quad, lightPipeline, emissive, vanillaShade); - copyLightData(quad); + tintQuad(quad); + shadeQuad(quad, lightPipeline, emissive, vanillaShade); + copyLightData(quad); bufferQuad(quad, vertexConsumer); - } + } - private void copyLightData(MutableQuadViewImpl quad) { + private void copyLightData(MutableQuadViewImpl quad) { for (int i = 0; i < 4; i++) { - quad.lightmap(i, this.quadLightData.lm[i]); - } - } + quad.lightmap(i, this.quadLightData.lm[i]); + } + } } 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 index 120314ca2..3448ad0a9 100644 --- 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 @@ -3,65 +3,71 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.MatrixUtil; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Supplier; + import net.fabricmc.fabric.api.renderer.v1.mesh.MeshView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.render.FabricLayerRenderState; import net.fabricmc.fabric.api.renderer.v1.render.RenderLayerHelper; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; +import net.minecraft.client.renderer.item.ItemStackRenderState; +import net.vulkanmod.mixin.render.frapi.ItemRendererAccessor; 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.block.model.BakedQuad; -import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.client.renderer.item.ItemStackRenderState; +import net.minecraft.util.RandomSource; import net.minecraft.world.item.ItemDisplayContext; -import net.vulkanmod.mixin.render.frapi.ItemRendererAccessor; import net.vulkanmod.render.chunk.build.frapi.helper.ColorHelper; import net.vulkanmod.render.chunk.build.frapi.mesh.MutableQuadViewImpl; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.List; - /** * Used during item buffering to support geometry added through {@link FabricLayerRenderState#emitter()}. */ public class ItemRenderContext extends AbstractRenderContext { - private static final int GLINT_COUNT = ItemStackRenderState.FoilType.values().length; - private final VertexConsumer[] vertexConsumerCache = new VertexConsumer[3 * GLINT_COUNT]; - private ItemDisplayContext itemDisplayContext; - private PoseStack matrixStack; - private MultiBufferSource vertexConsumerProvider; - private int lightmap; - private int[] tints; - private RenderType defaultLayer; - private ItemStackRenderState.FoilType defaultGlint; + private static final int GLINT_COUNT = ItemStackRenderState.FoilType.values().length; + + private ItemDisplayContext itemDisplayContext; + private PoseStack matrixStack; + private MultiBufferSource vertexConsumerProvider; + private int lightmap; + private int[] tints; + + private RenderType defaultLayer; + private ItemStackRenderState.FoilType defaultGlint; private boolean ignoreQuadGlint; - private PoseStack.Pose specialGlintEntry; - - public void renderModel(ItemDisplayContext itemDisplayContext, PoseStack matrixStack, MultiBufferSource bufferSource, int lightmap, int overlay, int[] tints, List modelQuads, MeshView mesh, RenderType renderType, ItemStackRenderState.FoilType foilType, boolean ignoreQuadGlint) { - this.itemDisplayContext = itemDisplayContext; - this.matrixStack = matrixStack; - this.vertexConsumerProvider = bufferSource; - this.lightmap = lightmap; - this.overlay = overlay; - this.tints = tints; - - defaultLayer = renderType; - defaultGlint = foilType; + + private PoseStack.Pose specialGlintEntry; + private final VertexConsumer[] vertexConsumerCache = new VertexConsumer[3 * GLINT_COUNT]; + + public void renderModel(ItemDisplayContext itemDisplayContext, PoseStack matrixStack, MultiBufferSource bufferSource, int lightmap, int overlay, int[] tints, List modelQuads, MeshView mesh, RenderType renderType, ItemStackRenderState.FoilType foilType, boolean ignoreQuadGlint) { + this.itemDisplayContext = itemDisplayContext; + this.matrixStack = matrixStack; + this.vertexConsumerProvider = bufferSource; + this.lightmap = lightmap; + this.overlay = overlay; + this.tints = tints; + + defaultLayer = renderType; + defaultGlint = foilType; this.ignoreQuadGlint = ignoreQuadGlint; - bufferQuads(modelQuads, mesh); + bufferQuads(modelQuads, mesh); - this.matrixStack = null; - this.vertexConsumerProvider = null; - this.tints = null; + this.matrixStack = null; + this.vertexConsumerProvider = null; + this.tints = null; - specialGlintEntry = null; - Arrays.fill(vertexConsumerCache, null); - } + specialGlintEntry = null; + Arrays.fill(vertexConsumerCache, null); + } private void bufferQuads(List vanillaQuads, MeshView mesh) { QuadEmitter emitter = getEmitter(); @@ -77,40 +83,40 @@ private void bufferQuads(List vanillaQuads, MeshView mesh) { mesh.outputTo(emitter); } - @Override - protected void bufferQuad(MutableQuadViewImpl quad) { + @Override + protected void bufferQuad(MutableQuadViewImpl quad) { final VertexConsumer vertexConsumer = getVertexConsumer(quad.renderLayer(), quad.glint()); tintQuad(quad); shadeQuad(quad, quad.emissive()); bufferQuad(quad, vertexConsumer); - } - - private void tintQuad(MutableQuadViewImpl quad) { - int tintIndex = quad.tintIndex(); - - if (tintIndex != -1 && tintIndex < tints.length) { - final int tint = tints[tintIndex]; - - for (int i = 0; i < 4; i++) { - quad.color(i, ColorHelper.multiplyColor(tint, 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)); - } - } - } + } + + private void tintQuad(MutableQuadViewImpl quad) { + int tintIndex = quad.tintIndex(); + + if (tintIndex != -1 && tintIndex < tints.length) { + final int tint = tints[tintIndex]; + + for (int i = 0; i < 4; i++) { + quad.color(i, ColorHelper.multiplyColor(tint, 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)); + } + } + } private VertexConsumer getVertexConsumer(@Nullable ChunkSectionLayer quadRenderLayer, @Nullable ItemStackRenderState.FoilType quadGlint) { RenderType layer; @@ -149,22 +155,22 @@ private VertexConsumer getVertexConsumer(@Nullable ChunkSectionLayer quadRenderL return vertexConsumer; } - private VertexConsumer createVertexConsumer(RenderType layer, ItemStackRenderState.FoilType glint) { - if (glint == ItemStackRenderState.FoilType.SPECIAL) { - if (specialGlintEntry == null) { - specialGlintEntry = matrixStack.last().copy(); + private VertexConsumer createVertexConsumer(RenderType layer, ItemStackRenderState.FoilType glint) { + if (glint == ItemStackRenderState.FoilType.SPECIAL) { + if (specialGlintEntry == null) { + specialGlintEntry = matrixStack.last().copy(); - if (itemDisplayContext == ItemDisplayContext.GUI) { - MatrixUtil.mulComponentWise(specialGlintEntry.pose(), 0.5F); - } else if (itemDisplayContext.firstPerson()) { - MatrixUtil.mulComponentWise(specialGlintEntry.pose(), 0.75F); - } - } + if (itemDisplayContext == ItemDisplayContext.GUI) { + MatrixUtil.mulComponentWise(specialGlintEntry.pose(), 0.5F); + } else if (itemDisplayContext.firstPerson()) { + MatrixUtil.mulComponentWise(specialGlintEntry.pose(), 0.75F); + } + } - return ItemRendererAccessor.getSpecialFoilBuffer(vertexConsumerProvider, layer, specialGlintEntry); - } + return ItemRendererAccessor.getSpecialFoilBuffer(vertexConsumerProvider, layer, specialGlintEntry); + } - return ItemRenderer.getFoilBuffer(vertexConsumerProvider, layer, true, glint != ItemStackRenderState.FoilType.NONE); - } + return ItemRenderer.getFoilBuffer(vertexConsumerProvider, layer, true, glint != ItemStackRenderState.FoilType.NONE); + } } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/MeshItemCommand.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/MeshItemCommand.java index 0618c7854..52acc30b1 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/MeshItemCommand.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/MeshItemCommand.java @@ -1,15 +1,12 @@ package net.vulkanmod.render.chunk.build.frapi.render; import com.mojang.blaze3d.vertex.PoseStack; +import java.util.List; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshView; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.world.item.ItemDisplayContext; -import java.util.List; - -public record MeshItemCommand(PoseStack.Pose positionMatrix, ItemDisplayContext displayContext, int lightCoords, - int overlayCoords, int outlineColor, int[] tintLayers, List quads, - RenderType renderLayer, ItemStackRenderState.FoilType glintType, MeshView mesh) { +public record MeshItemCommand(PoseStack.Pose positionMatrix, ItemDisplayContext displayContext, int lightCoords, int overlayCoords, int outlineColor, int[] tintLayers, List quads, RenderType renderLayer, ItemStackRenderState.FoilType glintType, MeshView mesh) { } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/SimpleBlockRenderContext.java b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/SimpleBlockRenderContext.java index 4a1f61a08..275738cfb 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/SimpleBlockRenderContext.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/frapi/render/SimpleBlockRenderContext.java @@ -20,6 +20,8 @@ import net.fabricmc.fabric.api.renderer.v1.render.BlockVertexConsumerProvider; 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.block.model.BlockStateModel; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.core.BlockPos; 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 f7fd90abe..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,23 +2,22 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.vulkanmod.render.chunk.build.light.data.QuadLightData; import net.vulkanmod.render.model.quad.ModelQuadView; +import net.vulkanmod.render.chunk.build.light.data.QuadLightData; /** * Light pipelines allow model quads for any location in the world to be lit using various backends, including fluids - * and block entities. + * and block entities. */ public interface LightPipeline { /** * Calculates the light data for a given block model quad, storing the result in {@param out}. - * - * @param quad The block model quad - * @param pos The block position of the model this quad belongs to - * @param out The data arrays which will store the calculated light data results - * @param cullFace The cull face of the quad + * @param quad The block model quad + * @param pos The block position of the model this quad belongs to + * @param out The data arrays which will store the calculated light data results + * @param cullFace The cull face of the quad * @param lightFace The light face of the quad - * @param shade True if the block is shaded by ambient occlusion + * @param shade True if the block is shaded by ambient occlusion */ 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/LightDataAccess.java b/src/main/java/net/vulkanmod/render/chunk/build/light/data/LightDataAccess.java index d662ff735..d2e532738 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 @@ -42,14 +42,100 @@ public abstract class LightDataAccess { private static final int FC_OFFSET = 31; private static final float AO_INV = 1.0f / 2048.0f; - final boolean subBlockLighting; + private final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); protected BlockAndTintGetter region; + final boolean subBlockLighting; + protected LightDataAccess() { this.subBlockLighting = Initializer.CONFIG.ambientOcclusion == LightMode.SUB_BLOCK; } + 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()); + } + + public int get(int x, int y, int z, SimpleDirection dir) { + return this.get(x + dir.getStepX(), + y + dir.getStepY(), + z + dir.getStepZ()); + } + + public int get(BlockPos pos, SimpleDirection dir) { + return this.get(pos.getX(), pos.getY(), pos.getZ(), dir); + } + + public int get(BlockPos pos) { + return this.get(pos.getX(), pos.getY(), pos.getZ()); + } + + /** + * Returns the light data for the block at the given position. The property fields can then be accessed using + * the various unpack methods below. + */ + public abstract int get(int x, int y, int z); + + protected int compute(int x, int y, int z) { + BlockPos pos = this.pos.set(x, y, z); + BlockState state = region.getBlockState(pos); + + boolean em = state.emissiveRendering(region, pos); + + boolean op; + if (this.subBlockLighting) + op = state.canOcclude(); + else + op = state.isViewBlocking(region, pos) && state.getLightBlock() != 0; + + boolean fo = state.isSolidRender(); + boolean fc = state.isCollisionShapeFullBlock(region, pos); + + int lu = state.getLightEmission(); + + // OPTIMIZE: Do not calculate light data if the block is full and opaque and does not emit light. + int bl; + int sl; + if (fo && lu == 0) { + bl = 0; + sl = 0; + } + else { + if (em) { + bl = region.getBrightness(LightLayer.BLOCK, pos); + sl = region.getBrightness(LightLayer.SKY, pos); + } + else { + int light = LevelRenderer.getLightColor(LevelRenderer.BrightnessGetter.DEFAULT, 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(region, pos); + } + else { + ao = 1.0f; + } + + boolean useAo = ao < 1.0f; + + bl = Math.max(bl, lu); + + int crs = (fo || fc) && lu == 0 && useAo ? 0xFF : 0; + 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); + } + public static int packBL(int blockLight) { return (blockLight & 0xF) << BL_OFFSET; } @@ -136,87 +222,6 @@ public static int getEmissiveLightmap(int word) { } } - 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()); - } - - public int get(int x, int y, int z, SimpleDirection dir) { - return this.get(x + dir.getStepX(), - y + dir.getStepY(), - z + dir.getStepZ()); - } - - public int get(BlockPos pos, SimpleDirection dir) { - return this.get(pos.getX(), pos.getY(), pos.getZ(), dir); - } - - public int get(BlockPos pos) { - return this.get(pos.getX(), pos.getY(), pos.getZ()); - } - - /** - * Returns the light data for the block at the given position. The property fields can then be accessed using - * the various unpack methods below. - */ - public abstract int get(int x, int y, int z); - - protected int compute(int x, int y, int z) { - BlockPos pos = this.pos.set(x, y, z); - BlockState state = region.getBlockState(pos); - - boolean em = state.emissiveRendering(region, pos); - - boolean op; - if (this.subBlockLighting) - op = state.canOcclude(); - else - op = state.isViewBlocking(region, pos) && state.getLightBlock() != 0; - - boolean fo = state.isSolidRender(); - boolean fc = state.isCollisionShapeFullBlock(region, pos); - - int lu = state.getLightEmission(); - - // OPTIMIZE: Do not calculate light data if the block is full and opaque and does not emit light. - int bl; - int sl; - if (fo && lu == 0) { - bl = 0; - sl = 0; - } else { - if (em) { - bl = region.getBrightness(LightLayer.BLOCK, pos); - sl = region.getBrightness(LightLayer.SKY, pos); - } else { - int light = LevelRenderer.getLightColor(LevelRenderer.BrightnessGetter.DEFAULT, 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(region, pos); - } else { - ao = 1.0f; - } - - boolean useAo = ao < 1.0f; - - bl = Math.max(bl, lu); - - int crs = (fo || fc) && lu == 0 && useAo ? 0xFF : 0; - 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); - } - public BlockAndTintGetter getRegion() { return this.region; } 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 333c09f0f..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 @@ -3,12 +3,12 @@ import net.minecraft.client.renderer.LightTexture; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.vulkanmod.render.chunk.build.light.LightPipeline; +import net.vulkanmod.render.chunk.util.SimpleDirection; +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; -import net.vulkanmod.render.chunk.util.SimpleDirection; import net.vulkanmod.render.model.quad.ModelQuadFlags; -import net.vulkanmod.render.model.quad.ModelQuadView; import java.util.Arrays; diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoFaceData.java b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoFaceData.java index 9d51ea902..d4be249f3 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoFaceData.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoFaceData.java @@ -2,8 +2,8 @@ import net.minecraft.client.renderer.LightTexture; import net.minecraft.core.BlockPos; -import net.vulkanmod.render.chunk.build.light.data.LightDataAccess; import net.vulkanmod.render.chunk.util.SimpleDirection; +import net.vulkanmod.render.chunk.build.light.data.LightDataAccess; import static net.vulkanmod.render.chunk.build.light.data.LightDataAccess.*; @@ -16,65 +16,6 @@ class AoFaceData { protected int flags; - static float weightedSum(float[] v, float[] w) { - float t0 = v[0] * w[0]; - float t1 = v[1] * w[1]; - float t2 = v[2] * w[2]; - float t3 = v[3] * w[3]; - - return t0 + t1 + t2 + t3; - } - - static float unpackSkyLight(int i) { - return (i >> 16) & 0xFF; - } - - static float unpackBlockLight(int i) { - return i & 0xFF; - } - - static int calculateCornerBrightness(int a, int b, int c, int d, boolean aem, boolean bem, boolean cem, boolean dem) { - // FIX: Normalize corner vectors correctly to the minimum non-zero value between each one to prevent - // strange issues - if ((a == 0) || (b == 0) || (c == 0) || (d == 0)) { - // Find the minimum value between all corners - final int min = minNonZero(minNonZero(a, b), minNonZero(c, d)); - - // Normalize the corner values - a = Math.max(a, min); - b = Math.max(b, min); - c = Math.max(c, min); - d = Math.max(d, min); - } - - // FIX: Apply the fullbright lightmap from emissive blocks at the very end so it cannot influence - // the minimum lightmap and produce incorrect results (for example, sculk sensors in a dark room) - if (aem) { - a = LightTexture.FULL_BRIGHT; - } - if (bem) { - b = LightTexture.FULL_BRIGHT; - } - if (cem) { - c = LightTexture.FULL_BRIGHT; - } - if (dem) { - d = LightTexture.FULL_BRIGHT; - } - - return ((a + b + c + d) >> 2) & 0xFF00FF; - } - - static int minNonZero(int a, int b) { - if (a == 0) { - return b; - } else if (b == 0) { - return a; - } - - return Math.min(a, b); - } - public void initLightData(LightDataAccess cache, BlockPos pos, SimpleDirection direction, boolean offset) { final int oX = pos.getX(); final int oY = pos.getY(); @@ -250,6 +191,65 @@ public float getBlendedShade(float[] w) { return weightedSum(this.ao, w); } + static float weightedSum(float[] v, float[] w) { + float t0 = v[0] * w[0]; + float t1 = v[1] * w[1]; + float t2 = v[2] * w[2]; + float t3 = v[3] * w[3]; + + return t0 + t1 + t2 + t3; + } + + static float unpackSkyLight(int i) { + return (i >> 16) & 0xFF; + } + + static float unpackBlockLight(int i) { + return i & 0xFF; + } + + static int calculateCornerBrightness(int a, int b, int c, int d, boolean aem, boolean bem, boolean cem, boolean dem) { + // FIX: Normalize corner vectors correctly to the minimum non-zero value between each one to prevent + // strange issues + if ((a == 0) || (b == 0) || (c == 0) || (d == 0)) { + // Find the minimum value between all corners + final int min = minNonZero(minNonZero(a, b), minNonZero(c, d)); + + // Normalize the corner values + a = Math.max(a, min); + b = Math.max(b, min); + c = Math.max(c, min); + d = Math.max(d, min); + } + + // FIX: Apply the fullbright lightmap from emissive blocks at the very end so it cannot influence + // the minimum lightmap and produce incorrect results (for example, sculk sensors in a dark room) + if (aem) { + a = LightTexture.FULL_BRIGHT; + } + if (bem) { + b = LightTexture.FULL_BRIGHT; + } + if (cem) { + c = LightTexture.FULL_BRIGHT; + } + if (dem) { + d = LightTexture.FULL_BRIGHT; + } + + return ((a + b + c + d) >> 2) & 0xFF00FF; + } + + static int minNonZero(int a, int b) { + if (a == 0) { + return b; + } else if (b == 0) { + return a; + } + + return Math.min(a, b); + } + public boolean hasLightData() { return (this.flags & FaceDataFlags.HAS_LIGHT_DATA) != 0; } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoNeighborInfo.java b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoNeighborInfo.java index fe57819db..c3ccad908 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoNeighborInfo.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/AoNeighborInfo.java @@ -8,10 +8,10 @@ */ @SuppressWarnings("UnnecessaryLocalVariable") enum AoNeighborInfo { - DOWN(new SimpleDirection[]{SimpleDirection.SOUTH, SimpleDirection.WEST, SimpleDirection.NORTH, SimpleDirection.EAST}, - new int[]{4, 5, 6, 7, - 0, 1, 2, 3}, - 0.5F) { + DOWN(new SimpleDirection[] { SimpleDirection.SOUTH, SimpleDirection.WEST, SimpleDirection.NORTH, SimpleDirection.EAST }, + new int[] {4, 5, 6, 7, + 0, 1, 2, 3}, + 0.5F) { @Override public void calculateCornerWeights(float x, float y, float z, float[] out) { final float u = 1.0f - x; @@ -35,10 +35,10 @@ public float getDepth(float x, float y, float z) { return y; } }, - UP(new SimpleDirection[]{SimpleDirection.NORTH, SimpleDirection.WEST, SimpleDirection.SOUTH, SimpleDirection.EAST}, - new int[]{2, 3, 0, 1, + UP(new SimpleDirection[] { SimpleDirection.NORTH, SimpleDirection.WEST, SimpleDirection.SOUTH, SimpleDirection.EAST }, + new int[] {2, 3, 0, 1, 6, 7, 4, 5}, - 1.0F) { + 1.0F) { @Override public void calculateCornerWeights(float x, float y, float z, float[] out) { final float u = 1.0f - x; @@ -62,8 +62,8 @@ public float getDepth(float x, float y, float z) { return 1.0f - y; } }, - NORTH(new SimpleDirection[]{SimpleDirection.UP, SimpleDirection.EAST, SimpleDirection.DOWN, SimpleDirection.WEST}, - new int[]{3, 2, 7, 6, + NORTH(new SimpleDirection[] { SimpleDirection.UP, SimpleDirection.EAST, SimpleDirection.DOWN, SimpleDirection.WEST }, + new int[] {3, 2, 7, 6, 1, 0, 5, 4}, 0.8F) { @Override @@ -89,8 +89,8 @@ public float getDepth(float x, float y, float z) { return z; } }, - SOUTH(new SimpleDirection[]{SimpleDirection.UP, SimpleDirection.WEST, SimpleDirection.DOWN, SimpleDirection.EAST}, - new int[]{0, 1, 4, 5, + SOUTH(new SimpleDirection[] { SimpleDirection.UP, SimpleDirection.WEST, SimpleDirection.DOWN, SimpleDirection.EAST }, + new int[] {0, 1, 4, 5, 2, 3, 6, 7}, 0.8F) { @Override @@ -116,8 +116,8 @@ public float getDepth(float x, float y, float z) { return 1.0f - z; } }, - WEST(new SimpleDirection[]{SimpleDirection.UP, SimpleDirection.NORTH, SimpleDirection.DOWN, SimpleDirection.SOUTH}, - new int[]{1, 3, 5, 7, + WEST(new SimpleDirection[] { SimpleDirection.UP, SimpleDirection.NORTH, SimpleDirection.DOWN, SimpleDirection.SOUTH }, + new int[] {1, 3, 5, 7, 0, 2, 4, 6}, 0.6F) { @Override @@ -143,8 +143,8 @@ public float getDepth(float x, float y, float z) { return x; } }, - EAST(new SimpleDirection[]{SimpleDirection.UP, SimpleDirection.SOUTH, SimpleDirection.DOWN, SimpleDirection.NORTH}, - new int[]{2, 0, 6, 4, + EAST(new SimpleDirection[] { SimpleDirection.UP, SimpleDirection.SOUTH, SimpleDirection.DOWN, SimpleDirection.NORTH }, + new int[] {2, 0, 6, 4, 3, 1, 7, 5}, 0.6F) { @Override @@ -171,21 +171,23 @@ public float getDepth(float x, float y, float z) { } }; - private static final AoNeighborInfo[] VALUES = AoNeighborInfo.values(); /** * The direction of each corner block from this face, which can be retrieved by offsetting the position of the origin * block by the direction vector. */ public final SimpleDirection[] faces; + /** * The constant brightness modifier for this face. This data exists to emulate the results of the OpenGL lighting * model which gives a faux directional light appearance to blocks in the game. Not currently used. */ public final float strength; + /** * The indexes of each inner corner occlusion bit for every model vertex. */ public final int[] inCornerBits = new int[4 * 2]; + /** * The indexes of each outer corner occlusion bit for every model vertex. */ @@ -199,6 +201,55 @@ public float getDepth(float x, float y, float z) { getOutCornerBits(this.outCornerBits, indices); } + /** + * Calculates how much each corner contributes to the final "darkening" of the vertex at the specified position. The + * weight is a function of the distance from the vertex's position to the corner block's position. + * + * @param x The x-position of the vertex + * @param y The y-position of the vertex + * @param z The z-position of the vertex + * @param out The weight values for each corner + */ + public abstract void calculateCornerWeights(float x, float y, float z, float[] out); + + public abstract float getU(float x, float y, float z); + + public abstract float getV(float x, float y, float z); + + /** + * Maps the light map and occlusion value arrays {@param lm0} and {@param ao0} from {@link AoFaceData} to the + * correct corners for this facing. + * + * @param lm0 The input light map texture coordinates array + * @param ao0 The input ambient occlusion color array + * @param lm1 The re-orientated output light map texture coordinates array + * @param ao1 The re-orientated output ambient occlusion color array + */ + public void copyLightValues(int[] lm0, float[] ao0, int[] lm1, float[] ao1) { + lm1[0] = lm0[0]; + lm1[1] = lm0[1]; + lm1[2] = lm0[2]; + lm1[3] = lm0[3]; + + ao1[0] = ao0[0]; + ao1[1] = ao0[1]; + ao1[2] = ao0[2]; + ao1[3] = ao0[3]; + } + + /** + * Calculates the depth (or inset) of the vertex into this facing of the block. Used to determine + * how much shadow is contributed by the direct neighbors of a block. + * + * @param x The x-position of the vertex + * @param y The y-position of the vertex + * @param z The z-position of the vertex + * @return The depth of the vertex into this face + */ + public abstract float getDepth(float x, float y, float z); + + private static final AoNeighborInfo[] VALUES = AoNeighborInfo.values(); + /** * @return Returns the {@link AoNeighborInfo} which corresponds with the specified direction */ @@ -252,7 +303,7 @@ private static void getOutCornerBits(int[] cornersBits, int[] idxs) { cornersBits[10] = idxs[1]; cornersBits[11] = idxs[0]; - cornersBits[12] = idxs[4]; + cornersBits[12 + 0] = idxs[4 + 0]; cornersBits[12 + 1] = idxs[4 + 3]; cornersBits[12 + 2] = idxs[4 + 1]; @@ -261,58 +312,11 @@ private static void getOutCornerBits(int[] cornersBits, int[] idxs) { cornersBits[12 + 5] = idxs[4 + 3]; cornersBits[12 + 6] = idxs[4 + 3]; - cornersBits[12 + 7] = idxs[4]; + cornersBits[12 + 7] = idxs[4 + 0]; cornersBits[12 + 8] = idxs[4 + 2]; cornersBits[12 + 9] = idxs[4 + 2]; cornersBits[12 + 10] = idxs[4 + 1]; - cornersBits[12 + 11] = idxs[4]; - } - - /** - * Calculates how much each corner contributes to the final "darkening" of the vertex at the specified position. The - * weight is a function of the distance from the vertex's position to the corner block's position. - * - * @param x The x-position of the vertex - * @param y The y-position of the vertex - * @param z The z-position of the vertex - * @param out The weight values for each corner - */ - public abstract void calculateCornerWeights(float x, float y, float z, float[] out); - - public abstract float getU(float x, float y, float z); - - public abstract float getV(float x, float y, float z); - - /** - * Maps the light map and occlusion value arrays {@param lm0} and {@param ao0} from {@link AoFaceData} to the - * correct corners for this facing. - * - * @param lm0 The input light map texture coordinates array - * @param ao0 The input ambient occlusion color array - * @param lm1 The re-orientated output light map texture coordinates array - * @param ao1 The re-orientated output ambient occlusion color array - */ - public void copyLightValues(int[] lm0, float[] ao0, int[] lm1, float[] ao1) { - lm1[0] = lm0[0]; - lm1[1] = lm0[1]; - lm1[2] = lm0[2]; - lm1[3] = lm0[3]; - - ao1[0] = ao0[0]; - ao1[1] = ao0[1]; - ao1[2] = ao0[2]; - ao1[3] = ao0[3]; + cornersBits[12 + 11] = idxs[4 + 0]; } - - /** - * Calculates the depth (or inset) of the vertex into this facing of the block. Used to determine - * how much shadow is contributed by the direct neighbors of a block. - * - * @param x The x-position of the vertex - * @param y The y-position of the vertex - * @param z The z-position of the vertex - * @return The depth of the vertex into this face - */ - public abstract float getDepth(float x, float y, float z); } 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 81a876727..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 @@ -3,12 +3,12 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.Mth; -import net.vulkanmod.render.chunk.build.light.LightPipeline; +import net.vulkanmod.render.chunk.util.SimpleDirection; +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; -import net.vulkanmod.render.chunk.util.SimpleDirection; import net.vulkanmod.render.model.quad.ModelQuadFlags; -import net.vulkanmod.render.model.quad.ModelQuadView; /** * A smooth light pipeline which introduces sub-block AO computations @@ -25,11 +25,13 @@ public class NewSmoothLightPipeline implements LightPipeline { * Face data to allow face self-occlusion computation. */ private final SubBlockAoFace self = new SubBlockAoFace(); + + private long cachedPos = Long.MIN_VALUE; + /** * A temporary array for storing the intermediary results of weight data for non-aligned face blending. */ private final float[] weights = new float[4]; - private long cachedPos = Long.MIN_VALUE; public NewSmoothLightPipeline(LightDataAccess cache) { this.lightCache = cache; @@ -39,26 +41,6 @@ public NewSmoothLightPipeline(LightDataAccess cache) { } } - /** - * Clamps the given float to the range [0.0, 1.0]. - */ - private static float clamp(float v) { - if (v < 0.0f) { - return 0.0f; - } else if (v > 1.0f) { - return 1.0f; - } - - return v; - } - - /** - * Returns texture coordinates for the light map texture using the given block and sky light values. - */ - private static int packLightMap(float sl, float bl) { - return (((int) sl & 0xFF) << 16) | ((int) bl & 0xFF); - } - @Override public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFaceO, boolean shade) { this.updateCachedData(pos.asLong()); @@ -278,4 +260,24 @@ private void updateCachedData(long key) { } } + /** + * Clamps the given float to the range [0.0, 1.0]. + */ + private static float clamp(float v) { + if (v < 0.0f) { + return 0.0f; + } else if (v > 1.0f) { + return 1.0f; + } + + return v; + } + + /** + * Returns texture coordinates for the light map texture using the given block and sky light values. + */ + private static int packLightMap(float sl, float bl) { + return (((int) sl & 0xFF) << 16) | ((int) bl & 0xFF); + } + } 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 d023fffce..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 @@ -3,39 +3,39 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.Mth; -import net.vulkanmod.render.chunk.build.light.LightPipeline; +import net.vulkanmod.render.chunk.util.SimpleDirection; +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; -import net.vulkanmod.render.chunk.util.SimpleDirection; import net.vulkanmod.render.model.quad.ModelQuadFlags; -import net.vulkanmod.render.model.quad.ModelQuadView; /** * Re-adapted Sodium's smooth light pipeline - *

+ * * A light pipeline which produces smooth interpolated lighting and ambient occlusion for model quads. This * implementation makes a number of improvements over vanilla's own "smooth lighting" option. In no particular order: - *

+ * * - Corner blocks are now selected from the correct set of neighbors above block faces (fixes MC-148689 and MC-12558) * - Shading issues caused by anisotropy are fixed by re-orientating quads to a consistent ordering (fixes MC-138211) * - Inset block faces are correctly shaded by their neighbors, fixing a number of problems with non-full blocks such as - * grass paths (fixes MC-11783 and MC-108621) + * grass paths (fixes MC-11783 and MC-108621) * - Blocks next to emissive blocks are too bright (MC-260989) * - Synchronization issues between the main render thread's light engine and chunk build worker threads are corrected - * by copying light data alongside block states, fixing a number of inconsistencies in baked chunks (no open issue) - *

+ * by copying light data alongside block states, fixing a number of inconsistencies in baked chunks (no open issue) + * * This implementation also includes a significant number of optimizations: - *

+ * * - Computed light data for a given block face is cached and re-used again when multiple quads exist for a given - * facing, making complex block models less expensive to render + * facing, making complex block models less expensive to render * - The light data cache encodes as much information as possible into integer words to improve cache locality and - * to eliminate the multiple array lookups that would otherwise be needed, significantly speeding up this section + * to eliminate the multiple array lookups that would otherwise be needed, significantly speeding up this section * - Block faces aligned to the block grid use a fast-path for mapping corner light values to vertices without expensive - * interpolation or blending, speeding up most block renders + * interpolation or blending, speeding up most block renders * - Some critical code paths have been re-written to hit the JVM's happy path, allowing it to perform auto-vectorization - * of the blend functions + * of the blend functions * - Information about a given model quad is cached to enable the light pipeline to make certain assumptions and skip - * unnecessary computation + * unnecessary computation */ public class SmoothLightPipeline implements LightPipeline { /** @@ -47,15 +47,17 @@ public class SmoothLightPipeline implements LightPipeline { * The cached face data for each side of a block, both inner and outer. */ private final AoFaceData[] cachedFaceData = new AoFaceData[6 * 2]; - /** - * A temporary array for storing the intermediary results of weight data for non-aligned face blending. - */ - private final float[] weights = new float[4]; + /** * The position at which the cached face data was taken at. */ private long cachedPos = Long.MIN_VALUE; + /** + * A temporary array for storing the intermediary results of weight data for non-aligned face blending. + */ + private final float[] weights = new float[4]; + public SmoothLightPipeline(LightDataAccess cache) { this.lightCache = cache; @@ -64,20 +66,6 @@ public SmoothLightPipeline(LightDataAccess cache) { } } - private static float clamp(float v) { - if (v < 0.0f) { - return 0.0f; - } else if (v > 1.0f) { - return 1.0f; - } - - return v; - } - - private static int packLightMap(float sl, float bl) { - return (((int) sl & 0xFF) << 16) | ((int) bl & 0xFF); - } - @Override public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Direction cullFace, Direction lightFaceO, boolean shade) { this.updateCachedData(pos.asLong()); @@ -260,4 +248,18 @@ private void updateCachedData(long key) { } } + private static float clamp(float v) { + if (v < 0.0f) { + return 0.0f; + } else if (v > 1.0f) { + return 1.0f; + } + + return v; + } + + private static int packLightMap(float sl, float bl) { + return (((int) sl & 0xFF) << 16) | ((int) bl & 0xFF); + } + } \ No newline at end of file diff --git a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SubBlockAoFace.java b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SubBlockAoFace.java index dee91e210..765039c17 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SubBlockAoFace.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/light/smooth/SubBlockAoFace.java @@ -1,8 +1,8 @@ package net.vulkanmod.render.chunk.build.light.smooth; import net.minecraft.core.BlockPos; -import net.vulkanmod.render.chunk.build.light.data.LightDataAccess; import net.vulkanmod.render.chunk.util.SimpleDirection; +import net.vulkanmod.render.chunk.build.light.data.LightDataAccess; import static net.vulkanmod.render.chunk.build.light.data.LightDataAccess.*; @@ -83,13 +83,14 @@ public void initLightData(LightDataAccess cache, BlockPos pos, SimpleDirection d float c0ao = c0oc ? 0.2f : 1.0f; final boolean c0em; - if ((f0c0 && f1c0) || (c0oc && d0co)) { + if((f0c0 && f1c0) || (c0oc && d0co)) { c0ao = 1.6f; - } else { + } + else { c0ao += f0c0 ? 0.2f : 1.0f; c0ao += f1c0 ? 0.2f : 1.0f; - if (offset) + if(offset) c0ao += d0co ? 0.2f : 1.0f; else c0ao += unpackFO(d0) ? 0.2f : 1.0f; @@ -114,13 +115,14 @@ public void initLightData(LightDataAccess cache, BlockPos pos, SimpleDirection d float c1ao = c1oc ? 0.2f : 1.0f; final boolean c1em; - if ((f1c1 && f2c1) || (c1oc && d1co)) { + if((f1c1 && f2c1) || (c1oc && d1co)) { c1ao = 1.6f; - } else { + } + else { c1ao += f1c1 ? 0.2f : 1.0f; c1ao += f2c1 ? 0.2f : 1.0f; - if (offset) + if(offset) c1ao += d1co ? 0.2f : 1.0f; else c1ao += unpackFO(d1) ? 0.2f : 1.0f; @@ -145,13 +147,14 @@ public void initLightData(LightDataAccess cache, BlockPos pos, SimpleDirection d float c2ao = c2oc ? 0.2f : 1.0f; final boolean c2em; - if ((f2c2 && f3c2) || (c2oc && d2co)) { + if((f2c2 && f3c2) || (c2oc && d2co)) { c2ao = 1.6f; - } else { + } + else { c2ao += f2c2 ? 0.2f : 1.0f; c2ao += f3c2 ? 0.2f : 1.0f; - if (offset) + if(offset) c2ao += d2co ? 0.2f : 1.0f; else c2ao += unpackFO(d2) ? 0.2f : 1.0f; @@ -176,13 +179,14 @@ public void initLightData(LightDataAccess cache, BlockPos pos, SimpleDirection d float c3ao = c3oc ? 0.2f : 1.0f; final boolean c3em; - if ((f3c3 && f0c3) || (c3oc && d3co)) { + if((f3c3 && f0c3) || (c3oc && d3co)) { c3ao = 1.6f; - } else { + } + else { c3ao += f3c3 ? 0.2f : 1.0f; c3ao += f0c3 ? 0.2f : 1.0f; - if (offset) + if(offset) c3ao += d3co ? 0.2f : 1.0f; else c3ao += unpackFO(d3) ? 0.2f : 1.0f; 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 index d76b6b50f..74e75ce19 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/renderer/BlockRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/renderer/BlockRenderer.java @@ -5,11 +5,13 @@ import net.fabricmc.fabric.api.util.TriState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BlockStateModel; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.SingleThreadedRandomSource; import net.minecraft.world.phys.Vec3; @@ -20,8 +22,8 @@ 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.ModelQuadView; 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; @@ -30,12 +32,19 @@ import org.joml.Vector3f; public class BlockRenderer extends AbstractBlockRenderContext { - final boolean backFaceCulling = Initializer.CONFIG.backFaceCulling; 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); @@ -43,10 +52,6 @@ public BlockRenderer(LightPipeline flatLightPipeline, LightPipeline smoothLightP this.random = new SingleThreadedRandomSource(42L); } - public void setResources(BuilderResources resources) { - this.resources = resources; - } - public void renderBlock(BlockState blockState, BlockPos blockPos, Vector3f pos) { this.pos = pos; this.blockPos = blockPos; 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 index 6f7cf270d..0fbbe5415 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/renderer/DefaultFluidRenderers.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/renderer/DefaultFluidRenderers.java @@ -5,13 +5,13 @@ public abstract class DefaultFluidRenderers { - private static final ReferenceOpenHashSet set = new ReferenceOpenHashSet<>(); + private static final ReferenceOpenHashSet set = new ReferenceOpenHashSet<>(); - public static void add(FluidRenderHandler handler) { - set.add(handler); - } + public static void add(FluidRenderHandler handler) { + set.add(handler); + } - public static boolean has(FluidRenderHandler handler) { - return set.contains(handler); - } + public static boolean has(FluidRenderHandler handler) { + return set.contains(handler); + } } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java b/src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java index 066d69983..f29acae11 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/renderer/FluidRenderer.java @@ -40,29 +40,19 @@ public class FluidRenderer implements FluidRendering.DefaultRenderer { private final BlockPos.MutableBlockPos mBlockPos = new BlockPos.MutableBlockPos(); private final ModelQuad modelQuad = new ModelQuad(); + + BuilderResources resources; + private final LightPipeline smoothLightPipeline; private final LightPipeline flatLightPipeline; + private final int[] quadColors = new int[4]; - BuilderResources resources; public FluidRenderer(LightPipeline flatLightPipeline, LightPipeline smoothLightPipeline) { this.smoothLightPipeline = smoothLightPipeline; this.flatLightPipeline = flatLightPipeline; } - public static boolean shouldRenderFace(BlockAndTintGetter blockAndTintGetter, BlockPos blockPos, FluidState fluidState, BlockState blockState, Direction direction, BlockState adjBlockState) { - - if (adjBlockState.getFluidState().getType().isSame(fluidState.getType())) - return false; - - // self-occlusion by waterlogging - if (blockState.canOcclude()) { - return !blockState.isFaceSturdy(blockAndTintGetter, blockPos, direction); - } - - return true; - } - public void setResources(BuilderResources resources) { this.resources = resources; } @@ -80,7 +70,7 @@ public void renderLiquid(BlockState blockState, FluidState fluidState, BlockPos handler = FluidRenderHandlerRegistry.INSTANCE.get(isLava ? Fluids.LAVA : Fluids.WATER); } - FluidRendering.render(handler, this.resources.getRegion(), blockPos, bufferBuilder, blockState, fluidState, this); + FluidRendering.render(handler, this.resources.getRegion(),blockPos, bufferBuilder, blockState, fluidState, this); } private boolean isFaceOccludedByState(BlockGetter blockGetter, float h, Direction direction, BlockPos blockPos, BlockState blockState) { @@ -102,6 +92,19 @@ private boolean isFaceOccludedByState(BlockGetter blockGetter, float h, Directio } } + public static boolean shouldRenderFace(BlockAndTintGetter blockAndTintGetter, BlockPos blockPos, FluidState fluidState, BlockState blockState, Direction direction, BlockState adjBlockState) { + + if (adjBlockState.getFluidState().getType().isSame(fluidState.getType())) + return false; + + // self-occlusion by waterlogging + if (blockState.canOcclude()) { + return !blockState.isFaceSturdy(blockAndTintGetter, blockPos, direction); + } + + return true; + } + public BlockState getAdjBlockState(BlockAndTintGetter blockAndTintGetter, int x, int y, int z, Direction dir) { mBlockPos.set(x + dir.getStepX(), y + dir.getStepY(), z + dir.getStepZ()); return blockAndTintGetter.getBlockState(mBlockPos); 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 0307b8030..0da19e2e1 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 @@ -13,10 +13,10 @@ import net.vulkanmod.Initializer; import net.vulkanmod.render.chunk.RenderSection; import net.vulkanmod.render.chunk.WorldRenderer; -import net.vulkanmod.render.chunk.build.RenderRegion; -import net.vulkanmod.render.chunk.build.UploadBuffer; 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.chunk.cull.QuadFacing; 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 5b692119a..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 @@ -10,19 +10,17 @@ public abstract class ChunkTask { public static final boolean BENCH = true; protected static TaskDispatcher taskDispatcher; - protected final RenderSection section; - public boolean highPriority = false; - protected AtomicBoolean cancelled = new AtomicBoolean(false); - ChunkTask(RenderSection renderSection) { - this.section = renderSection; - } public static BuildTask createBuildTask(RenderSection renderSection, RenderRegion renderRegion, boolean highPriority) { return new BuildTask(renderSection, renderRegion, highPriority); } - public static void setTaskDispatcher(TaskDispatcher dispatcher) { - taskDispatcher = dispatcher; + protected AtomicBoolean cancelled = new AtomicBoolean(false); + protected final RenderSection section; + public boolean highPriority = false; + + ChunkTask(RenderSection renderSection) { + this.section = renderSection; } public abstract String name(); @@ -33,6 +31,10 @@ public void cancel() { this.cancelled.set(true); } + public static void setTaskDispatcher(TaskDispatcher dispatcher) { + taskDispatcher = dispatcher; + } + public enum Result { CANCELLED, SUCCESSFUL diff --git a/src/main/java/net/vulkanmod/render/chunk/build/task/CompileResult.java b/src/main/java/net/vulkanmod/render/chunk/build/task/CompileResult.java index 13c1d4322..7a00bcf36 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/task/CompileResult.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/task/CompileResult.java @@ -15,9 +15,11 @@ public class CompileResult { public final RenderSection renderSection; public final boolean fullUpdate; - public final EnumMap renderedLayers = new EnumMap<>(TerrainRenderType.class); + final List globalBlockEntities = new ArrayList<>(); final List blockEntities = new ArrayList<>(); + public final EnumMap renderedLayers = new EnumMap<>(TerrainRenderType.class); + VisibilitySet visibilitySet; QuadSorter.SortState transparencyState; CompiledSection compiledSection; @@ -30,7 +32,7 @@ public class CompileResult { public void updateSection() { this.renderSection.updateGlobalBlockEntities(globalBlockEntities); this.renderSection.setCompiledSection(compiledSection); - this.renderSection.setVisibility(((VisibilitySetExtended) visibilitySet).getVisibility()); + this.renderSection.setVisibility(((VisibilitySetExtended)visibilitySet).getVisibility()); this.renderSection.setCompletelyEmpty(compiledSection.isCompletelyEmpty); this.renderSection.setContainsBlockEntities(!blockEntities.isEmpty()); } 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 d54a3e9d7..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,14 +3,15 @@ import com.google.common.collect.Lists; import net.minecraft.world.level.block.entity.BlockEntity; import net.vulkanmod.render.vertex.QuadSorter; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Nullable; import java.util.List; public class CompiledSection { public static final CompiledSection UNCOMPILED = new CompiledSection(); - final List blockEntities = Lists.newArrayList(); + boolean isCompletelyEmpty = false; + final List blockEntities = Lists.newArrayList(); @Nullable QuadSorter.SortState transparencyState; public boolean hasTransparencyState() { diff --git a/src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java b/src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java index cce281f88..e9bdac845 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/task/TaskDispatcher.java @@ -7,22 +7,24 @@ import net.vulkanmod.render.chunk.WorldRenderer; import net.vulkanmod.render.chunk.buffer.DrawBuffers; 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.chunk.build.thread.BuilderResources; import net.vulkanmod.render.vertex.TerrainRenderType; + import org.jetbrains.annotations.Nullable; import java.util.Queue; public class TaskDispatcher { - public final ThreadBuilderPack fixedBuffers; private final Queue compileResults = Queues.newLinkedBlockingDeque(); - private final Queue highPriorityTasks = Queues.newConcurrentLinkedQueue(); - private final Queue lowPriorityTasks = Queues.newConcurrentLinkedQueue(); + public final ThreadBuilderPack fixedBuffers; + private volatile boolean stopThreads; private Thread[] threads; private BuilderResources[] resources; private int idleThreads; + private final Queue highPriorityTasks = Queues.newConcurrentLinkedQueue(); + private final Queue lowPriorityTasks = Queues.newConcurrentLinkedQueue(); public TaskDispatcher() { this.fixedBuffers = new ThreadBuilderPack(); @@ -36,13 +38,13 @@ public void createThreads() { } public void createThreads(int n) { - if (!this.stopThreads) { + if(!this.stopThreads) { this.stopThreads(); } this.stopThreads = false; - if (this.resources != null) { + if(this.resources != null) { for (BuilderResources resources : this.resources) { resources.clear(); } @@ -69,10 +71,10 @@ public void createThreads(int n) { } private void runTaskThread(BuilderResources builderResources) { - while (!this.stopThreads) { + while(!this.stopThreads) { ChunkTask task = this.pollTask(); - if (task == null) + if(task == null) synchronized (this) { try { this.idleThreads++; @@ -83,7 +85,7 @@ private void runTaskThread(BuilderResources builderResources) { this.idleThreads--; } - if (task == null) + if(task == null) continue; task.runTask(builderResources); @@ -91,7 +93,7 @@ private void runTaskThread(BuilderResources builderResources) { } public void schedule(ChunkTask chunkTask) { - if (chunkTask == null) + if(chunkTask == null) return; if (chunkTask.highPriority) { @@ -109,14 +111,14 @@ public void schedule(ChunkTask chunkTask) { private ChunkTask pollTask() { ChunkTask task = this.highPriorityTasks.poll(); - if (task == null) + if(task == null) task = this.lowPriorityTasks.poll(); return task; } public void stopThreads() { - if (this.stopThreads) + if(this.stopThreads) return; this.stopThreads = true; @@ -138,7 +140,7 @@ public void stopThreads() { public boolean updateSections() { CompileResult result; boolean flag = false; - while ((result = this.compileResults.poll()) != null) { + while((result = this.compileResults.poll()) != null) { flag = true; doSectionUpdate(result); } @@ -160,12 +162,12 @@ private void doSectionUpdate(CompileResult compileResult) { if (chunkAreaManager.getChunkArea(renderArea.index) != renderArea) return; - if (compileResult.fullUpdate) { + if(compileResult.fullUpdate) { var renderLayers = compileResult.renderedLayers; - for (TerrainRenderType renderType : TerrainRenderType.VALUES) { + for(TerrainRenderType renderType : TerrainRenderType.VALUES) { UploadBuffer uploadBuffer = renderLayers.get(renderType); - if (uploadBuffer != null) { + if(uploadBuffer != null) { drawBuffers.upload(section, uploadBuffer, renderType); } else { section.resetDrawParameters(renderType); @@ -173,25 +175,24 @@ private void doSectionUpdate(CompileResult compileResult) { } compileResult.updateSection(); - } else { + } + else { UploadBuffer uploadBuffer = compileResult.renderedLayers.get(TerrainRenderType.TRANSLUCENT); drawBuffers.upload(section, uploadBuffer, TerrainRenderType.TRANSLUCENT); } } - public boolean isIdle() { - return this.idleThreads == this.threads.length && this.compileResults.isEmpty(); - } + public boolean isIdle() { return this.idleThreads == this.threads.length && this.compileResults.isEmpty(); } public void clearBatchQueue() { - while (!this.highPriorityTasks.isEmpty()) { + while(!this.highPriorityTasks.isEmpty()) { ChunkTask chunkTask = this.highPriorityTasks.poll(); if (chunkTask != null) { chunkTask.cancel(); } } - while (!this.lowPriorityTasks.isEmpty()) { + while(!this.lowPriorityTasks.isEmpty()) { ChunkTask chunkTask = this.lowPriorityTasks.poll(); if (chunkTask != null) { chunkTask.cancel(); 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 35b065ae4..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,6 +2,8 @@ import net.vulkanmod.Initializer; import net.vulkanmod.render.chunk.RenderSection; +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.color.TintCache; import net.vulkanmod.render.chunk.build.light.LightMode; @@ -11,8 +13,6 @@ 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; -import net.vulkanmod.render.chunk.build.renderer.BlockRenderer; -import net.vulkanmod.render.chunk.build.renderer.FluidRenderer; public class BuilderResources { public final ThreadBuilderPack builderPack = new ThreadBuilderPack(); @@ -34,7 +34,8 @@ public BuilderResources() { LightPipeline smoothLightPipeline; if (Initializer.CONFIG.ambientOcclusion == LightMode.SUB_BLOCK) { smoothLightPipeline = new NewSmoothLightPipeline(lightDataCache); - } else { + } + else { smoothLightPipeline = new SmoothLightPipeline(lightDataCache); } 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 6ff4bf0f2..64d702603 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 @@ -10,6 +10,15 @@ public class ThreadBuilderPack { private static Function terrainBuilderConstructor; + + public static void defaultTerrainBuilderConstructor() { + terrainBuilderConstructor = renderType -> new TerrainBuilder(TerrainRenderType.getLayer(renderType).bufferSize()); + } + + public static void setTerrainBuilderConstructor(Function constructor) { + terrainBuilderConstructor = constructor; + } + private final Map builders; public ThreadBuilderPack() { @@ -21,14 +30,6 @@ public ThreadBuilderPack() { builders = map; } - public static void defaultTerrainBuilderConstructor() { - terrainBuilderConstructor = renderType -> new TerrainBuilder(TerrainRenderType.getLayer(renderType).bufferSize()); - } - - public static void setTerrainBuilderConstructor(Function constructor) { - terrainBuilderConstructor = constructor; - } - public TerrainBuilder builder(TerrainRenderType renderType) { return this.builders.get(renderType); } diff --git a/src/main/java/net/vulkanmod/render/chunk/frustum/VFrustum.java b/src/main/java/net/vulkanmod/render/chunk/frustum/VFrustum.java index 158ca23ef..396e1f4dd 100644 --- a/src/main/java/net/vulkanmod/render/chunk/frustum/VFrustum.java +++ b/src/main/java/net/vulkanmod/render/chunk/frustum/VFrustum.java @@ -6,13 +6,14 @@ import org.joml.Vector4f; public class VFrustum { - private final FrustumIntersection frustum = new FrustumIntersection(); - private final Matrix4f matrix = new Matrix4f(); private Vector4f viewVector = new Vector4f(); private double camX; private double camY; private double camZ; + private final FrustumIntersection frustum = new FrustumIntersection(); + private final Matrix4f matrix = new Matrix4f(); + public VFrustum offsetToFullyIncludeCameraCube(int offset) { double d0 = Math.floor(this.camX / (double) offset) * (double) offset; double d1 = Math.floor(this.camY / (double) offset) * (double) offset; 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 c75737747..58b2d156e 100644 --- a/src/main/java/net/vulkanmod/render/chunk/graph/SectionGraph.java +++ b/src/main/java/net/vulkanmod/render/chunk/graph/SectionGraph.java @@ -12,10 +12,7 @@ import net.minecraft.world.phys.Vec3; import net.vulkanmod.Initializer; import net.vulkanmod.interfaces.FrustumMixed; -import net.vulkanmod.render.chunk.ChunkAreaManager; -import net.vulkanmod.render.chunk.RenderSection; -import net.vulkanmod.render.chunk.SectionGrid; -import net.vulkanmod.render.chunk.WorldRenderer; +import net.vulkanmod.render.chunk.*; import net.vulkanmod.render.chunk.build.RenderRegionBuilder; import net.vulkanmod.render.chunk.build.task.TaskDispatcher; import net.vulkanmod.render.chunk.frustum.VFrustum; @@ -27,19 +24,23 @@ import java.util.List; public class SectionGraph { + Minecraft minecraft; private final Level level; + private final SectionGrid sectionGrid; private final ChunkAreaManager chunkAreaManager; private final TaskDispatcher taskDispatcher; private final ResettableQueue sectionQueue = new ResettableQueue<>(); + private AreaSetQueue chunkAreaQueue; + private short lastFrame = 0; + private final ResettableQueue blockEntitiesSections = new ResettableQueue<>(); private final ResettableQueue rebuildQueue = new ResettableQueue<>(); + + private VFrustum frustum; + public RenderRegionBuilder renderRegionCache; - Minecraft minecraft; int nonEmptyChunks; - private final AreaSetQueue chunkAreaQueue; - private short lastFrame = 0; - private VFrustum frustum; public SectionGraph(Level level, SectionGrid sectionGrid, TaskDispatcher taskDispatcher) { @@ -53,27 +54,6 @@ public SectionGraph(Level level, SectionGrid sectionGrid, TaskDispatcher taskDis this.renderRegionCache = WorldRenderer.getInstance().renderRegionCache; } - private static void initFirstNode(RenderSection renderSection, short frame) { - renderSection.mainDir = 7; - renderSection.sourceDirs = (byte) (1 << 7); - renderSection.directions = (byte) 0xFF; - renderSection.setLastFrame(frame); - renderSection.visibility |= initVisibility(); - renderSection.directionChanges = 0; - renderSection.steps = 0; - } - - // Init special value used by first graph node - private static long initVisibility() { - long vis = 0; - for (int dir = 0; dir < 6; dir++) { - vis |= 1L << ((6 << 3) + dir); - vis |= 1L << ((7 << 3) + dir); - } - - return vis; - } - public void update(Camera camera, Frustum frustum, boolean spectator) { Profiler profiler = Profiler.getMainProfiler(); ProfilerFiller mcProfiler = net.minecraft.util.profiling.Profiler.get(); @@ -145,6 +125,27 @@ private void initializeQueueForFullUpdate(Camera camera) { } + private static void initFirstNode(RenderSection renderSection, short frame) { + renderSection.mainDir = 7; + renderSection.sourceDirs = (byte) (1 << 7); + renderSection.directions = (byte) 0xFF; + renderSection.setLastFrame(frame); + renderSection.visibility |= initVisibility(); + renderSection.directionChanges = 0; + renderSection.steps = 0; + } + + // Init special value used by first graph node + private static long initVisibility() { + long vis = 0; + for (int dir = 0; dir < 6; dir++) { + vis |= 1L << ((6 << 3) + dir); + vis |= 1L << ((7 << 3) + dir); + } + + return vis; + } + private void initUpdate() { this.resetUpdateQueues(); 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 9d33fa9ff..d8964eaa9 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/CircularIntList.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/CircularIntList.java @@ -7,9 +7,10 @@ public class CircularIntList { private final int size; private final int[] list; + private int startIndex; + private final OwnIterator iterator; private final RangeIterator rangeIterator; - private int startIndex; public CircularIntList(int size) { this.size = size; @@ -27,11 +28,11 @@ public void updateStartIdx(int startIndex) { list[size + 1] = -1; int k = 1; - for (int i = startIndex; i < size; ++i) { + for(int i = startIndex; i < size; ++i) { list[k] = i; ++k; } - for (int i = 0; i < startIndex; ++i) { + for(int i = 0; i < startIndex; ++i) { list[k] = i; ++k; } @@ -59,8 +60,8 @@ public RangeIterator createRangeIterator() { } public class OwnIterator implements Iterator { - private final int maxIndex = size; private int currentIndex = 0; + private final int maxIndex = size; @Override public boolean hasNext() { diff --git a/src/main/java/net/vulkanmod/render/chunk/util/ResettableQueue.java b/src/main/java/net/vulkanmod/render/chunk/util/ResettableQueue.java index 9893bebe5..910b435a4 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/ResettableQueue.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/ResettableQueue.java @@ -73,8 +73,8 @@ public void clear() { public Iterator iterator(boolean reverseOrder) { return reverseOrder ? new Iterator<>() { - final int limit = -1; int pos = ResettableQueue.this.limit - 1; + final int limit = -1; @Override public boolean hasNext() { @@ -87,8 +87,8 @@ public T next() { } } : new Iterator<>() { - final int limit = ResettableQueue.this.limit; int pos = 0; + final int limit = ResettableQueue.this.limit; @Override public boolean hasNext() { diff --git a/src/main/java/net/vulkanmod/render/chunk/util/SimpleDirection.java b/src/main/java/net/vulkanmod/render/chunk/util/SimpleDirection.java index 75bdd757d..b4c53e808 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/SimpleDirection.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/SimpleDirection.java @@ -12,11 +12,17 @@ public enum SimpleDirection { EAST(5, 4, 3, new Vec3i(1, 0, 0)); private static final SimpleDirection[] VALUES = SimpleDirection.values(); - public final byte nx, ny, nz; + + public static SimpleDirection of(Direction direction) { + return VALUES[direction.get3DDataValue()]; + } + private final int data3d; private final int oppositeIndex; private final int data2d; + public final byte nx, ny, nz; + SimpleDirection(int j, int k, int l, Vec3i normal) { this.data3d = j; this.oppositeIndex = k; @@ -27,10 +33,6 @@ public enum SimpleDirection { this.nz = (byte) normal.getZ(); } - public static SimpleDirection of(Direction direction) { - return VALUES[direction.get3DDataValue()]; - } - public int get3DDataValue() { return this.data3d; } diff --git a/src/main/java/net/vulkanmod/render/chunk/util/StaticQueue.java b/src/main/java/net/vulkanmod/render/chunk/util/StaticQueue.java index b2a919a4e..2d811c072 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/StaticQueue.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/StaticQueue.java @@ -7,9 +7,9 @@ public class StaticQueue implements Iterable { final T[] queue; - final int capacity; int position = 0; int limit = 0; + final int capacity; public StaticQueue() { this(1024); @@ -48,8 +48,8 @@ public void clear() { public Iterator iterator(boolean reverseOrder) { return reverseOrder ? new Iterator<>() { - final int limit = -1; int pos = StaticQueue.this.limit - 1; + final int limit = -1; @Override public boolean hasNext() { @@ -62,8 +62,8 @@ public T next() { } } : new Iterator<>() { - final int limit = StaticQueue.this.limit; int pos = 0; + final int limit = StaticQueue.this.limit; @Override public boolean hasNext() { 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 81be1eae0..caa063410 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/Util.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/Util.java @@ -1,6 +1,9 @@ package net.vulkanmod.render.chunk.util; import net.minecraft.core.Direction; +import org.lwjgl.system.MemoryUtil; + +import java.nio.ByteBuffer; public class Util { diff --git a/src/main/java/net/vulkanmod/render/engine/EGlProgram.java b/src/main/java/net/vulkanmod/render/engine/EGlProgram.java index 0a2da7b53..9bc7905d9 100644 --- a/src/main/java/net/vulkanmod/render/engine/EGlProgram.java +++ b/src/main/java/net/vulkanmod/render/engine/EGlProgram.java @@ -1,7 +1,7 @@ package net.vulkanmod.render.engine; import com.google.common.collect.Sets; -import com.mojang.blaze3d.opengl.Uniform; +import com.mojang.blaze3d.opengl.*; import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.logging.LogUtils; @@ -15,7 +15,7 @@ public class EGlProgram { private static final Logger LOGGER = LogUtils.getLogger(); - public static Set BUILT_IN_UNIFORMS = Sets.newHashSet("Projection", "Lighting", "Fog", "Globals"); + public static Set BUILT_IN_UNIFORMS = Sets.newHashSet("Projection", "Lighting", "Fog", "Globals"); public static EGlProgram INVALID_PROGRAM = new EGlProgram(-1, "invalid"); private final Map uniformsByName = new HashMap(); private final int programId; @@ -65,7 +65,7 @@ public void setupUniforms(Pipeline pipeline, List supplier, GpuTextureView col } else { this.inRenderPass = true; GpuTexture depthTexture1 = depthTexture != null ? depthTexture.texture() : null; - VkFbo fbo = ((VkGpuTexture) colorTexture.texture()).getFbo(depthTexture1); + VkFbo fbo = ((VkGpuTexture)colorTexture.texture()).getFbo(depthTexture1); fbo.bind(); int j = 0; @@ -149,7 +144,8 @@ public RenderPass createRenderPass(Supplier supplier, GpuTextureView col public void clearColorTexture(GpuTexture colorAttachment, int color) { if (this.inRenderPass) { throw new IllegalStateException("Close the existing render pass before creating a new one!"); - } else if (Renderer.isRecording()) { + } + else if (Renderer.isRecording()) { VkGpuTexture vkGpuTexture = (VkGpuTexture) colorAttachment; VkGlFramebuffer.bindFramebuffer(GL30.GL_FRAMEBUFFER, framebufferId); VkGlFramebuffer.framebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, vkGpuTexture.glId(), 0); @@ -158,7 +154,8 @@ public void clearColorTexture(GpuTexture colorAttachment, int color) { VRenderSystem.setClearColor(ARGB.redFloat(color), ARGB.greenFloat(color), ARGB.blueFloat(color), ARGB.alphaFloat(color)); Renderer.clearAttachments(16384); Renderer.getInstance().endRenderPass(); - } else { + } + else { GraphicsQueue graphicsQueue = DeviceManager.getGraphicsQueue(); var commandBuffer = graphicsQueue.getCommandBuffer(); VkGpuTexture vkGpuTexture = (VkGpuTexture) colorAttachment; @@ -187,15 +184,17 @@ public void clearColorTexture(GpuTexture colorAttachment, int color) { public void clearColorAndDepthTextures(GpuTexture colorAttachment, int clearColor, GpuTexture depthAttachment, double clearDepth) { if (this.inRenderPass) { throw new IllegalStateException("Close the existing render pass before creating a new one!"); - } else { + } + else { if (Minecraft.getInstance().getMainRenderTarget().getColorTexture() == colorAttachment) { Renderer.getInstance().getMainPass().rebindMainTarget(); VRenderSystem.clearDepth(clearDepth); VRenderSystem.setClearColor(ARGB.redFloat(clearColor), ARGB.greenFloat(clearColor), ARGB.blueFloat(clearColor), ARGB.alphaFloat(clearColor)); Renderer.clearAttachments(0x4100); - } else { - VkFbo fbo = ((VkGpuTexture) colorAttachment).getFbo(depthAttachment); + } + else { + VkFbo fbo = ((VkGpuTexture)colorAttachment).getFbo(depthAttachment); fbo.clear = 0x4100; fbo.clearColor = clearColor; @@ -203,7 +202,8 @@ public void clearColorAndDepthTextures(GpuTexture colorAttachment, int clearColo Framebuffer boundFramebuffer = Renderer.getInstance().getBoundFramebuffer(); if (boundFramebuffer.getColorAttachment() == ((VkGpuTexture) colorAttachment).getVulkanImage() - && boundFramebuffer.getDepthAttachment() == ((VkGpuTexture) depthAttachment).getVulkanImage()) { + && boundFramebuffer.getDepthAttachment() == ((VkGpuTexture) depthAttachment).getVulkanImage()) + { fbo.clearAttachments(); } } @@ -223,9 +223,11 @@ public void clearColorAndDepthTextures(GpuTexture colorAttachment, int clearColo Framebuffer boundFramebuffer = Renderer.getInstance().getBoundFramebuffer(); if (boundFramebuffer.getColorAttachment() == ((VkGpuTexture) colorAttachment).getVulkanImage() - && boundFramebuffer.getDepthAttachment() == ((VkGpuTexture) depthAttachment).getVulkanImage()) { + && boundFramebuffer.getDepthAttachment() == ((VkGpuTexture) depthAttachment).getVulkanImage()) + { Renderer.clearAttachments(0x4100, x0, y0, width, height); - } else { + } + else { // TODO // throw new IllegalStateException(); } @@ -236,7 +238,8 @@ public void clearColorAndDepthTextures(GpuTexture colorAttachment, int clearColo public void clearDepthTexture(GpuTexture depthAttachment, double clearDepth) { if (this.inRenderPass) { throw new IllegalStateException("Close the existing render pass before creating a new one!"); - } else { + } + else { // depthAttachment is not the target here VRenderSystem.clearDepth(clearDepth); Renderer.clearAttachments(256); @@ -251,7 +254,8 @@ public void writeToBuffer(GpuBufferSlice gpuBufferSlice, ByteBuffer byteBuffer) VkGpuBuffer vkGpuBuffer = (VkGpuBuffer) gpuBufferSlice.buffer(); if (vkGpuBuffer.closed) { throw new IllegalStateException("Buffer already closed"); - } else { + } + else { int size = byteBuffer.remaining(); if (size + gpuBufferSlice.offset() > vkGpuBuffer.size()) { throw new IllegalArgumentException( @@ -294,7 +298,7 @@ public GpuBuffer.MappedView mapBuffer(GpuBufferSlice gpuBufferSlice, boolean rea if (this.inRenderPass) { throw new IllegalStateException("Close the existing render pass before performing additional commands"); } else { - VkGpuBuffer gpuBuffer = (VkGpuBuffer) (gpuBufferSlice.buffer()); + VkGpuBuffer gpuBuffer = (VkGpuBuffer)(gpuBufferSlice.buffer()); if (gpuBuffer.closed) { throw new IllegalStateException("Buffer already closed"); } else if (!readable && !writable) { @@ -306,12 +310,12 @@ public GpuBuffer.MappedView mapBuffer(GpuBufferSlice gpuBufferSlice, boolean rea } else if (gpuBufferSlice.offset() + gpuBufferSlice.length() > gpuBuffer.size()) { throw new IllegalArgumentException( "Cannot map more data than this buffer can hold (attempting to map " - + gpuBufferSlice.length() - + " bytes at offset " - + gpuBufferSlice.offset() - + " from " - + gpuBuffer.size() - + " size buffer)" + + gpuBufferSlice.length() + + " bytes at offset " + + gpuBufferSlice.offset() + + " from " + + gpuBuffer.size() + + " size buffer)" ); } else { int i = 0; @@ -387,17 +391,17 @@ public void writeToTexture(GpuTexture gpuTexture, NativeImage nativeImage, int l if (unpackSkipPixels + width > nativeImage.getWidth() || unpackSkipRows + height > nativeImage.getHeight()) { throw new IllegalArgumentException( "Copy source (" - + nativeImage.getWidth() - + "x" - + nativeImage.getHeight() - + ") is not large enough to read a rectangle of " - + width - + "x" - + height - + " from " - + unpackSkipPixels - + "x" - + unpackSkipRows + + nativeImage.getWidth() + + "x" + + nativeImage.getHeight() + + ") is not large enough to read a rectangle of " + + width + + "x" + + height + + " from " + + unpackSkipPixels + + "x" + + unpackSkipRows ); } else if (xOffset + width > gpuTexture.getWidth(level) || yOffset + height > gpuTexture.getHeight(level)) { throw new IllegalArgumentException( @@ -427,17 +431,17 @@ public void writeToTexture(GpuTexture gpuTexture, ByteBuffer byteBuffer, NativeI } else if (xOffset + width > gpuTexture.getWidth(level) || yOffset + height > gpuTexture.getHeight(level)) { throw new IllegalArgumentException( "Dest texture (" - + gpuTexture.getWidth(level) - + "x" - + gpuTexture.getHeight(level) - + ") is not large enough to write a rectangle of " - + width - + "x" - + height - + " at " - + xOffset - + "x" - + yOffset + + gpuTexture.getWidth(level) + + "x" + + gpuTexture.getHeight(level) + + ") is not large enough to write a rectangle of " + + width + + "x" + + height + + " at " + + xOffset + + "x" + + yOffset ); } else if (gpuTexture.isClosed()) { throw new IllegalStateException("Destination texture is closed"); @@ -445,8 +449,9 @@ public void writeToTexture(GpuTexture gpuTexture, ByteBuffer byteBuffer, NativeI throw new IllegalStateException("Color texture must have USAGE_COPY_DST to be a destination for a write"); } else if (j >= gpuTexture.getDepthOrLayers()) { throw new UnsupportedOperationException("Depth or layer is out of range, must be >= 0 and < " + gpuTexture.getDepthOrLayers()); - } else { - GlStateManager._bindTexture(((VkGpuTexture) gpuTexture).id); + } + else { + GlStateManager._bindTexture(((VkGpuTexture)gpuTexture).id); GlStateManager._pixelStore(3314, width); GlStateManager._pixelStore(3316, 0); @@ -479,30 +484,31 @@ public void copyTextureToBuffer(GpuTexture gpuTexture, GpuBuffer gpuBuffer, int if (gpuTexture.getWidth(mipLevel) * gpuTexture.getHeight(mipLevel) * vkGpuTexture.getVulkanImage().formatSize + dstOffset > gpuBuffer.size()) { throw new IllegalArgumentException( "Buffer of size " - + gpuBuffer.size() - + " is not large enough to hold " - + width - + "x" - + height - + " pixels (" - + vkGpuTexture.getVulkanImage().formatSize - + " bytes each) starting from offset " - + dstOffset + + gpuBuffer.size() + + " is not large enough to hold " + + width + + "x" + + height + + " pixels (" + + vkGpuTexture.getVulkanImage().formatSize + + " bytes each) starting from offset " + + dstOffset ); - } else if (xOffset + width > gpuTexture.getWidth(mipLevel) || yOffset + height > gpuTexture.getHeight(mipLevel)) { + } + else if (xOffset + width > gpuTexture.getWidth(mipLevel) || yOffset + height > gpuTexture.getHeight(mipLevel)) { throw new IllegalArgumentException( "Copy source texture (" - + gpuTexture.getWidth(mipLevel) - + "x" - + gpuTexture.getHeight(mipLevel) - + ") is not large enough to read a rectangle of " - + width - + "x" - + height - + " from " - + xOffset - + "," - + yOffset + + gpuTexture.getWidth(mipLevel) + + "x" + + gpuTexture.getHeight(mipLevel) + + ") is not large enough to read a rectangle of " + + width + + "x" + + height + + " from " + + xOffset + + "," + + yOffset ); } else if (gpuTexture.isClosed()) { throw new IllegalStateException("Source texture is closed"); @@ -526,32 +532,32 @@ public void copyTextureToTexture(GpuTexture gpuTexture, GpuTexture gpuTexture2, if (j + n > gpuTexture2.getWidth(mipLevel) || k + o > gpuTexture2.getHeight(mipLevel)) { throw new IllegalArgumentException( "Dest texture (" - + gpuTexture2.getWidth(mipLevel) - + "x" - + gpuTexture2.getHeight(mipLevel) - + ") is not large enough to write a rectangle of " - + n - + "x" - + o - + " at " - + j - + "x" - + k + + gpuTexture2.getWidth(mipLevel) + + "x" + + gpuTexture2.getHeight(mipLevel) + + ") is not large enough to write a rectangle of " + + n + + "x" + + o + + " at " + + j + + "x" + + k ); } else if (l + n > gpuTexture.getWidth(mipLevel) || m + o > gpuTexture.getHeight(mipLevel)) { throw new IllegalArgumentException( "Source texture (" - + gpuTexture.getWidth(mipLevel) - + "x" - + gpuTexture.getHeight(mipLevel) - + ") is not large enough to read a rectangle of " - + n - + "x" - + o - + " at " - + l - + "x" - + m + + gpuTexture.getWidth(mipLevel) + + "x" + + gpuTexture.getHeight(mipLevel) + + ") is not large enough to read a rectangle of " + + n + + "x" + + o + + " at " + + l + + "x" + + m ); } else if (gpuTexture.isClosed()) { throw new IllegalStateException("Source texture is closed"); @@ -633,11 +639,11 @@ protected void executeDrawMultiple( if (biConsumer != null) { biConsumer.accept(object, (string, gpuBufferSlice) -> { EGlProgram glProgram = ExtendedRenderPipeline.of(renderPass.pipeline).getProgram(); - if (glProgram.getUniform(string) instanceof Uniform.Ubo(int blockBinding)) { + if (glProgram.getUniform(string) instanceof Uniform.Ubo ubo) { int blockBinding; try { - blockBinding = blockBinding; + blockBinding = ubo.blockBinding(); } catch (Throwable var7) { throw new MatchException(var7.toString(), var7); } @@ -682,7 +688,8 @@ protected void executeDraw(VkRenderPass renderPass, int i, int j, int k, @Nullab } public void drawFromBuffers(VkRenderPass renderPass, int vertexOffset, int firstIndex, int vertexCount, - @Nullable VertexFormat.IndexType indexType, RenderPipeline renderPipeline, int instanceCount) { + @Nullable VertexFormat.IndexType indexType, RenderPipeline renderPipeline, int instanceCount) + { if (instanceCount < 1) { instanceCount = 1; } @@ -695,14 +702,14 @@ public void drawFromBuffers(VkRenderPass renderPass, int vertexOffset, int first } VkCommandBuffer vkCommandBuffer = Renderer.getCommandBuffer(); - VkGpuBuffer vertexBuffer = (VkGpuBuffer) renderPass.vertexBuffers[0]; + VkGpuBuffer vertexBuffer = (VkGpuBuffer)renderPass.vertexBuffers[0]; try (MemoryStack stack = stackPush()) { if (vertexBuffer != null) { VK11.vkCmdBindVertexBuffers(vkCommandBuffer, 0, stack.longs(vertexBuffer.buffer.getId()), stack.longs(0)); } if (renderPass.indexBuffer != null) { - VkGpuBuffer indexBuffer = (VkGpuBuffer) renderPass.indexBuffer; + VkGpuBuffer indexBuffer = (VkGpuBuffer)renderPass.indexBuffer; int vkIndexType = switch (indexType) { case SHORT -> VK_INDEX_TYPE_UINT16; @@ -711,13 +718,15 @@ public void drawFromBuffers(VkRenderPass renderPass, int vertexOffset, int first VK11.vkCmdBindIndexBuffer(vkCommandBuffer, indexBuffer.buffer.getId(), 0, vkIndexType); VK11.vkCmdDrawIndexed(vkCommandBuffer, vertexCount, instanceCount, firstIndex, vertexOffset, 0); - } else { + } + else { var autoIndexBuffer = Renderer.getDrawer().getAutoIndexBuffer(renderPipeline.getVertexFormatMode(), vertexCount); if (autoIndexBuffer != null) { int indexCount = autoIndexBuffer.getIndexCount(vertexCount); VK11.vkCmdBindIndexBuffer(vkCommandBuffer, autoIndexBuffer.getIndexBuffer().getId(), 0, autoIndexBuffer.getIndexBuffer().indexType.value); VK11.vkCmdDrawIndexed(vkCommandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, 0); - } else { + } + else { VK11.vkCmdDraw(vkCommandBuffer, vertexCount, instanceCount, vertexOffset, 0); } } diff --git a/src/main/java/net/vulkanmod/render/engine/VkDebugLabel.java b/src/main/java/net/vulkanmod/render/engine/VkDebugLabel.java index 7e9f648e2..60ac40491 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkDebugLabel.java +++ b/src/main/java/net/vulkanmod/render/engine/VkDebugLabel.java @@ -1,23 +1,17 @@ package net.vulkanmod.render.engine; -import com.mojang.blaze3d.opengl.GlProgram; -import com.mojang.blaze3d.opengl.GlShaderModule; -import com.mojang.blaze3d.opengl.VertexArrayCache; +import com.mojang.blaze3d.opengl.*; import com.mojang.logging.LogUtils; +import java.util.Set; + import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import org.slf4j.Logger; -import java.util.Set; - @Environment(EnvType.CLIENT) public class VkDebugLabel { private static final Logger LOGGER = LogUtils.getLogger(); - public static VkDebugLabel create(boolean bl, Set set) { - return new VkDebugLabel(); - } - public void applyLabel(VkGpuBuffer glBuffer) { } @@ -33,6 +27,10 @@ public void applyLabel(GlProgram glProgram) { public void applyLabel(VertexArrayCache.VertexArray vertexArray) { } + public static VkDebugLabel create(boolean bl, Set set) { + return new VkDebugLabel(); + } + public boolean exists() { return true; } diff --git a/src/main/java/net/vulkanmod/render/engine/VkFbo.java b/src/main/java/net/vulkanmod/render/engine/VkFbo.java index 6dce9c934..22bb06ac5 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkFbo.java +++ b/src/main/java/net/vulkanmod/render/engine/VkFbo.java @@ -5,7 +5,11 @@ import net.vulkanmod.gl.VkGlFramebuffer; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; +import net.vulkanmod.vulkan.framebuffer.Framebuffer; import org.lwjgl.opengl.GL33; +import org.lwjgl.system.MemoryStack; + +import static org.lwjgl.system.MemoryStack.stackPush; public class VkFbo { final int glId; diff --git a/src/main/java/net/vulkanmod/render/engine/VkGpuBuffer.java b/src/main/java/net/vulkanmod/render/engine/VkGpuBuffer.java index e35461b3a..1c672841e 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkGpuBuffer.java +++ b/src/main/java/net/vulkanmod/render/engine/VkGpuBuffer.java @@ -1,6 +1,9 @@ package net.vulkanmod.render.engine; import com.mojang.blaze3d.buffers.GpuBuffer; + +import java.nio.ByteBuffer; +import java.util.function.Supplier; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.vulkanmod.vulkan.memory.MemoryManager; @@ -9,16 +12,13 @@ import net.vulkanmod.vulkan.memory.buffer.Buffer; import org.jetbrains.annotations.Nullable; -import java.nio.ByteBuffer; -import java.util.function.Supplier; - import static org.lwjgl.vulkan.VK10.*; @Environment(EnvType.CLIENT) public class VkGpuBuffer extends GpuBuffer { - @Nullable - protected final Supplier label; protected boolean closed; + @Nullable protected final Supplier label; + Buffer buffer; protected VkGpuBuffer(VkDebugLabel glDebugLabel, @Nullable Supplier supplier, int usage, int size) { @@ -46,29 +46,15 @@ protected VkGpuBuffer(VkDebugLabel glDebugLabel, @Nullable Supplier supp } boolean mappable = (usage & GpuBuffer.USAGE_MAP_READ) != 0 | - (usage & GpuBuffer.USAGE_MAP_WRITE) != 0 | - (usage & GpuBuffer.USAGE_HINT_CLIENT_STORAGE) != 0; + (usage & GpuBuffer.USAGE_MAP_WRITE) != 0 | + (usage & GpuBuffer.USAGE_HINT_CLIENT_STORAGE) != 0; - MemoryType memoryType = mappable ? MemoryTypes.HOST_MEM : MemoryTypes.GPU_MEM; + MemoryType memoryType = mappable ? MemoryTypes.HOST_MEM : MemoryTypes.GPU_MEM; this.buffer = new Buffer(vkUsage, memoryType); this.buffer.createBuffer(this.size()); } - public static int bufferUsageToGlEnum(int i) { - boolean stream = (i & 4) != 0; - // Draw - if ((i & 2) != 0) { - return stream ? 35040 : 35044; - } - // Read - else if ((i & 1) != 0) { - return stream ? 35041 : 35045; - } else { - return 35044; - } - } - @Override public boolean isClosed() { return this.closed; @@ -87,6 +73,20 @@ public Buffer getBuffer() { return buffer; } + public static int bufferUsageToGlEnum(int i) { + boolean stream = (i & 4) != 0; + // Draw + if ((i & 2) != 0) { + return stream ? 35040 : 35044; + } + // Read + else if ((i & 1) != 0) { + return stream ? 35041 : 35045; + } else { + return 35044; + } + } + @Environment(EnvType.CLIENT) public static class MappedView implements GpuBuffer.MappedView { private final int target; diff --git a/src/main/java/net/vulkanmod/render/engine/VkGpuDevice.java b/src/main/java/net/vulkanmod/render/engine/VkGpuDevice.java index 0c88bd4e4..6c641decf 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkGpuDevice.java +++ b/src/main/java/net/vulkanmod/render/engine/VkGpuDevice.java @@ -63,22 +63,6 @@ public VkGpuDevice(long l, int i, boolean bl, BiFunction= 1024; j >>= 1) { - GlStateManager._texImage2D(32868, 0, 6408, j, j, 0, 6408, 5121, null); - int k = GlStateManager._getTexLevelParameter(32868, 0, 4096); - if (k != 0) { - return j; - } - } - - int jx = Math.max(i, 1024); - LOGGER.info("Failed to determine maximum texture size by probing, trying GL_MAX_TEXTURE_SIZE = {}", jx); - return jx; - } - public VkDebugLabel debugLabels() { return this.debugLabels; } @@ -109,13 +93,13 @@ public GpuTexture createTexture(@Nullable String string, int usage, TextureForma int attachmentUsage = depthFormat ? VK10.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : VK10.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; VulkanImage texture = VulkanImage.builder(width, height) - .setName(string) - .setFormat(format) - .setArrayLayers(layers) - .setMipLevels(mipLevels) - .addUsage(attachmentUsage) - .setViewType(viewType) - .createVulkanImage(); + .setName(string) + .setFormat(format) + .setArrayLayers(layers) + .setMipLevels(mipLevels) + .addUsage(attachmentUsage) + .setViewType(viewType) + .createVulkanImage(); VkGlTexture vGlTexture = VkGlTexture.getTexture(id); vGlTexture.setVulkanImage(texture); @@ -192,7 +176,7 @@ public boolean isDebuggingEnabled() { @Override public String getRenderer() { - return "VulkanMod %s".formatted(Initializer.getVersion()); + return "VulkanMod %s".formatted(Initializer.getVersion()) ; } @Override @@ -210,6 +194,22 @@ public String getVersion() { return Vulkan.getDevice().vkVersion; } + private static int getMaxSupportedTextureSize() { + int i = GlStateManager._getInteger(3379); + + for (int j = Math.max(32768, i); j >= 1024; j >>= 1) { + GlStateManager._texImage2D(32868, 0, 6408, j, j, 0, 6408, 5121, null); + int k = GlStateManager._getTexLevelParameter(32868, 0, 4096); + if (k != 0) { + return j; + } + } + + int jx = Math.max(i, 1024); + LOGGER.info("Failed to determine maximum texture size by probing, trying GL_MAX_TEXTURE_SIZE = {}", jx); + return jx; + } + @Override public int getMaxTextureSize() { return this.maxSupportedTextureSize; @@ -383,11 +383,16 @@ public String toString() { } } - private record VkRenderPipeline(RenderPipeline renderPipeline) implements CompiledRenderPipeline { + private static class VkRenderPipeline implements CompiledRenderPipeline { + final RenderPipeline renderPipeline; + + public VkRenderPipeline(RenderPipeline renderPipeline) { + this.renderPipeline = renderPipeline; + } @Override - public boolean isValid() { - return true; - } + public boolean isValid() { + return true; } + } } diff --git a/src/main/java/net/vulkanmod/render/engine/VkGpuTexture.java b/src/main/java/net/vulkanmod/render/engine/VkGpuTexture.java index e12cf45f2..b5e5a5b65 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkGpuTexture.java +++ b/src/main/java/net/vulkanmod/render/engine/VkGpuTexture.java @@ -1,27 +1,28 @@ package net.vulkanmod.render.engine; +import com.mojang.blaze3d.opengl.GlConst; import com.mojang.blaze3d.opengl.GlStateManager; import com.mojang.blaze3d.opengl.GlTexture; import com.mojang.blaze3d.textures.AddressMode; import com.mojang.blaze3d.textures.FilterMode; import com.mojang.blaze3d.textures.GpuTexture; import com.mojang.blaze3d.textures.TextureFormat; -import it.unimi.dsi.fastutil.ints.Int2ReferenceMap; -import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.ints.*; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.vulkanmod.gl.VkGlTexture; import net.vulkanmod.vulkan.texture.SamplerManager; import net.vulkanmod.vulkan.texture.VulkanImage; import org.jetbrains.annotations.Nullable; +import org.lwjgl.opengl.GL11; import org.lwjgl.vulkan.VK10; @Environment(EnvType.CLIENT) //public class VkGpuTexture extends GpuTexture { public class VkGpuTexture extends GlTexture { + protected VkGlTexture glTexture; protected final int id; private final Int2ReferenceMap fboCache = new Int2ReferenceOpenHashMap<>(); - protected VkGlTexture glTexture; protected boolean closed; protected boolean modesDirty = true; @@ -31,44 +32,6 @@ protected VkGpuTexture(int usage, String string, TextureFormat textureFormat, in this.glTexture = glTexture; } - public static TextureFormat textureFormat(int format) { - return switch (format) { - case VK10.VK_FORMAT_R8G8B8A8_UNORM, VK10.VK_FORMAT_B8G8R8A8_UNORM -> TextureFormat.RGBA8; - case VK10.VK_FORMAT_R8_UNORM -> TextureFormat.RED8; - case VK10.VK_FORMAT_D32_SFLOAT -> TextureFormat.DEPTH32; - default -> throw new IllegalStateException("Unexpected value: " + format); - }; - } - - public static int vkFormat(TextureFormat textureFormat) { - return switch (textureFormat) { - case RGBA8 -> VK10.VK_FORMAT_R8G8B8A8_UNORM; - case RED8 -> VK10.VK_FORMAT_R8_UNORM; - case RED8I -> VK10.VK_FORMAT_R8_SINT; - case DEPTH32 -> VK10.VK_FORMAT_D32_SFLOAT; - }; - } - -// public int getFbo(DirectStateAccess directStateAccess, @Nullable GpuTexture gpuTexture) { -// int i = gpuTexture == null ? 0 : ((VkGpuTexture)gpuTexture).id; -// return this.fboCache.computeIfAbsent(i, j -> { -// int k = directStateAccess.createFrameBufferObject(); -// directStateAccess.bindFrameBufferTextures(k, this.id, i, 0, 0); -// return k; -// }); -// } - - public static int vkImageViewType(int usage) { - int viewType; - if ((usage & GpuTexture.USAGE_CUBEMAP_COMPATIBLE) != 0) { - viewType = VK10.VK_IMAGE_VIEW_TYPE_CUBE; - } else { - viewType = VK10.VK_IMAGE_VIEW_TYPE_2D; - } - - return viewType; - } - @Override public void close() { if (!this.closed) { @@ -86,6 +49,15 @@ public boolean isClosed() { return this.closed; } +// public int getFbo(DirectStateAccess directStateAccess, @Nullable GpuTexture gpuTexture) { +// int i = gpuTexture == null ? 0 : ((VkGpuTexture)gpuTexture).id; +// return this.fboCache.computeIfAbsent(i, j -> { +// int k = directStateAccess.createFrameBufferObject(); +// directStateAccess.bindFrameBufferTextures(k, this.id, i, 0, 0); +// return k; +// }); +// } + public void flushModeChanges() { if (this.modesDirty) { // GlStateManager._texParameter(3553, 10242, GlConst.toGl(this.addressModeU)); @@ -144,12 +116,42 @@ public void setUseMipmaps(boolean bl) { } public VkFbo getFbo(@Nullable GpuTexture depthAttachment) { - int depthAttachmentId = depthAttachment == null ? 0 : ((VkGpuTexture) depthAttachment).id; + int depthAttachmentId = depthAttachment == null ? 0 : ((VkGpuTexture)depthAttachment).id; return this.fboCache.computeIfAbsent(depthAttachmentId, j -> new VkFbo(this, (VkGpuTexture) depthAttachment)); } public VulkanImage getVulkanImage() { return glTexture.getVulkanImage(); } + + public static TextureFormat textureFormat(int format) { + return switch (format) { + case VK10.VK_FORMAT_R8G8B8A8_UNORM, VK10.VK_FORMAT_B8G8R8A8_UNORM -> TextureFormat.RGBA8; + case VK10.VK_FORMAT_R8_UNORM -> TextureFormat.RED8; + case VK10.VK_FORMAT_D32_SFLOAT -> TextureFormat.DEPTH32; + default -> throw new IllegalStateException("Unexpected value: " + format); + }; + } + + public static int vkFormat(TextureFormat textureFormat) { + return switch (textureFormat) { + case RGBA8 -> VK10.VK_FORMAT_R8G8B8A8_UNORM; + case RED8 -> VK10.VK_FORMAT_R8_UNORM; + case RED8I -> VK10.VK_FORMAT_R8_SINT; + case DEPTH32 -> VK10.VK_FORMAT_D32_SFLOAT; + }; + } + + public static int vkImageViewType(int usage) { + int viewType; + if ((usage & GpuTexture.USAGE_CUBEMAP_COMPATIBLE) != 0) { + viewType = VK10.VK_IMAGE_VIEW_TYPE_CUBE; + } + else { + viewType = VK10.VK_IMAGE_VIEW_TYPE_2D; + } + + return viewType; + } } diff --git a/src/main/java/net/vulkanmod/render/engine/VkRenderPass.java b/src/main/java/net/vulkanmod/render/engine/VkRenderPass.java index 411ed5032..8d9c039bc 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkRenderPass.java +++ b/src/main/java/net/vulkanmod/render/engine/VkRenderPass.java @@ -5,38 +5,40 @@ import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.systems.RenderPass; import com.mojang.blaze3d.systems.ScissorState; +import com.mojang.blaze3d.textures.GpuTexture; import com.mojang.blaze3d.textures.GpuTextureView; import com.mojang.blaze3d.vertex.VertexFormat; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.SharedConstants; -import net.vulkanmod.interfaces.shader.ExtendedRenderPipeline; -import org.jetbrains.annotations.Nullable; - import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import java.util.function.Supplier; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.SharedConstants; +import net.vulkanmod.interfaces.shader.ExtendedRenderPipeline; +import org.jetbrains.annotations.Nullable; +import org.joml.Matrix4f; + @Environment(EnvType.CLIENT) public class VkRenderPass implements RenderPass { - public static final boolean VALIDATION = SharedConstants.IS_RUNNING_IN_IDE; protected static final int MAX_VERTEX_BUFFERS = 1; - protected final GpuBuffer[] vertexBuffers = new GpuBuffer[1]; - protected final HashMap uniforms = new HashMap<>(); - protected final HashMap samplers = new HashMap<>(); - protected final Set dirtyUniforms = new HashSet<>(); + public static final boolean VALIDATION = SharedConstants.IS_RUNNING_IN_IDE; private final VkCommandEncoder encoder; private final boolean hasDepthTexture; - private final ScissorState scissorState = new ScissorState(); + private boolean closed; @Nullable protected RenderPipeline pipeline; + protected final GpuBuffer[] vertexBuffers = new GpuBuffer[1]; @Nullable protected GpuBuffer indexBuffer; protected VertexFormat.IndexType indexType = VertexFormat.IndexType.INT; + private final ScissorState scissorState = new ScissorState(); + protected final HashMap uniforms = new HashMap<>(); + protected final HashMap samplers = new HashMap<>(); + protected final Set dirtyUniforms = new HashSet<>(); protected int pushedDebugGroups; - private boolean closed; public VkRenderPass(VkCommandEncoder commandEncoder, boolean bl) { this.encoder = commandEncoder; @@ -69,6 +71,20 @@ public void popDebugGroup() { } } + @Override + public void setPipeline(RenderPipeline renderPipeline) { + if (this.pipeline == null || this.pipeline != renderPipeline) { + this.dirtyUniforms.addAll(this.uniforms.keySet()); + } + + + this.pipeline = renderPipeline; + + if (ExtendedRenderPipeline.of(renderPipeline).getPipeline() == null) { + this.encoder.getDevice().compilePipeline(renderPipeline); + } + } + @Override public void bindSampler(String string, @Nullable GpuTextureView gpuTextureView) { if (gpuTextureView == null) { @@ -127,9 +143,7 @@ public int getScissorHeight() { return this.scissorState.height(); } - public ScissorState getScissorState() { - return this.scissorState; - } + public ScissorState getScissorState() { return this.scissorState; } @Override public void setVertexBuffer(int i, GpuBuffer gpuBuffer) { @@ -194,19 +208,5 @@ public void close() { public @Nullable RenderPipeline getPipeline() { return pipeline; } - - @Override - public void setPipeline(RenderPipeline renderPipeline) { - if (this.pipeline == null || this.pipeline != renderPipeline) { - this.dirtyUniforms.addAll(this.uniforms.keySet()); - } - - - this.pipeline = renderPipeline; - - if (ExtendedRenderPipeline.of(renderPipeline).getPipeline() == null) { - this.encoder.getDevice().compilePipeline(renderPipeline); - } - } } diff --git a/src/main/java/net/vulkanmod/render/model/CubeModel.java b/src/main/java/net/vulkanmod/render/model/CubeModel.java index 1439893a8..ef5bb5548 100644 --- a/src/main/java/net/vulkanmod/render/model/CubeModel.java +++ b/src/main/java/net/vulkanmod/render/model/CubeModel.java @@ -9,14 +9,15 @@ public class CubeModel { + private Polygon[] polygons; public float minX; public float minY; public float minZ; public float maxX; public float maxY; public float maxZ; + Vertex[] vertices; - private Polygon[] polygons; public void setVertices(int u, int v, float minX, float minY, float minZ, float dimX, float dimY, float dimZ, float growX, float growY, float growZ, boolean mirror, float uTexScale, float vTexScale, Set set) { this.minX = minX; @@ -43,24 +44,24 @@ public void setVertices(int u, int v, float minX, float minY, float minZ, float this.vertices = new Vertex[]{ new Vertex(minX, minY, minZ, 0.0F, 0.0F), - new Vertex(s, minY, minZ, 0.0F, 8.0F), - new Vertex(s, t, minZ, 8.0F, 8.0F), - new Vertex(minX, t, minZ, 8.0F, 0.0F), - new Vertex(minX, minY, u1, 0.0F, 0.0F), - new Vertex(s, minY, u1, 0.0F, 8.0F), - new Vertex(s, t, u1, 8.0F, 8.0F), - new Vertex(minX, t, u1, 8.0F, 0.0F) + new Vertex(s, minY, minZ, 0.0F, 8.0F), + new Vertex(s, t, minZ, 8.0F, 8.0F), + new Vertex(minX, t, minZ, 8.0F, 0.0F), + new Vertex(minX, minY, u1, 0.0F, 0.0F), + new Vertex(s, minY, u1, 0.0F, 8.0F), + new Vertex(s, t, u1, 8.0F, 8.0F), + new Vertex(minX, t, u1, 8.0F, 0.0F) }; - float w = (float) u; - float x = (float) u + dimZ; - float y = (float) u + dimZ + dimX; - float z = (float) u + dimZ + dimX + dimX; - float aa = (float) u + dimZ + dimX + dimZ; - float ab = (float) u + dimZ + dimX + dimZ + dimX; - float ac = (float) v; - float ad = (float) v + dimZ; - float ae = (float) v + dimZ + dimY; + float w = (float)u; + float x = (float)u + dimZ; + float y = (float)u + dimZ + dimX; + float z = (float)u + dimZ + dimX + dimX; + float aa = (float)u + dimZ + dimX + dimZ; + float ab = (float)u + dimZ + dimX + dimZ + dimX; + float ac = (float)v; + float ad = (float)v + dimZ; + float ae = (float)v + dimZ + dimY; Vertex vertex1 = this.vertices[0]; Vertex vertex2 = this.vertices[1]; 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 9316097c1..d87df233d 100644 --- a/src/main/java/net/vulkanmod/render/model/quad/ModelQuad.java +++ b/src/main/java/net/vulkanmod/render/model/quad/ModelQuad.java @@ -9,24 +9,23 @@ */ public class ModelQuad implements ModelQuadView { public static final int VERTEX_SIZE = 8; - private final int[] data = new int[4 * VERTEX_SIZE]; - Direction direction; - TextureAtlasSprite sprite; - private int flags; public static int vertexOffset(int vertexIndex) { return vertexIndex * VERTEX_SIZE; } + private final int[] data = new int[4 * VERTEX_SIZE]; + + Direction direction; + TextureAtlasSprite sprite; + + private int flags; + @Override public int getFlags() { return flags; } - public void setFlags(int f) { - this.flags = f; - } - @Override public float getX(int idx) { return Float.intBitsToFloat(this.data[vertexOffset(idx)]); @@ -105,6 +104,10 @@ public float setV(int idx, float f) { } + public void setFlags(int f) { + this.flags = f; + } + public void setSprite(TextureAtlasSprite sprite) { this.sprite = sprite; } 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 41bd087c7..bb1dc0cca 100644 --- a/src/main/java/net/vulkanmod/render/model/quad/ModelQuadFlags.java +++ b/src/main/java/net/vulkanmod/render/model/quad/ModelQuadFlags.java @@ -51,7 +51,7 @@ public static int getQuadFlags(ModelQuadView quad, Direction face) { case Z -> minX >= 0.0001f || minY >= 0.0001f || maxX <= 0.9999F || maxY <= 0.9999F; }; - boolean parallel = switch (face.getAxis()) { + boolean parallel = switch(face.getAxis()) { case X -> minX == maxX; case Y -> minY == maxY; case Z -> minZ == maxZ; diff --git a/src/main/java/net/vulkanmod/render/model/quad/QuadUtils.java b/src/main/java/net/vulkanmod/render/model/quad/QuadUtils.java index f1500d1c4..9f7c7f1d7 100644 --- a/src/main/java/net/vulkanmod/render/model/quad/QuadUtils.java +++ b/src/main/java/net/vulkanmod/render/model/quad/QuadUtils.java @@ -10,9 +10,9 @@ public abstract class QuadUtils { public static int getIterationStartIdx(float[] aos, int[] lms) { final float ao00_11 = aos[0] + aos[2]; final float ao10_01 = aos[1] + aos[3]; - if (ao00_11 > ao10_01) { + if(ao00_11 > ao10_01) { return DEFAULT_START_IDX; - } else if (ao00_11 < ao10_01) { + } else if(ao00_11 < ao10_01) { return FLIPPED_START_IDX; } @@ -24,7 +24,7 @@ public static int getIterationStartIdx(float[] aos, int[] lms) { // return FLIPPED_START_IDX; // } - if (lm00_11 >= lm10_01) { + if(lm00_11 >= lm10_01) { return FLIPPED_START_IDX; } else { return DEFAULT_START_IDX; @@ -37,7 +37,7 @@ public static int getIterationStartIdx(float[] aos, int[] lms) { public static int getIterationStartIdx(float[] aos) { final float ao00_11 = aos[0] + aos[2]; final float ao10_01 = aos[1] + aos[3]; - if (ao00_11 >= ao10_01) { + if(ao00_11 >= ao10_01) { return DEFAULT_START_IDX; } else { return FLIPPED_START_IDX; diff --git a/src/main/java/net/vulkanmod/render/profiling/BuildTimeProfiler.java b/src/main/java/net/vulkanmod/render/profiling/BuildTimeProfiler.java index e7455a599..f93c28fb7 100644 --- a/src/main/java/net/vulkanmod/render/profiling/BuildTimeProfiler.java +++ b/src/main/java/net/vulkanmod/render/profiling/BuildTimeProfiler.java @@ -9,12 +9,12 @@ public abstract class BuildTimeProfiler { private static float deltaTime; public static void runBench(boolean building) { - if (bench) { + if(bench) { if (startTime == 0) { startTime = System.nanoTime(); } - if (!building) { + if(!building) { deltaTime = (System.nanoTime() - startTime) * 0.000001f; bench = false; startTime = 0; diff --git a/src/main/java/net/vulkanmod/render/profiling/Profiler.java b/src/main/java/net/vulkanmod/render/profiling/Profiler.java index 4287d36b5..ccfe5cb59 100644 --- a/src/main/java/net/vulkanmod/render/profiling/Profiler.java +++ b/src/main/java/net/vulkanmod/render/profiling/Profiler.java @@ -16,33 +16,41 @@ public class Profiler { private static final float CONVERSION = NANOS_IN_MS; private static final float INV_CONVERSION = 1.0f / CONVERSION; private static final int SAMPLE_COUNT = 200; - private static final Profiler MAIN_PROFILER = new Profiler("Main"); + public static boolean ACTIVE = FORCE_ACTIVE; + + private static final Profiler MAIN_PROFILER = new Profiler("Main"); + + public static Profiler getMainProfiler() { + return MAIN_PROFILER; + } + + public static void setActive(boolean b) { + if (!FORCE_ACTIVE) + ACTIVE = b; + + } + private final String name; + LongArrayList startTimes = new LongArrayList(); ObjectArrayList nodeStack = new ObjectArrayList<>(); + ObjectArrayList nodes = new ObjectArrayList<>(); ObjectArrayList currentFrameNodes = new ObjectArrayList<>(); Object2ReferenceOpenHashMap nodeMap = new Object2ReferenceOpenHashMap<>(); + Node mainNode; Node selectedNode; Node currentNode; + ProfilerResults profilerResults = new ProfilerResults(); + public Profiler(String s) { this.name = s; this.currentNode = this.selectedNode = this.mainNode = new Node(s); } - public static Profiler getMainProfiler() { - return MAIN_PROFILER; - } - - public static void setActive(boolean b) { - if (!FORCE_ACTIVE) - ACTIVE = b; - - } - public void push(String s) { if (!(ACTIVE)) return; diff --git a/src/main/java/net/vulkanmod/render/shader/CustomRenderPipelines.java b/src/main/java/net/vulkanmod/render/shader/CustomRenderPipelines.java index 02ba082b1..07ca57f3c 100644 --- a/src/main/java/net/vulkanmod/render/shader/CustomRenderPipelines.java +++ b/src/main/java/net/vulkanmod/render/shader/CustomRenderPipelines.java @@ -15,12 +15,12 @@ public class CustomRenderPipelines { public static final List pipelines = new ArrayList<>(); public static final RenderPipeline.Snippet GUI_TRIANGLES_SNIPPET = RenderPipeline.builder(RenderPipelines.MATRICES_PROJECTION_SNIPPET) - .withVertexShader("core/gui") - .withFragmentShader("core/gui") - .withBlend(BlendFunction.TRANSLUCENT) - .withVertexFormat(DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.TRIANGLES) - .withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST) - .buildSnippet(); + .withVertexShader("core/gui") + .withFragmentShader("core/gui") + .withBlend(BlendFunction.TRANSLUCENT) + .withVertexFormat(DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.TRIANGLES) + .withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST) + .buildSnippet(); public static final RenderPipeline GUI_TRIANGLES = register(RenderPipeline.builder(GUI_TRIANGLES_SNIPPET).withLocation("pipeline/gui").build()); diff --git a/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java b/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java index 86cc2515c..2c7bb5567 100644 --- a/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java +++ b/src/main/java/net/vulkanmod/render/shader/ShaderLoadUtil.java @@ -10,23 +10,23 @@ import net.vulkanmod.vulkan.shader.SPIRVUtils; import org.apache.commons.io.IOUtils; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +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; +import java.util.HashSet; +import java.util.Map; import java.util.Set; public abstract class ShaderLoadUtil { - public static final Set REMAPPED_SHADERS = Sets.newHashSet("core/screenquad.vsh", "core/rendertype_item_entity_translucent_cull.vsh"); private static final String RESOURCES_PATH = SPIRVUtils.class.getResource("/assets/vulkanmod").toExternalForm(); + public static final Set REMAPPED_SHADERS = Sets.newHashSet("core/screenquad.vsh","core/rendertype_item_entity_translucent_cull.vsh"); + 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; @@ -220,7 +220,7 @@ public static String removeNameSpace(String path) { public static String[] splitPath(String path) { int idx = path.lastIndexOf('/'); - return new String[]{path.substring(0, idx), path.substring(idx + 1)}; + return new String[] {path.substring(0, idx), path.substring(idx + 1)}; } public static InputStream getInputStream(String path) { diff --git a/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java b/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java index 90cfc95f4..60943f029 100644 --- a/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java +++ b/src/main/java/net/vulkanmod/render/sky/CloudRenderer.java @@ -57,32 +57,6 @@ public CloudRenderer() { loadTexture(); } - 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.getPixelsABGR(); - - return new CloudGrid(pixels, width); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - public void loadTexture() { this.cloudGrid = createCloudGrid(TEXTURE_LOCATION); } @@ -108,9 +82,11 @@ public void renderClouds(ClientLevel level, float ticks, float partialTicks, dou byte yState; if (centerY < -4.0f) { yState = Y_BELOW_CLOUDS; - } else if (centerY > 0.0f) { + } + else if (centerY > 0.0f) { yState = Y_ABOVE_CLOUDS; - } else { + } + else { yState = Y_INSIDE_CLOUDS; } @@ -238,25 +214,25 @@ private MeshData buildClouds(Tesselator tesselator, int centerCellX, int centerC if ((renderFaces & DIR_POS_Y_BIT) != 0 && cloudY <= 0.0f) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, upFaceBrightness); putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, color); - putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, color); - putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, color); } if ((renderFaces & DIR_NEG_Y_BIT) != 0 && cloudY >= -CELL_HEIGHT) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, downFaceBrightness); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); } if ((renderFaces & DIR_POS_X_BIT) != 0 && (x < 1.0f || insideClouds)) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, xDirBrightness); putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); - putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, color); } if ((renderFaces & DIR_NEG_X_BIT) != 0 && (x > -1.0f || insideClouds)) { @@ -269,23 +245,24 @@ private MeshData buildClouds(Tesselator tesselator, int centerCellX, int centerC if ((renderFaces & DIR_POS_Z_BIT) != 0 && (z < 1.0f || insideClouds)) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, zDirBrightness); - putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + CELL_WIDTH, color); } if ((renderFaces & DIR_NEG_Z_BIT) != 0 && (z > -1.0f || insideClouds)) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, zDirBrightness); putVertex(bufferBuilder, x + CELL_WIDTH, CELL_HEIGHT, z + 0.0f, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); - putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, CELL_HEIGHT, z + 0.0f, color); } } } - } else { + } + else { for (int cellX = -renderDistance; cellX < renderDistance; ++cellX) { for (int cellZ = -renderDistance; cellZ < renderDistance; ++cellZ) { @@ -298,9 +275,9 @@ private MeshData buildClouds(Tesselator tesselator, int centerCellX, int centerC if ((renderFaces & DIR_NEG_Y_BIT) != 0) { final int color = ColorUtil.ARGB.multiplyRGB(baseColor, upFaceBrightness); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); - putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); - putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + CELL_WIDTH, color); + putVertex(bufferBuilder, x + 0.0f, 0.0f, z + 0.0f, color); + putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + 0.0f, color); putVertex(bufferBuilder, x + CELL_WIDTH, 0.0f, z + CELL_WIDTH, color); } @@ -311,6 +288,32 @@ private MeshData buildClouds(Tesselator tesselator, int centerCellX, int centerC 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.getPixelsABGR(); + + return new CloudGrid(pixels, width); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + static class CloudGrid { final int width; final int[] pixels; @@ -323,10 +326,6 @@ static class CloudGrid { this.renderFaces = computeRenderFaces(); } - private static boolean hasColor(int pixel) { - return ((pixel >> 24) & 0xFF) > 1; - } - byte[] computeRenderFaces() { byte[] renderFaces = new byte[pixels.length]; @@ -400,5 +399,9 @@ int getWrappedIdx(int x, int 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/SpriteUpdateUtil.java b/src/main/java/net/vulkanmod/render/texture/SpriteUpdateUtil.java index 7e3082cc1..82f0ceab2 100644 --- a/src/main/java/net/vulkanmod/render/texture/SpriteUpdateUtil.java +++ b/src/main/java/net/vulkanmod/render/texture/SpriteUpdateUtil.java @@ -9,8 +9,8 @@ public abstract class SpriteUpdateUtil { - private static final Set transitionedLayouts = new HashSet<>(); private static boolean doUpload = true; + private static final Set transitionedLayouts = new HashSet<>(); public static void setDoUpload(boolean b) { doUpload = b; diff --git a/src/main/java/net/vulkanmod/render/util/DrawUtil.java b/src/main/java/net/vulkanmod/render/util/DrawUtil.java index 46d6dfc65..b4e527eb8 100644 --- a/src/main/java/net/vulkanmod/render/util/DrawUtil.java +++ b/src/main/java/net/vulkanmod/render/util/DrawUtil.java @@ -1,10 +1,12 @@ package net.vulkanmod.render.util; +import com.mojang.blaze3d.ProjectionType; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.shader.GraphicsPipeline; +import net.vulkanmod.vulkan.shader.Pipeline; import net.vulkanmod.vulkan.texture.VTextureSelector; import net.vulkanmod.vulkan.texture.VulkanImage; import org.joml.Matrix4f; diff --git a/src/main/java/net/vulkanmod/render/util/SortUtil.java b/src/main/java/net/vulkanmod/render/util/SortUtil.java index 08f6150b5..ef524b6ce 100644 --- a/src/main/java/net/vulkanmod/render/util/SortUtil.java +++ b/src/main/java/net/vulkanmod/render/util/SortUtil.java @@ -23,12 +23,13 @@ public static void mergeSort(int[] indices, float[] distances, int from, int to, if (Float.compare(distances[supp[mid]], distances[supp[mid - 1]]) <= 0) { System.arraycopy(supp, from, indices, from, len); - } else { + } + else { int i = from; int p = from; - for (int q = mid; i < to; ++i) { - if (q < to && (p >= mid || Float.compare(distances[supp[q]], distances[supp[p]]) > 0)) { + for(int q = mid; i < to; ++i) { + if (q < to && (p >= mid || Float.compare(distances[supp[q]], distances[supp[p]]) > 0)) { indices[i] = supp[q++]; } else { indices[i] = supp[p++]; @@ -67,31 +68,33 @@ public static void quickSort(int[] is, float[] distances, int from, int to) { swap(is, m, d); float mValue = distances[v]; - while (true) { + while(true) { - while (b < c) { - if (Float.compare(distances[is[b]], mValue) > 0) { - while (b < c) { - if (Float.compare(distances[is[c]], mValue) < 0) { + while(b < c) { + if(Float.compare(distances[is[b]], mValue) > 0) { + while(b < c) { + if(Float.compare(distances[is[c]], mValue) < 0) { swap(is, b, c); b++; c--; break; - } else { + } + else { c--; } } - } else { + } + else { b++; } } swap(is, d, b); - if (b - a > 1) + if(b - a > 1) quickSort(is, distances, a, b); - if (d - b > 1) + if(d - b > 1) quickSort(is, distances, b, d); return; @@ -103,7 +106,7 @@ public static void quickSort(int[] is, float[] distances, int from, int to) { private static void insertionSort(int[] is, float[] distances, int from, int to) { int i = from; - while (true) { + while(true) { ++i; if (i >= to) { return; @@ -112,7 +115,7 @@ private static void insertionSort(int[] is, float[] distances, int from, int to) int t = is[i]; int j = i; - for (int u = is[i - 1]; Float.compare(distances[u], distances[t]) < 0; u = is[j - 1]) { + for(int u = is[i - 1]; Float.compare(distances[u], distances[t]) < 0; u = is[j - 1]) { is[j] = u; if (from == j - 1) { --j; @@ -127,7 +130,7 @@ private static void insertionSort(int[] is, float[] distances, int from, int to) } public static void swap(int[] x, int a, int b, int n) { - for (int i = 0; i < n; ++b, ++i, ++a) { + for(int i = 0; i < n; ++b, ++i, ++a) { swap(x, a, b); } diff --git a/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java b/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java index 9d596da15..437345ff8 100644 --- a/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java +++ b/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java @@ -5,16 +5,16 @@ 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_POSITION = new VertexFormatElement(0, 0,VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.POSITION, 4); public static final VertexFormatElement ELEMENT_COLOR = new VertexFormatElement(1, 0, VertexFormatElement.Type.UINT, VertexFormatElement.Usage.COLOR, 1); public static final VertexFormatElement ELEMENT_UV0 = new VertexFormatElement(2, 0, VertexFormatElement.Type.USHORT, VertexFormatElement.Usage.UV, 2); public static final VertexFormat COMPRESSED_TERRAIN = VertexFormat.builder() - .add("Position", ELEMENT_POSITION) - .add("UV0", ELEMENT_UV0) - .add("Color", ELEMENT_COLOR) - .build(); + .add("Position", ELEMENT_POSITION) + .add("UV0", ELEMENT_UV0) + .add("Color", ELEMENT_COLOR) + .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 50cfcb523..91c26a129 100644 --- a/src/main/java/net/vulkanmod/render/vertex/QuadSorter.java +++ b/src/main/java/net/vulkanmod/render/vertex/QuadSorter.java @@ -55,10 +55,10 @@ public void setupQuadSortingPoints(long bufferPtr, int vertexCount, VertexFormat for (int m = 0; m < pointCount; ++m) { long ptr = bufferPtr + (long) m * quadStride; - short x0 = MemoryUtil.memGetShort(ptr); + short x0 = MemoryUtil.memGetShort(ptr + 0); short y0 = MemoryUtil.memGetShort(ptr + 2); short z0 = MemoryUtil.memGetShort(ptr + 4); - short x2 = MemoryUtil.memGetShort(ptr + offset); + short x2 = MemoryUtil.memGetShort(ptr + offset + 0); short y2 = MemoryUtil.memGetShort(ptr + offset + 2); short z2 = MemoryUtil.memGetShort(ptr + offset + 4); @@ -71,10 +71,10 @@ public void setupQuadSortingPoints(long bufferPtr, int vertexCount, VertexFormat for (int m = 0; m < pointCount; ++m) { long ptr = bufferPtr + (long) m * quadStride; - float x0 = MemoryUtil.memGetFloat(ptr); + float x0 = MemoryUtil.memGetFloat(ptr + 0); float y0 = MemoryUtil.memGetFloat(ptr + 4); float z0 = MemoryUtil.memGetFloat(ptr + 8); - float x2 = MemoryUtil.memGetFloat(ptr + offset); + float x2 = MemoryUtil.memGetFloat(ptr + offset + 0); float y2 = MemoryUtil.memGetFloat(ptr + offset + 4); float z2 = MemoryUtil.memGetFloat(ptr + offset + 8); @@ -111,12 +111,12 @@ public void putSortedQuadIndices(TerrainBufferBuilder bufferBuilder, VertexForma final int quadIndex = sortingPointsIndices[i]; final int baseVertex = quadIndex * stride; - MemoryUtil.memPutInt(ptr + (0L), baseVertex); - MemoryUtil.memPutInt(ptr + ((long) size), baseVertex + 1); + 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); + MemoryUtil.memPutInt(ptr + (size * 5L), baseVertex + 0); ptr += size * 6L; } @@ -143,12 +143,12 @@ public void putSortedQuadIndices(TerrainBuilder bufferBuilder, VertexFormat.Inde final int quadIndex = sortingPoints[i]; final int baseVertex = quadIndex * stride; - MemoryUtil.memPutInt(ptr + (0L), baseVertex); - MemoryUtil.memPutInt(ptr + ((long) size), baseVertex + 1); + 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); + MemoryUtil.memPutInt(ptr + (size * 5L), baseVertex + 0); ptr += size * 6L; } diff --git a/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java b/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java index d25fce8fe..9e8651dae 100644 --- a/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java @@ -11,14 +11,18 @@ public class TerrainBufferBuilder implements VertexConsumer { private static final Logger LOGGER = Initializer.LOGGER; private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false); + + private int capacity; + private int vertexSize; + protected long bufferPtr; + protected int nextElementByte; int vertices; - private int capacity; - private final int vertexSize; - private long elementPtr; - private final VertexBuilder vertexBuilder; + private long elementPtr; + + private VertexBuilder vertexBuilder; public TerrainBufferBuilder(int size, int vertexSize, VertexBuilder vertexBuilder) { this.bufferPtr = ALLOCATOR.malloc(size); @@ -84,54 +88,54 @@ public int getNextElementByte() { return nextElementByte; } - @Override - public VertexConsumer addVertex(float x, float y, float z) { - this.elementPtr = this.bufferPtr + this.nextElementByte; - this.endVertex(); + @Override + public VertexConsumer addVertex(float x, float y, float z) { + this.elementPtr = this.bufferPtr + this.nextElementByte; + this.endVertex(); - this.vertexBuilder.position(this.elementPtr, x, y, z); + this.vertexBuilder.position(this.elementPtr, x, y, z); - return this; - } + return this; + } - @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); + @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); - this.vertexBuilder.color(this.elementPtr, color); + this.vertexBuilder.color(this.elementPtr, color); - return this; - } + return this; + } - @Override - public VertexConsumer setUv(float u, float v) { - this.vertexBuilder.uv(this.elementPtr, u, v); + @Override + public VertexConsumer setUv(float u, float v) { + this.vertexBuilder.uv(this.elementPtr, u, v); - return this; - } + return this; + } - public VertexConsumer setLight(int i) { - this.vertexBuilder.light(this.elementPtr, i); + public VertexConsumer setLight(int i) { + this.vertexBuilder.light(this.elementPtr, i); - return this; - } + return this; + } - @Override - public VertexConsumer setNormal(float f, float g, float h) { - int packedNormal = I32_SNorm.packNormal(f, g, h); + @Override + public VertexConsumer setNormal(float f, float g, float h) { + int packedNormal = I32_SNorm.packNormal(f, g, h); - this.vertexBuilder.normal(this.elementPtr, packedNormal); + this.vertexBuilder.normal(this.elementPtr, packedNormal); - return this; - } + return this; + } - @Override - public VertexConsumer setUv1(int i, int j) { - return this; - } + @Override + public VertexConsumer setUv1(int i, int j) { + return this; + } - @Override - public VertexConsumer setUv2(int i, int j) { - return this; - } + @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 index 188604ca2..f12c69a17 100644 --- a/src/main/java/net/vulkanmod/render/vertex/TerrainBuilder.java +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainBuilder.java @@ -13,17 +13,25 @@ public class TerrainBuilder { private static final Logger LOGGER = Initializer.LOGGER; private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false); - private final VertexFormat format; - private final QuadSorter quadSorter = new QuadSorter(); - private final TerrainBufferBuilder[] bufferBuilders; + protected long indexBufferPtr; - protected long bufferPtr; - protected VertexBuilder vertexBuilder; + 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); diff --git a/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java b/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java index 83c53854a..2c1281920 100644 --- a/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java @@ -38,8 +38,12 @@ public enum TerrainRenderType { this.alphaCutout = alphaCutout; } + public void setCutoutUniform() { + VRenderSystem.alphaCutout = this.alphaCutout; + } + public static TerrainRenderType get(RenderType renderType) { - return ((ExtendedRenderType) renderType).getTerrainRenderType(); + return ((ExtendedRenderType)renderType).getTerrainRenderType(); } public static TerrainRenderType get(ChunkSectionLayer layer) { @@ -91,8 +95,4 @@ public static void updateMapping() { public static TerrainRenderType getRemapped(TerrainRenderType renderType) { return remapper.apply(renderType); } - - public void setCutoutUniform() { - VRenderSystem.alphaCutout = this.alphaCutout; - } } diff --git a/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java b/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java index 4a8d0f0eb..5f6555459 100644 --- a/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java +++ b/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java @@ -21,7 +21,7 @@ class DefaultVertexBuilder implements VertexBuilder { private static final int VERTEX_SIZE = 32; public void vertex(long ptr, float x, float y, float z, int color, float u, float v, int light, int packedNormal) { - MemoryUtil.memPutFloat(ptr, x); + MemoryUtil.memPutFloat(ptr + 0, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); @@ -69,18 +69,20 @@ public int getStride() { } class CompressedVertexBuilder implements VertexBuilder { + 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; - private static final int VERTEX_SIZE = 16; 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); 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, sX); + MemoryUtil.memPutShort(ptr + 0, sX); MemoryUtil.memPutShort(ptr + 2, sY); MemoryUtil.memPutShort(ptr + 4, sZ); @@ -99,7 +101,7 @@ public void position(long ptr, float x, float y, float z) { 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, sX); + MemoryUtil.memPutShort(ptr + 0, sX); MemoryUtil.memPutShort(ptr + 2, sY); MemoryUtil.memPutShort(ptr + 4, sZ); } diff --git a/src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java b/src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java index e1e4923d2..fb8366991 100644 --- a/src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java +++ b/src/main/java/net/vulkanmod/render/vertex/format/I32_SNorm.java @@ -8,22 +8,22 @@ public static int packNormal(float x, float y, float z) { y *= 127.0f; z *= 127.0f; - return ((int) x & 0xFF) | ((int) y & 0xFF) << 8 | ((int) z & 0xFF) << 16; + return ((int)x & 0xFF) | ((int)y & 0xFF) << 8| ((int)z & 0xFF) << 16; } public static int packNormal(int x, int y, int z) { - return (x & 0xFF) | (y & 0xFF) << 8 | (z & 0xFF) << 16; + return (x & 0xFF) | (y & 0xFF) << 8| (z & 0xFF) << 16; } public static float unpackX(int i) { - return (byte) (i & 0xFF) * NORM_INV; + return (byte)(i & 0xFF) * NORM_INV; } public static float unpackY(int i) { - return (byte) ((i >> 8) & 0xFF) * NORM_INV; + return (byte)((i >> 8) & 0xFF) * NORM_INV; } public static float unpackZ(int i) { - return (byte) ((i >> 16) & 0xFF) * NORM_INV; + 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 a0928c0a4..fd2ae33f8 100644 --- a/src/main/java/net/vulkanmod/vulkan/Drawer.java +++ b/src/main/java/net/vulkanmod/vulkan/Drawer.java @@ -1,8 +1,7 @@ package net.vulkanmod.vulkan; import com.mojang.blaze3d.vertex.VertexFormat; -import net.vulkanmod.vulkan.memory.MemoryManager; -import net.vulkanmod.vulkan.memory.MemoryTypes; +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; @@ -27,15 +26,18 @@ public class Drawer { private static final LongBuffer offsets = MemoryUtil.memAllocLong(1); private static final long pBuffers = MemoryUtil.memAddress0(buffers); private static final long pOffsets = MemoryUtil.memAddress0(offsets); + + 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 int framesNum; - private VertexBuffer[] vertexBuffers; - private IndexBuffer[] indexBuffers; + private UniformBuffer[] uniformBuffers; private int currentFrame; @@ -104,7 +106,8 @@ public void draw(ByteBuffer vertexData, ByteBuffer indexData, VertexFormat.Mode int indexCount = vertexCount * 3 / 2; drawIndexed(vertexBuffer, indexBuffer, indexCount); - } else { + } + else { AutoIndexBuffer autoIndexBuffer = getAutoIndexBuffer(mode, vertexCount); if (autoIndexBuffer != null) { @@ -112,14 +115,15 @@ public void draw(ByteBuffer vertexData, ByteBuffer indexData, VertexFormat.Mode autoIndexBuffer.checkCapacity(indexCount); drawIndexed(vertexBuffer, autoIndexBuffer.getIndexBuffer(), indexCount); - } else { + } + else { draw(vertexBuffer, vertexCount); } } } public void drawIndexed(Buffer vertexBuffer, IndexBuffer indexBuffer, int indexCount) { - drawIndexed(vertexBuffer, indexBuffer, indexCount, indexBuffer.indexType.value); + drawIndexed(vertexBuffer, indexBuffer, indexCount, indexBuffer.indexType.value); } public void drawIndexed(Buffer vertexBuffer, Buffer indexBuffer, int indexCount, int indexType) { @@ -205,6 +209,6 @@ public AutoIndexBuffer getAutoIndexBuffer(VertexFormat.Mode mode, int vertexCoun 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 6576e8b00..5e5a30f75 100644 --- a/src/main/java/net/vulkanmod/vulkan/Renderer.java +++ b/src/main/java/net/vulkanmod/vulkan/Renderer.java @@ -40,8 +40,7 @@ import java.util.List; import java.util.Set; -import static net.vulkanmod.vulkan.Vulkan.createStagingBuffers; -import static net.vulkanmod.vulkan.Vulkan.getCommandPool; +import static net.vulkanmod.vulkan.Vulkan.*; import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; import static org.lwjgl.system.MemoryStack.stackPush; @@ -50,38 +49,12 @@ import static org.lwjgl.vulkan.VK10.*; public class Renderer { - public static boolean skipRendering = false; private static Renderer INSTANCE; - private static VkDevice device; - private static boolean swapChainUpdate = false; - private static int currentFrame = 0; - private static int imageIndex; - private static int lastReset = -1; - private final Set usedPipelines = new ObjectOpenHashSet<>(); - private final List onResizeCallbacks = new ObjectArrayList<>(); - MainPass mainPass; - private Pipeline boundPipeline; - private long boundPipelineHandle; - - private Drawer drawer; - - private SwapChain swapChain; - private int framesNum; - private List commandBuffers; - private ArrayList imageAvailableSemaphores; - private ArrayList renderFinishedSemaphores; - private ArrayList inFlightFences; - private List transferCbs; + private static VkDevice device; - private Framebuffer boundFramebuffer; - private RenderPass boundRenderPass; - private VkCommandBuffer currentCmdBuffer; - private boolean recordingCmds = false; - public Renderer() { - device = Vulkan.getVkDevice(); - framesNum = Initializer.CONFIG.frameQueueSize; - } + private static boolean swapChainUpdate = false; + public static boolean skipRendering = false; public static void initRenderer() { INSTANCE = new Renderer(); @@ -104,212 +77,44 @@ public static int getCurrentImage() { return imageIndex; } - public static void setLineWidth(float width) { - if (INSTANCE.boundFramebuffer == null) { - return; - } - vkCmdSetLineWidth(INSTANCE.currentCmdBuffer, width); - } - - private static void resetDynamicState(VkCommandBuffer commandBuffer) { - vkCmdSetDepthBias(commandBuffer, 0.0F, 0.0F, 0.0F); - - vkCmdSetLineWidth(commandBuffer, 1.0F); - } - - public static void setDepthBias(float constant, float slope) { - VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; - - vkCmdSetDepthBias(commandBuffer, constant, 0.0f, slope); - } - - public static void clearAttachments(int attachments) { - clearAttachments(INSTANCE.currentCmdBuffer, attachments); - } - - public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments) { - Framebuffer framebuffer = Renderer.getInstance().boundFramebuffer; - if (framebuffer == null) - return; - - clearAttachments(commandBuffer, attachments, framebuffer.getWidth(), framebuffer.getHeight()); - } - - public static void clearAttachments(int attachments, int width, int height) { - clearAttachments(INSTANCE.currentCmdBuffer, attachments, width, height); - } - - public static void clearAttachments(int attachments, int x, int y, int width, int height) { - clearAttachments(INSTANCE.currentCmdBuffer, attachments, x, y, width, height); - } - - public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments, int width, int height) { - clearAttachments(commandBuffer, attachments, 0, 0, width, height); - } - - public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments, int x, int y, int width, int height) { - if (skipRendering) - return; - - try (MemoryStack stack = stackPush()) { - //ClearValues have to be different for each attachment to clear, - //it seems it uses the same buffer: color and depth values override themselves - VkClearValue colorValue = VkClearValue.calloc(stack); - colorValue.color().float32(VRenderSystem.clearColor); - - VkClearValue depthValue = VkClearValue.calloc(stack); - depthValue.depthStencil().set(VRenderSystem.clearDepthValue, 0); //Use fast depth clears if possible - - int attachmentsCount = attachments == (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT) ? 2 : 1; - final VkClearAttachment.Buffer pAttachments = VkClearAttachment.malloc(attachmentsCount, stack); - switch (attachments) { - case GL_DEPTH_BUFFER_BIT -> { - - VkClearAttachment clearDepth = pAttachments.get(0); - clearDepth.aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); - clearDepth.colorAttachment(0); - clearDepth.clearValue(depthValue); - } - case GL_COLOR_BUFFER_BIT -> { - - VkClearAttachment clearColor = pAttachments.get(0); - clearColor.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); - clearColor.colorAttachment(0); - clearColor.clearValue(colorValue); - } - case GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT -> { - - VkClearAttachment clearColor = pAttachments.get(0); - clearColor.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); - clearColor.colorAttachment(0); - clearColor.clearValue(colorValue); - - VkClearAttachment clearDepth = pAttachments.get(1); - clearDepth.aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); - clearDepth.colorAttachment(0); - clearDepth.clearValue(depthValue); - } - default -> throw new RuntimeException("unexpected value"); - } - - //Rect to clear - VkRect2D renderArea = VkRect2D.malloc(stack); - renderArea.offset().set(x, y); - renderArea.extent().set(width, height); - - VkClearRect.Buffer pRect = VkClearRect.malloc(1, stack); - pRect.rect(renderArea); - pRect.baseArrayLayer(0); - pRect.layerCount(1); - - vkCmdClearAttachments(commandBuffer, pAttachments, pRect); - } - } - - public static void setInvertedViewport(int x, int y, int width, int 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) { - try (MemoryStack stack = stackPush()) { - setViewport(x, y, width, height, stack); - } - } + private final Set usedPipelines = new ObjectOpenHashSet<>(); + private Pipeline boundPipeline; + private long boundPipelineHandle; - public static void setViewport(int x, int y, int width, int height, MemoryStack stack) { - if (!INSTANCE.recordingCmds) - return; + private Drawer drawer; - VkViewport.Buffer viewport = VkViewport.malloc(1, stack); - viewport.x(x); - viewport.y(height + y); - viewport.width(width); - viewport.height(-height); - viewport.minDepth(0.0f); - viewport.maxDepth(1.0f); + private SwapChain swapChain; - vkCmdSetViewport(INSTANCE.currentCmdBuffer, 0, viewport); - } + private int framesNum; + private List commandBuffers; + private ArrayList imageAvailableSemaphores; + private ArrayList renderFinishedSemaphores; + private ArrayList inFlightFences; + private List transferCbs; - public static void setScissor(int x, int y, int width, int height) { - if (!INSTANCE.recordingCmds || INSTANCE.boundFramebuffer == null) - return; + private Framebuffer boundFramebuffer; + private RenderPass boundRenderPass; - try (MemoryStack stack = stackPush()) { - int framebufferHeight = INSTANCE.boundFramebuffer.getHeight(); + private static int currentFrame = 0; + private static int imageIndex; + private static int lastReset = -1; + private VkCommandBuffer currentCmdBuffer; + private boolean recordingCmds = false; - x = Math.max(0, x); + MainPass mainPass; - VkRect2D.Buffer scissor = VkRect2D.malloc(1, stack); - scissor.offset().set(x, framebufferHeight - (y + height)); - scissor.extent().set(width, height); + private final List onResizeCallbacks = new ObjectArrayList<>(); - vkCmdSetScissor(INSTANCE.currentCmdBuffer, 0, scissor); - } + public Renderer() { + device = Vulkan.getVkDevice(); + framesNum = Initializer.CONFIG.frameQueueSize; } - public static void resetScissor() { - if (INSTANCE.boundFramebuffer == null) + public static void setLineWidth(float width) { + if (INSTANCE.boundFramebuffer == null) { return; - - try (MemoryStack stack = stackPush()) { - VkRect2D.Buffer scissor = INSTANCE.boundFramebuffer.scissor(stack); - vkCmdSetScissor(INSTANCE.currentCmdBuffer, 0, scissor); } - } - - public static void pushDebugSection(String s) { - if (Vulkan.ENABLE_VALIDATION_LAYERS) { - VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; - - try (MemoryStack stack = stackPush()) { - VkDebugUtilsLabelEXT markerInfo = VkDebugUtilsLabelEXT.calloc(stack); - markerInfo.sType(VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT); - ByteBuffer string = stack.UTF8(s); - markerInfo.pLabelName(string); - vkCmdBeginDebugUtilsLabelEXT(commandBuffer, markerInfo); - } - } - } - - public static void popDebugSection() { - if (Vulkan.ENABLE_VALIDATION_LAYERS) { - VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; - - vkCmdEndDebugUtilsLabelEXT(commandBuffer); - } - } - - public static void popPushDebugSection(String s) { - popDebugSection(); - pushDebugSection(s); - } - - public static int getFramesNum() { - return INSTANCE.framesNum; - } - - public static VkCommandBuffer getCommandBuffer() { - return INSTANCE.currentCmdBuffer; - } - - public static boolean isRecording() { - return INSTANCE.recordingCmds; - } - - public static void scheduleSwapChainUpdate() { - swapChainUpdate = true; + vkCmdSetLineWidth(INSTANCE.currentCmdBuffer, width); } private void init() { @@ -391,8 +196,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); } @@ -466,7 +271,7 @@ public void beginFrame() { IntBuffer pImageIndex = stack.mallocInt(1); int vkResult = vkAcquireNextImageKHR(device, swapChain.getId(), VUtil.UINT64_MAX, - imageAvailableSemaphores.get(currentFrame), VK_NULL_HANDLE, pImageIndex); + imageAvailableSemaphores.get(currentFrame), VK_NULL_HANDLE, pImageIndex); if (vkResult == VK_SUBOPTIMAL_KHR || vkResult == VK_ERROR_OUT_OF_DATE_KHR || swapChainUpdate) { swapChainUpdate = true; @@ -683,9 +488,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().vkQueue(), info, inFlightFences.get(currentFrame)); vkWaitForFences(device, inFlightFences.get(currentFrame), true, -1); @@ -795,30 +600,30 @@ public Pipeline getBoundPipeline() { return boundPipeline; } - public Framebuffer getBoundFramebuffer() { - return boundFramebuffer; - } - public void setBoundFramebuffer(Framebuffer framebuffer) { this.boundFramebuffer = framebuffer; } - public RenderPass getBoundRenderPass() { - return boundRenderPass; + public Framebuffer getBoundFramebuffer() { + return boundFramebuffer; } public void setBoundRenderPass(RenderPass boundRenderPass) { this.boundRenderPass = boundRenderPass; } - public MainPass getMainPass() { - return this.mainPass; + public RenderPass getBoundRenderPass() { + return boundRenderPass; } public void setMainPass(MainPass mainPass) { this.mainPass = mainPass; } + public MainPass getMainPass() { + return this.mainPass; + } + public SwapChain getSwapChain() { return swapChain; } @@ -826,4 +631,205 @@ public SwapChain getSwapChain() { public CommandPool.CommandBuffer getTransferCb() { return transferCbs.get(currentFrame); } + + private static void resetDynamicState(VkCommandBuffer commandBuffer) { + vkCmdSetDepthBias(commandBuffer, 0.0F, 0.0F, 0.0F); + + vkCmdSetLineWidth(commandBuffer, 1.0F); + } + + public static void setDepthBias(float constant, float slope) { + VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; + + vkCmdSetDepthBias(commandBuffer, constant, 0.0f, slope); + } + + public static void clearAttachments(int attachments) { + clearAttachments(INSTANCE.currentCmdBuffer, attachments); + } + + public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments) { + Framebuffer framebuffer = Renderer.getInstance().boundFramebuffer; + if (framebuffer == null) + return; + + clearAttachments(commandBuffer, attachments, framebuffer.getWidth(), framebuffer.getHeight()); + } + + public static void clearAttachments(int attachments, int width, int height) { + clearAttachments(INSTANCE.currentCmdBuffer, attachments, width ,height); + } + + public static void clearAttachments(int attachments, int x, int y, int width, int height) { + clearAttachments(INSTANCE.currentCmdBuffer, attachments, x, y, width ,height); + } + + public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments, int width, int height) { + clearAttachments(commandBuffer, attachments, 0, 0, width, height); + } + + public static void clearAttachments(VkCommandBuffer commandBuffer, int attachments, int x, int y, int width, int height) { + if (skipRendering) + return; + + try (MemoryStack stack = stackPush()) { + //ClearValues have to be different for each attachment to clear, + //it seems it uses the same buffer: color and depth values override themselves + VkClearValue colorValue = VkClearValue.calloc(stack); + colorValue.color().float32(VRenderSystem.clearColor); + + VkClearValue depthValue = VkClearValue.calloc(stack); + depthValue.depthStencil().set(VRenderSystem.clearDepthValue, 0); //Use fast depth clears if possible + + int attachmentsCount = attachments == (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT) ? 2 : 1; + final VkClearAttachment.Buffer pAttachments = VkClearAttachment.malloc(attachmentsCount, stack); + switch (attachments) { + case GL_DEPTH_BUFFER_BIT -> { + + VkClearAttachment clearDepth = pAttachments.get(0); + clearDepth.aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); + clearDepth.colorAttachment(0); + clearDepth.clearValue(depthValue); + } + case GL_COLOR_BUFFER_BIT -> { + + VkClearAttachment clearColor = pAttachments.get(0); + clearColor.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); + clearColor.colorAttachment(0); + clearColor.clearValue(colorValue); + } + case GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT -> { + + VkClearAttachment clearColor = pAttachments.get(0); + clearColor.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); + clearColor.colorAttachment(0); + clearColor.clearValue(colorValue); + + VkClearAttachment clearDepth = pAttachments.get(1); + clearDepth.aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); + clearDepth.colorAttachment(0); + clearDepth.clearValue(depthValue); + } + default -> throw new RuntimeException("unexpected value"); + } + + //Rect to clear + VkRect2D renderArea = VkRect2D.malloc(stack); + renderArea.offset().set(x, y); + renderArea.extent().set(width, height); + + VkClearRect.Buffer pRect = VkClearRect.malloc(1, stack); + pRect.rect(renderArea); + pRect.baseArrayLayer(0); + pRect.layerCount(1); + + vkCmdClearAttachments(commandBuffer, pAttachments, pRect); + } + } + + public static void setInvertedViewport(int x, int y, int width, int 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) { + try (MemoryStack stack = stackPush()) { + setViewport(x, y, width, height, stack); + } + } + + public static void setViewport(int x, int y, int width, int height, MemoryStack stack) { + if (!INSTANCE.recordingCmds) + return; + + VkViewport.Buffer viewport = VkViewport.malloc(1, stack); + viewport.x(x); + viewport.y(height + y); + 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.recordingCmds || INSTANCE.boundFramebuffer == null) + return; + + try (MemoryStack stack = stackPush()) { + int framebufferHeight = INSTANCE.boundFramebuffer.getHeight(); + + x = Math.max(0, x); + + VkRect2D.Buffer scissor = VkRect2D.malloc(1, stack); + scissor.offset().set(x, framebufferHeight - (y + height)); + scissor.extent().set(width, height); + + vkCmdSetScissor(INSTANCE.currentCmdBuffer, 0, scissor); + } + } + + public static void resetScissor() { + if (INSTANCE.boundFramebuffer == null) + return; + + try (MemoryStack stack = stackPush()) { + VkRect2D.Buffer scissor = INSTANCE.boundFramebuffer.scissor(stack); + vkCmdSetScissor(INSTANCE.currentCmdBuffer, 0, scissor); + } + } + + public static void pushDebugSection(String s) { + if (Vulkan.ENABLE_VALIDATION_LAYERS) { + VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; + + try (MemoryStack stack = stackPush()) { + VkDebugUtilsLabelEXT markerInfo = VkDebugUtilsLabelEXT.calloc(stack); + markerInfo.sType(VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT); + ByteBuffer string = stack.UTF8(s); + markerInfo.pLabelName(string); + vkCmdBeginDebugUtilsLabelEXT(commandBuffer, markerInfo); + } + } + } + + public static void popDebugSection() { + if (Vulkan.ENABLE_VALIDATION_LAYERS) { + VkCommandBuffer commandBuffer = INSTANCE.currentCmdBuffer; + + vkCmdEndDebugUtilsLabelEXT(commandBuffer); + } + } + + public static void popPushDebugSection(String s) { + popDebugSection(); + pushDebugSection(s); + } + + public static int getFramesNum() { + return INSTANCE.framesNum; + } + + public static VkCommandBuffer getCommandBuffer() { + return INSTANCE.currentCmdBuffer; + } + + public static boolean isRecording() { + return INSTANCE.recordingCmds; + } + + public static void scheduleSwapChainUpdate() { + swapChainUpdate = true; + } } diff --git a/src/main/java/net/vulkanmod/vulkan/Synchronization.java b/src/main/java/net/vulkanmod/vulkan/Synchronization.java index 0c873ba7b..609052db3 100644 --- a/src/main/java/net/vulkanmod/vulkan/Synchronization.java +++ b/src/main/java/net/vulkanmod/vulkan/Synchronization.java @@ -18,23 +18,12 @@ public class Synchronization { private final LongBuffer fences; private int idx = 0; - private final ObjectArrayList commandBuffers = new ObjectArrayList<>(); + private ObjectArrayList commandBuffers = new ObjectArrayList<>(); Synchronization(int allocSize) { this.fences = MemoryUtil.memAllocLong(allocSize); } - public static void waitFence(long fence) { - VkDevice device = Vulkan.getVkDevice(); - - vkWaitForFences(device, fence, true, VUtil.UINT64_MAX); - } - - public static boolean checkFenceStatus(long fence) { - VkDevice device = Vulkan.getVkDevice(); - return vkGetFenceStatus(device, fence) == VK_SUCCESS; - } - public synchronized void addCommandBuffer(CommandPool.CommandBuffer commandBuffer) { this.addFence(commandBuffer.getFence()); this.commandBuffers.add(commandBuffer); @@ -65,4 +54,15 @@ public synchronized void waitFences() { idx = 0; } + public static void waitFence(long fence) { + VkDevice device = Vulkan.getVkDevice(); + + vkWaitForFences(device, fence, true, VUtil.UINT64_MAX); + } + + public static boolean checkFenceStatus(long fence) { + VkDevice device = Vulkan.getVkDevice(); + return vkGetFenceStatus(device, fence) == VK_SUCCESS; + } + } diff --git a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java index 486ad3210..fb1fe4468 100644 --- a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java +++ b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.buffers.GpuBufferSlice; import com.mojang.blaze3d.platform.Window; + import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.fog.FogData; import net.vulkanmod.render.engine.VkGpuBuffer; @@ -14,38 +15,50 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.system.MemoryUtil; +import static org.lwjgl.vulkan.VK10.*; + import java.nio.ByteBuffer; import java.nio.FloatBuffer; -import static org.lwjgl.vulkan.VK10.*; - public abstract class VRenderSystem { private static final float DEFAULT_DEPTH_VALUE = 1.0f; + + private static long window; + public static boolean depthTest = true; public static boolean depthMask = true; public static int depthFun = 515; public static int topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; public static int polygonMode = VK_POLYGON_MODE_FILL; public static boolean canSetLineWidth = false; + public static int colorMask = PipelineState.ColorMask.getColorMask(true, true, true, true); + public static boolean cull = true; + public static boolean logicOp = false; public static int logicOpFun = 0; + public static float clearDepthValue = DEFAULT_DEPTH_VALUE; public static FloatBuffer clearColor = MemoryUtil.memCallocFloat(4); + public static MappedBuffer modelViewMatrix = new MappedBuffer(16 * 4); public static MappedBuffer projectionMatrix = new MappedBuffer(16 * 4); public static MappedBuffer TextureMatrix = new MappedBuffer(16 * 4); public static MappedBuffer MVP = new MappedBuffer(16 * 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); + public static MappedBuffer shaderColor = new MappedBuffer(4 * 4); public static MappedBuffer shaderFogColor = new MappedBuffer(4 * 4); public static FogData fogData; + public static MappedBuffer screenSize = new MappedBuffer(2 * 4); + public static float alphaCutout = 0.0f; - private static long window; + private static boolean depthBiasEnabled = false; private static float depthBiasConstant = 0.0f; private static float depthBiasSlope = 0.0f; @@ -109,14 +122,14 @@ public static void calculateMVP() { P.mul(MV).get(MVP.buffer); } - public static MappedBuffer getTextureMatrix() { - return TextureMatrix; - } - public static void setTextureMatrix(Matrix4f mat) { mat.get(TextureMatrix.buffer.asFloatBuffer()); } + public static MappedBuffer getTextureMatrix() { + return TextureMatrix; + } + public static MappedBuffer getModelViewMatrix() { return modelViewMatrix; } @@ -180,7 +193,7 @@ public static void depthMask(boolean b) { public static void setPrimitiveTopologyGL(final int mode) { VRenderSystem.topology = switch (mode) { - case GL11.GL_LINES, GL11.GL_LINE_STRIP -> VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + case GL11.GL_LINES, GL11.GL_LINE_STRIP -> VK_PRIMITIVE_TOPOLOGY_LINE_LIST; case GL11.GL_TRIANGLE_FAN, GL11.GL_TRIANGLES, GL11.GL_TRIANGLE_STRIP -> VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; default -> throw new RuntimeException(String.format("Unknown GL primitive topology: %s", mode)); }; diff --git a/src/main/java/net/vulkanmod/vulkan/Vulkan.java b/src/main/java/net/vulkanmod/vulkan/Vulkan.java index 627cf0c38..f2f0a1646 100644 --- a/src/main/java/net/vulkanmod/vulkan/Vulkan.java +++ b/src/main/java/net/vulkanmod/vulkan/Vulkan.java @@ -3,9 +3,9 @@ import net.vulkanmod.vulkan.device.Device; import net.vulkanmod.vulkan.device.DeviceManager; import net.vulkanmod.vulkan.framebuffer.SwapChain; +import net.vulkanmod.vulkan.memory.buffer.Buffer; import net.vulkanmod.vulkan.memory.MemoryManager; import net.vulkanmod.vulkan.memory.MemoryTypes; -import net.vulkanmod.vulkan.memory.buffer.Buffer; import net.vulkanmod.vulkan.memory.buffer.StagingBuffer; import net.vulkanmod.vulkan.queue.Queue; import net.vulkanmod.vulkan.shader.Pipeline; @@ -44,18 +44,6 @@ public class Vulkan { public static final boolean DYNAMIC_RENDERING = false; public static final Set VALIDATION_LAYERS; - public static final Set REQUIRED_EXTENSION = getRequiredExtensionSet(); - public static long window; - public static boolean use24BitsDepthFormat = true; - private static VkInstance instance; - private static long debugMessenger; - private static long surface; - private static long commandPool; - private static VkCommandBuffer immediateCmdBuffer; - private static long immediateFence; - private static long allocator; - private static StagingBuffer[] stagingBuffers; - private static int DEFAULT_DEPTH_FORMAT = 0; static { if (ENABLE_VALIDATION_LAYERS) { @@ -69,6 +57,8 @@ public class Vulkan { } } + public static final Set REQUIRED_EXTENSION = getRequiredExtensionSet(); + private static Set getRequiredExtensionSet() { ArrayList extensions = new ArrayList<>(List.of(VK_KHR_SWAPCHAIN_EXTENSION_NAME)); @@ -127,6 +117,23 @@ public static long getAllocator() { return allocator; } + public static long window; + + private static VkInstance instance; + private static long debugMessenger; + private static long surface; + + private static long commandPool; + private static VkCommandBuffer immediateCmdBuffer; + private static long immediateFence; + + private static long allocator; + + private static StagingBuffer[] stagingBuffers; + + public static boolean use24BitsDepthFormat = true; + private static int DEFAULT_DEPTH_FORMAT = 0; + public static void initVulkan(long window) { createInstance(); setupDebugMessenger(); diff --git a/src/main/java/net/vulkanmod/vulkan/device/Device.java b/src/main/java/net/vulkanmod/vulkan/device/Device.java index 9f2ae25db..da850d3b9 100644 --- a/src/main/java/net/vulkanmod/vulkan/device/Device.java +++ b/src/main/java/net/vulkanmod/vulkan/device/Device.java @@ -1,7 +1,10 @@ package net.vulkanmod.vulkan.device; +import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.*; +import oshi.SystemInfo; +import oshi.hardware.CentralProcessor; import java.nio.IntBuffer; import java.util.HashSet; @@ -16,18 +19,21 @@ import static org.lwjgl.vulkan.VK11.vkGetPhysicalDeviceFeatures2; public class Device { + final VkPhysicalDevice physicalDevice; + final VkPhysicalDeviceProperties properties; + + private final int vendorId; public final String vendorIdString; public final String deviceName; public final String driverVersion; public final String vkVersion; + public final VkPhysicalDeviceFeatures2 availableFeatures; public final VkPhysicalDeviceVulkan11Features availableFeatures11; - final VkPhysicalDevice physicalDevice; - final VkPhysicalDeviceProperties properties; - private final int vendorId; // public final VkPhysicalDeviceVulkan13Features availableFeatures13; // public final boolean vulkan13Support; + private boolean drawIndirectSupported; public Device(VkPhysicalDevice device) { diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java index 674c4431d..8a2d5ad09 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java @@ -19,21 +19,24 @@ public class Framebuffer { public static final int DEFAULT_FORMAT = VK_FORMAT_R8G8B8A8_UNORM; // private long id; - private final Reference2LongArrayMap renderpassToFramebufferMap = new Reference2LongArrayMap<>(); + protected int format; protected int depthFormat; protected int width, height; protected boolean linearFiltering; protected boolean depthLinearFiltering; protected int attachmentCount; - protected VulkanImage depthAttachment; + boolean hasColorAttachment; boolean hasDepthAttachment; + private VulkanImage colorAttachment; + protected VulkanImage depthAttachment; + + private final Reference2LongArrayMap renderpassToFramebufferMap = new Reference2LongArrayMap<>(); //SwapChain - protected Framebuffer() { - } + protected Framebuffer() {} public Framebuffer(Builder builder) { this.format = builder.format; @@ -53,14 +56,6 @@ public Framebuffer(Builder builder) { } } - public static Builder builder(int width, int height, int colorAttachments, boolean hasDepthAttachment) { - return new Builder(width, height, colorAttachments, hasDepthAttachment); - } - - public static Builder builder(VulkanImage colorAttachment, VulkanImage depthAttachment) { - return new Builder(colorAttachment, depthAttachment); - } - public void createImages() { if (this.hasColorAttachment) { this.colorAttachment = VulkanImage.builder(this.width, this.height) @@ -212,6 +207,14 @@ public int getDepthFormat() { return this.depthFormat; } + public static Builder builder(int width, int height, int colorAttachments, boolean hasDepthAttachment) { + return new Builder(width, height, colorAttachments, hasDepthAttachment); + } + + public static Builder builder(VulkanImage colorAttachment, VulkanImage depthAttachment) { + return new Builder(colorAttachment, depthAttachment); + } + public static class Builder { final boolean createImages; final int width, height; @@ -220,7 +223,7 @@ public static class Builder { VulkanImage colorAttachment; VulkanImage depthAttachment; - // int colorAttachments; +// int colorAttachments; boolean hasColorAttachment; boolean hasDepthAttachment; diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java index a8a35cbdc..56300de44 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java @@ -13,9 +13,10 @@ import static org.lwjgl.vulkan.VK10.*; public class RenderPass { - final int attachmentCount; Framebuffer framebuffer; long id; + + final int attachmentCount; AttachmentInfo colorAttachmentInfo; AttachmentInfo depthAttachmentInfo; @@ -38,10 +39,6 @@ public RenderPass(Framebuffer framebuffer, AttachmentInfo colorAttachmentInfo, A } - public static Builder builder(Framebuffer framebuffer) { - return new Builder(framebuffer); - } - private void createRenderPass() { try (MemoryStack stack = MemoryStack.stackPush()) { @@ -170,7 +167,8 @@ public void beginRenderPass(VkCommandBuffer commandBuffer, long framebufferId, M public void endRenderPass(VkCommandBuffer commandBuffer) { if (Vulkan.DYNAMIC_RENDERING) { KHRDynamicRendering.vkCmdEndRenderingKHR(commandBuffer); - } else { + } + else { vkCmdEndRenderPass(commandBuffer); if (colorAttachmentInfo != null) @@ -290,6 +288,10 @@ public enum Type { } } + public static Builder builder(Framebuffer framebuffer) { + return new Builder(framebuffer); + } + public static class Builder { Framebuffer framebuffer; AttachmentInfo colorAttachmentInfo; diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java index 016bc8e9f..e760a72d6 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java @@ -33,10 +33,11 @@ public class SwapChain extends Framebuffer { private static final int defUncappedMode = checkPresentMode(VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR); private final Long2ReferenceOpenHashMap FBO_map = new Long2ReferenceOpenHashMap<>(); - public boolean isBGRAformat; + private long swapChainId = VK_NULL_HANDLE; private List swapChainImages; private VkExtent2D extent2D; + public boolean isBGRAformat; private boolean vsync = false; public SwapChain() { @@ -49,43 +50,6 @@ public SwapChain() { recreate(); } - private static VkExtent2D getExtent(VkSurfaceCapabilitiesKHR capabilities) { - - if (capabilities.currentExtent().width() != UINT32_MAX) { - return capabilities.currentExtent(); - } - - // Fallback - IntBuffer width = stackGet().ints(0); - IntBuffer height = stackGet().ints(0); - - glfwGetFramebufferSize(window, width, height); - - VkExtent2D actualExtent = VkExtent2D.mallocStack().set(width.get(0), height.get(0)); - - VkExtent2D minExtent = capabilities.minImageExtent(); - VkExtent2D maxExtent = capabilities.maxImageExtent(); - - actualExtent.width(MathUtil.clamp(minExtent.width(), maxExtent.width(), actualExtent.width())); - actualExtent.height(MathUtil.clamp(minExtent.height(), maxExtent.height(), actualExtent.height())); - - return actualExtent; - } - - private static int checkPresentMode(int... requestedModes) { - try (MemoryStack stack = MemoryStack.stackPush()) { - var a = DeviceManager.querySurfaceProperties(vkDevice.getPhysicalDevice(), stack).presentModes; - for (int dMode : requestedModes) { - for (int i = 0; i < a.capacity(); i++) { - if (a.get(i) == dMode) { - return dMode; - } - } - } - return VK_PRESENT_MODE_FIFO_KHR; // If None of the request modes exist/are supported by Driver - } - } - public void recreate() { if (this.depthAttachment != null) { this.depthAttachment.free(); @@ -321,6 +285,43 @@ private String getDisplayModeString(int requestedMode) { }; } + private static VkExtent2D getExtent(VkSurfaceCapabilitiesKHR capabilities) { + + if (capabilities.currentExtent().width() != UINT32_MAX) { + return capabilities.currentExtent(); + } + + // Fallback + IntBuffer width = stackGet().ints(0); + IntBuffer height = stackGet().ints(0); + + glfwGetFramebufferSize(window, width, height); + + VkExtent2D actualExtent = VkExtent2D.mallocStack().set(width.get(0), height.get(0)); + + VkExtent2D minExtent = capabilities.minImageExtent(); + VkExtent2D maxExtent = capabilities.maxImageExtent(); + + actualExtent.width(MathUtil.clamp(minExtent.width(), maxExtent.width(), actualExtent.width())); + actualExtent.height(MathUtil.clamp(minExtent.height(), maxExtent.height(), actualExtent.height())); + + return actualExtent; + } + + private static int checkPresentMode(int... requestedModes) { + try (MemoryStack stack = MemoryStack.stackPush()) { + var a = DeviceManager.querySurfaceProperties(vkDevice.getPhysicalDevice(), stack).presentModes; + for (int dMode : requestedModes) { + for (int i = 0; i < a.capacity(); i++) { + if (a.get(i) == dMode) { + return dMode; + } + } + } + return VK_PRESENT_MODE_FIFO_KHR; // If None of the request modes exist/are supported by Driver + } + } + public boolean isVsync() { return this.vsync; } diff --git a/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java b/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java index 1d290e1e1..b52be1121 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java @@ -29,23 +29,41 @@ import static org.lwjgl.vulkan.VK10.*; public class MemoryManager { - public static final long BYTES_IN_MB = 1024 * 1024; private static final boolean DEBUG = false; + public static final long BYTES_IN_MB = 1024 * 1024; + + private static MemoryManager INSTANCE; private static final long ALLOCATOR = Vulkan.getAllocator(); + private static final Long2ReferenceOpenHashMap buffers = new Long2ReferenceOpenHashMap<>(); private static final Long2ReferenceOpenHashMap images = new Long2ReferenceOpenHashMap<>(); + static int Frames; - private static MemoryManager INSTANCE; + private static long deviceMemory = 0; private static long nativeMemory = 0; + + private int currentFrame = 0; + private final ObjectArrayList[] freeableBuffers = new ObjectArrayList[Frames]; private final ObjectArrayList[] freeableImages = new ObjectArrayList[Frames]; + private final ObjectArrayList[] frameOps = new ObjectArrayList[Frames]; private final ObjectArrayList>[] segmentsToFree = new ObjectArrayList[Frames]; - private int currentFrame = 0; + //debug private ObjectArrayList[] stackTraces; + public static MemoryManager getInstance() { + return INSTANCE; + } + + public static void createInstance(int frames) { + Frames = frames; + + INSTANCE = new MemoryManager(); + } + MemoryManager() { for (int i = 0; i < Frames; ++i) { this.freeableBuffers[i] = new ObjectArrayList<>(); @@ -63,57 +81,6 @@ public class MemoryManager { } } - public static MemoryManager getInstance() { - return INSTANCE; - } - - public static void createInstance(int frames) { - Frames = frames; - - INSTANCE = new MemoryManager(); - } - - public static void addImage(VulkanImage image) { - images.putIfAbsent(image.getId(), image); - - deviceMemory += image.size; - } - - public static void MapAndCopy(long allocation, Consumer consumer) { - try (MemoryStack stack = stackPush()) { - PointerBuffer data = stack.mallocPointer(1); - - vmaMapMemory(ALLOCATOR, allocation, data); - consumer.accept(data); - vmaUnmapMemory(ALLOCATOR, allocation); - } - } - - public static void freeBuffer(long buffer, long allocation) { - vmaDestroyBuffer(ALLOCATOR, buffer, allocation); - - buffers.remove(buffer); - } - - private static void freeBuffer(Buffer.BufferInfo bufferInfo) { - vmaDestroyBuffer(ALLOCATOR, bufferInfo.id(), bufferInfo.allocation()); - - if (bufferInfo.type() == MemoryType.Type.DEVICE_LOCAL) { - deviceMemory -= bufferInfo.bufferSize(); - } else { - nativeMemory -= bufferInfo.bufferSize(); - } - - buffers.remove(bufferInfo.id()); - } - - public static void freeImage(long imageId, long allocation) { - vmaDestroyImage(ALLOCATOR, imageId, allocation); - - VulkanImage image = images.remove(imageId); - deviceMemory -= image.size; - } - public synchronized void initFrame(int frame) { this.setCurrentFrame(frame); this.freeBuffers(frame); @@ -174,7 +141,8 @@ public synchronized void createBuffer(Buffer buffer, long size, int usage, int p if ((properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0) { deviceMemory += size; - } else { + } + else { nativeMemory += size; } @@ -218,6 +186,22 @@ public void createImage(int width, int height, int arrayLayers, int mipLevels, } } + public static void addImage(VulkanImage image) { + images.putIfAbsent(image.getId(), image); + + deviceMemory += image.size; + } + + public static void MapAndCopy(long allocation, Consumer consumer) { + try (MemoryStack stack = stackPush()) { + PointerBuffer data = stack.mallocPointer(1); + + vmaMapMemory(ALLOCATOR, allocation, data); + consumer.accept(data); + vmaUnmapMemory(ALLOCATOR, allocation); + } + } + public PointerBuffer Map(long allocation) { PointerBuffer data = MemoryUtil.memAllocPointer(1); @@ -226,6 +210,32 @@ public PointerBuffer Map(long allocation) { return data; } + public static void freeBuffer(long buffer, long allocation) { + vmaDestroyBuffer(ALLOCATOR, buffer, allocation); + + buffers.remove(buffer); + } + + private static void freeBuffer(Buffer.BufferInfo bufferInfo) { + vmaDestroyBuffer(ALLOCATOR, bufferInfo.id(), bufferInfo.allocation()); + + if (bufferInfo.type() == MemoryType.Type.DEVICE_LOCAL) { + deviceMemory -= bufferInfo.bufferSize(); + } + else { + nativeMemory -= bufferInfo.bufferSize(); + } + + buffers.remove(bufferInfo.id()); + } + + public static void freeImage(long imageId, long allocation) { + vmaDestroyImage(ALLOCATOR, imageId, allocation); + + VulkanImage image = images.remove(imageId); + deviceMemory -= image.size; + } + public synchronized void addToFreeable(Buffer buffer) { Buffer.BufferInfo bufferInfo = buffer.getBufferInfo(); diff --git a/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java b/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java index d751e28c5..15bf8d6df 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/MemoryType.java @@ -7,9 +7,9 @@ import java.nio.ByteBuffer; public abstract class MemoryType { + final Type type; public final VkMemoryType vkMemoryType; public final VkMemoryHeap vkMemoryHeap; - final Type type; MemoryType(Type type, VkMemoryType vkMemoryType, VkMemoryHeap vkMemoryHeap) { this.type = type; @@ -26,7 +26,7 @@ public abstract class MemoryType { public abstract boolean mappable(); public Type getType() { - return this.type; + return this.type; } public enum Type { diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java index f13f2600c..ac8ac91e4 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/Buffer.java @@ -68,10 +68,6 @@ public long getAllocation() { return allocation; } - public void setAllocation(long allocation) { - this.allocation = allocation; - } - public long getUsedBytes() { return usedBytes; } @@ -84,20 +80,24 @@ public long getId() { return id; } - public void setId(long id) { - this.id = id; - } - public long getBufferSize() { return bufferSize; } + public long getDataPtr() { + return dataPtr; + } + public void setBufferSize(long size) { this.bufferSize = size; } - public long getDataPtr() { - return dataPtr; + public void setId(long id) { + this.id = id; + } + + public void setAllocation(long allocation) { + this.allocation = allocation; } public BufferInfo getBufferInfo() { diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java index b8ce2109f..6b09cb0cb 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/IndirectBuffer.java @@ -3,6 +3,7 @@ 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; diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java index ecbec6252..03d764c5a 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/StagingBuffer.java @@ -10,7 +10,7 @@ import java.nio.ByteBuffer; import static org.lwjgl.system.libc.LibCString.nmemcpy; -import static org.lwjgl.vulkan.VK10.VK_BUFFER_USAGE_TRANSFER_SRC_BIT; +import static org.lwjgl.vulkan.VK10.*; public class StagingBuffer extends Buffer { private static final long DEFAULT_SIZE = 64 * 1024 * 1024; diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java index 12c50e5c8..b9d102d18 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/UniformBuffer.java @@ -9,15 +9,15 @@ public class UniformBuffer extends Buffer { private final static int MIN_OFFSET_ALIGNMENT = (int) DeviceManager.deviceProperties.limits().minUniformBufferOffsetAlignment(); + public static int getAlignedSize(int uploadSize) { + return align(uploadSize, MIN_OFFSET_ALIGNMENT); + } + public UniformBuffer(int size, MemoryType memoryType) { super(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memoryType); this.createBuffer(size); } - public static int getAlignedSize(int uploadSize) { - return align(uploadSize, MIN_OFFSET_ALIGNMENT); - } - public void checkCapacity(int size) { if (size > this.bufferSize - this.usedBytes) { resizeBuffer((this.bufferSize + size) * 2); diff --git a/src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java index 45735b0c4..6fead50d2 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/buffer/index/AutoIndexBuffer.java @@ -23,6 +23,61 @@ public AutoIndexBuffer(int vertexCount, DrawType type) { createIndexBuffer(vertexCount); } + private void createIndexBuffer(int vertexCount) { + this.vertexCount = vertexCount; + ByteBuffer buffer; + + 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 (indexType == IndexBuffer.IndexType.UINT16) + buffer = genQuadIndices(vertexCount); + else { + buffer = genIntQuadIndices(vertexCount); + } + } + case TRIANGLE_FAN -> buffer = genTriangleFanIndices(vertexCount); + case TRIANGLE_STRIP -> buffer = genTriangleStripIndices(vertexCount); + case LINES -> buffer = genLinesIndices(vertexCount); + case DEBUG_LINE_STRIP -> buffer = genDebugLineStripIndices(vertexCount); + default -> throw new IllegalArgumentException("Unsupported drawType: %s".formatted(this.drawType)); + } + + int size = buffer.capacity(); + this.indexBuffer = new IndexBuffer(size, MemoryTypes.GPU_MEM, indexType); + this.indexBuffer.copyBuffer(buffer, buffer.remaining()); + + MemoryUtil.memFree(buffer); + } + + public void checkCapacity(int vertexCount) { + if (vertexCount > this.vertexCount) { + int newVertexCount = Math.max(this.vertexCount * 2, vertexCount); + Initializer.LOGGER.info("Reallocating AutoIndexBuffer from {} to {}", this.vertexCount, newVertexCount); + + 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 -> { @@ -55,7 +110,7 @@ public static ByteBuffer genQuadIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount; i += 4) { - idxs.put(j, (short) (i)); + idxs.put(j + 0, (short) (i)); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); idxs.put(j + 3, (short) (i)); @@ -77,7 +132,7 @@ public static ByteBuffer genIntQuadIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount; i += 4) { - idxs.put(j, (i)); + idxs.put(j + 0, (i)); idxs.put(j + 1, (i + 1)); idxs.put(j + 2, (i + 2)); idxs.put(j + 3, (i)); @@ -99,7 +154,7 @@ public static ByteBuffer genLinesIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount; i += 4) { - idxs.put(j, (short) (i)); + idxs.put(j + 0, (short) (i)); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); idxs.put(j + 3, (short) (i + 3)); @@ -119,7 +174,7 @@ public static ByteBuffer genTriangleFanIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount - 2; ++i) { - idxs.put(j, (short) 0); + idxs.put(j + 0, (short) 0); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); @@ -137,7 +192,7 @@ public static ByteBuffer genTriangleStripIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount - 2; ++i) { - idxs.put(j, (short) i); + idxs.put(j + 0, (short) i); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); @@ -155,7 +210,7 @@ public static ByteBuffer genDebugLineStripIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount - 1; ++i) { - idxs.put(j, (short) i); + idxs.put(j + 0, (short) i); idxs.put(j + 1, (short) (i + 1)); j += 2; @@ -168,61 +223,6 @@ public static int roundUpToDivisible(int n, int d) { return ((n + d - 1) / d) * d; } - private void createIndexBuffer(int vertexCount) { - this.vertexCount = vertexCount; - ByteBuffer buffer; - - 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 (indexType == IndexBuffer.IndexType.UINT16) - buffer = genQuadIndices(vertexCount); - else { - buffer = genIntQuadIndices(vertexCount); - } - } - case TRIANGLE_FAN -> buffer = genTriangleFanIndices(vertexCount); - case TRIANGLE_STRIP -> buffer = genTriangleStripIndices(vertexCount); - case LINES -> buffer = genLinesIndices(vertexCount); - case DEBUG_LINE_STRIP -> buffer = genDebugLineStripIndices(vertexCount); - default -> throw new IllegalArgumentException("Unsupported drawType: %s".formatted(this.drawType)); - } - - int size = buffer.capacity(); - this.indexBuffer = new IndexBuffer(size, MemoryTypes.GPU_MEM, indexType); - this.indexBuffer.copyBuffer(buffer, buffer.remaining()); - - MemoryUtil.memFree(buffer); - } - - public void checkCapacity(int vertexCount) { - if (vertexCount > this.vertexCount) { - int newVertexCount = Math.max(this.vertexCount * 2, vertexCount); - Initializer.LOGGER.info("Reallocating AutoIndexBuffer from {} to {}", this.vertexCount, newVertexCount); - - 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 enum DrawType { QUADS(7), TRIANGLE_FAN(6), diff --git a/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java b/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java index a6479dedd..94801d758 100644 --- a/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java +++ b/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java @@ -16,18 +16,26 @@ import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.VkCommandBuffer; import org.lwjgl.vulkan.VkRect2D; +import org.lwjgl.vulkan.VkViewport; import static org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; import static org.lwjgl.vulkan.VK10.*; public class DefaultMainPass implements MainPass { + public static DefaultMainPass create() { + return new DefaultMainPass(); + } + + private RenderTarget mainTarget; private final Framebuffer mainFramebuffer; - private final RenderTarget mainTarget; + private RenderPass mainRenderPass; private RenderPass auxRenderPass; + private GpuTexture[] colorAttachmentTextures; private GpuTextureView[] colorAttachmentTextureViews; + DefaultMainPass() { this.mainTarget = Minecraft.getInstance().getMainRenderTarget(); this.mainFramebuffer = Renderer.getInstance().getSwapChain(); @@ -36,10 +44,6 @@ public class DefaultMainPass implements MainPass { createSwapChainTextures(); } - public static DefaultMainPass create() { - return new DefaultMainPass(); - } - private void createRenderPasses() { RenderPass.Builder builder = RenderPass.builder(this.mainFramebuffer); builder.getColorAttachmentInfo().setFinalLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); diff --git a/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java b/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java index 3ff80f539..63a843c58 100644 --- a/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java +++ b/src/main/java/net/vulkanmod/vulkan/pass/MainPass.java @@ -15,17 +15,13 @@ public interface MainPass { void onResize(); - default void mainTargetBindWrite() { - } + default void mainTargetBindWrite() {} - default void mainTargetUnbindWrite() { - } + default void mainTargetUnbindWrite() {} - default void rebindMainTarget() { - } + default void rebindMainTarget() {} - default void bindAsTexture() { - } + default void bindAsTexture() {} default GpuTexture getColorAttachment() { return null; diff --git a/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java b/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java index 4130d74d8..8500e8da4 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java @@ -14,9 +14,10 @@ import static org.lwjgl.vulkan.VK10.*; public class CommandPool { + long id; + private final List commandBuffers = new ObjectArrayList<>(); private final java.util.Queue availableCmdBuffers = new ArrayDeque<>(); - long id; CommandPool(int queueFamilyIndex) { this.createCommandPool(queueFamilyIndex); diff --git a/src/main/java/net/vulkanmod/vulkan/queue/GraphicsQueue.java b/src/main/java/net/vulkanmod/vulkan/queue/GraphicsQueue.java index f7f25a411..e449f617b 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/GraphicsQueue.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/GraphicsQueue.java @@ -1,9 +1,13 @@ package net.vulkanmod.vulkan.queue; import net.vulkanmod.vulkan.Synchronization; +import net.vulkanmod.vulkan.Vulkan; +import net.vulkanmod.vulkan.memory.MemoryManager; +import net.vulkanmod.vulkan.util.VUtil; import org.lwjgl.system.MemoryStack; +import org.lwjgl.vulkan.*; -import static org.lwjgl.vulkan.VK10.VK_NULL_HANDLE; +import static org.lwjgl.vulkan.VK10.*; public class GraphicsQueue extends Queue { public static GraphicsQueue INSTANCE; diff --git a/src/main/java/net/vulkanmod/vulkan/queue/Queue.java b/src/main/java/net/vulkanmod/vulkan/queue/Queue.java index b45437c97..3e5b07fce 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/Queue.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/Queue.java @@ -25,6 +25,15 @@ public abstract class Queue { protected CommandPool commandPool; + public synchronized CommandPool.CommandBuffer beginCommands() { + try (MemoryStack stack = stackPush()) { + CommandPool.CommandBuffer commandBuffer = this.commandPool.getCommandBuffer(stack); + commandBuffer.begin(stack); + + return commandBuffer; + } + } + Queue(MemoryStack stack, int familyIndex) { this(stack, familyIndex, true); } @@ -38,6 +47,35 @@ public abstract class Queue { this.commandPool = new CommandPool(familyIndex); } + public synchronized long submitCommands(CommandPool.CommandBuffer commandBuffer) { + try (MemoryStack stack = stackPush()) { + return commandBuffer.submitCommands(stack, vkQueue, false); + } + } + + public VkQueue vkQueue() { + return this.vkQueue; + } + + public void cleanUp() { + if (commandPool != null) + commandPool.cleanUp(); + } + + public void waitIdle() { + vkQueueWaitIdle(vkQueue); + } + + public CommandPool getCommandPool() { + return commandPool; + } + + public enum Family { + Graphics, + Transfer, + Compute + } + public static QueueFamilyIndices getQueueFamilies() { if (device == null) device = Vulkan.getVkDevice(); @@ -153,44 +191,6 @@ public static QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) { } } - public synchronized CommandPool.CommandBuffer beginCommands() { - try (MemoryStack stack = stackPush()) { - CommandPool.CommandBuffer commandBuffer = this.commandPool.getCommandBuffer(stack); - commandBuffer.begin(stack); - - return commandBuffer; - } - } - - public synchronized long submitCommands(CommandPool.CommandBuffer commandBuffer) { - try (MemoryStack stack = stackPush()) { - return commandBuffer.submitCommands(stack, vkQueue, false); - } - } - - public VkQueue vkQueue() { - return this.vkQueue; - } - - public void cleanUp() { - if (commandPool != null) - commandPool.cleanUp(); - } - - public void waitIdle() { - vkQueueWaitIdle(vkQueue); - } - - public CommandPool getCommandPool() { - return commandPool; - } - - public enum Family { - Graphics, - Transfer, - Compute - } - public static class QueueFamilyIndices { public int graphicsFamily = VK_QUEUE_FAMILY_IGNORED; public int presentFamily = VK_QUEUE_FAMILY_IGNORED; diff --git a/src/main/java/net/vulkanmod/vulkan/queue/TransferQueue.java b/src/main/java/net/vulkanmod/vulkan/queue/TransferQueue.java index 7f83744f2..4cd17c4d6 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/TransferQueue.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/TransferQueue.java @@ -19,19 +19,6 @@ public TransferQueue(MemoryStack stack, int familyIndex) { super(stack, familyIndex); } - public static void uploadBufferCmd(VkCommandBuffer commandBuffer, long srcBuffer, long srcOffset, long dstBuffer, long dstOffset, long size) { - - try (MemoryStack stack = stackPush()) { - - VkBufferCopy.Buffer copyRegion = VkBufferCopy.calloc(1, stack); - copyRegion.size(size); - copyRegion.srcOffset(srcOffset); - copyRegion.dstOffset(dstOffset); - - vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, copyRegion); - } - } - public long copyBufferCmd(long srcBuffer, long srcOffset, long dstBuffer, long dstOffset, long size) { try (MemoryStack stack = stackPush()) { @@ -70,4 +57,17 @@ public void uploadBufferImmediate(long srcBuffer, long srcOffset, long dstBuffer } } + public static void uploadBufferCmd(VkCommandBuffer commandBuffer, long srcBuffer, long srcOffset, long dstBuffer, long dstOffset, long size) { + + try (MemoryStack stack = stackPush()) { + + VkBufferCopy.Buffer copyRegion = VkBufferCopy.calloc(1, stack); + copyRegion.size(size); + copyRegion.srcOffset(srcOffset); + copyRegion.dstOffset(dstOffset); + + vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, copyRegion); + } + } + } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/DescriptorSets.java b/src/main/java/net/vulkanmod/vulkan/shader/DescriptorSets.java index 1c35a2a0c..3bfb14bca 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/DescriptorSets.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/DescriptorSets.java @@ -18,20 +18,22 @@ import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK10.vkDestroyDescriptorPool; public class DescriptorSets { private static final VkDevice DEVICE = Vulkan.getVkDevice(); private final Pipeline pipeline; - private final long[] boundUBs; - private final ImageDescriptor.State[] boundTextures; - private final IntBuffer dynamicOffsets; private int poolSize = 10; private long descriptorPool; private LongBuffer sets; private long currentSet; private int currentIdx = -1; + private final long[] boundUBs; + private final ImageDescriptor.State[] boundTextures; + private final IntBuffer dynamicOffsets; + DescriptorSets(Pipeline pipeline) { this.pipeline = pipeline; this.boundTextures = new ImageDescriptor.State[pipeline.imageDescriptors.size()]; @@ -53,7 +55,7 @@ protected void bindSets(VkCommandBuffer commandBuffer, UniformBuffer uniformBuff this.updateDescriptorSet(stack, uniformBuffer); vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipeline.pipelineLayout, - 0, stack.longs(currentSet), dynamicOffsets); + 0, stack.longs(currentSet), dynamicOffsets); } } @@ -66,7 +68,8 @@ private void updateUniforms(UniformBuffer globalUB) { if (useOwnUB) { BufferSlice bufferSlice = ubo.getBufferSlice(); offset = bufferSlice.getOffset(); - } else { + } + else { offset = (int) globalUB.getUsedBytes(); int alignedSize = UniformBuffer.getAlignedSize(ubo.getSize()); globalUB.checkCapacity(alignedSize); diff --git a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java index c8324cd36..abf9e7e07 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java @@ -52,138 +52,6 @@ public class GraphicsPipeline extends Pipeline { PIPELINES.add(this); } - private static VkVertexInputBindingDescription.Buffer getBindingDescription(VertexFormat vertexFormat) { - VkVertexInputBindingDescription.Buffer bindingDescription = VkVertexInputBindingDescription.calloc(1); - - bindingDescription.binding(0); - bindingDescription.stride(vertexFormat.getVertexSize()); - bindingDescription.inputRate(VK_VERTEX_INPUT_RATE_VERTEX); - - return bindingDescription; - } - - private static VkVertexInputAttributeDescription.Buffer getAttributeDescriptions(VertexFormat vertexFormat) { - List elements = vertexFormat.getElements(); - - int size = elements.size(); - - VkVertexInputAttributeDescription.Buffer attributeDescriptions = VkVertexInputAttributeDescription.calloc(size); - - int offset = 0; - - for (int i = 0; i < size; ++i) { - VkVertexInputAttributeDescription posDescription = attributeDescriptions.get(i); - posDescription.binding(0); - posDescription.location(i); - - VertexFormatElement formatElement = elements.get(i); - VertexFormatElement.Usage usage = formatElement.usage(); - VertexFormatElement.Type type = formatElement.type(); - int elementCount = formatElement.count(); - - switch (usage) { - case POSITION -> { - switch (type) { - case FLOAT -> { - posDescription.format(VK_FORMAT_R32G32B32_SFLOAT); - posDescription.offset(offset); - - offset += 12; - } - case SHORT -> { - posDescription.format(VK_FORMAT_R16G16B16A16_SINT); - posDescription.offset(offset); - - offset += 8; - } - case BYTE -> { - posDescription.format(VK_FORMAT_R8G8B8A8_SINT); - posDescription.offset(offset); - - offset += 4; - } - } - - } - - case COLOR -> { - switch (type) { - case UBYTE -> { - posDescription.format(VK_FORMAT_R8G8B8A8_UNORM); - posDescription.offset(offset); - - offset += 4; - } - case UINT -> { - posDescription.format(VK_FORMAT_R32_UINT); - posDescription.offset(offset); - - offset += 4; - } - } - } - - case UV -> { - switch (type) { - case FLOAT -> { - posDescription.format(VK_FORMAT_R32G32_SFLOAT); - posDescription.offset(offset); - - offset += 8; - } - case SHORT -> { - posDescription.format(VK_FORMAT_R16G16_SINT); - posDescription.offset(offset); - - offset += 4; - } - case USHORT -> { - posDescription.format(VK_FORMAT_R16G16_UINT); - posDescription.offset(offset); - - offset += 4; - } - case UINT -> { - posDescription.format(VK_FORMAT_R32_UINT); - posDescription.offset(offset); - - offset += 4; - } - } - } - - case NORMAL -> { - posDescription.format(VK_FORMAT_R8G8B8A8_SNORM); - posDescription.offset(offset); - - offset += 4; - } - - case GENERIC -> { - if (type == VertexFormatElement.Type.SHORT && elementCount == 1) { - posDescription.format(VK_FORMAT_R16_SINT); - posDescription.offset(offset); - - offset += 2; - } else if (type == VertexFormatElement.Type.INT && elementCount == 1) { - posDescription.format(VK_FORMAT_R32_SINT); - posDescription.offset(offset); - - offset += 4; - } else { - throw new RuntimeException(String.format("Unknown format: %s", usage)); - } - } - - default -> throw new RuntimeException(String.format("Unknown format: %s", usage)); - } - - posDescription.offset(((VertexFormatMixed) (vertexFormat)).getOffset(i)); - } - - return attributeDescriptions.rewind(); - } - public long getHandle(PipelineState state) { return graphicsPipelines.computeIfAbsent(state, this::createGraphicsPipeline); } @@ -282,7 +150,8 @@ private long createGraphicsPipeline(PipelineState state) { colorBlendAttachment.srcAlphaBlendFactor(PipelineState.BlendState.getSrcAlphaFactor(state.blendState_i)); colorBlendAttachment.dstAlphaBlendFactor(PipelineState.BlendState.getDstAlphaFactor(state.blendState_i)); colorBlendAttachment.alphaBlendOp(PipelineState.BlendState.blendOp(state.blendState_i)); - } else { + } + else { colorBlendAttachment.blendEnable(false); } @@ -301,8 +170,9 @@ private long createGraphicsPipeline(PipelineState state) { 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 { + VK_DYNAMIC_STATE_LINE_WIDTH)); + } + else { dynamicStates.pDynamicStates( stack.ints(VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR)); } @@ -325,7 +195,8 @@ private long createGraphicsPipeline(PipelineState state) { if (!Vulkan.DYNAMIC_RENDERING) { pipelineInfo.renderPass(state.renderPass.getId()); pipelineInfo.subpass(0); - } else { + } + else { //dyn-rendering VkPipelineRenderingCreateInfoKHR renderingInfo = VkPipelineRenderingCreateInfoKHR.calloc(stack); renderingInfo.sType(KHRDynamicRendering.VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR); @@ -337,7 +208,7 @@ private long createGraphicsPipeline(PipelineState state) { LongBuffer pGraphicsPipeline = stack.mallocLong(1); Vulkan.checkResult(vkCreateGraphicsPipelines(DeviceManager.vkDevice, PIPELINE_CACHE, pipelineInfo, null, pGraphicsPipeline), - "Failed to create graphics pipeline " + this.name); + "Failed to create graphics pipeline " + this.name); return pGraphicsPipeline.get(0); } @@ -376,7 +247,8 @@ static class VertexInputDescription { if (vertexFormat != DefaultVertexFormat.EMPTY) { this.bindingDescriptions = getBindingDescription(vertexFormat); this.attributeDescriptions = getAttributeDescriptions(vertexFormat); - } else { + } + else { this.bindingDescriptions = null; this.attributeDescriptions = null; } @@ -389,4 +261,138 @@ void cleanUp() { } } } + + private static VkVertexInputBindingDescription.Buffer getBindingDescription(VertexFormat vertexFormat) { + VkVertexInputBindingDescription.Buffer bindingDescription = VkVertexInputBindingDescription.calloc(1); + + bindingDescription.binding(0); + bindingDescription.stride(vertexFormat.getVertexSize()); + bindingDescription.inputRate(VK_VERTEX_INPUT_RATE_VERTEX); + + return bindingDescription; + } + + private static VkVertexInputAttributeDescription.Buffer getAttributeDescriptions(VertexFormat vertexFormat) { + List elements = vertexFormat.getElements(); + + int size = elements.size(); + + VkVertexInputAttributeDescription.Buffer attributeDescriptions = VkVertexInputAttributeDescription.calloc(size); + + int offset = 0; + + for (int i = 0; i < size; ++i) { + VkVertexInputAttributeDescription posDescription = attributeDescriptions.get(i); + posDescription.binding(0); + posDescription.location(i); + + VertexFormatElement formatElement = elements.get(i); + VertexFormatElement.Usage usage = formatElement.usage(); + VertexFormatElement.Type type = formatElement.type(); + int elementCount = formatElement.count(); + + switch (usage) { + case POSITION -> { + switch (type) { + case FLOAT -> { + posDescription.format(VK_FORMAT_R32G32B32_SFLOAT); + posDescription.offset(offset); + + offset += 12; + } + case SHORT -> { + posDescription.format(VK_FORMAT_R16G16B16A16_SINT); + posDescription.offset(offset); + + offset += 8; + } + case BYTE -> { + posDescription.format(VK_FORMAT_R8G8B8A8_SINT); + posDescription.offset(offset); + + offset += 4; + } + } + + } + + case COLOR -> { + switch (type) { + case UBYTE -> { + posDescription.format(VK_FORMAT_R8G8B8A8_UNORM); + posDescription.offset(offset); + + offset += 4; + } + case UINT -> { + posDescription.format(VK_FORMAT_R32_UINT); + posDescription.offset(offset); + + offset += 4; + } + } + } + + case UV -> { + switch (type) { + case FLOAT -> { + posDescription.format(VK_FORMAT_R32G32_SFLOAT); + posDescription.offset(offset); + + offset += 8; + } + case SHORT -> { + posDescription.format(VK_FORMAT_R16G16_SINT); + posDescription.offset(offset); + + offset += 4; + } + case USHORT -> { + posDescription.format(VK_FORMAT_R16G16_UINT); + posDescription.offset(offset); + + offset += 4; + } + case UINT -> { + posDescription.format(VK_FORMAT_R32_UINT); + posDescription.offset(offset); + + offset += 4; + } + } + } + + case NORMAL -> { + posDescription.format(VK_FORMAT_R8G8B8A8_SNORM); + posDescription.offset(offset); + + offset += 4; + } + + case GENERIC -> { + if (type == VertexFormatElement.Type.SHORT && elementCount == 1) { + posDescription.format(VK_FORMAT_R16_SINT); + posDescription.offset(offset); + + offset += 2; + } + else if (type == VertexFormatElement.Type.INT && elementCount == 1) { + posDescription.format(VK_FORMAT_R32_SINT); + posDescription.offset(offset); + + offset += 4; + } + else { + throw new RuntimeException(String.format("Unknown format: %s", usage)); + } + } + + default -> throw new RuntimeException(String.format("Unknown format: %s", usage)); + } + + posDescription.offset(((VertexFormatMixed) (vertexFormat)).getOffset(i)); + } + + return attributeDescriptions.rewind(); + } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java index 6b6f6eb81..2c70890fc 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java @@ -39,20 +39,9 @@ public abstract class Pipeline { - protected static final List PIPELINES = new LinkedList<>(); private static final VkDevice DEVICE = Vulkan.getVkDevice(); protected static final long PIPELINE_CACHE = createPipelineCache(); - public final String name; - protected long descriptorSetLayout; - protected long pipelineLayout; - protected DescriptorSets[] descriptorSets; - protected List buffers; - protected ManualUBO manualUBO; - protected List imageDescriptors; - protected PushConstants pushConstants; - public Pipeline(String name) { - this.name = name; - } + protected static final List PIPELINES = new LinkedList<>(); private static long createPipelineCache() { try (MemoryStack stack = stackPush()) { @@ -81,23 +70,19 @@ public static void recreateDescriptorSets(int frames) { }); } - static long createShaderModule(ByteBuffer spirvCode) { - - try (MemoryStack stack = stackPush()) { - - VkShaderModuleCreateInfo createInfo = VkShaderModuleCreateInfo.calloc(stack); - - createInfo.sType(VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); - createInfo.pCode(spirvCode); + public final String name; - LongBuffer pShaderModule = stack.mallocLong(1); + protected long descriptorSetLayout; + protected long pipelineLayout; - if (vkCreateShaderModule(DEVICE, createInfo, null, pShaderModule) != VK_SUCCESS) { - throw new RuntimeException("Failed to create shader module"); - } + protected DescriptorSets[] descriptorSets; + protected List buffers; + protected ManualUBO manualUBO; + protected List imageDescriptors; + protected PushConstants pushConstants; - return pShaderModule.get(0); - } + public Pipeline(String name) { + this.name = name; } protected void createDescriptorSetLayout() { @@ -255,6 +240,25 @@ public void bindDescriptorSets(VkCommandBuffer commandBuffer, UniformBuffer unif this.descriptorSets[frame].bindSets(commandBuffer, uniformBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS); } + static long createShaderModule(ByteBuffer spirvCode) { + + try (MemoryStack stack = stackPush()) { + + VkShaderModuleCreateInfo createInfo = VkShaderModuleCreateInfo.calloc(stack); + + createInfo.sType(VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); + createInfo.pCode(spirvCode); + + LongBuffer pShaderModule = stack.mallocLong(1); + + if (vkCreateShaderModule(DEVICE, createInfo, null, pShaderModule) != VK_SUCCESS) { + throw new RuntimeException("Failed to create shader module"); + } + + return pShaderModule.get(0); + } + } + public static class Builder { final VertexFormat vertexFormat; final String shaderPath; @@ -284,17 +288,6 @@ public Builder() { this(null, null); } - public static int getStageFromString(String s) { - return switch (s) { - case "vertex" -> VK_SHADER_STAGE_VERTEX_BIT; - case "fragment" -> VK_SHADER_STAGE_FRAGMENT_BIT; - case "all" -> VK_SHADER_STAGE_ALL_GRAPHICS; - case "compute" -> VK_SHADER_STAGE_COMPUTE_BIT; - - default -> throw new RuntimeException("cannot identify type.."); - }; - } - public GraphicsPipeline createGraphicsPipeline() { Validate.isTrue(this.imageDescriptors != null && this.UBOs != null && this.vertShaderSPIRV != null && this.fragShaderSPIRV != null, @@ -390,7 +383,8 @@ private void parseUboNode(JsonElement jsonelement) { } uniformInfo.setBufferSupplier(uniformSupplier); - } else { + } + else { throw new IllegalStateException("No uniform supplier found for uniform: (%s:%s)".formatted(type2, name)); } } @@ -445,5 +439,16 @@ private void parsePushConstantNode(JsonArray jsonArray) { this.pushConstants = builder.buildPushConstant(); } + + public static int getStageFromString(String s) { + return switch (s) { + case "vertex" -> VK_SHADER_STAGE_VERTEX_BIT; + case "fragment" -> VK_SHADER_STAGE_FRAGMENT_BIT; + case "all" -> VK_SHADER_STAGE_ALL_GRAPHICS; + case "compute" -> VK_SHADER_STAGE_COMPUTE_BIT; + + default -> throw new RuntimeException("cannot identify type.."); + }; + } } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java b/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java index c4d8129f9..1c7d0e5cd 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java @@ -16,23 +16,6 @@ public class PipelineState { public static final PipelineState DEFAULT = new PipelineState(getAssemblyRasterState(), getBlendState(), getDepthState(), getLogicOpState(), VRenderSystem.getColorMask(), null); public static PipelineState currentState = DEFAULT; - final RenderPass renderPass; - int assemblyRasterState; - int blendState_i; - int depthState_i; - int colorMask_i; - int logicOp_i; - - public PipelineState(int assemblyRasterState, int blendState, int depthState, int logicOp, int colorMask, - RenderPass renderPass) { - this.renderPass = renderPass; - - this.assemblyRasterState = assemblyRasterState; - this.blendState_i = blendState; - this.depthState_i = depthState; - this.colorMask_i = colorMask; - this.logicOp_i = logicOp; - } public static PipelineState getCurrentPipelineState(RenderPass renderPass) { int assemblyRasterState = getAssemblyRasterState(); @@ -76,17 +59,31 @@ public static int getLogicOpState() { return logicOpState; } - public static BlendInfo defaultBlendInfo() { - return new BlendInfo(true, VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD); + final RenderPass renderPass; + + int assemblyRasterState; + int blendState_i; + int depthState_i; + int colorMask_i; + int logicOp_i; + + public PipelineState(int assemblyRasterState, int blendState, int depthState, int logicOp, int colorMask, + RenderPass renderPass) { + this.renderPass = renderPass; + + this.assemblyRasterState = assemblyRasterState; + this.blendState_i = blendState; + this.depthState_i = depthState; + this.colorMask_i = colorMask; + this.logicOp_i = logicOp; } private boolean checkEquals(int assemblyRasterState, int blendState, int depthState, int logicOp, int colorMask, RenderPass renderPass) { return (blendState == this.blendState_i) && (depthState == this.depthState_i) - && renderPass == this.renderPass && logicOp == this.logicOp_i - && (assemblyRasterState == this.assemblyRasterState) - && colorMask == this.colorMask_i; + && renderPass == this.renderPass && logicOp == this.logicOp_i + && (assemblyRasterState == this.assemblyRasterState) + && colorMask == this.colorMask_i; } @Override @@ -98,9 +95,9 @@ public boolean equals(Object o) { PipelineState that = (PipelineState) o; return (blendState_i == that.blendState_i) && (depthState_i == that.depthState_i) - && this.renderPass == that.renderPass && logicOp_i == that.logicOp_i - && this.assemblyRasterState == that.assemblyRasterState - && this.colorMask_i == that.colorMask_i; + && this.renderPass == that.renderPass && logicOp_i == that.logicOp_i + && this.assemblyRasterState == that.assemblyRasterState + && this.colorMask_i == that.colorMask_i; } @Override @@ -108,6 +105,11 @@ public int hashCode() { return Objects.hash(blendState_i, depthState_i, logicOp_i, assemblyRasterState, colorMask_i, renderPass); } + public static BlendInfo defaultBlendInfo() { + return new BlendInfo(true, VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD); + } + public static class BlendInfo { public boolean enabled; public int srcRgbFactor; @@ -126,6 +128,31 @@ public BlendInfo(boolean enabled, int srcRgbFactor, int dstRgbFactor, int srcAlp this.blendOp = blendOp; } + /* gl to Vulkan conversion */ + public void setBlendFunction(int sourceFactor, int destFactor) { + this.srcRgbFactor = glToVulkanBlendFactor(sourceFactor); + this.srcAlphaFactor = glToVulkanBlendFactor(sourceFactor); + this.dstRgbFactor = glToVulkanBlendFactor(destFactor); + this.dstAlphaFactor = glToVulkanBlendFactor(destFactor); + } + + /* gl to Vulkan conversion */ + public void setBlendFuncSeparate(int srcRgb, int dstRgb, int srcAlpha, int dstAlpha) { + this.srcRgbFactor = glToVulkanBlendFactor(srcRgb); + this.srcAlphaFactor = glToVulkanBlendFactor(srcAlpha); + this.dstRgbFactor = glToVulkanBlendFactor(dstRgb); + this.dstAlphaFactor = glToVulkanBlendFactor(dstAlpha); + } + + public void setBlendOp(int i) { + this.blendOp = glToVulkanBlendOp(i); + } + + + public int createBlendState() { + return BlendState.getState(this); + } + private static int glToVulkanBlendOp(int value) { return switch (value) { case 0x8006 -> VK_BLEND_OP_ADD; @@ -174,30 +201,6 @@ private static int glToVulkanBlendFactor(int value) { // ZERO(0); }; } - - /* gl to Vulkan conversion */ - public void setBlendFunction(int sourceFactor, int destFactor) { - this.srcRgbFactor = glToVulkanBlendFactor(sourceFactor); - this.srcAlphaFactor = glToVulkanBlendFactor(sourceFactor); - this.dstRgbFactor = glToVulkanBlendFactor(destFactor); - this.dstAlphaFactor = glToVulkanBlendFactor(destFactor); - } - - /* gl to Vulkan conversion */ - public void setBlendFuncSeparate(int srcRgb, int dstRgb, int srcAlpha, int dstAlpha) { - this.srcRgbFactor = glToVulkanBlendFactor(srcRgb); - this.srcAlphaFactor = glToVulkanBlendFactor(srcAlpha); - this.dstRgbFactor = glToVulkanBlendFactor(dstRgb); - this.dstAlphaFactor = glToVulkanBlendFactor(dstAlpha); - } - - public void setBlendOp(int i) { - this.blendOp = glToVulkanBlendOp(i); - } - - public int createBlendState() { - return BlendState.getState(this); - } } public static class BlendState { @@ -324,9 +327,9 @@ public static abstract class ColorMask { public static int getColorMask(boolean r, boolean g, boolean b, boolean a) { return (r ? VK_COLOR_COMPONENT_R_BIT : 0) - | (g ? VK_COLOR_COMPONENT_G_BIT : 0) - | (b ? VK_COLOR_COMPONENT_B_BIT : 0) - | (a ? VK_COLOR_COMPONENT_A_BIT : 0); + | (g ? VK_COLOR_COMPONENT_G_BIT : 0) + | (b ? VK_COLOR_COMPONENT_B_BIT : 0) + | (a ? VK_COLOR_COMPONENT_A_BIT : 0); } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java b/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java index 0dbe756fa..a45379fde 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java @@ -24,12 +24,15 @@ public class SPIRVUtils { private static final boolean DEBUG = true; private static final boolean OPTIMIZATIONS = false; + + private static long compiler; + private static long options; + //The dedicated Includer and Releaser Inner Classes used to Initialise #include Support for ShaderC private static final ShaderIncluder SHADER_INCLUDER = new ShaderIncluder(); private static final ShaderReleaser SHADER_RELEASER = new ShaderReleaser(); private static final long pUserData = 0; - private static long compiler; - private static long options; + private static ObjectArrayList includePaths; static { @@ -120,9 +123,9 @@ public long invoke(long user_data, long requested_source, int type, long request 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 048e0d411..e7e81619d 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/Uniforms.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/Uniforms.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; import net.vulkanmod.vulkan.VRenderSystem; +import net.vulkanmod.vulkan.shader.layout.Uniform; import net.vulkanmod.vulkan.util.MappedBuffer; import java.util.function.Supplier; diff --git a/src/main/java/net/vulkanmod/vulkan/shader/converter/Attribute.java b/src/main/java/net/vulkanmod/vulkan/shader/converter/Attribute.java index cab4742c2..4bce3fb51 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/converter/Attribute.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/converter/Attribute.java @@ -9,8 +9,7 @@ public class Attribute { public Attribute(String ioType, String type, String id) { switch (ioType) { - case "in", "out" -> { - } + case "in", "out" -> {} default -> throw new IllegalArgumentException(); } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/converter/GLSLParser.java b/src/main/java/net/vulkanmod/vulkan/shader/converter/GLSLParser.java index 4ef77c346..e3fae4055 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/converter/GLSLParser.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/converter/GLSLParser.java @@ -15,28 +15,31 @@ * Simple parser used to convert GLSL shader code to make it Vulkan compatible */ public class GLSLParser { + private Lexer lexer; + private List tokens; + private int currentTokenIdx; + private Token currentToken; + + private Stage stage; State state = State.DEFAULT; + LinkedList vsStream = new LinkedList<>(); LinkedList fsStream = new LinkedList<>(); + int currentUniformLocation = 0; List uniformBlocks = new ArrayList<>(); Map uniformBlockMap = new HashMap<>(); List samplers = new ArrayList<>(); Map samplerMap = new HashMap<>(); + VertexFormat vertexFormat; int currentInAtt = 0, currentOutAtt = 0; ArrayList vertInAttributes = new ArrayList<>(); ArrayList vertOutAttributes = new ArrayList<>(); ArrayList fragInAttributes = new ArrayList<>(); ArrayList fragOutAttributes = new ArrayList<>(); - private Lexer lexer; - private List tokens; - private int currentTokenIdx; - private Token currentToken; - private Stage stage; - public GLSLParser() { - } + public GLSLParser() {} public void setVertexFormat(VertexFormat vertexFormat) { this.vertexFormat = vertexFormat; @@ -86,7 +89,7 @@ public void parse(Lexer lexer, Stage stage) { } } - private void parsePreprocessor() { + private void parsePreprocessor() { if (!currentToken.value.startsWith("#line")) { appendToken(currentToken); } @@ -127,7 +130,8 @@ private void parseSampler(Sampler.Type type) { if (next.type == Token.TokenType.SPACING) { if (Objects.equals(next.value, "\n")) { currentTokenIdx++; - } else { + } + else { int i = next.value.indexOf("\n"); if (i >= 0) { next.value = next.value.substring(i + 1); @@ -139,7 +143,8 @@ private void parseSampler(Sampler.Type type) { if (samplerMap.get(name) != null) { sampler = samplerMap.get(name); - } else { + } + else { sampler.setBinding(currentUniformLocation++); this.samplerMap.put(name, sampler); this.samplers.add(sampler); @@ -206,8 +211,7 @@ private void parseUniformBlock() { nextToken(true); switch (currentToken.type) { - case SEMICOLON -> { - } + case SEMICOLON -> {} case IDENTIFIER -> { ub.setAlias(currentToken.value); @@ -225,7 +229,8 @@ private void parseUniformBlock() { if (next.type == Token.TokenType.SPACING) { if (Objects.equals(next.value, "\n")) { currentTokenIdx++; - } else { + } + else { int i = next.value.indexOf("\n"); if (i >= 0) { next.value = next.value.substring(i + 1); @@ -235,7 +240,8 @@ private void parseUniformBlock() { if (uniformBlockMap.get(ub.name) != null) { ub = uniformBlockMap.get(ub.name); - } else { + } + else { ub.setBinding(this.currentUniformLocation++); this.uniformBlockMap.put(ub.name, ub); this.uniformBlocks.add(ub); @@ -270,7 +276,8 @@ private void parseAttribute() { if (next.type == Token.TokenType.SPACING) { if (Objects.equals(next.value, "\n")) { currentTokenIdx++; - } else { + } + else { int i = next.value.indexOf("\n"); if (i >= 0) { next.value = next.value.substring(i + 1); @@ -315,7 +322,8 @@ private void parseAttribute() { if (vertAttribute != null) { attribute.setLocation(vertAttribute.location); fragInAttributes.add(attribute); - } else { + } + else { return; } } @@ -420,7 +428,7 @@ public UBO[] createUBOs() { builder.addUniformInfo(uniformInfo); } - ubos[i] = builder.buildUBO(uniformBlock.name, uniformBlock.binding, VK11.VK_SHADER_STAGE_ALL); + ubos[i] = builder.buildUBO(uniformBlock.name, uniformBlock.binding, VK11.VK_SHADER_STAGE_ALL); ++i; } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/converter/Token.java b/src/main/java/net/vulkanmod/vulkan/shader/converter/Token.java index ce1ba5859..560f9df07 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/converter/Token.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/converter/Token.java @@ -2,21 +2,6 @@ public class Token { - public final TokenType type; - public String value; - public Token(TokenType type, String value) { - this.type = type; - this.value = value; - } - - @Override - public String toString() { - return "Token{" + - "type=" + type + - ", value='" + value + '\'' + - '}'; - } - public enum TokenType { PREPROCESSOR, KEYWORD, @@ -45,4 +30,20 @@ public enum TokenType { EOF } + + public final TokenType type; + public String value; + + public Token(TokenType type, String value) { + this.type = type; + this.value = value; + } + + @Override + public String toString() { + return "Token{" + + "type=" + type + + ", value='" + value + '\'' + + '}'; + } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/Descriptor.java b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/Descriptor.java index 2a8fd774a..2685ccd0e 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/Descriptor.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/Descriptor.java @@ -2,9 +2,9 @@ public interface Descriptor { - int getBinding(); + int getBinding(); - int getType(); + int getType(); - int getStages(); + int getStages(); } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java index 9d73fcd06..0354402ac 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java @@ -7,11 +7,12 @@ public class ImageDescriptor implements Descriptor { + private final int descriptorType; + private final int binding; public final String qualifier; public final String name; public final int imageIdx; - private final int descriptorType; - private final int binding; + public boolean useSampler; public boolean isReadOnlyLayout; private int layout; @@ -57,23 +58,23 @@ public int getStages() { return VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT; } - public int getLayout() { - return layout; - } - public void setLayout(int layout) { this.layout = layout; this.isReadOnlyLayout = layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } - public int getMipLevel() { - return mipLevel; + public int getLayout() { + return layout; } public void setMipLevel(int mipLevel) { this.mipLevel = mipLevel; } + public int getMipLevel() { + return mipLevel; + } + public VulkanImage getImage() { return VTextureSelector.getImage(this.imageIdx); } 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 af4f54aae..1229f1ada 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java @@ -29,10 +29,10 @@ public UBO(String name, int binding, int stages, int size, List in @Override public String toString() { return "UBO{" + - "name='" + name + '\'' + - ", binding=" + binding + - ", useGlobalBuffer=" + useGlobalBuffer + - '}'; + "name='" + name + '\'' + + ", binding=" + binding + + ", useGlobalBuffer=" + useGlobalBuffer + + '}'; } public int getBinding() { diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat3.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat3.java index 8ed9f6064..82f067323 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat3.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat3.java @@ -12,7 +12,7 @@ public class Mat3 extends Uniform { void update(long ptr) { MappedBuffer src = values.get(); - MemoryUtil.memCopy(src.ptr, ptr + this.offset, 12); + MemoryUtil.memCopy(src.ptr + 0, ptr + this.offset + 0, 12); MemoryUtil.memCopy(src.ptr + 12, ptr + this.offset + 16, 12); MemoryUtil.memCopy(src.ptr + 24, ptr + this.offset + 32, 12); } 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 118a773ed..8c1509df1 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java @@ -8,9 +8,10 @@ public class Uniform { protected Supplier values; + + Info info; protected long offset; protected int size; - Info info; Uniform(Info info) { this.info = info; @@ -20,6 +21,24 @@ public class Uniform { this.setupSupplier(); } + protected void setupSupplier() { + this.values = this.info.bufferSupplier; + } + + public void setSupplier(Supplier supplier) { + this.values = supplier; + } + + public String getName() { + return this.info.name; + } + + void update(long ptr) { + MappedBuffer src = values.get(); + + MemoryUtil.memCopy(src.ptr, ptr + this.offset, this.size); + } + public static Uniform createField(Info info) { return switch (info.type) { case "mat4", "vec3", "vec4", "vec2" -> new Uniform(info); @@ -30,6 +49,20 @@ public static Uniform createField(Info info) { }; } + public int getOffset() { + return info.offset; + } + + 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); + } + //TODO public static Info createUniformInfo(String type, String name, int count) { return switch (type) { @@ -62,40 +95,6 @@ public static Info createUniformInfo(String type, String name) { }; } - protected void setupSupplier() { - this.values = this.info.bufferSupplier; - } - - public void setSupplier(Supplier supplier) { - this.values = supplier; - } - - public String getName() { - return this.info.name; - } - - void update(long ptr) { - MappedBuffer src = values.get(); - - MemoryUtil.memCopy(src.ptr, ptr + this.offset, this.size); - } - - public int getOffset() { - return info.offset; - } - - 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); - } - public static class Info { public final String type; public final String name; @@ -114,9 +113,7 @@ public static class Info { this.size = size; } - int getSizeBytes() { - return 4 * this.size; - } + int getSizeBytes() { return 4 * this.size; } int computeAlignmentOffset(int builderOffset) { return this.offset = builderOffset + ((align - (builderOffset % align)) % align); 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 954934708..700fd00bf 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java @@ -1,6 +1,8 @@ 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; diff --git a/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java b/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java index 6557b23cb..84a5665bc 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java @@ -46,18 +46,18 @@ 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); + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + pStagingBuffer, pStagingAllocation); copyImageToBufferCmd(stack, commandBuffer.getHandle(), pStagingBuffer.get(0), image.getId(), 0, image.width, - image.height, 0, 0, 0, 0, 0); + 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)); } @@ -72,7 +72,7 @@ public static void copyImageToBuffer(VulkanImage image, Buffer buffer, int mipLe image.transitionImageLayout(stack, commandBuffer.getHandle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); copyImageToBufferCmd(stack, commandBuffer.getHandle(), buffer.getId(), image.getId(), mipLevel, width, - height, xOffset, yOffset, bufferOffset, bufferRowLength, bufferImageHeight); + height, xOffset, yOffset, bufferOffset, bufferRowLength, bufferImageHeight); image.transitionImageLayout(stack, commandBuffer.getHandle(), prevLayout); long fence = DeviceManager.getGraphicsQueue().submitCommands(commandBuffer); @@ -115,18 +115,18 @@ public static void blitFramebuffer(VulkanImage dstImage, int srcX0, int srcY0, i 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); + .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); + .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.getId(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, blit, VK_FILTER_LINEAR); dstImage.transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); @@ -166,7 +166,7 @@ public static void generateMipmaps(VulkanImage image) { barrier.dstAccessMask(VK_ACCESS_TRANSFER_READ_BIT); vkCmdPipelineBarrier(commandBuffer.getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, 0, null, null, barrier); + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, null, null, barrier); prevLevel = level - 1; @@ -174,18 +174,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); + .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); + image.getId(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, blit, VK_FILTER_LINEAR); } @@ -208,20 +208,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/SamplerManager.java b/src/main/java/net/vulkanmod/vulkan/texture/SamplerManager.java index cfb05a4bf..f58fb4255 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/SamplerManager.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/SamplerManager.java @@ -17,13 +17,8 @@ import static org.lwjgl.vulkan.VK12.VK_SAMPLER_REDUCTION_MODE_MIN; public abstract class SamplerManager { - public static final byte LINEAR_FILTERING_BIT = 0b1; - public static final byte CLAMP_BIT = 0b10; - public static final byte USE_MIPMAPS_BIT = 0b100; - public static final byte MIPMAP_LINEAR_FILTERING_BIT = 0b1000; - public static final byte REDUCTION_MIN_BIT = 0b10000; - public static final byte REDUCTION_MAX_BIT = 0b100000; static final float MIP_BIAS = -0.5f; + static final Short2LongMap SAMPLERS = new Short2LongOpenHashMap(); public static long getTextureSampler(byte maxLod, byte flags) { @@ -111,4 +106,11 @@ public static void cleanUp() { vkDestroySampler(DeviceManager.vkDevice, id, null); } } + + public static final byte LINEAR_FILTERING_BIT = 0b1; + public static final byte CLAMP_BIT = 0b10; + public static final byte USE_MIPMAPS_BIT = 0b100; + public static final byte MIPMAP_LINEAR_FILTERING_BIT = 0b1000; + public static final byte REDUCTION_MIN_BIT = 0b10000; + public static final byte REDUCTION_MAX_BIT = 0b100000; } diff --git a/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java b/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java index 59dfa793a..58d1b31a7 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java @@ -49,7 +49,7 @@ public static void uploadSubTexture(int mipLevel, int width, int height, int xOf int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, ByteBuffer buffer) { uploadSubTexture(mipLevel, 0, width, height, xOffset, yOffset, unpackSkipRows, unpackSkipPixels, unpackRowLength, - MemoryUtil.memAddress(buffer)); + MemoryUtil.memAddress(buffer)); } public static void uploadSubTexture(int mipLevel, int arrayLayer, int width, int height, int xOffset, int yOffset, @@ -61,7 +61,7 @@ public static void uploadSubTexture(int mipLevel, int arrayLayer, int width, int throw new NullPointerException("Texture is null at index: " + activeTexture); texture.uploadSubTextureAsync(mipLevel, arrayLayer, width, height, xOffset, yOffset, unpackSkipRows, unpackSkipPixels, - unpackRowLength, bufferPtr); + unpackRowLength, bufferPtr); } public static int getTextureIdx(String name) { diff --git a/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java b/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java index 05408346f..ab89a99d2 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java @@ -24,8 +24,10 @@ import static org.lwjgl.vulkan.VK10.*; public class VulkanImage { - private static final VkDevice DEVICE = Vulkan.getVkDevice(); public static int DefaultFormat = VK_FORMAT_R8G8B8A8_UNORM; + + private static final VkDevice DEVICE = Vulkan.getVkDevice(); + public final String name; public final int format; public final int aspect; @@ -132,6 +134,32 @@ public static VulkanImage createWhiteTexture() { } } + private void createImage() { + try (MemoryStack stack = stackPush()) { + LongBuffer pTextureImage = stack.mallocLong(1); + PointerBuffer pAllocation = stack.pointers(0L); + + int flags = viewType == VK_IMAGE_VIEW_TYPE_CUBE ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0; + + MemoryManager.getInstance() + .createImage(width, height, arrayLayers, mipLevels, + format, VK_IMAGE_TILING_OPTIMAL, + usage, flags, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + pTextureImage, + pAllocation); + + id = pTextureImage.get(0); + allocation = pAllocation.get(0); + + MemoryManager.addImage(this); + + if (this.name != null) { + Vulkan.setDebugLabel(stack, VK_OBJECT_TYPE_IMAGE, pTextureImage.get(), this.name); + } + } + } + public static int getAspect(int format) { return switch (format) { case VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT -> @@ -180,6 +208,111 @@ public static long createImageView(long image, int viewType, int format, int asp } } + public void uploadSubTextureAsync(int mipLevel, + int width, int height, + int xOffset, int yOffset, + int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, + ByteBuffer buffer) + { + this.uploadSubTextureAsync(mipLevel, 0, width, height, + xOffset, yOffset, + unpackSkipRows, unpackSkipPixels, unpackRowLength, + MemoryUtil.memAddress(buffer)); + } + + public void uploadSubTextureAsync(int mipLevel, int arrayLayer, + int width, int height, + int xOffset, int yOffset, + int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, + ByteBuffer buffer) + { + this.uploadSubTextureAsync(mipLevel, arrayLayer, width, height, + xOffset, yOffset, + unpackSkipRows, unpackSkipPixels, unpackRowLength, + MemoryUtil.memAddress(buffer)); + } + + public void uploadSubTextureAsync(int mipLevel, int arrayLayer, + int width, int height, + int xOffset, int yOffset, + int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, + long srcPtr) + { + long uploadSize = (long) (unpackRowLength * height - unpackSkipPixels) * this.formatSize; + + 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(); + } + + srcPtr += ((long) unpackRowLength * unpackSkipRows + unpackSkipPixels) * this.formatSize; + + stagingBuffer.align(this.formatSize); + stagingBuffer.copyBuffer((int) uploadSize, srcPtr); + + long bufferId = stagingBuffer.getId(); + + VkCommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer().getHandle(); + try (MemoryStack stack = stackPush()) { + transferDstLayout(stack, commandBuffer); + + final int srcOffset = (int) (stagingBuffer.getOffset()); + + ImageUtil.copyBufferToImageCmd(stack, commandBuffer, bufferId, this.id, + arrayLayer, mipLevel, width, height, xOffset, yOffset, + srcOffset, unpackRowLength, height); + } + } + + private void transferDstLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { + transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + } + + public void readOnlyLayout() { + if (this.currentLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + return; + + try (MemoryStack stack = MemoryStack.stackPush()) { + if (Renderer.getInstance().getBoundRenderPass() != null) { + CommandPool.CommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer(); + VkCommandBuffer vkCommandBuffer = commandBuffer.getHandle(); + + readOnlyLayout(stack, vkCommandBuffer); + } + else { + readOnlyLayout(stack, Renderer.getCommandBuffer()); + } + } + } + + public void readOnlyLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { + transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + } + + public void updateTextureSampler(boolean blur, boolean clamp, boolean mipmaps) { + byte flags = blur ? LINEAR_FILTERING_BIT : 0; + flags |= clamp ? CLAMP_BIT : 0; + flags |= (byte) (mipmaps ? USE_MIPMAPS_BIT | MIPMAP_LINEAR_FILTERING_BIT : 0); + + this.updateTextureSampler(flags); + } + + public void updateTextureSampler(byte flags) { + updateTextureSampler(this.mipLevels - 1, flags); + } + + public void updateTextureSampler(int maxLod, byte flags) { + this.sampler = SamplerManager.getTextureSampler((byte) maxLod, flags); + } + + public void transitionImageLayout(MemoryStack stack, VkCommandBuffer commandBuffer, int newLayout) { + transitionImageLayout(stack, commandBuffer, this, newLayout); + } + public static void transitionImageLayout(MemoryStack stack, VkCommandBuffer commandBuffer, VulkanImage image, int newLayout) { if (image.currentLayout == newLayout) { // System.out.println("new layout is equal to current layout"); @@ -288,137 +421,6 @@ private static boolean hasStencilComponent(int format) { return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT; } - public static Builder builder(int width, int height) { - return new Builder(width, height); - } - - private void createImage() { - try (MemoryStack stack = stackPush()) { - LongBuffer pTextureImage = stack.mallocLong(1); - PointerBuffer pAllocation = stack.pointers(0L); - - int flags = viewType == VK_IMAGE_VIEW_TYPE_CUBE ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0; - - MemoryManager.getInstance() - .createImage(width, height, arrayLayers, mipLevels, - format, VK_IMAGE_TILING_OPTIMAL, - usage, flags, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - pTextureImage, - pAllocation); - - id = pTextureImage.get(0); - allocation = pAllocation.get(0); - - MemoryManager.addImage(this); - - if (this.name != null) { - Vulkan.setDebugLabel(stack, VK_OBJECT_TYPE_IMAGE, pTextureImage.get(), this.name); - } - } - } - - public void uploadSubTextureAsync(int mipLevel, - int width, int height, - int xOffset, int yOffset, - int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, - ByteBuffer buffer) { - this.uploadSubTextureAsync(mipLevel, 0, width, height, - xOffset, yOffset, - unpackSkipRows, unpackSkipPixels, unpackRowLength, - MemoryUtil.memAddress(buffer)); - } - - public void uploadSubTextureAsync(int mipLevel, int arrayLayer, - int width, int height, - int xOffset, int yOffset, - int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, - ByteBuffer buffer) { - this.uploadSubTextureAsync(mipLevel, arrayLayer, width, height, - xOffset, yOffset, - unpackSkipRows, unpackSkipPixels, unpackRowLength, - MemoryUtil.memAddress(buffer)); - } - - public void uploadSubTextureAsync(int mipLevel, int arrayLayer, - int width, int height, - int xOffset, int yOffset, - int unpackSkipRows, int unpackSkipPixels, int unpackRowLength, - long srcPtr) { - long uploadSize = (long) ((long) unpackRowLength * height - unpackSkipPixels) * this.formatSize; - - 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(); - } - - srcPtr += ((long) unpackRowLength * unpackSkipRows + unpackSkipPixels) * this.formatSize; - - stagingBuffer.align(this.formatSize); - stagingBuffer.copyBuffer((int) uploadSize, srcPtr); - - long bufferId = stagingBuffer.getId(); - - VkCommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer().getHandle(); - try (MemoryStack stack = stackPush()) { - transferDstLayout(stack, commandBuffer); - - final int srcOffset = (int) (stagingBuffer.getOffset()); - - ImageUtil.copyBufferToImageCmd(stack, commandBuffer, bufferId, this.id, - arrayLayer, mipLevel, width, height, xOffset, yOffset, - srcOffset, unpackRowLength, height); - } - } - - private void transferDstLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { - transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - } - - public void readOnlyLayout() { - if (this.currentLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - return; - - try (MemoryStack stack = MemoryStack.stackPush()) { - if (Renderer.getInstance().getBoundRenderPass() != null) { - CommandPool.CommandBuffer commandBuffer = ImageUploadHelper.INSTANCE.getOrStartCommandBuffer(); - VkCommandBuffer vkCommandBuffer = commandBuffer.getHandle(); - - readOnlyLayout(stack, vkCommandBuffer); - } else { - readOnlyLayout(stack, Renderer.getCommandBuffer()); - } - } - } - - public void readOnlyLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { - transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - } - - public void updateTextureSampler(boolean blur, boolean clamp, boolean mipmaps) { - byte flags = blur ? LINEAR_FILTERING_BIT : 0; - flags |= clamp ? CLAMP_BIT : 0; - flags |= (byte) (mipmaps ? USE_MIPMAPS_BIT | MIPMAP_LINEAR_FILTERING_BIT : 0); - - this.updateTextureSampler(flags); - } - - public void updateTextureSampler(byte flags) { - updateTextureSampler(this.mipLevels - 1, flags); - } - - public void updateTextureSampler(int maxLod, byte flags) { - this.sampler = SamplerManager.getTextureSampler((byte) maxLod, flags); - } - - public void transitionImageLayout(MemoryStack stack, VkCommandBuffer commandBuffer, int newLayout) { - transitionImageLayout(stack, commandBuffer, this, newLayout); - } - public void free() { MemoryManager.getInstance().addToFreeable(this); } @@ -470,6 +472,10 @@ public long getSampler() { return sampler; } + public static Builder builder(int width, int height) { + return new Builder(width, height); + } + public static class Builder { final int width; final int height; @@ -491,18 +497,6 @@ public Builder(int width, int height) { this.height = height; } - private static int formatSize(int format) { - return switch (format) { - case VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB, - VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, - 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; - }; - } - public Builder setName(String name) { this.name = name; return this; @@ -568,5 +562,17 @@ public VulkanImage createVulkanImage() { return VulkanImage.createTextureImage(this); } + + private static int formatSize(int format) { + return switch (format) { + case VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB, + VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, + 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; + }; + } } } diff --git a/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java b/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java index 5c44dfa8e..0c2c0990b 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java @@ -13,61 +13,13 @@ public static void useGammaCorrection(boolean b) { } public static int floatToInt(float f) { - return (int) (f * 255.0f) & 0xFF; + return (int)(f * 255.0f) & 0xFF; } public static float unpackColor(int c, int s) { return ((c >> s) & 0xFF) * COLOR_INV; } - public static int BGRAtoRGBA(int v) { - byte r = (byte) (v >> 16); - byte b = (byte) (v); - return r & 0xFF | (b << 16) & 0xFF0000 | v & 0xFF00FF00; - } - - public static float gamma(float f) { - return (float) Math.pow(f, 2.2); - } - - public static void setRGBA_Buffer(MappedBuffer buffer, float r, float g, float b, float a) { - colorConsumer.setRGBA_Buffer(buffer, r, g, b, a); - } - - public static void setRGBA_Buffer(FloatBuffer buffer, float r, float g, float b, float a) { - colorConsumer.setRGBA_Buffer(buffer, r, g, b, a); - } - - interface ColorConsumer { - - void setRGBA_Buffer(MappedBuffer buffer, float r, float g, float b, float a); - - void setRGBA_Buffer(FloatBuffer buffer, float r, float g, float b, float a); - - void setRGBA_Buffer(ByteBuffer buffer, float r, float g, float b, float a); - - default void putColor(MappedBuffer buffer, float r, float g, float b, float a) { - buffer.putFloat(0, r); - buffer.putFloat(4, g); - buffer.putFloat(8, b); - buffer.putFloat(12, a); - } - - default void putColor(FloatBuffer buffer, float r, float g, float b, float a) { - buffer.put(0, r); - buffer.put(1, g); - buffer.put(2, b); - buffer.put(3, a); - } - - default void putColor(ByteBuffer buffer, float r, float g, float b, float a) { - buffer.putFloat(0, r); - buffer.putFloat(4, g); - buffer.putFloat(8, b); - buffer.putFloat(12, a); - } - } - public static class ARGB { public static int pack(float r, float g, float b, float a) { int color = floatToInt(a) << 24 | floatToInt(r) << 16 | floatToInt(g) << 8 | floatToInt(b); @@ -134,6 +86,52 @@ public static int fromArgb32(int i) { } } + public static int BGRAtoRGBA(int v) { + byte r = (byte) (v >> 16); + byte b = (byte) (v); + return r & 0xFF | (b << 16) & 0xFF0000 | v & 0xFF00FF00; + } + + public static float gamma(float f) { + return (float) Math.pow(f, 2.2); + } + + public static void setRGBA_Buffer(MappedBuffer buffer, float r, float g, float b, float a) { + colorConsumer.setRGBA_Buffer(buffer, r, g, b, a); + } + + public static void setRGBA_Buffer(FloatBuffer buffer, float r, float g, float b, float a) { + colorConsumer.setRGBA_Buffer(buffer, r, g, b, a); + } + + interface ColorConsumer { + + void setRGBA_Buffer(MappedBuffer buffer, float r, float g, float b, float a); + void setRGBA_Buffer(FloatBuffer buffer, float r, float g, float b, float a); + void setRGBA_Buffer(ByteBuffer buffer, float r, float g, float b, float a); + + default void putColor(MappedBuffer buffer, float r, float g, float b, float a) { + buffer.putFloat(0, r); + buffer.putFloat(4, g); + buffer.putFloat(8, b); + buffer.putFloat(12, a); + } + + default void putColor(FloatBuffer buffer, float r, float g, float b, float a) { + buffer.put(0, r); + buffer.put(1, g); + buffer.put(2, b); + buffer.put(3, a); + } + + default void putColor(ByteBuffer buffer, float r, float g, float b, float a) { + buffer.putFloat(0, r); + buffer.putFloat(4, g); + buffer.putFloat(8, b); + buffer.putFloat(12, a); + } + } + public static class DefaultColorConsumer implements ColorConsumer { @Override diff --git a/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java b/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java index b2e7ccd19..fd2a9ece0 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java @@ -1,5 +1,6 @@ package net.vulkanmod.vulkan.util; +import com.mojang.blaze3d.systems.RenderSystem; import net.vulkanmod.render.PipelineManager; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; diff --git a/src/main/java/net/vulkanmod/vulkan/util/MappedBuffer.java b/src/main/java/net/vulkanmod/vulkan/util/MappedBuffer.java index 130d3a9eb..67b0f246f 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/MappedBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/util/MappedBuffer.java @@ -9,6 +9,9 @@ public class MappedBuffer { public final ByteBuffer buffer; public final long ptr; + public static MappedBuffer createFromBuffer(ByteBuffer buffer) { + return new MappedBuffer(buffer, MemoryUtil.memAddress0(buffer)); + } MappedBuffer(ByteBuffer buffer, long ptr) { this.buffer = buffer; this.ptr = ptr; @@ -19,10 +22,6 @@ public MappedBuffer(int size) { this.ptr = MemoryUtil.memAddress0(this.buffer); } - public static MappedBuffer createFromBuffer(ByteBuffer buffer) { - return new MappedBuffer(buffer, MemoryUtil.memAddress0(buffer)); - } - public void putFloat(int idx, float f) { VUtil.UNSAFE.putFloat(ptr + idx, f); } diff --git a/src/main/java/net/vulkanmod/vulkan/util/Pair.java b/src/main/java/net/vulkanmod/vulkan/util/Pair.java index d8c300b99..3b05f1425 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/Pair.java +++ b/src/main/java/net/vulkanmod/vulkan/util/Pair.java @@ -1,6 +1,6 @@ package net.vulkanmod.vulkan.util; -public class Pair { +public class Pair { public A first; public B second;