很多bug

This commit is contained in:
Color_yr committed 2026-07-11 17:17:28 +08:00
1 parent b3fdfe5e5c
commit a7777d627e
22 files changed
+1061 -317

No files matched your search

+1
View File
@@ -51,6 +51,7 @@ allprojects {
afterEvaluate {
if (plugins.hasPlugin("com.gtnewhorizons.retrofuturagradle")) return@afterEvaluate
if (plugins.hasPlugin("fabric-loom")) return@afterEvaluate
val rfgObfAttr = Attribute.of("com.gtnewhorizons.retrofuturagradle.obfuscation", String::class.java)
val rfgDeobfAttr = Attribute.of("rfgDeobfuscatorTransformed", Boolean::class.javaObjectType)
@@ -6,6 +6,7 @@ import com.coloryr.allmusic.client.core.render.PictureFrameBuffer;
import com.coloryr.allmusic.client.core.render.TextFrameBuffer;
import com.coloryr.allmusic.client.core.render.TextureRender;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.loader.api.FabricLoader;
@@ -30,6 +31,14 @@ public class AllMusicClient implements ClientModInitializer, AllMusicBridge {
public static final Logger LOGGER = LogManager.getLogger("AllMusic Client");
/** 当前帧的 PoseStack,由 GuiShow mixin 注入 */
public static PoseStack context;
/** 由 HUD 渲染 mixin 调用,缓存当前帧的 PoseStack */
public static void update(PoseStack matrices) {
context = matrices;
}
public int getScreenWidth() {
return Minecraft.getInstance().getWindow().getGuiScaledWidth();
}
@@ -69,7 +78,7 @@ public class AllMusicClient implements ClientModInitializer, AllMusicBridge {
@Override
public TextFrameBuffer makeTextRender(String name) {
return new CoreRenderTarget();
return new CoreRenderTarget(name);
}
@Override
@@ -4,322 +4,198 @@ import com.coloryr.allmusic.client.core.AllMusicHud;
import com.coloryr.allmusic.client.core.Point2f;
import com.coloryr.allmusic.client.core.render.TextFrameBuffer;
import com.coloryr.allmusic.codec.HudPosType;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.Window;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Matrix4f;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.network.chat.Component;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL30;
import java.util.ArrayList;
import java.util.List;
public class CoreRenderTarget extends TextFrameBuffer {
private static final RenderBuffers renderBuffers = new RenderBuffers();
private static class TextEntry {
final Component component;
final int y;
final int color;
final boolean shadow;
final int width;
final int height;
private final RenderTarget target;
TextEntry(Component component, int y, int color, boolean shadow, int width, int height) {
this.component = component;
this.y = y;
this.color = color;
this.shadow = shadow;
this.width = width;
this.height = height;
}
}
public CoreRenderTarget() {
target = new RenderTarget(800, 200, false, false);
target.setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
private final List<TextEntry> entries = new ArrayList<>();
private final boolean isState;
public CoreRenderTarget(String name) {
isState = name.equals("state");
}
@Override
public void resize(int width, int height) {
Window window = Minecraft.getInstance().getWindow();
nowWidth = (int) (width * window.getGuiScale());
nowHeight = (int) (height * window.getGuiScale());
if (nowWidth > target.width || nowHeight > target.height) {
target.resize(nowWidth, nowHeight, false);
}
nowWidth = width;
nowHeight = height;
}
@Override
public void use() {
isDraw = true;
clear();
target.clear(false);
target.bindWrite(true);
Window window = Minecraft.getInstance().getWindow();
RenderSystem.ortho(0.0F, (float) (target.width / window.getGuiScale()),
(float) (target.height / window.getGuiScale()), 0.0F, 1000.0F, 21000.0F);
entries.clear();
}
@Override
public void unUse() {
isDraw = false;
Window window = Minecraft.getInstance().getWindow();
RenderSystem.ortho(0.0F, (double) window.getWidth() / window.getGuiScale(), (double) window.getHeight() / window.getGuiScale(), 0.0F, 1000.0F, 3000.0F);
RenderTarget main = Minecraft.getInstance().getMainRenderTarget();
main.bindWrite(true);
}
@Override
public void drawText(String text, int y, int color, boolean shadow) {
Window window = Minecraft.getInstance().getWindow();
Font font = Minecraft.getInstance().font;
color = (color & 0x00FFFFFF) | 0xFF000000;
Component component = MiniMessage.parse(text);
if (font.width(component) == 0) {
Font font = Minecraft.getInstance().font;
int width = font.width(component);
if (width == 0) {
return;
}
int width;
if (shadow) {
width = font.drawShadow(new PoseStack(), component, 0, 0, color);
} else {
width = font.draw(new PoseStack(), component, 0, 0, color);
int height = font.lineHeight + (shadow ? 1 : 0);
if (isState) {
y = 0;
}
RenderSystem.disableDepthTest();
renderBuffers.bufferSource().endBatch();
RenderSystem.enableDepthTest();
TextItem item = new TextItem(width, font.lineHeight + (shadow ? 1 : 0), y, (float) window.getGuiScale());
texts.add(item);
}
/**
* 渲染贴图的一部分到屏幕指定位置
*
* @param alpha 透明度
* @param x 屏幕X坐标(左上角)
* @param y 屏幕Y坐标(左上角)
* @param width 需要渲染的宽度
* @param height 需要渲染的高度
* @param texX 贴图左上角X坐标
* @param texY 贴图左上角Y坐标
* @param scale 贴图缩放
*/
private void draw(float alpha, float x, float y, float width, float height, float texX, float texY, float scale) {
RenderSystem.bindTexture(target.getColorTextureId());
RenderSystem.enableTexture();
RenderSystem.depthMask(false);
RenderSystem.enableBlend();
RenderSystem.depthFunc(GL30.GL_ALWAYS);
float w = (width / 2);
float h = (height / 2);
Matrix4f matrix = Matrix4f.createTranslateMatrix(x + w, y + h, 0);
float x0 = -w;
float x1 = w;
float y0 = -h;
float y1 = h;
float z = 0;
// 计算贴图区域UV
float u0 = texX * scale / target.width;
float v0 = 1 - (texY * scale / target.height);
float u1 = (texX + width) * scale / target.width;
float v1 = 1 - ((texY + height) * scale / target.height);
BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder();
bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
bufferBuilder.vertex(matrix, x0, y1, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u0, v1).endVertex();
bufferBuilder.vertex(matrix, x1, y1, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u1, v1).endVertex();
bufferBuilder.vertex(matrix, x1, y0, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u1, v0).endVertex();
bufferBuilder.vertex(matrix, x0, y0, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u0, v0).endVertex();
bufferBuilder.end();
BufferUploader.end(bufferBuilder);
RenderSystem.disableBlend();
RenderSystem.depthMask(true);
target.unbindRead();
}
public void drawLoop(float alpha, float x, float y,
float texX, float texY,
float textWidth, float textHeight,
int maxWidth, float offsetX, float scale) {
// 如果宽度不大于最大宽度,直接全部渲染
if (maxWidth == -1 || textWidth <= maxWidth) {
draw(alpha, x, y, textWidth, textHeight, texX, texY, scale);
return;
}
if (textWidth - offsetX < maxWidth) {
float nowWith = textWidth - offsetX;
draw(alpha, x, y, nowWith, textHeight, offsetX, texY, scale);
draw(alpha, x + nowWith, y, maxWidth - nowWith, textHeight, 0, texY, scale);
} else {
draw(alpha, x, y, maxWidth, textHeight, offsetX, texY, scale);
}
}
/**
* 居中百分比显示(根据百分比选择显示贴图的中间部分)
*
* @param alpha 透明度
* @param startX 起始X坐标(屏幕左上角)
* @param startY 起始Y坐标(屏幕左上角)
* @param texX 贴图左上角X
* @param texY 贴图左上角Y
* @param texWidth 贴图总宽度
* @param texHeight 贴图高度
* @param maxWidth 最大渲染宽度
* @param percent 百分比(0.0-1.0),0%显示左边,100%显示右边
*/
public void drawByPercent(float alpha, float startX, float startY,
float texX, float texY,
float texWidth, float texHeight,
int maxWidth, float percent, float scale) {
// 限制百分比范围
percent = Math.min(1.0f, Math.max(0.0f, percent));
// 如果贴图宽度小于等于最大宽度,直接全部显示
if (texWidth <= maxWidth) {
draw(alpha, startX, startY, (int) (texWidth * percent), texHeight, texX, texY, scale);
return;
}
// 计算贴图的起始位置(根据百分比)
float maxOffset = texWidth - maxWidth;
int texOffset = (int) (maxOffset * percent);
// 渲染
draw(alpha, startX, startY, maxWidth, texHeight, texX + texOffset, texY, scale);
}
/**
* 正向百分比显示(从左开始显示,右边空白)
*
* @param alpha 透明度
* @param startX 起始X坐标(屏幕左上角)
* @param startY 起始Y坐标(屏幕左上角)
* @param texX 贴图左上角X
* @param texY 贴图左上角Y
* @param texWidth 贴图总宽度
* @param texHeight 贴图高度
* @param maxWidth 最大渲染宽度
* @param percent 百分比(0.0-1.0),表示显示的内容比例,例如0.4表示显示前面40%的内容
*/
public void drawByForwardPercent(float alpha, int startX, int startY,
int texX, int texY,
int texWidth, int texHeight,
int maxWidth, float percent, float scale) {
// 限制百分比范围
percent = Math.min(1.0f, Math.max(0.0f, percent));
// 如果要显示的内容为0,直接返回
if (percent <= 0) {
return;
}
// 计算要显示的内容宽度
int contentWidth = (int) (texWidth * percent);
// 实际渲染宽度
int renderWidth = Math.min(contentWidth, maxWidth);
// 屏幕偏移为0(靠左显示)
int screenOffset = 0;
// 贴图偏移为0(从左边开始)
int texOffset = 0;
// 渲染
draw(alpha, startX + screenOffset, startY,
renderWidth, texHeight,
texX + texOffset, texY, scale);
}
/**
* 反向百分比显示(从右开始显示,左边空白)
*
* @param alpha 透明度
* @param startX 起始X坐标(屏幕左上角)
* @param startY 起始Y坐标(屏幕左上角)
* @param texX 贴图左上角X
* @param texY 贴图左上角Y
* @param texWidth 贴图总宽度
* @param texHeight 贴图高度
* @param maxWidth 最大渲染宽度
* @param percent 百分比(0.0-1.0),表示显示的内容比例,例如0.4表示显示后面40%的内容
*/
public void drawByReversePercent(float alpha, int startX, int startY,
int texX, int texY,
int texWidth, int texHeight,
int maxWidth, float percent, float scale) {
// 限制百分比范围
percent = Math.min(1.0f, Math.max(0.0f, percent));
// 如果要显示的内容为0,直接返回
if (percent <= 0) {
return;
}
// 计算要显示的内容宽度
int contentWidth = (int) (texWidth * percent);
// 实际渲染宽度
int renderWidth = Math.min(contentWidth, maxWidth);
// 屏幕偏移(靠右显示)
int screenOffset = maxWidth - renderWidth;
// 贴图偏移(显示后面部分)
int texOffset = texWidth - contentWidth;
// 渲染
draw(alpha, startX + screenOffset, startY,
renderWidth, texHeight,
texX + texOffset, texY, scale);
entries.add(new TextEntry(component, y, color, shadow, width, height));
texts.add(new TextItem(width, height, y, 1.0f));
}
@Override
public void draw(float alpha, int x, int y, int maxWidth, HudPosType dir) {
for (TextItem item : texts) {
Point2f point = AllMusicHud.getPos(Math.min(maxWidth, item.textWidth), item.textHeight, x, y, dir);
if (texts.isEmpty()) {
return;
}
drawLoop(alpha, point.x, point.y + item.y, 0, item.y, item.textWidth, item.textHeight, maxWidth, getOffset(item) % item.textWidth, item.scale);
PoseStack matrices = AllMusicClient.context;
if (matrices == null) return;
Font font = Minecraft.getInstance().font;
for (TextEntry entry : entries) {
int displayWidth = maxWidth != -1 ? Math.min(entry.width, maxWidth) : entry.width;
Point2f point = AllMusicHud.getPos(displayWidth, entry.height, x, y, dir);
int drawX = (int) point.x;
int drawY = (int) (point.y + entry.y);
int finalColor = applyAlpha(entry.color, alpha);
if (maxWidth != -1 && entry.width > maxWidth) {
int scrollOffset = (int) (offsetX % entry.width);
enableScissor(drawX, drawY, maxWidth, entry.height);
drawString(font, matrices, entry, drawX - scrollOffset, drawY, finalColor);
if (scrollOffset > 0) {
drawString(font, matrices, entry, drawX - scrollOffset + entry.width, drawY, finalColor);
}
disableScissor();
} else {
drawString(font, matrices, entry, drawX, drawY, finalColor);
}
}
}
@Override
public void drawLine(float x, float y, float alpha, int line) {
if (line >= texts.size()) {
if (texts.isEmpty()) {
return;
}
TextItem item = texts.get(line);
draw(alpha, x, y, item.textWidth, item.textHeight, 0, item.y, item.scale);
if (line >= texts.size() || line >= entries.size()) {
return;
}
PoseStack matrices = AllMusicClient.context;
if (matrices == null) return;
Font font = Minecraft.getInstance().font;
TextEntry entry = entries.get(line);
drawString(font, matrices, entry,
(int) x, (int) (y + entry.y),
applyAlpha(entry.color, alpha));
}
@Override
public Point2f getLine(int line) {
if (line >= texts.size()) {
if (line >= texts.size() || line >= entries.size()) {
return new Point2f(0, 0);
}
TextItem item = texts.get(line);
return new Point2f(item.textWidth, item.textHeight);
TextEntry entry = entries.get(line);
return new Point2f(entry.width, entry.height);
}
@Override
public void drawWithState(float alpha, int x, int y, int maxWidth, float state, HudPosType dir) {
for (TextItem item : texts) {
Point2f point = AllMusicHud.getPos(Math.min(maxWidth, item.textWidth), item.textHeight, x, y, dir);
drawByPercent(alpha, point.x, point.y + item.y, 0, item.y, item.textWidth, item.textHeight, maxWidth, state, item.scale);
if (texts.isEmpty()) {
return;
}
PoseStack matrices = AllMusicClient.context;
if (matrices == null) return;
Font font = Minecraft.getInstance().font;
target.unbindRead();
for (TextEntry entry : entries) {
int displayWidth = maxWidth != -1 ? Math.min(entry.width, maxWidth) : entry.width;
Point2f point = AllMusicHud.getPos(displayWidth, entry.height, x, y, dir);
int drawX = (int) point.x;
int drawY = (int) (point.y + entry.y);
int finalColor = applyAlpha(entry.color, alpha);
if (maxWidth != -1 && entry.width > maxWidth) {
float maxOffset = entry.width - maxWidth;
int texOffset = (int) (maxOffset * state);
int revealWidth = (int) (maxWidth * state);
enableScissor(drawX, drawY, revealWidth, entry.height);
drawString(font, matrices, entry, drawX - texOffset, drawY, finalColor);
disableScissor();
} else {
int revealWidth = (int) (entry.width * state);
enableScissor(drawX, drawY, revealWidth, entry.height);
drawString(font, matrices, entry, drawX, drawY, finalColor);
disableScissor();
}
}
}
private static void drawString(Font font, PoseStack matrices, TextEntry entry,
int x, int y, int color) {
if (entry.shadow) {
font.drawShadow(matrices, entry.component, x, y, color);
} else {
font.draw(matrices, entry.component, x, (float) y, color);
}
}
private static void enableScissor(int x, int y, int width, int height) {
Window window = Minecraft.getInstance().getWindow();
double scale = window.getGuiScale();
int sx = (int) (x * scale);
int sy = (int) (window.getHeight() - (y + height) * scale);
int sw = (int) (width * scale);
int sh = (int) (height * scale);
GL11.glEnable(GL11.GL_SCISSOR_TEST);
GL11.glScissor(sx, sy, sw, sh);
}
private static void disableScissor() {
GL11.glDisable(GL11.GL_SCISSOR_TEST);
}
private static int applyAlpha(int color, float alpha) {
int a = (int) (alpha * 255);
if (a < 0) a = 0;
if (a > 255) a = 255;
return (color & 0x00FFFFFF) | (a << 24);
}
}
@@ -12,8 +12,8 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Matrix4f;
import com.mojang.math.Quaternion;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.texture.DynamicTexture;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL30;
import java.io.ByteArrayInputStream;
@@ -48,12 +48,8 @@ public class PicRender extends PictureFrameBuffer {
public void draw(boolean rotate, int size, float x, float y, int ang, HudPosType dir, float alpha) {
Point2f point = AllMusicHud.getPos(size, size, x, y, dir);
RenderSystem.bindTexture(rotate ? rotateTexture.getId() : sourceTexture.getId());
RenderSystem.enableTexture();
RenderSystem.depthMask(false);
RenderSystem.enableBlend();
RenderSystem.depthFunc(GL30.GL_ALWAYS);
RenderSystem.setShaderTexture(0, rotate ? rotateTexture.getId() : sourceTexture.getId());
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
RenderSystem.depthMask(false);
RenderSystem.enableBlend();
RenderSystem.depthFunc(GL30.GL_ALWAYS);
@@ -79,7 +75,7 @@ public class PicRender extends PictureFrameBuffer {
float v1 = 1;
BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder();
bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
bufferBuilder.begin(7, DefaultVertexFormat.POSITION_COLOR_TEX);
bufferBuilder.vertex(matrix, x0, y1, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u0, v1).endVertex();
bufferBuilder.vertex(matrix, x1, y1, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u1, v1).endVertex();
bufferBuilder.vertex(matrix, x1, y0, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u1, v0).endVertex();
@@ -13,11 +13,11 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.texture.SimpleTexture;
import net.minecraft.client.resources.metadata.texture.TextureMetadataSection;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL30;
import java.io.IOException;
@@ -42,8 +42,8 @@ public class TexRender extends TextureRender {
@Override
public void drawPic(float x, float y, float alpha) {
RenderSystem.bindTexture(sourceTexture.getId());
RenderSystem.enableTexture();
RenderSystem.setShaderTexture(0, sourceTexture.getId());
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
RenderSystem.depthMask(false);
RenderSystem.enableBlend();
RenderSystem.depthFunc(GL30.GL_ALWAYS);
@@ -64,7 +64,7 @@ public class TexRender extends TextureRender {
float v1 = 1;
BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder();
bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
bufferBuilder.begin(7, DefaultVertexFormat.POSITION_COLOR_TEX);
bufferBuilder.vertex(matrix, x0, y1, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u0, v1).endVertex();
bufferBuilder.vertex(matrix, x1, y1, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u1, v1).endVertex();
bufferBuilder.vertex(matrix, x1, y0, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u1, v0).endVertex();
@@ -78,8 +78,8 @@ public class TexRender extends TextureRender {
@Override
public void drawPic(float x, float y, float width, float alpha) {
RenderSystem.bindTexture(sourceTexture.getId());
RenderSystem.enableTexture();
RenderSystem.setShaderTexture(0, sourceTexture.getId());
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
RenderSystem.depthMask(false);
RenderSystem.enableBlend();
RenderSystem.depthFunc(GL30.GL_ALWAYS);
@@ -100,7 +100,7 @@ public class TexRender extends TextureRender {
float v1 = 1;
BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder();
bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
bufferBuilder.begin(7, DefaultVertexFormat.POSITION_COLOR_TEX);
bufferBuilder.vertex(matrix, x0, y1, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u0, v1).endVertex();
bufferBuilder.vertex(matrix, x1, y1, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u1, v1).endVertex();
bufferBuilder.vertex(matrix, x1, y0, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u1, v0).endVertex();
@@ -117,8 +117,8 @@ public class TexRender extends TextureRender {
public void drawPic(float x, float y, float width, float height, HudPosType dir, float alpha) {
Point2f point = AllMusicHud.getPos(width, height, x, y, dir);
RenderSystem.bindTexture(sourceTexture.getId());
RenderSystem.enableTexture();
RenderSystem.setShaderTexture(0, sourceTexture.getId());
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
RenderSystem.depthMask(false);
RenderSystem.enableBlend();
RenderSystem.depthFunc(GL30.GL_ALWAYS);
@@ -134,12 +134,12 @@ public class TexRender extends TextureRender {
float y1 = h1;
float z = 0;
float u0 = 0;
float u1 = width;
float u1 = 1;
float v0 = 0;
float v1 = 1;
BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder();
bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
bufferBuilder.begin(7, DefaultVertexFormat.POSITION_COLOR_TEX);
bufferBuilder.vertex(matrix, x0, y1, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u0, v1).endVertex();
bufferBuilder.vertex(matrix, x1, y1, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u1, v1).endVertex();
bufferBuilder.vertex(matrix, x1, y0, z).color(1.0f, 1.0f, 1.0f, alpha).uv(u1, v0).endVertex();
@@ -1,6 +1,8 @@
package com.coloryr.allmusic.client.mixins;
import com.coloryr.allmusic.client.AllMusicClient;
import com.coloryr.allmusic.client.core.AllMusicCore;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.Gui;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -10,7 +12,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Gui.class)
public class GuiShow {
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Inventory;getArmor(I)Lnet/minecraft/world/item/ItemStack;"))
public void Gui(CallbackInfo info) {
public void Gui(PoseStack poseStack, float partialTick, CallbackInfo info) {
AllMusicClient.update(poseStack);
AllMusicCore.hudUpdate();
}
}
}
@@ -57,10 +57,9 @@ public class AllMusicClient implements AllMusicBridge {
evt.getModConfigurationDirectory().mkdirs();
}
AllMusicCore.init(evt.getModConfigurationDirectory().toPath(), this);
AllMusicCore.glInit();
MinecraftForge.EVENT_BUS.register(this);
try {
Class<?> server = Class.forName("com.coloryr.allmusic.server.AllMusicForge");
Class<?> server = Class.forName("com.coloryr.allmusic.server.AllMusicServer");
Field m = server.getField("channel");
FMLEventChannel channel = (FMLEventChannel) m.get(null);
channel.register(this);
@@ -185,6 +185,93 @@ public class CoreRenderTarget extends TextFrameBuffer {
draw(alpha, startX, startY, maxWidth, texHeight, texX + texOffset, texY, scale);
}
/**
* 正向百分比显示(从左开始显示,右边空白)
*
* @param alpha 透明度
* @param startX 起始X坐标(屏幕左上角)
* @param startY 起始Y坐标(屏幕左上角)
* @param texX 贴图左上角X
* @param texY 贴图左上角Y
* @param texWidth 贴图总宽度
* @param texHeight 贴图高度
* @param maxWidth 最大渲染宽度
* @param percent 百分比(0.0-1.0),表示显示的内容比例,例如0.4表示显示前面40%的内容
*/
public void drawByForwardPercent(float alpha, int startX, int startY,
int texX, int texY,
int texWidth, int texHeight,
int maxWidth, float percent, float scale) {
// 限制百分比范围
percent = Math.min(1.0f, Math.max(0.0f, percent));
// 如果要显示的内容为0,直接返回
if (percent <= 0) {
return;
}
// 计算要显示的内容宽度
int contentWidth = (int) (texWidth * percent);
// 实际渲染宽度
int renderWidth = Math.min(contentWidth, maxWidth);
// 屏幕偏移为0(靠左显示)
int screenOffset = 0;
// 贴图偏移为0(从左边开始)
int texOffset = 0;
// 渲染
draw(alpha, startX + screenOffset, startY,
renderWidth, texHeight,
texX + texOffset, texY, scale);
}
/**
* 反向百分比显示(从右开始显示,左边空白)
*
* @param alpha 透明度
* @param startX 起始X坐标(屏幕左上角)
* @param startY 起始Y坐标(屏幕左上角)
* @param texX 贴图左上角X
* @param texY 贴图左上角Y
* @param texWidth 贴图总宽度
* @param texHeight 贴图高度
* @param maxWidth 最大渲染宽度
* @param percent 百分比(0.0-1.0),表示显示的内容比例,例如0.4表示显示后面40%的内容
*/
public void drawByReversePercent(float alpha, int startX, int startY,
int texX, int texY,
int texWidth, int texHeight,
int maxWidth, float percent, float scale) {
// 限制百分比范围
percent = Math.min(1.0f, Math.max(0.0f, percent));
// 如果要显示的内容为0,直接返回
if (percent <= 0) {
return;
}
// 计算要显示的内容宽度
int contentWidth = (int) (texWidth * percent);
// 实际渲染宽度
int renderWidth = Math.min(contentWidth, maxWidth);
// 屏幕偏移(靠右显示)
int screenOffset = maxWidth - renderWidth;
// 贴图偏移(显示后面部分)
int texOffset = texWidth - contentWidth;
// 渲染
draw(alpha, startX + screenOffset, startY,
renderWidth, texHeight,
texX + texOffset, texY, scale);
}
@Override
public void draw(float alpha, int x, int y, int maxWidth, HudPosType dir) {
for (TextItem item : texts) {
@@ -75,13 +75,11 @@ public class CoreRenderTarget extends TextFrameBuffer {
return;
}
int width;
if (shadow) {
width = font.drawShadow(new PoseStack(), component, 0, 0, color);
} else {
width = font.draw(new PoseStack(), component, 0, 0, color);
}
// 使用 drawInBatch 将文字渲染到 CoreRenderTarget 自己的 buffer,
// 而不是 Font 内部的 buffer。这样 endBatch() 才能正确 flush 到当前 RenderTarget(FBO)。
int width = font.drawInBatch(component, 0, y, color, shadow,
new Matrix4f(), renderBuffers.bufferSource(),
false, 0, 15728880);
RenderSystem.disableDepthTest();
renderBuffers.bufferSource().endBatch();
@@ -122,10 +120,11 @@ public class CoreRenderTarget extends TextFrameBuffer {
float z = 0;
// 计算贴图区域UV
// 注意:1.16.5 的 FBO 纹理不需要 Y 轴翻转,纹理原点在左上角
float u0 = texX * scale / target.width;
float v0 = 1 - (texY * scale / target.height);
float v0 = texY * scale / target.height;
float u1 = (texX + width) * scale / target.width;
float v1 = 1 - ((texY + height) * scale / target.height);
float v1 = (texY + height) * scale / target.height;
BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder();
bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
@@ -1,15 +1,21 @@
package com.coloryr.allmusic.client;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.ByteBuffer;
import java.io.InputStream;
import java.util.List;
import com.coloryr.allmusic.client.core.AllMusicBridge;
import com.coloryr.allmusic.client.core.AllMusicCore;
import com.coloryr.allmusic.client.core.render.PictureFrameBuffer;
import com.coloryr.allmusic.client.core.render.TextFrameBuffer;
import com.coloryr.allmusic.client.core.render.TextureRender;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SoundCategory;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.resources.IResource;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.sound.PlaySoundEvent17;
import net.minecraftforge.common.MinecraftForge;
@@ -67,7 +73,7 @@ public class AllMusic implements AllMusicBridge {
List<Channel> list = sound1.allMusic_Client$getStreamingChannels();
ChannelLWJGLOpenAL channel = (ChannelLWJGLOpenAL) list.get(list.size() - 1);
AllMusicCore.init(new File("config").toPath(), this, channel.ALSource);
AllMusicCore.glInit();
AllMusicCore.renderInit();
}
@Mod.EventHandler
@@ -108,11 +114,6 @@ public class AllMusic implements AllMusicBridge {
AllMusicCore.onServerQuit();
}
@Override
public Object genTexture(int size) {
return AllMusicCore.genGLTexture(size);
}
public int getScreenWidth() {
Minecraft mc = Minecraft.getMinecraft();
ScaledResolution scaledresolution = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
@@ -133,17 +134,59 @@ public class AllMusic implements AllMusicBridge {
return Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT;
}
@Override
public void updateTexture(Object tex, int size, ByteBuffer byteBuffer) {
AllMusicCore.updateGLTexture((int) tex, size, byteBuffer);
}
@Override
public void stopPlayMusic() {
Minecraft.getMinecraft().getSoundHandler().stopSounds();
Minecraft.getMinecraft().getSoundHandler().stopSounds();
}
@Override
public TextFrameBuffer makeTextRender(String name) {
return new CoreRenderTarget();
}
@Override
public TextureRender makeTextureRender(String file) {
return new TexRender(file);
}
@Override
public PictureFrameBuffer makePictureRender(int size) {
return new PicRender(size);
}
@Override
public String readText(String file) {
try {
IResource resource = Minecraft.getMinecraft().getResourceManager()
.getResource(new ResourceLocation("allmusic_client", file));
InputStream inputStream = resource.getInputStream();
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
inputStream.close();
return result.toString("UTF-8");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
public InputStream readFile(String file) {
try {
IResource resource = Minecraft.getMinecraft().getResourceManager()
.getResource(new ResourceLocation("allmusic_client", file));
return resource.getInputStream();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onClientPacket(final FMLNetworkEvent.ClientCustomPacketEvent evt) {
@@ -0,0 +1,303 @@
package com.coloryr.allmusic.client;
import com.coloryr.allmusic.client.core.AllMusicHud;
import com.coloryr.allmusic.client.core.Point2f;
import com.coloryr.allmusic.client.core.render.TextFrameBuffer;
import com.coloryr.allmusic.codec.HudPosType;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.shader.Framebuffer;
import org.lwjgl.opengl.GL11;
public class CoreRenderTarget extends TextFrameBuffer {
private final Framebuffer target;
public CoreRenderTarget() {
target = new Framebuffer(800, 200, false);
target.setFramebufferColor(0.0f, 0.0f, 0.0f, 0.0f);
}
@Override
public void resize(int width, int height) {
Minecraft mc = Minecraft.getMinecraft();
ScaledResolution scaledresolution = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
nowWidth = (width * scaledresolution.getScaledWidth());
nowHeight = (height * scaledresolution.getScaledHeight());
if (nowWidth > target.framebufferWidth || nowHeight > target.framebufferHeight) {
target.createFramebuffer(nowWidth, nowHeight);
}
}
@Override
public void use() {
isDraw = true;
clear();
target.framebufferClear();
target.bindFramebuffer(true);
}
@Override
public void unUse() {
isDraw = false;
Minecraft minecraft = Minecraft.getMinecraft();
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(true);
}
@Override
public void drawText(String text, int y, int color, boolean shadow) {
Minecraft minecraft = Minecraft.getMinecraft();
ScaledResolution scaledresolution = new ScaledResolution(minecraft, minecraft.displayWidth, minecraft.displayHeight);
FontRenderer font = minecraft.fontRenderer;
int width;
if (shadow) {
width = font.drawStringWithShadow(text, 0, 0, color);
} else {
width = font.drawString(text, 0, 0, color);
}
TextItem item = new TextItem(width, font.FONT_HEIGHT + (shadow ? 1 : 0), y, (float) scaledresolution.getScaledWidth());
texts.add(item);
}
/**
* 渲染贴图的一部分到屏幕指定位置
*
* @param alpha 透明度
* @param x 屏幕X坐标(左上角)
* @param y 屏幕Y坐标(左上角)
* @param width 需要渲染的宽度
* @param height 需要渲染的高度
* @param texX 贴图左上角X坐标
* @param texY 贴图左上角Y坐标
* @param scale 贴图缩放
*/
private void draw(float alpha, float x, float y, float width, float height, float texX, float texY, float scale) {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, target.framebufferTexture);
GL11.glDepthMask(false);
GL11.glEnable(GL11.GL_BLEND);
float w = (width / 2);
float h = (height / 2);
GL11.glPushMatrix();
GL11.glTranslatef(x + w, y + h, 0.0f);
float x0 = -w;
float x1 = w;
float y0 = -h;
float y1 = h;
float z = 0;
// 计算贴图区域UV
float u0 = texX * scale / target.framebufferWidth;
float v0 = 1 - (texY * scale / target.framebufferHeight);
float u1 = (texX + width) * scale / target.framebufferWidth;
float v1 = 1 - ((texY + height) * scale / target.framebufferHeight);
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.setColorRGBA_F(1.0f, 1.0f, 1.0f, alpha);
tessellator.addVertexWithUV(x0, y1, z, u0, v1);
tessellator.addVertexWithUV(x1, y1, z, u1, v1);
tessellator.addVertexWithUV(x1, y0, z, u1, v0);
tessellator.addVertexWithUV(x0, y0, z, u0, v0);
tessellator.draw();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDepthMask(true);
GL11.glPopMatrix();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
}
public void drawLoop(float alpha, float x, float y,
float texX, float texY,
float textWidth, float textHeight,
int maxWidth, float offsetX, float scale) {
// 如果宽度不大于最大宽度,直接全部渲染
if (maxWidth == -1 || textWidth <= maxWidth) {
draw(alpha, x, y, textWidth, textHeight, texX, texY, scale);
return;
}
if (textWidth - offsetX < maxWidth) {
float nowWith = textWidth - offsetX;
draw(alpha, x, y, nowWith, textHeight, offsetX, texY, scale);
draw(alpha, x + nowWith, y, maxWidth - nowWith, textHeight, 0, texY, scale);
} else {
draw(alpha, x, y, maxWidth, textHeight, offsetX, texY, scale);
}
}
/**
* 居中百分比显示(根据百分比选择显示贴图的中间部分)
*
* @param alpha 透明度
* @param startX 起始X坐标(屏幕左上角)
* @param startY 起始Y坐标(屏幕左上角)
* @param texX 贴图左上角X
* @param texY 贴图左上角Y
* @param texWidth 贴图总宽度
* @param texHeight 贴图高度
* @param maxWidth 最大渲染宽度
* @param percent 百分比(0.0-1.0),0%显示左边,100%显示右边
*/
public void drawByPercent(float alpha, float startX, float startY,
float texX, float texY,
float texWidth, float texHeight,
int maxWidth, float percent, float scale) {
// 限制百分比范围
percent = Math.min(1.0f, Math.max(0.0f, percent));
// 如果贴图宽度小于等于最大宽度,直接全部显示
if (texWidth <= maxWidth) {
draw(alpha, startX, startY, (int) (texWidth * percent), texHeight, texX, texY, scale);
return;
}
// 计算贴图的起始位置(根据百分比)
float maxOffset = texWidth - maxWidth;
int texOffset = (int) (maxOffset * percent);
// 渲染
draw(alpha, startX, startY, maxWidth, texHeight, texX + texOffset, texY, scale);
}
/**
* 正向百分比显示(从左开始显示,右边空白)
*
* @param alpha 透明度
* @param startX 起始X坐标(屏幕左上角)
* @param startY 起始Y坐标(屏幕左上角)
* @param texX 贴图左上角X
* @param texY 贴图左上角Y
* @param texWidth 贴图总宽度
* @param texHeight 贴图高度
* @param maxWidth 最大渲染宽度
* @param percent 百分比(0.0-1.0),表示显示的内容比例,例如0.4表示显示前面40%的内容
*/
public void drawByForwardPercent(float alpha, int startX, int startY,
int texX, int texY,
int texWidth, int texHeight,
int maxWidth, float percent, float scale) {
// 限制百分比范围
percent = Math.min(1.0f, Math.max(0.0f, percent));
// 如果要显示的内容为0,直接返回
if (percent <= 0) {
return;
}
// 计算要显示的内容宽度
int contentWidth = (int) (texWidth * percent);
// 实际渲染宽度
int renderWidth = Math.min(contentWidth, maxWidth);
// 屏幕偏移为0(靠左显示)
int screenOffset = 0;
// 贴图偏移为0(从左边开始)
int texOffset = 0;
// 渲染
draw(alpha, startX + screenOffset, startY,
renderWidth, texHeight,
texX + texOffset, texY, scale);
}
/**
* 反向百分比显示(从右开始显示,左边空白)
*
* @param alpha 透明度
* @param startX 起始X坐标(屏幕左上角)
* @param startY 起始Y坐标(屏幕左上角)
* @param texX 贴图左上角X
* @param texY 贴图左上角Y
* @param texWidth 贴图总宽度
* @param texHeight 贴图高度
* @param maxWidth 最大渲染宽度
* @param percent 百分比(0.0-1.0),表示显示的内容比例,例如0.4表示显示后面40%的内容
*/
public void drawByReversePercent(float alpha, int startX, int startY,
int texX, int texY,
int texWidth, int texHeight,
int maxWidth, float percent, float scale) {
// 限制百分比范围
percent = Math.min(1.0f, Math.max(0.0f, percent));
// 如果要显示的内容为0,直接返回
if (percent <= 0) {
return;
}
// 计算要显示的内容宽度
int contentWidth = (int) (texWidth * percent);
// 实际渲染宽度
int renderWidth = Math.min(contentWidth, maxWidth);
// 屏幕偏移(靠右显示)
int screenOffset = maxWidth - renderWidth;
// 贴图偏移(显示后面部分)
int texOffset = texWidth - contentWidth;
// 渲染
draw(alpha, startX + screenOffset, startY,
renderWidth, texHeight,
texX + texOffset, texY, scale);
}
@Override
public void draw(float alpha, int x, int y, int maxWidth, HudPosType dir) {
for (TextItem item : texts) {
Point2f point = AllMusicHud.getPos(Math.min(maxWidth, item.textWidth), item.textHeight, x, y, dir);
drawLoop(alpha, point.x, point.y + item.y, 0, item.y, item.textWidth, item.textHeight, maxWidth, getOffset(item) % item.textWidth, item.scale);
}
}
@Override
public void drawLine(float x, float y, float alpha, int line) {
if (line >= texts.size()) {
return;
}
TextItem item = texts.get(line);
draw(alpha, x, y, item.textWidth, item.textHeight, 0, item.y, item.scale);
}
@Override
public Point2f getLine(int line) {
if (line >= texts.size()) {
return new Point2f(0, 0);
}
TextItem item = texts.get(line);
return new Point2f(item.textWidth, item.textHeight);
}
@Override
public void drawWithState(float alpha, int x, int y, int maxWidth, float state, HudPosType dir) {
for (TextItem item : texts) {
Point2f point = AllMusicHud.getPos(Math.min(maxWidth, item.textWidth), item.textHeight, x, y, dir);
drawByPercent(alpha, point.x, point.y + item.y, 0, item.y, item.textWidth, item.textHeight, maxWidth, state, item.scale);
}
}
}
@@ -0,0 +1,83 @@
package com.coloryr.allmusic.client;
import com.coloryr.allmusic.client.core.AllMusicHud;
import com.coloryr.allmusic.client.core.Point2f;
import com.coloryr.allmusic.client.core.render.PictureFrameBuffer;
import com.coloryr.allmusic.codec.HudPosType;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.DynamicTexture;
import org.lwjgl.opengl.GL11;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
public class PicRender extends PictureFrameBuffer {
private final DynamicTexture sourceTexture;
private final DynamicTexture rotateTexture;
public PicRender(int size) {
sourceTexture = new DynamicTexture(size, size);
rotateTexture = new DynamicTexture(size, size);
}
@Override
public void update(byte[] source, byte[] rotate) {
try {
ByteArrayInputStream stream = new ByteArrayInputStream(source);
BufferedImage image = ImageIO.read(stream);
image.getRGB(0, 0, image.getWidth(), image.getHeight(), sourceTexture.getTextureData(), 0, image.getWidth());
sourceTexture.updateDynamicTexture();
stream = new ByteArrayInputStream(rotate);
image = ImageIO.read(stream);
image.getRGB(0, 0, image.getWidth(), image.getHeight(), rotateTexture.getTextureData(), 0, image.getWidth());
rotateTexture.updateDynamicTexture();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void draw(boolean rotate, int size, float x, float y, int ang, HudPosType dir, float alpha) {
Point2f point = AllMusicHud.getPos(size, size, x, y, dir);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, rotate ? rotateTexture.getGlTextureId() : sourceTexture.getGlTextureId());
GL11.glDepthMask(false);
GL11.glEnable(GL11.GL_BLEND);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
int a = size / 2;
GL11.glPushMatrix();
GL11.glTranslatef(point.x + a, point.y + a, 0.0f);
if (ang > 0) {
GL11.glRotatef(ang, 0, 0, 1f);
}
int x0 = -a;
int x1 = a;
int y0 = -a;
int y1 = a;
int z = 0;
float u0 = 0;
float u1 = 1;
float v0 = 0;
float v1 = 1;
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.setColorRGBA_F(1.0f, 1.0f, 1.0f, alpha);
tessellator.addVertexWithUV(x0, y1, z, u0, v1);
tessellator.addVertexWithUV(x1, y1, z, u1, v1);
tessellator.addVertexWithUV(x1, y0, z, u1, v0);
tessellator.addVertexWithUV(x0, y0, z, u0, v0);
tessellator.draw();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDepthMask(true);
GL11.glPopMatrix();
}
}
@@ -0,0 +1,192 @@
package com.coloryr.allmusic.client;
import com.coloryr.allmusic.client.core.AllMusicHud;
import com.coloryr.allmusic.client.core.Point2f;
import com.coloryr.allmusic.client.core.render.TextureRender;
import com.coloryr.allmusic.codec.HudPosType;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.SimpleTexture;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.data.TextureMetadataSection;
import net.minecraft.util.ResourceLocation;
import org.apache.commons.io.IOUtils;
import org.lwjgl.opengl.GL11;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
public class TexRender extends TextureRender {
private final Tex sourceTexture;
public TexRender(String texture) {
super(texture);
ResourceLocation location = new ResourceLocation("allmusic_client", texture);
sourceTexture = new Tex(location);
try {
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
sourceTexture.loadTexture(resourceManager, this);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void drawPic(float x, float y, float alpha) {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, sourceTexture.getGlTextureId());
GL11.glDepthMask(false);
GL11.glEnable(GL11.GL_BLEND);
float w1 = (float) width / 2;
float h1 = (float) height / 2;
GL11.glPushMatrix();
GL11.glTranslatef(x + w1, y + h1, 0.0f);
float x0 = -w1;
float x1 = w1;
float y0 = -h1;
float y1 = h1;
float z = 0;
float u0 = 0;
float u1 = 1;
float v0 = 0;
float v1 = 1;
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.setColorRGBA_F(1.0f, 1.0f, 1.0f, alpha);
tessellator.addVertexWithUV(x0, y1, z, u0, v1);
tessellator.addVertexWithUV(x1, y1, z, u1, v1);
tessellator.addVertexWithUV(x1, y0, z, u1, v0);
tessellator.addVertexWithUV(x0, y0, z, u0, v0);
tessellator.draw();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDepthMask(true);
GL11.glPopMatrix();
}
@Override
public void drawPic(float x, float y, float width, float alpha) {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, sourceTexture.getGlTextureId());
GL11.glDepthMask(false);
GL11.glEnable(GL11.GL_BLEND);
float w1 = (float) (this.width / 2) * width;
float h1 = (float) height / 2;
GL11.glPushMatrix();
GL11.glTranslatef(x + w1, y + h1, 0.0f);
float x0 = -w1;
float x1 = w1;
float y0 = -h1;
float y1 = h1;
float z = 0;
float u0 = 0;
float u1 = width;
float v0 = 0;
float v1 = 1;
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.setColorRGBA_F(1.0f, 1.0f, 1.0f, alpha);
tessellator.addVertexWithUV(x0, y1, z, u0, v1);
tessellator.addVertexWithUV(x1, y1, z, u1, v1);
tessellator.addVertexWithUV(x1, y0, z, u1, v0);
tessellator.addVertexWithUV(x0, y0, z, u0, v0);
tessellator.draw();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDepthMask(true);
GL11.glPopMatrix();
}
@Override
public void drawPic(float x, float y, float width, float height, HudPosType dir, float alpha) {
Point2f point = AllMusicHud.getPos(width, height, x, y, dir);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, sourceTexture.getGlTextureId());
GL11.glDepthMask(false);
GL11.glEnable(GL11.GL_BLEND);
float w1 = width / 2;
float h1 = height / 2;
GL11.glPushMatrix();
GL11.glTranslatef(point.x + w1, point.y + h1, 0.0f);
float x0 = -w1;
float x1 = w1;
float y0 = -h1;
float y1 = h1;
float z = 0;
float u0 = 0;
float u1 = width;
float v0 = 0;
float v1 = 1;
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.setColorRGBA_F(1.0f, 1.0f, 1.0f, alpha);
tessellator.addVertexWithUV(x0, y1, z, u0, v1);
tessellator.addVertexWithUV(x1, y1, z, u1, v1);
tessellator.addVertexWithUV(x1, y0, z, u1, v0);
tessellator.addVertexWithUV(x0, y0, z, u0, v0);
tessellator.draw();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDepthMask(true);
GL11.glPopMatrix();
}
public static class Tex extends SimpleTexture {
public Tex(ResourceLocation resourceLocation) {
super(resourceLocation);
}
public void loadTexture(IResourceManager resourceManager, TexRender render) throws IOException {
this.deleteGlTexture();
IResource iresource = null;
InputStream inputstream = null;
try {
iresource = resourceManager.getResource(this.textureLocation);
inputstream = iresource.getInputStream();
BufferedImage bufferedimage = ImageIO.read(inputstream);
render.width = bufferedimage.getWidth();
render.height = bufferedimage.getHeight();
boolean flag = false;
boolean flag1 = false;
if (iresource.hasMetadata()) {
try {
TextureMetadataSection texturemetadatasection = (TextureMetadataSection) iresource.getMetadata("texture");
if (texturemetadatasection != null) {
flag = texturemetadatasection.getTextureBlur();
flag1 = texturemetadatasection.getTextureClamp();
}
} catch (Exception e) {
e.printStackTrace();
}
}
TextureUtil.uploadTextureImageAllocate(this.getGlTextureId(), bufferedimage, flag, flag1);
} finally {
IOUtils.closeQuietly(inputstream);
}
}
}
}
+40
View File
@@ -0,0 +1,40 @@
subprojects {
val shadowImplementation by configurations.getting
dependencies {
shadowImplementation(project(":client"))
shadowImplementation(project(":codec"))
shadowImplementation(project(":server"))
}
tasks {
shadowJar {
configurations = listOf(project.configurations.shadow.get())
}
}
}
dependencies {
shadowImplementation(project(":codec"))
shadowImplementation("org.apache.httpcomponents.client5:httpclient5:${Versions.httpclient5}")
shadowImplementation("org.apache.httpcomponents.core5:httpcore5:${Versions.httpcore5}")
shadowImplementation("org.apache.httpcomponents.core5:httpcore5-h2:${Versions.httpcore5_h2}")
compileOnly("com.google.code.gson:gson:${Versions.gson}")
compileOnly("net.kyori:adventure-text-minimessage:${Versions.minimessage}")
compileOnly("org.lwjgl.lwjgl:lwjgl:2.9.3")
compileOnly("org.apache.logging.log4j:log4j-core:2.25.4")
}
tasks.register("buildOnJar") {
group = "build"
dependsOn(rootProject.subprojects.filter { it.path.startsWith(":onejar:") }
.map { it.tasks.named("build") })
}
tasks {
clean {
delete("$projectDir/../build")
}
}
+67
View File
@@ -0,0 +1,67 @@
plugins {
id("fabric-loom") version Versions.fabricLoom
}
// 直接引用 client 和 server 模块的源码目录,无需手动复制
val clientSourceDir = project(":client:fabric_1_16_5").projectDir.resolve("src/main/java")
val serverSourceDir = project(":server:fabric_1_16_5").projectDir.resolve("src/main/java")
val clientResDir = project(":client:fabric_1_16_5").projectDir.resolve("src/main/resources")
val serverResDir = project(":server:fabric_1_16_5").projectDir.resolve("src/main/resources")
sourceSets {
main {
java {
setSrcDirs(listOf(clientSourceDir, serverSourceDir))
}
resources {
setSrcDirs(listOf(
file("src/main/resources"), // onejar 自己的合并资源(fabric.mod.json)
clientResDir,
serverResDir
))
}
}
}
dependencies {
minecraft("com.mojang:minecraft:1.16.5")
mappings(loom.officialMojangMappings())
modCompileOnly("net.fabricmc:fabric-loader:0.18.5")
modCompileOnly("net.fabricmc.fabric-api:fabric-api:0.42.0+1.16")
modImplementation(include("net.kyori:examination-api:1.3.0")!!)
modImplementation(include("net.kyori:examination-string:1.3.0")!!)
modImplementation(include("net.kyori:adventure-platform-api:4.0.0")!!)
modImplementation(include("net.kyori:adventure-text-serializer-gson:4.9.3")!!)
modImplementation(include("net.kyori:adventure-text-serializer-legacy:4.9.3")!!)
modImplementation(include("net.kyori:adventure-text-serializer-plain:4.9.3")!!)
modImplementation(include("net.kyori:adventure-text-minimessage:4.26.1")!!)
modImplementation(include("net.kyori:adventure-api:4.26.1")!!)
modImplementation(include("net.kyori:adventure-key:4.26.1")!!)
}
tasks {
processResources {
// onejar 自己的 fabric.mod.json 优先(排在 srcDirs 第一位),
// client/server 的 fabric.mod.json 作为重复项被排除
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
filesMatching("fabric.mod.json") {
expand(
"version" to project.version
)
}
}
remapJar {
inputFile.set(shadowJar.get().archiveFile)
archiveFileName.set("[fabric-1.16.5]AllMusic-${project.version}.jar")
destinationDirectory.set(file("${parent!!.projectDir}/../build"))
}
build {
dependsOn(remapJar)
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

@@ -0,0 +1,41 @@
{
"schemaVersion": 1,
"id": "allmusic_client",
"version": "${version}",
"name": "AllMusic Client",
"description": "AllMusic Client Mod",
"authors": [
"Color_yr"
],
"contact": {
"homepage": "https://github.com/Coloryr/AllMusic",
"sources": "https://github.com/Coloryr/AllMusic"
},
"license": "GPL-3.0",
"icon": "assets/allmusic/icon.png",
"environment": "*",
"entrypoints": {
"main": [
"com.coloryr.allmusic.server.AllMusicServer",
"com.coloryr.allmusic.server.adventure.impl.AdventureCommon"
],
"preLaunch": [
"com.coloryr.allmusic.server.adventure.impl.AdventurePrelaunch"
],
"client": [
"com.coloryr.allmusic.client.AllMusicClient"
]
},
"mixins": [
"allmusic_client.mixins.json",
"allmusic_server.mixins.json",
"adventure-platform-fabric.accessor.mixins.json",
"adventure-platform-fabric.mixins.json"
],
"depends": {
"fabricloader": ">=0.15.11",
"fabric": "*",
"minecraft": ">=1.16"
},
"suggests": {}
}
@@ -2,7 +2,7 @@ package com.coloryr.allmusic.server;
import com.coloryr.allmusic.server.adventure.FabricServerAudiences;
import com.coloryr.allmusic.server.core.AllMusic;
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.resources.ResourceLocation;
@@ -12,14 +12,14 @@ import org.apache.logging.log4j.Logger;
import java.io.File;
public class AllMusicServer implements DedicatedServerModInitializer {
public class AllMusicServer implements ModInitializer {
public static final Logger LOGGER = LogManager.getLogger("AllMusic Server");
public static final ResourceLocation ID = new ResourceLocation("allmusic", "channel");
public static MinecraftServer server;
public static FabricServerAudiences audiences;
@Override
public void onInitializeServer() {
public void onInitialize() {
AllMusic.log = new LogFabric();
AllMusic.side = new SideFabric();
@@ -15,10 +15,8 @@
"icon": "assets/allmusic_server/icon.png",
"environment": "*",
"entrypoints": {
"server": [
"com.coloryr.allmusic.server.AllMusicServer"
],
"main": [
"com.coloryr.allmusic.server.AllMusicServer",
"com.coloryr.allmusic.server.adventure.impl.AdventureCommon"
],
"preLaunch": [
@@ -4,7 +4,7 @@ import com.coloryr.allmusic.server.core.AllMusic;
import com.coloryr.allmusic.server.core.music.PlayMusic;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minecraft.command.ServerCommandManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.common.MinecraftForge;
@@ -56,8 +56,7 @@ public class AllMusicServer {
public void onServerStarting(FMLServerStartingEvent event) {
server = event.getServer();
ServerCommandManager commandManager = (ServerCommandManager) server.commandManager;
commandManager.registerCommand(new CommandForge());
event.registerServerCommand(new CommandForge());
}
@Mod.EventHandler
@@ -364,6 +364,9 @@ public class AllMusic {
* @param player 用户名
*/
public static void joinPlay(String player) {
if (AllMusic.side == null) {
return;
}
AllMusic.side.runTask(() -> joinPlayNow(player), AllMusic.config.joinDelay);
}
+8 -3
View File
@@ -3,6 +3,7 @@ rootProject.name = "AllMusic"
include(":codec")
include(":client")
include(":client:fabric_1_16_5")
include(":client:fabric_1_20_1")
include(":client:fabric_1_21")
@@ -13,10 +14,12 @@ include(":client:fabric_1_21_8")
include(":client:fabric_1_21_11")
include(":client:fabric_26_1")
include(":client:fabric_26_2")
//include(":client:forge_1_7_10")
//include(":client:forge_1_12_2")
include(":client:forge_1_7_10")
include(":client:forge_1_12_2")
include(":client:forge_1_16_5")
include(":client:forge_1_20_1")
include(":client:neoforge_1_21")
include(":client:neoforge_1_21_3")
include(":client:neoforge_1_21_4")
@@ -54,6 +57,8 @@ include(":server:velocity")
include(":onejar")
include(":onejar:fabric_1_16_5")
pluginManagement {
repositories {
mavenCentral()
@@ -64,4 +69,4 @@ pluginManagement {
maven("https://maven.architectury.dev/")
maven("https://nexus.gtnewhorizons.com/repository/public/")
}
}
}