diff --git a/src/main/java/ru/dbotthepony/mc/otm/screen/RenderHelper.java b/src/main/java/ru/dbotthepony/mc/otm/screen/RenderHelper.java new file mode 100644 index 000000000..dc3eaccc3 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/screen/RenderHelper.java @@ -0,0 +1,287 @@ +package ru.dbotthepony.mc.otm.screen; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.*; +import com.mojang.math.Matrix4f; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.resources.ResourceLocation; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; + +/** + * I am too lazy to learn how Mojang's API works + * so I just recreate part of GMod's API in here + */ +public class RenderHelper { + private static final Matrix4f identity = new Matrix4f(); + public static final ResourceLocation WIDGETS = new ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets.png"); + + static { + identity.setIdentity(); + } + + // Regular functions + + /** + * Draws a textured rectangle on screen + * translated by a given matrix + * + * @param matrix Matrix translation to use + * @param x screen X position (with matrix transformation) + * @param y screen Y position (with matrix transformation) + * @param width width of drawn rectangle + * @param height height of drawn rectangle + * @param u0 initial U position ranging from 0-1 (single) or beyond (repetitive) + * @param v0 initial V position ranging from 0-1 (single) or beyond (repetitive) + * @param u1 final U position ranging from 0-1 (single) or beyond (repetitive) + * @param v1 final V position ranging from 0-1 (single) or beyond (repetitive) + */ + public static void drawTexturedRectUV( + Matrix4f matrix, + float x, + float y, + float width, + float height, + float u0, + float v0, + float u1, + float v1 + ) { + RenderSystem.setShader(GameRenderer::getPositionTexShader); + + var builder = Tesselator.getInstance().getBuilder(); + builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); + builder.vertex(matrix, x, y + height, 0).uv(u0, v1).endVertex(); + builder.vertex(matrix, x + width, y + height, 0).uv(u1, v1).endVertex(); + builder.vertex(matrix, x + width, y, 0).uv(u1, v0).endVertex(); + builder.vertex(matrix, x, y, 0).uv(u0, v0).endVertex(); + builder.end(); + BufferUploader.end(builder); + } + + /** + * Draws a textured rectangle on screen + * + * @param x screen X position (with matrix transformation) + * @param y screen Y position (with matrix transformation) + * @param width width of drawn rectangle + * @param height height of drawn rectangle + * @param u0 initial U position ranging from 0-1 (single) or beyond (repetitive) + * @param v0 initial V position ranging from 0-1 (single) or beyond (repetitive) + * @param u1 final U position ranging from 0-1 (single) or beyond (repetitive) + * @param v1 final V position ranging from 0-1 (single) or beyond (repetitive) + */ + public static void drawTexturedRectUV( + float x, + float y, + float width, + float height, + float u0, + float v0, + float u1, + float v1 + ) { + drawTexturedRectUV(identity, x, y, width, height, u0, v0, u1, v1); + } + + /** + * Draws a textured rectangle on screen + * with matrix from pose + * + * @param stack PoseStack containing translation matrix + * @param x screen X position (with matrix transformation) + * @param y screen Y position (with matrix transformation) + * @param width width of drawn rectangle + * @param height height of drawn rectangle + * @param u0 initial U position ranging from 0-1 (single) or beyond (repetitive) + * @param v0 initial V position ranging from 0-1 (single) or beyond (repetitive) + * @param u1 final U position ranging from 0-1 (single) or beyond (repetitive) + * @param v1 final V position ranging from 0-1 (single) or beyond (repetitive) + */ + public static void drawTexturedRectUV( + PoseStack stack, + float x, + float y, + float width, + float height, + float u0, + float v0, + float u1, + float v1 + ) { + drawTexturedRectUV(stack.last().pose(), x, y, width, height, u0, v0, u1, v1); + } + + /** + * Draws a textured rectangle on screen + * with matrix from pose + * UVs are 0-1 + * + * @param stack PoseStack containing translation matrix + * @param x screen X position (with matrix transformation) + * @param y screen Y position (with matrix transformation) + * @param width width of drawn rectangle + * @param height height of drawn rectangle + */ + public static void drawTexturedRect( + PoseStack stack, + float x, + float y, + float width, + float height + ) { + drawTexturedRectUV(stack, x, y, width, height, 0, 0, 1, 1); + } + + public record SkinElement(ResourceLocation texture, float image_x, float image_y, float rect_w, float rect_h, float defined_width, float defined_height) { + public void render(PoseStack stack, float x, float y, float width, float height) { + RenderSystem.setShaderTexture(0, texture); + + drawTexturedRectUV( + stack, + x, + y, + width, + height, + image_x / defined_width, + image_y / defined_height, + (image_x + rect_w) / defined_width, + (image_y + rect_h) / defined_height); + } + + public void renderRaw(PoseStack stack, float x, float y, float width, float height) { + // RenderSystem.setShader(GameRenderer::getPositionTexShader); + // RenderSystem.setShaderTexture(0, texture); + + drawTexturedRectUV( + stack, + x, + y, + width, + height, + image_x / defined_width, + image_y / defined_height, + (image_x + rect_w) / defined_width, + (image_y + rect_h) / defined_height); + } + } + + public static final SkinElement upper_left_window_corner = new SkinElement( + WIDGETS, + 18, + 0, + 6, + 6, + 256, + 256 + ); + + public static final SkinElement upper_right_window_corner = new SkinElement( + WIDGETS, + 24, + 0, + 6, + 6, + 256, + 256 + ); + + public static final SkinElement bottom_left_window_corner = new SkinElement( + WIDGETS, + 18, + 6, + 6, + 6, + 256, + 256 + ); + + public static final SkinElement bottom_right_window_corner = new SkinElement( + WIDGETS, + 24, + 6, + 6, + 6, + 256, + 256 + ); + + public static final SkinElement left_window_border = new SkinElement( + WIDGETS, + 18, + 4, + 3, + 5, + 256, + 256 + ); + + public static final SkinElement right_window_border = new SkinElement( + WIDGETS, + 27, + 3, + 3, + 5, + 256, + 256 + ); + + public static final SkinElement top_window_border = new SkinElement( + WIDGETS, + 22, + 0, + 5, + 3, + 256, + 256 + ); + + public static final SkinElement bottom_window_border = new SkinElement( + WIDGETS, + 21, + 9, + 5, + 3, + 256, + 256 + ); + + public static final SkinElement window_background = new SkinElement( + WIDGETS, + 22, + 4, + 4, + 4, + 256, + 256 + ); + + public static void drawWindowBackground( + PoseStack stack, + float x, + float y, + float width, + float height + ) { + float bg_width = width - 4; + float bg_height = height - 4; + + // background + if (bg_width > 0 && bg_height > 0) { + window_background.render(stack, x + 3, y + 3, bg_width, bg_height); + } + + // borders + left_window_border.render(stack, x, y + 4, 3, height - 8); + right_window_border.renderRaw(stack, x + width - 3, y + 4, 3, height - 6); + + top_window_border.renderRaw(stack, x + 4, y, width - 8, 3); + bottom_window_border.renderRaw(stack, x + 4, y + height - 3, width - 8, 3); + + // corners + upper_left_window_corner.renderRaw(stack, x, y, 6, 6); + upper_right_window_corner.renderRaw(stack, x + width - 6, y, 6, 6); + + bottom_left_window_corner.renderRaw(stack, x, y + height - 6, 6, 6); + bottom_right_window_corner.renderRaw(stack, x + width - 6, y + height - 6, 6, 6); + } +} diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.png index 25976bebc..90a4a9675 100644 Binary files a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.png and b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.png differ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf index fa56b0d7c..702d1ed0f 100644 --- a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf +++ b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d3c951d9fd4bf3a35c714cd22159fef1fea42c0f9b621202340c297bb62b338 -size 7712 +oid sha256:1e15d574534de8d8ca9126e07638dc455f0de6afe2e9d7c126876104cdbfd9bd +size 10004