diff options
author | DeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com> | 2022-05-03 18:25:32 +0200 |
---|---|---|
committer | DeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com> | 2022-05-03 18:25:32 +0200 |
commit | a0ff501947a84b268e099524a06b56a6b900dad2 (patch) | |
tree | db27ca1b28dbc7e57b8c99f54c80732d3042e856 /src/main/java/cc/polyfrost/oneconfig/lwjgl | |
parent | b798930b21b89b81be05a31281f768667a6dd7f3 (diff) | |
download | OneConfig-a0ff501947a84b268e099524a06b56a6b900dad2.tar.gz OneConfig-a0ff501947a84b268e099524a06b56a6b900dad2.tar.bz2 OneConfig-a0ff501947a84b268e099524a06b56a6b900dad2.zip |
move to cc.polyfrost
Diffstat (limited to 'src/main/java/cc/polyfrost/oneconfig/lwjgl')
14 files changed, 927 insertions, 0 deletions
diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/BlurHandler.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/BlurHandler.java new file mode 100644 index 0000000..914c483 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/BlurHandler.java @@ -0,0 +1,159 @@ +package cc.polyfrost.oneconfig.lwjgl; + +import cc.polyfrost.oneconfig.gui.OneConfigGui; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.shader.Shader; +import net.minecraft.client.shader.ShaderUniform; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; + +/** + * An implementation of the BlurMC mod by tterrag1098. + * + * For the original source see https://github.com/tterrag1098/Blur/blob/1.8.9/src/main/java/com/tterrag/blur/Blur.java + * For the public license, see https://github.com/tterrag1098/Blur/blob/1.8.9/LICENSE + * + * License available under https://github.com/boomboompower/ToggleChat/blob/master/src/main/resources/licenses/BlurMC-License.txt + * + * @author tterrag1098, boomboompower + * + * Taken from ToggleChat + * https://github.com/boomboompower/ToggleChat/blob/master/LICENSE + */ +public class BlurHandler { + private final ResourceLocation blurShader = new ResourceLocation("shaders/post/fade_in_blur.json"); + private final Logger logger = LogManager.getLogger("OneConfig - Blur"); + private final Minecraft mc = Minecraft.getMinecraft(); + + private long start; + private float lastProgress = 0; + + public static BlurHandler INSTANCE = new BlurHandler(); + + /** + * Simply initializes the blur mod so events are properly handled by forge. + */ + public void load() { + MinecraftForge.EVENT_BUS.register(this); + } + + @SubscribeEvent + public void onGuiChange(GuiOpenEvent event) { + reloadBlur(event.gui); + } + + @SubscribeEvent + public void onRenderTick(final TickEvent.RenderTickEvent event) { + this.mc.mcProfiler.startSection("blur"); + + if (event.phase != TickEvent.Phase.END) { + this.mc.mcProfiler.endSection(); + return; + } + + // Only blur on our own menus + if (this.mc.currentScreen == null) { + this.mc.mcProfiler.endSection(); + return; + } + + // Only update the shader if one is active + if (!this.mc.entityRenderer.isShaderActive()) { + this.mc.mcProfiler.endSection(); + return; + } + + float progress = getBlurStrengthProgress(); + + // If the new progress value matches the old one this + // will skip the frame update, which (hopefully) resolves the issue + // with the heavy computations after the "animation" is complete. + if (progress == this.lastProgress) { + this.mc.mcProfiler.endSection(); + return; + } + + // Store it for the next iteration! + this.lastProgress = progress; + + // This is hilariously bad, and could cause frame issues on low-end computers. + // Why is this being computed every tick? Surely there is a better way? + // This needs to be optimized. + try { + final List<Shader> listShaders = this.mc.entityRenderer.getShaderGroup().listShaders; + + // Should not happen. Something bad happened. + if (listShaders == null) { + this.mc.mcProfiler.endSection(); + return; + } + + // Iterate through the list of shaders. + for (Shader shader : listShaders) { + ShaderUniform su = shader.getShaderManager().getShaderUniform("Progress"); + + if (su == null) { + continue; + } + + // All this for this. + su.set(progress); + } + } catch (IllegalArgumentException ex) { + this.logger.error("An error occurred while updating ToggleChat's blur. Please report this!", ex); + } + + this.mc.mcProfiler.endSection(); + } + + /** + * Activates/deactivates the blur in the current world if + * one of many conditions are met, such as no current other shader + * is being used, we actually have the blur setting enabled + */ + public void reloadBlur(GuiScreen gui) { + // Don't do anything if no world is loaded + if (this.mc.theWorld == null) { + return; + } + + EntityRenderer er = this.mc.entityRenderer; + + // If a shader is not already active and the UI is + // a one of ours, we should load our own blur! + if (!er.isShaderActive() && gui instanceof OneConfigGui) { + this.mc.entityRenderer.loadShader(this.blurShader); + + this.start = System.currentTimeMillis(); + + // If a shader is active and the incoming UI is null or we have blur disabled, stop using the shader. + } else if (er.isShaderActive() && (gui == null)) { + String name = er.getShaderGroup().getShaderGroupName(); + + // Only stop our specific blur ;) + if (!name.endsWith("fade_in_blur.json")) { + return; + } + + er.stopUseShader(); + } + } + + /** + * Returns the strength of the blur as determined by the duration the effect of the blur. + * + * The strength of the blur does not go below 5.0F. + */ + private float getBlurStrengthProgress() { + return Math.min((System.currentTimeMillis() - this.start) / 50F, 5.0F); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/IOUtil.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/IOUtil.java new file mode 100644 index 0000000..1394239 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/IOUtil.java @@ -0,0 +1,56 @@ +package cc.polyfrost.oneconfig.lwjgl; + +import org.apache.commons.io.IOUtils; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.file.Files; + +public final class IOUtil { + + private IOUtil() { + } + + /** + * Taken from legui under MIT License + * <a href="https://github.com/SpinyOwl/legui/blob/develop/LICENSE">https://github.com/SpinyOwl/legui/blob/develop/LICENSE</a> + */ + public static ByteBuffer resourceToByteBuffer(String path) throws IOException { + byte[] bytes; + path = path.trim(); + if (path.startsWith("http")) { + bytes = IOUtils.toByteArray(new URL(path)); + } else { + InputStream stream; + File file = new File(path); + if (file.exists() && file.isFile()) { + stream = Files.newInputStream(file.toPath()); + } else { + stream = IOUtil.class.getResourceAsStream(path); + } + if (stream == null) { + throw new FileNotFoundException(path); + } + bytes = IOUtils.toByteArray(stream); + } + ByteBuffer data = ByteBuffer.allocateDirect(bytes.length).order(ByteOrder.nativeOrder()) + .put(bytes); + ((Buffer) data).flip(); + return data; + } + + public static ByteBuffer resourceToByteBufferNullable(String path) { + try { + return resourceToByteBuffer(path); + } catch (Exception ignored) { + return null; + } + } + +}
\ No newline at end of file diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider.java new file mode 100644 index 0000000..e00570e --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider.java @@ -0,0 +1,39 @@ +package cc.polyfrost.oneconfig.lwjgl; + +import org.lwjgl.opengl.GLContext; +import org.lwjgl.system.FunctionProvider; + +import java.lang.reflect.Method; +import java.nio.ByteBuffer; + +/** + * Taken from LWJGLTwoPointFive under The Unlicense + * <a href="https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/">https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/</a> + */ +public class Lwjgl2FunctionProvider implements FunctionProvider { + + private final Method m_getFunctionAddress; + + public Lwjgl2FunctionProvider() { + try { + m_getFunctionAddress = GLContext.class.getDeclaredMethod("getFunctionAddress", String.class); + m_getFunctionAddress.setAccessible(true); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public long getFunctionAddress(CharSequence functionName) { + try { + return (long) m_getFunctionAddress.invoke(null, functionName.toString()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public long getFunctionAddress(ByteBuffer byteBuffer) { + throw new UnsupportedOperationException(); + } +}
\ No newline at end of file diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/RenderManager.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/RenderManager.java new file mode 100644 index 0000000..0ad1748 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/RenderManager.java @@ -0,0 +1,306 @@ +package cc.polyfrost.oneconfig.lwjgl; + +import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.lwjgl.font.FontManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.lwjgl.image.Image; +import cc.polyfrost.oneconfig.lwjgl.image.ImageLoader; +import cc.polyfrost.oneconfig.lwjgl.image.Images; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.shader.Framebuffer; +import org.lwjgl.nanovg.NVGColor; +import org.lwjgl.nanovg.NVGPaint; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.util.function.LongConsumer; + +import static org.lwjgl.nanovg.NanoVG.*; +import static org.lwjgl.nanovg.NanoVGGL2.NVG_ANTIALIAS; +import static org.lwjgl.nanovg.NanoVGGL2.nvgCreate; + +public final class RenderManager { + private RenderManager() { + + } + + //nanovg + + private static long vg = -1; + + public static void setupAndDraw(LongConsumer consumer) { + setupAndDraw(false, consumer); + } + + public static void setupAndDraw(boolean mcScaling, LongConsumer consumer) { + if (vg == -1) { + vg = nvgCreate(NVG_ANTIALIAS); + if (vg == -1) { + throw new RuntimeException("Failed to create nvg context"); + } + FontManager.INSTANCE.initialize(vg); + } + + Framebuffer fb = Minecraft.getMinecraft().getFramebuffer(); + if (!fb.isStencilEnabled()) { + fb.enableStencil(); + } + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); + + if (mcScaling) { + ScaledResolution resolution = new ScaledResolution(Minecraft.getMinecraft()); + nvgBeginFrame(vg, (float) resolution.getScaledWidth_double(), (float) resolution.getScaledHeight_double(), resolution.getScaleFactor()); + } else { + // If we get blurry problems with high DPI monitors, 1 might need to be replaced with Display.getPixelScaleFactor() + nvgBeginFrame(vg, Display.getWidth(), Display.getHeight(), 1); + } + + consumer.accept(vg); + + nvgEndFrame(vg); + + GlStateManager.popAttrib(); + } + + public static void drawRectangle(long vg, float x, float y, float width, float height, int color) { // TODO make everything use this one day + if (OneConfigConfig.ROUNDED_CORNERS) { + drawRoundedRect(vg, x, y, width, height, color, OneConfigConfig.CORNER_RADIUS); + } else { + drawRect(vg, x, y, width, height, color); + } + } + + + public static void drawGradientRoundedRect(long vg, float x, float y, float width, float height, int color, int color2, float radius) { + NVGPaint bg = NVGPaint.create(); + nvgBeginPath(vg); + nvgRoundedRect(vg, x, y, width, height, radius); + NVGColor nvgColor = color(vg, color); + NVGColor nvgColor2 = color(vg, color2); + nvgFillPaint(vg, nvgLinearGradient(vg, x, y + height, x + width, y, nvgColor, nvgColor2, bg)); + nvgFill(vg); + nvgColor.free(); + nvgColor2.free(); + } + + public static void drawGradientRect(long vg, float x, float y, float width, float height, int color, int color2) { + NVGPaint bg = NVGPaint.create(); + nvgBeginPath(vg); + nvgRect(vg, x, y, width, height); + NVGColor nvgColor = color(vg, color); + NVGColor nvgColor2 = color(vg, color2); + nvgFillPaint(vg, nvgLinearGradient(vg, x, y + height, x + width, y, nvgColor, nvgColor2, bg)); + nvgFillPaint(vg, bg); + nvgFill(vg); + nvgColor.free(); + nvgColor2.free(); + } + + public static void drawRect(long vg, float x, float y, float width, float height, int color) { + nvgBeginPath(vg); + nvgRect(vg, x, y, width, height); + NVGColor nvgColor = color(vg, color); + nvgFill(vg); + nvgColor.free(); + } + + public static void drawRoundedRect(long vg, float x, float y, float width, float height, int color, float radius) { + nvgBeginPath(vg); + nvgRoundedRect(vg, x, y, width, height, radius); + color(vg, color); + NVGColor nvgColor = color(vg, color); + nvgFill(vg); + nvgColor.free(); + } + + public static void drawRoundedRectVaried(long vg, float x, float y, float width, float height, int color, float radiusTL, float radiusTR, float radiusBR, float radiusBL) { + nvgBeginPath(vg); + nvgRoundedRectVarying(vg, x, y, width, height, radiusTL, radiusTR, radiusBR, radiusBL); + color(vg, color); + NVGColor nvgColor = color(vg, color); + nvgFill(vg); + nvgColor.free(); + } + + public static void drawHollowRoundRect(long vg, float x, float y, float width, float height, int color, float radius, float thickness) { + nvgBeginPath(vg); + nvgRoundedRect(vg, x + thickness, y + thickness, width - thickness, height - thickness, radius); + nvgStrokeWidth(vg, thickness); + nvgPathWinding(vg, NVG_HOLE); + color(vg, color); + NVGColor nvgColor = color(vg, color); + nvgStrokeColor(vg, nvgColor); + nvgStroke(vg); + nvgColor.free(); + } + + public static void drawCircle(long vg, float x, float y, float radius, int color) { + nvgBeginPath(vg); + nvgCircle(vg, x, y, radius); + NVGColor nvgColor = color(vg, color); + nvgFill(vg); + nvgColor.free(); + } + + + public static void drawString(long vg, String text, float x, float y, int color, float size, Fonts font) { + nvgBeginPath(vg); + nvgFontSize(vg, size); + nvgFontFace(vg, font.font.getName()); + nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); + NVGColor nvgColor = color(vg, color); + nvgText(vg, x, y, text); + nvgFill(vg); + nvgColor.free(); + } + + public static void drawString(long vg, String text, float x, float y, int color, float size, int lineHeight, Fonts font) { + nvgBeginPath(vg); + nvgFontSize(vg, size); + nvgFontFace(vg, font.font.getName()); + nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP); + nvgTextLineHeight(vg, lineHeight); + NVGColor nvgColor = color(vg, color); + nvgText(vg, x, y, text); + nvgFill(vg); + nvgColor.free(); + } + + public static void drawWrappedString(long vg, String text, float x, float y, float width, int color, float size, Fonts font) { + nvgBeginPath(vg); + nvgFontSize(vg, size); + nvgFontFace(vg, font.font.getName()); + nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); + NVGColor nvgColor = color(vg, color); + nvgTextBox(vg, x, y, width, text); + nvgFill(vg); + nvgColor.free(); + } + + public static void drawImage(long vg, String filePath, float x, float y, float width, float height) { + if (ImageLoader.INSTANCE.loadImage(vg, filePath)) { + NVGPaint imagePaint = NVGPaint.calloc(); + cc.polyfrost.oneconfig.lwjgl.image.Image image = ImageLoader.INSTANCE.getImage(filePath); + nvgBeginPath(vg); + nvgImagePattern(vg, x, y, width, height, 0, image.getReference(), 1, imagePaint); + nvgRect(vg, x, y, width, height); + nvgFillPaint(vg, imagePaint); + nvgFill(vg); + imagePaint.free(); + } + } + + public static void drawImage(long vg, String filePath, float x, float y, float width, float height, int color) { + if (ImageLoader.INSTANCE.loadImage(vg, filePath)) { + NVGPaint imagePaint = NVGPaint.calloc(); + Image image = ImageLoader.INSTANCE.getImage(filePath); + nvgBeginPath(vg); + nvgImagePattern(vg, x, y, width, height, 0, image.getReference(), 1, imagePaint); + nvgRGBA((byte) (color >> 16 & 0xFF), (byte) (color >> 8 & 0xFF), (byte) (color & 0xFF), (byte) (color >> 24 & 0xFF), imagePaint.innerColor()); + nvgRect(vg, x, y, width, height); + nvgFillPaint(vg, imagePaint); + nvgFill(vg); + imagePaint.free(); + } + } + + public static void drawImage(long vg, Images filePath, float x, float y, float width, float height) { + drawImage(vg, filePath.filePath, x, y, width, height); + } + + public static void drawImage(long vg, Images filePath, float x, float y, float width, float height, int color) { + drawImage(vg, filePath.filePath, x, y, width, height, color); + } + + + public static float getTextWidth(long vg, String text, float fontSize, Fonts font) { + float[] bounds = new float[4]; + nvgFontSize(vg, fontSize); + nvgFontFace(vg, font.font.getName()); + return nvgTextBounds(vg, 0, 0, text, bounds); + } + + public static void drawLine(long vg, float x, float y, float endX, float endY, float width, int color) { + nvgBeginPath(vg); + nvgMoveTo(vg, x, y); + nvgLineTo(vg, endX, endY); + NVGColor nvgColor = color(vg, color); + nvgStrokeColor(vg, nvgColor); + nvgStrokeWidth(vg, width); + nvgStroke(vg); + nvgColor.free(); + } + + public static void drawDropShadow(long vg, float x, float y, float w, float h, float cornerRadius, float spread, int color) { // TODO broken + NVGColor color1 = NVGColor.calloc(); + NVGColor color2 = NVGColor.calloc(); + NVGPaint shadowPaint = NVGPaint.calloc(); + nvgRGBA((byte) 0, (byte) 0, (byte) 0, (byte) 128, color1); + nvgRGBA((byte) 0, (byte) 0, (byte) 0, (byte) 0, color2); + nvgBoxGradient(vg, x, y + 2, w, h, cornerRadius * 2, 10f, color2, color1, shadowPaint); + nvgBeginPath(vg); + nvgRect(vg, x - 10, y - 10, w + 20, h + 30); + nvgRoundedRect(vg, x, y, w, h, cornerRadius); + nvgPathWinding(vg, NVG_HOLE); + nvgFillPaint(vg, shadowPaint); + nvgFill(vg); + shadowPaint.free(); + color1.free(); + color2.free(); + } + + + public static NVGColor color(long vg, int color) { + NVGColor nvgColor = NVGColor.calloc(); + nvgRGBA((byte) (color >> 16 & 0xFF), (byte) (color >> 8 & 0xFF), (byte) (color & 0xFF), (byte) (color >> 24 & 0xFF), nvgColor); + nvgFillColor(vg, nvgColor); + return nvgColor; + } + + + // gl + public static void glColor(Color color) { + glColor(color.getRGB()); + } + + public static void drawScaledString(String text, float x, float y, int color, boolean shadow, float scale) { + GlStateManager.pushMatrix(); + GlStateManager.scale(scale, scale, 1); + Minecraft.getMinecraft().fontRendererObj.drawString(text, x * (1 / scale), y * (1 / scale), color, shadow); + GlStateManager.popMatrix(); + } + + public static void glColor(int color) { + float f = (float) (color >> 24 & 255) / 255.0F; + float f1 = (float) (color >> 16 & 255) / 255.0F; + float f2 = (float) (color >> 8 & 255) / 255.0F; + float f3 = (float) (color & 255) / 255.0F; + GlStateManager.color(f1, f2, f3, f); + } + + public static void drawDottedLine(float sx, float sy, float ex, float ey, int width, int factor, int color) { + GlStateManager.pushMatrix(); + GL11.glLineStipple(factor, (short) 0xAAAA); + GL11.glEnable(GL11.GL_LINE_STIPPLE); + GlStateManager.pushMatrix(); + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + glColor(color); + GL11.glLineWidth(width); + GL11.glBegin(GL11.GL_LINES); + GL11.glVertex2d(sx, sy); + GL11.glVertex2d(ex, ey); + GL11.glEnd(); + GlStateManager.disableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableTexture2D(); + GlStateManager.popMatrix(); + GL11.glDisable(GL11.GL_LINE_STIPPLE); + GlStateManager.popMatrix(); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/Scissor.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/Scissor.java new file mode 100644 index 0000000..93e104e --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/Scissor.java @@ -0,0 +1,22 @@ +package cc.polyfrost.oneconfig.lwjgl; + +public class Scissor { + public int x; + public int y; + public int width; + public int height; + + public Scissor(int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + public Scissor(Scissor scissor) { + this.x = scissor.x; + this.y = scissor.y; + this.width = scissor.width; + this.height = scissor.height; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/ScissorManager.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/ScissorManager.java new file mode 100644 index 0000000..ee78eca --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/ScissorManager.java @@ -0,0 +1,40 @@ +package cc.polyfrost.oneconfig.lwjgl; + +import org.lwjgl.nanovg.NanoVG; + +import java.util.ArrayList; + +public class ScissorManager { + private static final ArrayList<Scissor> scissors = new ArrayList<>(); + + public static Scissor scissor(long vg, int x, int y, int width, int height) { + Scissor scissor = new Scissor(x, y, width, height); + if (scissors.contains(scissor)) return scissor; + scissors.add(scissor); + applyScissors(vg); + return scissor; + } + + public static void resetScissor(long vg, Scissor scissor) { + if (scissors.contains(scissor)) { + scissors.remove(scissor); + applyScissors(vg); + } + } + + private static void applyScissors(long vg) { + NanoVG.nvgResetScissor(vg); + if (scissors.size() <= 0) return; + Scissor finalScissor = new Scissor(scissors.get(0)); + for (int i = 1; i < scissors.size(); i++) { + Scissor scissor = scissors.get(i); + int rightX = Math.min(scissor.x + scissor.width, finalScissor.x + finalScissor.width); + int rightY = Math.min(scissor.y + scissor.height, finalScissor.y + finalScissor.height); + finalScissor.x = Math.max(finalScissor.x, scissor.x); + finalScissor.y = Math.max(finalScissor.y, scissor.y); + finalScissor.width = rightX - finalScissor.x; + finalScissor.height = rightY - finalScissor.y; + } + NanoVG.nvgScissor(vg, finalScissor.x, finalScissor.y, finalScissor.width, finalScissor.height); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/font/Font.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/font/Font.java new file mode 100644 index 0000000..970c073 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/font/Font.java @@ -0,0 +1,39 @@ +package cc.polyfrost.oneconfig.lwjgl.font; + +import java.nio.ByteBuffer; + +public class Font { + private final String fileName; + private final String name; + private boolean loaded = false; + private ByteBuffer buffer = null; + + public Font(String name, String fileName) { + this.name = name; + this.fileName = fileName; + } + + public String getName() { + return name; + } + + public String getFileName() { + return fileName; + } + + public boolean isLoaded() { + return loaded; + } + + void setLoaded(boolean loaded) { + this.loaded = loaded; + } + + public ByteBuffer getBuffer() { + return buffer; + } + + void setBuffer(ByteBuffer buffer) { + this.buffer = buffer; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/font/FontManager.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/font/FontManager.java new file mode 100644 index 0000000..0974019 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/font/FontManager.java @@ -0,0 +1,31 @@ +package cc.polyfrost.oneconfig.lwjgl.font; + +import cc.polyfrost.oneconfig.lwjgl.IOUtil; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import static org.lwjgl.nanovg.NanoVG.nvgCreateFontMem; + +public class FontManager { + public static FontManager INSTANCE = new FontManager(); + + public void initialize(long vg) { + for (Fonts fonts : Fonts.values()) { + Font font = fonts.font; + int loaded = -1; + try { + ByteBuffer buffer = IOUtil.resourceToByteBuffer(font.getFileName()); + loaded = nvgCreateFontMem(vg, font.getName(), buffer, 0); + font.setBuffer(buffer); + } catch (IOException e) { + e.printStackTrace(); + } + if (loaded == -1) { + throw new RuntimeException("Failed to initialize font " + font.getName()); + } else { + font.setLoaded(true); + } + } + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/font/Fonts.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/font/Fonts.java new file mode 100644 index 0000000..aef639c --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/font/Fonts.java @@ -0,0 +1,15 @@ +package cc.polyfrost.oneconfig.lwjgl.font; + +public enum Fonts { + INTER_BOLD(new Font("inter-bold", "/assets/oneconfig/font/Inter-Bold.otf")), + INTER_REGULAR(new Font("inter-regular", "/assets/oneconfig/font/Inter-Regular.otf")), + INTER_SEMIBOLD(new Font("inter-semibold", "/assets/oneconfig/font/Inter-SemiBold.otf")), + INTER_MEDIUM(new Font("inter-medium", "/assets/oneconfig/font/Inter-Medium.otf")), + MC_REGULAR(new Font("mc-regular", "/assets/oneconfig/font/Minecraft-Regular.otf")); + + public final Font font; + + Fonts(Font font) { + this.font = font; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/image/Image.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/image/Image.java new file mode 100644 index 0000000..2e63154 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/image/Image.java @@ -0,0 +1,21 @@ +package cc.polyfrost.oneconfig.lwjgl.image; + +import java.nio.ByteBuffer; + +public class Image { + private final int reference; + private final ByteBuffer buffer; + + public Image(int reference, ByteBuffer buffer) { + this.reference = reference; + this.buffer = buffer; + } + + public ByteBuffer getBuffer() { + return buffer; + } + + public int getReference() { + return reference; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/image/ImageLoader.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/image/ImageLoader.java new file mode 100644 index 0000000..8e72828 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/image/ImageLoader.java @@ -0,0 +1,45 @@ +package cc.polyfrost.oneconfig.lwjgl.image; + +import cc.polyfrost.oneconfig.lwjgl.IOUtil; +import org.lwjgl.nanovg.NanoVG; +import org.lwjgl.stb.STBImage; + +import java.nio.ByteBuffer; +import java.util.HashMap; + +public class ImageLoader { + private final HashMap<String, Image> imageHashMap = new HashMap<>(); + public static ImageLoader INSTANCE = new ImageLoader(); + + public boolean loadImage(long vg, String fileName) { + if (!imageHashMap.containsKey(fileName)) { + int[] width = {0}; + int[] height = {0}; + int[] channels = {0}; + + ByteBuffer image = IOUtil.resourceToByteBufferNullable(fileName); + if (image == null) { + return false; + } + + ByteBuffer buffer = STBImage.stbi_load_from_memory(image, width, height, channels, 4); + if (buffer == null) { + return false; + } + + imageHashMap.put(fileName, new Image(NanoVG.nvgCreateImageRGBA(vg, width[0], height[0], NanoVG.NVG_IMAGE_REPEATX | NanoVG.NVG_IMAGE_REPEATY | NanoVG.NVG_IMAGE_GENERATE_MIPMAPS, buffer), buffer)); + return true; + } + return true; + } + + + public void removeImage(String fileName) { + imageHashMap.remove(fileName); + } + + public Image getImage(String fileName) { + return imageHashMap.get(fileName); + } + +} diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/image/Images.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/image/Images.java new file mode 100644 index 0000000..f5e4213 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/image/Images.java @@ -0,0 +1,47 @@ +package cc.polyfrost.oneconfig.lwjgl.image; + +public enum Images { + CHEVRON_ARROW("/assets/oneconfig/textures/gui/general/arrows/chevron.png"), + DROPDOWN_ARROW("/assets/oneconfig/textures/gui/general/arrows/dropdown_arrow.png"), + UP_ARROW("/assets/oneconfig/textures/gui/general/arrows/up_arrow.png"), + CIRCLE_ARROW("/assets/oneconfig/textures/gui/general/arrows/circle_arrow.png"), + + CHECKMARK("/assets/oneconfig/textures/gui/general/configs/checkmark.png"), + FAVORITE("/assets/oneconfig/textures/gui/general/configs/favorite_active.png"), + FAVORITE_OFF("/assets/oneconfig/textures/gui/general/configs/favorite_inactive.png"), + HIDE_EYE("/assets/oneconfig/textures/gui/general/configs/hide_eye.png"), + HIDE_EYE_OFF("/assets/oneconfig/textures/gui/general/configs/hide_eye_off.png"), + + // TODO color picker ones + COLOR_BASE("/assets/oneconfig/textures/gui/general/color/color_base.png"), + + + SHARE("/assets/oneconfig/textures/gui/general/nav/share.png"), + LAUNCH("/assets/oneconfig/textures/gui/general/nav/launch.png"), + SEARCH("/assets/oneconfig/textures/gui/general/nav/search.png"), + MINIMIZE("/assets/oneconfig/textures/gui/general/nav/minimize.png"), + CLOSE("/assets/oneconfig/textures/gui/general/nav/close.png"), + + LOGO("/assets/oneconfig/textures/gui/general/logo.png"), + + HUD("/assets/oneconfig/textures/gui/icons/hud/hud.png"), + HUD_SETTINGS("/assets/oneconfig/textures/gui/icons/hud/settings.png"), + + MOD_BOX("/assets/oneconfig/textures/gui/icons/mod/mod_box.png"), + MODS("/assets/oneconfig/textures/gui/icons/mod/mods.png"), + PERFORMANCE("/assets/oneconfig/textures/gui/icons/mod/performance.png"), + + DASHBOARD("/assets/oneconfig/textures/gui/icons/dashboard.png"), + PREFERENCES("/assets/oneconfig/textures/gui/icons/preferences.png"), + PROFILES("/assets/oneconfig/textures/gui/icons/profiles.png"), + SCREENSHOT("/assets/oneconfig/textures/gui/icons/screenshot.png"), + THEMES("/assets/oneconfig/textures/gui/icons/themes.png"), + UPDATES("/assets/oneconfig/textures/gui/icons/updates.png"), + ; + + public final String filePath; + + Images(String filePath) { + this.filePath = filePath; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/plugin/ClassTransformer.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/plugin/ClassTransformer.java new file mode 100644 index 0000000..c34f3b8 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/plugin/ClassTransformer.java @@ -0,0 +1,55 @@ +package cc.polyfrost.oneconfig.lwjgl.plugin; + +import net.minecraft.launchwrapper.IClassTransformer; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.*; + +/** + * Taken from LWJGLTwoPointFive under The Unlicense + * <a href="https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/">https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/</a> + */ +public class ClassTransformer implements IClassTransformer { + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + if (name.equals("org.lwjgl.nanovg.NanoVGGLConfig")) { + ClassReader reader = new ClassReader(basicClass); + ClassNode node = new ClassNode(); + reader.accept(node, ClassReader.EXPAND_FRAMES); + + for (MethodNode method : node.methods) { + if (method.name.equals("configGL")) { + InsnList list = new InsnList(); + + list.add(new VarInsnNode(Opcodes.LLOAD, 0)); + list.add(new TypeInsnNode(Opcodes.NEW, "cc/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider")); + list.add(new InsnNode(Opcodes.DUP)); + list.add(new MethodInsnNode( + Opcodes.INVOKESPECIAL, + "cc/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider", + "<init>", + "()V", + false + )); + list.add(new MethodInsnNode( + Opcodes.INVOKESTATIC, + "org/lwjgl/nanovg/NanoVGGLConfig", + "config", + "(JLorg/lwjgl/system/FunctionProvider;)V", + false + )); + list.add(new InsnNode(Opcodes.RETURN)); + + method.instructions.clear(); + method.instructions.insert(list); + } + } + + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + node.accept(cw); + return cw.toByteArray(); + } + return basicClass; + } +}
\ No newline at end of file diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/plugin/LoadingPlugin.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/plugin/LoadingPlugin.java new file mode 100644 index 0000000..b2ae799 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/plugin/LoadingPlugin.java @@ -0,0 +1,52 @@ +package cc.polyfrost.oneconfig.lwjgl.plugin; + +import net.minecraft.launchwrapper.Launch; +import net.minecraft.launchwrapper.LaunchClassLoader; +import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Set; + +/** + * Taken from LWJGLTwoPointFive under The Unlicense + * <a href="https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/">https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/</a> + */ +public class LoadingPlugin implements IFMLLoadingPlugin { + + public LoadingPlugin() { + try { + Field f_exceptions = LaunchClassLoader.class.getDeclaredField("classLoaderExceptions"); + f_exceptions.setAccessible(true); + Set<String> exceptions = (Set<String>) f_exceptions.get(Launch.classLoader); + exceptions.remove("org.lwjgl."); + } catch (Exception e) { + throw new RuntimeException("e"); + } + } + + @Override + public String[] getASMTransformerClass() { + return new String[]{"cc.polyfrost.oneconfig.lwjgl.plugin.ClassTransformer"}; + } + + @Override + public String getModContainerClass() { + return null; + } + + @Override + public String getSetupClass() { + return null; + } + + @Override + public void injectData(Map<String, Object> data) { + + } + + @Override + public String getAccessTransformerClass() { + return null; + } +}
\ No newline at end of file |