Skip to content

Commit 9b831c1

Browse files
committed
1.21.10 port
1 parent 9698619 commit 9b831c1

File tree

13 files changed

+1123
-32
lines changed

13 files changed

+1123
-32
lines changed

MINECRAFT_1.21.10_GUIDE.md

Lines changed: 533 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ Advanced Twitch chat integration for Minecraft. Show chat messages in 3D or as a
5050
./gradlew build
5151
```
5252

53+
## Development
54+
55+
For developers working on this mod:
56+
57+
- **[MINECRAFT_1.21.10_GUIDE.md](MINECRAFT_1.21.10_GUIDE.md)** - Complete guide for Minecraft 1.21.10 update
58+
- API changes and fixes
59+
- Custom rendering system
60+
- Usage examples
61+
- Troubleshooting
62+
5363
## License
5464

5565
MIT License. See `LICENSE` for details.

gradle.properties

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ org.gradle.parallel=true
44

55
# Fabric Properties
66
# check these on https://fabricmc.net/develop
7-
minecraft_version=1.21.7
8-
yarn_mappings=1.21.7+build.6
9-
loader_version=0.16.14
7+
minecraft_version=1.21.10
8+
yarn_mappings=1.21.10+build.2
9+
loader_version=0.17.3
1010
loom_version=1.11-SNAPSHOT
1111

1212
# Mod Properties
@@ -15,4 +15,4 @@ maven_group=takeyourminestream.modid
1515
archives_base_name=tyms
1616

1717
# Dependencies
18-
fabric_version=0.129.0+1.21.7
18+
fabric_version=0.137.0+1.21.10

src/client/java/takeyourminestream/modid/BanwordConfigScreen.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,11 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
138138
}
139139

140140
@Override
141-
public boolean mouseClicked(double mouseX, double mouseY, int button) {
141+
public boolean mouseClicked(net.minecraft.client.gui.Click click, boolean rightClick) {
142+
double mouseX = click.x();
143+
double mouseY = click.y();
144+
int button = click.button();
145+
142146
if (button == 0) {
143147
int top = 40;
144148
int bottom = this.height - 60;
@@ -175,7 +179,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) {
175179
y += LINE_HEIGHT;
176180
}
177181
}
178-
return super.mouseClicked(mouseX, mouseY, button);
182+
return super.mouseClicked(click, rightClick);
179183
}
180184

181185
@Override

src/client/java/takeyourminestream/modid/input/KeyBindingManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void registerKeyBindings() {
2929
"key.takeyourminestream.openconfig",
3030
InputUtil.Type.KEYSYM,
3131
GLFW.GLFW_KEY_RIGHT_BRACKET, // Клавиша ']'
32-
"category.takeyourminestream.general"
32+
KeyBinding.Category.MISC
3333
));
3434

3535
// Обработка нажатия клавиш

src/client/java/takeyourminestream/modid/messages/MessagePosition.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static Vec3d generateRandomPosition(MinecraftClient client) {
2020
}
2121

2222
Random random = client.world.random;
23-
Vec3d playerPos = client.player.getPos();
23+
Vec3d playerPos = client.player.getEyePos();
2424

2525
// Генерируем случайный угол и радиус
2626
double angle = random.nextDouble() * 2 * Math.PI;

src/client/java/takeyourminestream/modid/messages/MessageRenderer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package takeyourminestream.modid.messages;
22

3-
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
3+
import net.fabricmc.fabric.api.client.rendering.v1.world.WorldRenderEvents;
44
import net.minecraft.client.MinecraftClient;
55
import net.minecraft.client.font.TextRenderer;
66
import net.minecraft.client.render.VertexConsumerProvider;
@@ -51,7 +51,7 @@ public MessageRenderer(MessageLifecycleManager lifecycleManager, MessageParticle
5151
return;
5252
}
5353

54-
MatrixStack matrices = context.matrixStack();
54+
MatrixStack matrices = context.matrices();
5555
TextRenderer textRenderer = client.textRenderer;
5656
VertexConsumerProvider consumers = context.consumers();
5757

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package takeyourminestream.modid.mixin.client;
2+
3+
import net.minecraft.client.render.GameRenderer;
4+
import org.spongepowered.asm.mixin.Mixin;
5+
import org.spongepowered.asm.mixin.injection.At;
6+
import org.spongepowered.asm.mixin.injection.Inject;
7+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
8+
import takeyourminestream.modid.rendering.CustomRenderPipeline;
9+
10+
/**
11+
* Mixin для очистки ресурсов кастомного рендер-пайплайна
12+
*/
13+
@Mixin(GameRenderer.class)
14+
public class GameRendererMixin {
15+
16+
@Inject(method = "close", at = @At("TAIL"))
17+
private void onClose(CallbackInfo ci) {
18+
CustomRenderPipeline instance = CustomRenderPipeline.getInstance();
19+
if (instance != null) {
20+
instance.close();
21+
}
22+
}
23+
}
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
package takeyourminestream.modid.rendering;
2+
3+
import java.util.OptionalDouble;
4+
import java.util.OptionalInt;
5+
6+
import com.mojang.blaze3d.buffers.GpuBuffer;
7+
import com.mojang.blaze3d.buffers.GpuBufferSlice;
8+
import com.mojang.blaze3d.pipeline.RenderPipeline;
9+
import com.mojang.blaze3d.platform.DepthTestFunction;
10+
import com.mojang.blaze3d.systems.CommandEncoder;
11+
import com.mojang.blaze3d.systems.RenderPass;
12+
import com.mojang.blaze3d.systems.RenderSystem;
13+
import com.mojang.blaze3d.vertex.VertexFormat;
14+
import org.joml.Vector3f;
15+
import org.joml.Vector4f;
16+
import org.lwjgl.system.MemoryUtil;
17+
18+
import net.minecraft.client.MinecraftClient;
19+
import net.minecraft.client.gl.MappableRingBuffer;
20+
import net.minecraft.client.gl.RenderPipelines;
21+
import net.minecraft.client.render.BufferBuilder;
22+
import net.minecraft.client.render.BuiltBuffer;
23+
import net.minecraft.client.render.RenderLayer;
24+
import net.minecraft.client.render.VertexFormats;
25+
import net.minecraft.client.render.VertexRendering;
26+
import net.minecraft.client.util.BufferAllocator;
27+
import net.minecraft.client.util.math.MatrixStack;
28+
import net.minecraft.util.Identifier;
29+
import net.minecraft.util.math.Vec3d;
30+
31+
import net.fabricmc.api.ClientModInitializer;
32+
import net.fabricmc.fabric.api.client.rendering.v1.world.WorldRenderContext;
33+
import net.fabricmc.fabric.api.client.rendering.v1.world.WorldRenderEvents;
34+
35+
/**
36+
* Пример кастомного рендер-пайплайна для Minecraft 1.21.1+
37+
* Рендерит waypoint через стены
38+
*/
39+
public class CustomRenderPipeline implements ClientModInitializer {
40+
private static CustomRenderPipeline instance;
41+
42+
// Определяем кастомный рендер-пайплайн
43+
private static final RenderPipeline FILLED_THROUGH_WALLS = RenderPipelines.register(
44+
RenderPipeline.builder(RenderPipelines.POSITION_COLOR_SNIPPET)
45+
.withLocation(Identifier.of("take-your-minestream", "pipeline/debug_filled_box_through_walls"))
46+
.withVertexFormat(VertexFormats.POSITION_COLOR, VertexFormat.DrawMode.TRIANGLE_STRIP)
47+
.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST)
48+
.build()
49+
);
50+
51+
// Фаза extraction
52+
private static final BufferAllocator allocator = new BufferAllocator(RenderLayer.CUTOUT_BUFFER_SIZE);
53+
private BufferBuilder buffer;
54+
55+
// Фаза drawing
56+
private static final Vector4f COLOR_MODULATOR = new Vector4f(1f, 1f, 1f, 1f);
57+
private MappableRingBuffer vertexBuffer;
58+
59+
public static CustomRenderPipeline getInstance() {
60+
return instance;
61+
}
62+
63+
@Override
64+
public void onInitializeClient() {
65+
instance = this;
66+
WorldRenderEvents.AFTER_ENTITIES.register(this::extractAndDrawWaypoint);
67+
}
68+
69+
private void extractAndDrawWaypoint(WorldRenderContext context) {
70+
renderWaypoint(context);
71+
drawFilledThroughWalls(MinecraftClient.getInstance(), FILLED_THROUGH_WALLS);
72+
}
73+
74+
/**
75+
* Фаза extraction - добавляем waypoint в буфер
76+
*/
77+
private void renderWaypoint(WorldRenderContext context) {
78+
MatrixStack matrices = context.matrices();
79+
MinecraftClient client = MinecraftClient.getInstance();
80+
Vec3d camera = client.gameRenderer.getCamera().getPos();
81+
82+
assert matrices != null;
83+
matrices.push();
84+
matrices.translate(-camera.x, -camera.y, -camera.z);
85+
86+
if (buffer == null) {
87+
buffer = new BufferBuilder(allocator, FILLED_THROUGH_WALLS.getVertexFormatMode(), FILLED_THROUGH_WALLS.getVertexFormat());
88+
}
89+
90+
// Рендерим зеленый куб на координатах (0, 100, 0)
91+
VertexRendering.drawFilledBox(matrices, buffer, 0f, 100f, 0f, 1f, 101f, 1f, 0f, 1f, 0f, 0.5f);
92+
93+
matrices.pop();
94+
}
95+
96+
/**
97+
* Фаза drawing - отрисовываем буфер на экран
98+
*/
99+
private void drawFilledThroughWalls(MinecraftClient client, RenderPipeline pipeline) {
100+
// Строим буфер
101+
BuiltBuffer builtBuffer = buffer.end();
102+
BuiltBuffer.DrawParameters drawParameters = builtBuffer.getDrawParameters();
103+
VertexFormat format = drawParameters.format();
104+
105+
GpuBuffer vertices = upload(drawParameters, format, builtBuffer);
106+
107+
draw(client, pipeline, builtBuffer, drawParameters, vertices, format);
108+
109+
// Ротируем vertex buffer чтобы избежать конфликтов с GPU
110+
vertexBuffer.rotate();
111+
buffer = null;
112+
}
113+
114+
private GpuBuffer upload(BuiltBuffer.DrawParameters drawParameters, VertexFormat format, BuiltBuffer builtBuffer) {
115+
// Вычисляем размер vertex buffer
116+
int vertexBufferSize = drawParameters.vertexCount() * format.getVertexSize();
117+
118+
// Инициализируем или изменяем размер vertex buffer
119+
if (vertexBuffer == null || vertexBuffer.size() < vertexBufferSize) {
120+
vertexBuffer = new MappableRingBuffer(
121+
() -> "take-your-minestream example render pipeline",
122+
GpuBuffer.USAGE_VERTEX | GpuBuffer.USAGE_MAP_WRITE,
123+
vertexBufferSize
124+
);
125+
}
126+
127+
// Копируем данные вершин в vertex buffer
128+
CommandEncoder commandEncoder = RenderSystem.getDevice().createCommandEncoder();
129+
130+
try (GpuBuffer.MappedView mappedView = commandEncoder.mapBuffer(
131+
vertexBuffer.getBlocking().slice(0, builtBuffer.getBuffer().remaining()), false, true)) {
132+
MemoryUtil.memCopy(builtBuffer.getBuffer(), mappedView.data());
133+
}
134+
135+
return vertexBuffer.getBlocking();
136+
}
137+
138+
private static void draw(MinecraftClient client, RenderPipeline pipeline, BuiltBuffer builtBuffer,
139+
BuiltBuffer.DrawParameters drawParameters, GpuBuffer vertices, VertexFormat format) {
140+
GpuBuffer indices;
141+
VertexFormat.IndexType indexType;
142+
143+
if (pipeline.getVertexFormatMode() == VertexFormat.DrawMode.QUADS) {
144+
// Сортируем квады если есть прозрачность
145+
builtBuffer.sortQuads(allocator, RenderSystem.getProjectionType().getVertexSorter());
146+
// Загружаем index buffer
147+
indices = pipeline.getVertexFormat().uploadImmediateIndexBuffer(builtBuffer.getSortedBuffer());
148+
indexType = builtBuffer.getDrawParameters().indexType();
149+
} else {
150+
// Используем общий shape index buffer для не-quad режимов
151+
RenderSystem.ShapeIndexBuffer shapeIndexBuffer = RenderSystem.getSequentialBuffer(pipeline.getVertexFormatMode());
152+
indices = shapeIndexBuffer.getIndexBuffer(drawParameters.indexCount());
153+
indexType = shapeIndexBuffer.getIndexType();
154+
}
155+
156+
// Выполняем отрисовку
157+
GpuBufferSlice dynamicTransforms = RenderSystem.getDynamicUniforms()
158+
.write(RenderSystem.getModelViewMatrix(), COLOR_MODULATOR, new Vector3f(), RenderSystem.getTextureMatrix(), 1f);
159+
160+
try (RenderPass renderPass = RenderSystem.getDevice()
161+
.createCommandEncoder()
162+
.createRenderPass(
163+
() -> "take-your-minestream example render pipeline rendering",
164+
client.getFramebuffer().getColorAttachmentView(),
165+
OptionalInt.empty(),
166+
client.getFramebuffer().getDepthAttachmentView(),
167+
OptionalDouble.empty()
168+
)) {
169+
renderPass.setPipeline(pipeline);
170+
171+
RenderSystem.bindDefaultUniforms(renderPass);
172+
renderPass.setUniform("DynamicTransforms", dynamicTransforms);
173+
174+
// Привязываем текстуру если нужно:
175+
// Sampler0 используется для текстурных входов в вершинах
176+
// renderPass.bindSampler("Sampler0", textureView);
177+
178+
renderPass.setVertexBuffer(0, vertices);
179+
renderPass.setIndexBuffer(indices, indexType);
180+
181+
// Base vertex - это начальный индекс когда мы копировали данные в vertex buffer деленный на размер вершины
182+
renderPass.drawIndexed(0 / format.getVertexSize(), 0, drawParameters.indexCount(), 1);
183+
}
184+
185+
builtBuffer.close();
186+
}
187+
188+
/**
189+
* Очистка ресурсов - должна вызываться при закрытии GameRenderer
190+
*/
191+
public void close() {
192+
allocator.close();
193+
194+
if (vertexBuffer != null) {
195+
vertexBuffer.close();
196+
vertexBuffer = null;
197+
}
198+
}
199+
}

0 commit comments

Comments
 (0)