From e3dbe718cfe09d46ccbd61903f066e64631fae73 Mon Sep 17 00:00:00 2001 From: xCollateral <> Date: Wed, 25 Oct 2023 23:03:08 +0200 Subject: [PATCH] Improved GL texture compatibility --- src/main/java/net/vulkanmod/gl/GlTexture.java | 50 ++++++++++++++++--- src/main/java/net/vulkanmod/gl/Util.java | 22 ++++++++ .../mixin/render/GlStateManagerM.java | 8 +++ .../vulkanmod/mixin/texture/MTextureUtil.java | 2 +- 4 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/vulkanmod/gl/GlTexture.java b/src/main/java/net/vulkanmod/gl/GlTexture.java index dfe6879a2..99ab1e755 100644 --- a/src/main/java/net/vulkanmod/gl/GlTexture.java +++ b/src/main/java/net/vulkanmod/gl/GlTexture.java @@ -1,16 +1,19 @@ package net.vulkanmod.gl; +import com.mojang.blaze3d.platform.NativeImage; +import com.mojang.blaze3d.systems.RenderSystem; import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; import net.vulkanmod.vulkan.texture.VTextureSelector; import net.vulkanmod.vulkan.texture.VulkanImage; import org.jetbrains.annotations.Nullable; +import org.lwjgl.opengl.GL11; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; import java.nio.ByteBuffer; import java.nio.IntBuffer; -import static org.lwjgl.vulkan.VK10.VK_FORMAT_R8G8B8A8_UNORM; +import static org.lwjgl.vulkan.VK10.*; public class GlTexture { private static int ID_COUNT = 0; @@ -52,6 +55,8 @@ public static void texImage2D(int target, int level, int internalFormat, int wid if(width == 0 || height == 0) return; + boundTexture.internalFormat = internalFormat; + if(width != boundTexture.vulkanImage.width || height != boundTexture.vulkanImage.height || vulkanFormat(format, type) != boundTexture.vulkanImage.format) { boundTexture.allocateVulkanImage(width, height); } @@ -59,7 +64,6 @@ public static void texImage2D(int target, int level, int internalFormat, int wid boundTexture.uploadImage(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; @@ -67,6 +71,19 @@ public static void texSubImage2D(int target, int level, int xOffset, int yOffset VTextureSelector.uploadSubTexture(level, width, height, xOffset, yOffset,0, 0, width, pixels); } + public static int getTexLevelParameter(int target, int level, int pName) { + if(boundTexture == null || target == GL11.GL_TEXTURE_2D) + return -1; + + return switch (pName) { + case GL11.GL_TEXTURE_INTERNAL_FORMAT -> getGlFormat(boundTexture.vulkanImage.format); + case GL11.GL_TEXTURE_WIDTH -> boundTexture.vulkanImage.width; + case GL11.GL_TEXTURE_HEIGHT -> boundTexture.vulkanImage.height; + + default -> -1; + }; + } + public static void setVulkanImage(int id, VulkanImage vulkanImage) { GlTexture texture = map.get(id); @@ -75,6 +92,7 @@ public static void setVulkanImage(int id, VulkanImage vulkanImage) { final int id; VulkanImage vulkanImage; + int internalFormat; public GlTexture(int id) { this.id = id; @@ -93,8 +111,15 @@ private void uploadImage(@Nullable ByteBuffer pixels) { int height = this.vulkanImage.height; if(pixels != null) { -// if(pixels.remaining() != width * height * 4) -// throw new IllegalArgumentException("buffer size does not match image size"); + + if(internalFormat == GL11.GL_RGB && vulkanImage.format == VK_FORMAT_R8G8B8A8_UNORM) { + + ByteBuffer RGBA_buffer = Util.RGBtoRGBA_buffer(pixels); + this.vulkanImage.uploadSubTextureAsync(0, width, height, 0, 0, 0, 0, 0, RGBA_buffer); + MemoryUtil.memFree(RGBA_buffer); + + return; + } this.vulkanImage.uploadSubTextureAsync(0, width, height, 0, 0, 0, 0, 0, pixels); } @@ -107,9 +132,14 @@ private void uploadImage(@Nullable ByteBuffer pixels) { private static int vulkanFormat(int glFormat, int type) { return switch (glFormat) { - case 6408 -> + case GL11.GL_RGBA -> + switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; + default -> throw new IllegalStateException("Unexpected value: " + type); + }; + case GL11.GL_RED -> switch (type) { - case 5121 -> VK_FORMAT_R8G8B8A8_UNORM; + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8_UNORM; default -> throw new IllegalStateException("Unexpected value: " + type); }; @@ -117,4 +147,12 @@ private static int vulkanFormat(int glFormat, int type) { }; } + public static int getGlFormat(int vFormat) { + return switch (vFormat) { + case VK_FORMAT_R8G8B8A8_UNORM -> GL11.GL_RGBA; + case VK_FORMAT_R8_UNORM -> GL11.GL_RED; + default -> throw new IllegalStateException("Unexpected value: " + vFormat); + }; + } + } diff --git a/src/main/java/net/vulkanmod/gl/Util.java b/src/main/java/net/vulkanmod/gl/Util.java index b7b475b82..58695af8b 100644 --- a/src/main/java/net/vulkanmod/gl/Util.java +++ b/src/main/java/net/vulkanmod/gl/Util.java @@ -1,6 +1,10 @@ package net.vulkanmod.gl; import net.vulkanmod.vulkan.shader.SPIRVUtils; +import org.apache.commons.lang3.Validate; +import org.lwjgl.system.MemoryUtil; + +import java.nio.ByteBuffer; public class Util { @@ -11,4 +15,22 @@ public static SPIRVUtils.ShaderKind extToShaderKind(String in) { default -> throw new RuntimeException("unknown shader type: " + in); }; } + + //Created buffer will need to be freed + public static ByteBuffer RGBtoRGBA_buffer(ByteBuffer in) { + Validate.isTrue(in.remaining() % 3 == 0, "bytebuffer is not RGB"); + + int outSize = in.remaining() * 4 / 3; + ByteBuffer out = MemoryUtil.memAlloc(outSize); + + int j = 0; + 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)); + out.put(i + 3, (byte) 0xFF); + } + + return out; + } } diff --git a/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java b/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java index 59a39e54f..afa6a94b6 100644 --- a/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java +++ b/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java @@ -133,6 +133,14 @@ public static void _texParameter(int i, int j, float k) { //TODO } + /** + * @author + */ + @Overwrite(remap = false) + public static int _getTexLevelParameter(int i, int j, int k) { + return GlTexture.getTexLevelParameter(i, j, k); + } + /** * @author */ diff --git a/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java b/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java index 6f13d1a98..6d24500f8 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java +++ b/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java @@ -16,7 +16,7 @@ public class MTextureUtil { */ @Overwrite(remap = false) public static int generateTextureId() { - return GlStateManager._genTexture(); + return GlTexture.genTextureId(); } /**