superb-warfare/src/main/java/com/atsuishio/superbwarfare/client/RenderHelper.java
2025-02-03 22:41:11 +08:00

139 lines
9 KiB
Java

package com.atsuishio.superbwarfare.client;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.Vec3;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import javax.annotation.Nullable;
public class RenderHelper {
public static void preciseBlit(GuiGraphics gui, ResourceLocation pAtlasLocation, float pX, float pY, float pUOffset, float pVOffset, float pWidth, float pHeight, float pTextureWidth, float pTextureHeight) {
preciseBlit(gui, pAtlasLocation, pX, pY, 0, pUOffset, pVOffset, pWidth, pHeight, pTextureWidth, pTextureHeight);
}
public static void preciseBlit(GuiGraphics gui, ResourceLocation pAtlasLocation, float pX, float pY, float pBlitOffset, float pUOffset, float pVOffset, float pWidth, float pHeight, float pTextureWidth, float pTextureHeight) {
float pX2 = pX + pWidth;
float pY2 = pY + pHeight;
float pMinU = pUOffset / pTextureWidth;
float pMaxU = (pUOffset + pWidth) / pTextureWidth;
float pMinV = pVOffset / pTextureHeight;
float pMaxV = (pVOffset + pHeight) / pTextureHeight;
RenderSystem.setShaderTexture(0, pAtlasLocation);
RenderSystem.setShader(GameRenderer::getPositionTexShader);
Matrix4f matrix4f = gui.pose().last().pose();
BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder();
bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);
bufferbuilder.vertex(matrix4f, pX, pY, pBlitOffset).uv(pMinU, pMinV).endVertex();
bufferbuilder.vertex(matrix4f, pX, pY2, pBlitOffset).uv(pMinU, pMaxV).endVertex();
bufferbuilder.vertex(matrix4f, pX2, pY2, pBlitOffset).uv(pMaxU, pMaxV).endVertex();
bufferbuilder.vertex(matrix4f, pX2, pY, pBlitOffset).uv(pMaxU, pMinV).endVertex();
BufferUploader.drawWithShader(bufferbuilder.end());
}
/**
* Codes based on @Xjqsh
*/
@Nullable
public static Vec3 worldToScreen(Vec3 pos, Vec3 cameraPos) {
Minecraft minecraft = Minecraft.getInstance();
Frustum frustum = minecraft.levelRenderer.getFrustum();
Vector3f relativePos = pos.subtract(cameraPos).toVector3f();
Vector3f transformedPos = frustum.matrix.transformProject(relativePos.x, relativePos.y, relativePos.z, new Vector3f());
double scaleFactor = minecraft.getWindow().getGuiScale();
float guiScaleMul = 0.5f / (float) scaleFactor;
Vector3f screenPos = transformedPos.mul(1.0f, -1.0f, 1.0f).add(1.0f, 1.0f, 0.0f)
.mul(guiScaleMul * minecraft.getWindow().getWidth(), guiScaleMul * minecraft.getWindow().getHeight(), 1.0f);
return transformedPos.z < 1.0f ? new Vec3(screenPos.x, screenPos.y, transformedPos.z) : null;
}
public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, float pX, float pY, float pUOffset, float pVOffset, float pWidth, float pHeight, float pTextureWidth, float pTextureHeight, int color) {
blit(pose, pAtlasLocation, pX, pY, pWidth, pHeight, pUOffset, pVOffset, pWidth, pHeight, pTextureWidth, pTextureHeight, color);
}
public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, float pX, float pY, float pWidth, float pHeight, float pUOffset, float pVOffset, float pUWidth, float pVHeight, float pTextureWidth, float pTextureHeight, int color) {
blit(pose, pAtlasLocation, pX, pX + pWidth, pY, pY + pHeight, 0, pUWidth, pVHeight, pUOffset, pVOffset, pTextureWidth, pTextureHeight, color);
}
public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, float pX1, float pX2, float pY1, float pY2, float pBlitOffset, float pUWidth, float pVHeight, float pUOffset, float pVOffset, float pTextureWidth, float pTextureHeight, int color) {
innerBlit(pose, pAtlasLocation, pX1, pX2, pY1, pY2, pBlitOffset, (pUOffset + 0.0F) / pTextureWidth, (pUOffset + pUWidth) / pTextureWidth, (pVOffset + 0.0F) / pTextureHeight, (pVOffset + pVHeight) / pTextureHeight, color);
}
public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, float pX, float pY, float pUOffset, float pVOffset, float pWidth, float pHeight, float pTextureWidth, float pTextureHeight, float alpha, boolean opposite) {
blit(pose, pAtlasLocation, pX, pY, pWidth, pHeight, pUOffset, pVOffset, pWidth, pHeight, pTextureWidth, pTextureHeight, alpha, opposite);
}
public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, float pX, float pY, float pUOffset, float pVOffset, float pWidth, float pHeight, float pTextureWidth, float pTextureHeight, float alpha) {
blit(pose, pAtlasLocation, pX, pY, pUOffset, pVOffset, pWidth, pHeight, pTextureWidth, pTextureHeight, alpha, false);
}
public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, float pX, float pY, float pWidth, float pHeight, float pUOffset, float pVOffset, float pUWidth, float pVHeight, float pTextureWidth, float pTextureHeight, float alpha, boolean opposite) {
blit(pose, pAtlasLocation, pX, pX + pWidth, pY, pY + pHeight, 0, pUWidth, pVHeight, pUOffset, pVOffset, pTextureWidth, pTextureHeight, alpha, opposite);
}
public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, float pX1, float pX2, float pY1, float pY2, float pBlitOffset, float pUWidth, float pVHeight, float pUOffset, float pVOffset, float pTextureWidth, float pTextureHeight, float alpha, boolean opposite) {
innerBlit(pose, pAtlasLocation, pX1, pX2, pY1, pY2, pBlitOffset, (pUOffset + 0.0F) / pTextureWidth, (pUOffset + pUWidth) / pTextureWidth, (pVOffset + 0.0F) / pTextureHeight, (pVOffset + pVHeight) / pTextureHeight, alpha, opposite);
}
private static void innerBlit(PoseStack pose, ResourceLocation pAtlasLocation, float pX1, float pX2, float pY1, float pY2, float pBlitOffset, float pMinU, float pMaxU, float pMinV, float pMaxV, int color) {
RenderSystem.setShaderTexture(0, pAtlasLocation);
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
Matrix4f matrix4f = pose.last().pose();
BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder();
bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
vertexC(pX1, pX2, pY1, pY2, pBlitOffset, pMinU, pMaxU, pMinV, pMaxV, color, matrix4f, bufferbuilder);
BufferUploader.drawWithShader(bufferbuilder.end());
}
private static void innerBlit(PoseStack pose, ResourceLocation pAtlasLocation, float pX1, float pX2, float pY1, float pY2, float pBlitOffset, float pMinU, float pMaxU, float pMinV, float pMaxV, float alpha, boolean opposite) {
RenderSystem.setShaderTexture(0, pAtlasLocation);
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
RenderSystem.enableBlend();
Matrix4f matrix4f = pose.last().pose();
BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder();
bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
if (opposite) {
vertex(pX1, pX2, pY1, pY2, pBlitOffset, pMaxU, pMinU, pMinV, pMaxV, alpha, matrix4f, bufferbuilder);
} else {
vertex(pX1, pX2, pY1, pY2, pBlitOffset, pMinU, pMaxU, pMinV, pMaxV, alpha, matrix4f, bufferbuilder);
}
BufferUploader.drawWithShader(bufferbuilder.end());
RenderSystem.disableBlend();
}
private static void vertex(float pX1, float pX2, float pY1, float pY2, float pBlitOffset, float pMinU, float pMaxU, float pMinV, float pMaxV, float alpha, Matrix4f matrix4f, BufferBuilder bufferBuilder) {
bufferBuilder.vertex(matrix4f, pX1, pY1, pBlitOffset).color(1f, 1f, 1f, alpha).uv(pMinU, pMinV).endVertex();
bufferBuilder.vertex(matrix4f, pX1, pY2, pBlitOffset).color(1f, 1f, 1f, alpha).uv(pMinU, pMaxV).endVertex();
bufferBuilder.vertex(matrix4f, pX2, pY2, pBlitOffset).color(1f, 1f, 1f, alpha).uv(pMaxU, pMaxV).endVertex();
bufferBuilder.vertex(matrix4f, pX2, pY1, pBlitOffset).color(1f, 1f, 1f, alpha).uv(pMaxU, pMinV).endVertex();
}
private static void vertexC(float pX1, float pX2, float pY1, float pY2, float pBlitOffset, float pMinU, float pMaxU, float pMinV, float pMaxV, int color, Matrix4f matrix4f, BufferBuilder bufferBuilder) {
float r = (color >> 16 & 255) / 255.0F;
float g = (color >> 8 & 255) / 255.0F;
float b = (color & 255) / 255.0F;
bufferBuilder.vertex(matrix4f, pX1, pY1, pBlitOffset).color(r, g, b, 1f).uv(pMinU, pMinV).endVertex();
bufferBuilder.vertex(matrix4f, pX1, pY2, pBlitOffset).color(r, g, b, 1f).uv(pMinU, pMaxV).endVertex();
bufferBuilder.vertex(matrix4f, pX2, pY2, pBlitOffset).color(r, g, b, 1f).uv(pMaxU, pMaxV).endVertex();
bufferBuilder.vertex(matrix4f, pX2, pY1, pBlitOffset).color(r, g, b, 1f).uv(pMaxU, pMinV).endVertex();
}
}