Skip to content

Commit 7537fe8

Browse files
committed
Rewrite PanoramaRendererUtility
1 parent 4694f08 commit 7537fe8

File tree

2 files changed

+138
-70
lines changed

2 files changed

+138
-70
lines changed

src/main/java/org/visuals/legacy/animatium/mixins/v1/gui/MixinPanoramaRenderer_LegacyRendering.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,12 @@
4545
public abstract class MixinPanoramaRenderer_LegacyRendering {
4646
@WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/CubeMap;render(Lnet/minecraft/client/Minecraft;FF)V", ordinal = 0))
4747
private void animatium$panoramaRendering(CubeMap instance, Minecraft minecraft, float xRot, float yRot, Operation<Void> original, @Local(argsOnly = true) GuiGraphics guiGraphics, @Local(argsOnly = true, ordinal = 0) int width, @Local(argsOnly = true, ordinal = 1) int height) {
48-
final boolean enabled = Animatium.ENABLED && AnimatiumConfig.instance().screen.panoramaRendering;
49-
final RenderTarget renderTarget = minecraft.getMainRenderTarget();
50-
if (enabled) {
51-
PanoramaRendererUtility.setup(renderTarget);
48+
if (Animatium.ENABLED && AnimatiumConfig.instance().screen.panoramaRendering) {
49+
final RenderTarget renderTarget = minecraft.getMainRenderTarget();
5250
PanoramaRendererUtility.update(minecraft.getDeltaTracker().getRealtimeDeltaTicks());
53-
xRot = PanoramaRendererUtility.getXRot();
54-
yRot = PanoramaRendererUtility.getYRot();
55-
}
56-
57-
original.call(instance, minecraft, xRot, yRot);
58-
if (enabled) {
5951
PanoramaRendererUtility.render(guiGraphics, renderTarget, width, height);
52+
} else {
53+
original.call(instance, minecraft, xRot, yRot);
6054
}
6155
}
6256

src/main/java/org/visuals/legacy/animatium/util/PanoramaRendererUtility.java

Lines changed: 134 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -25,130 +25,202 @@
2525

2626
package org.visuals.legacy.animatium.util;
2727

28+
import com.mojang.blaze3d.ProjectionType;
29+
import com.mojang.blaze3d.buffers.GpuBufferSlice;
2830
import com.mojang.blaze3d.opengl.GlDevice;
2931
import com.mojang.blaze3d.opengl.GlStateManager;
3032
import com.mojang.blaze3d.opengl.GlTexture;
31-
import com.mojang.blaze3d.opengl.GlTextureView;
3233
import com.mojang.blaze3d.pipeline.BlendFunction;
3334
import com.mojang.blaze3d.pipeline.RenderPipeline;
3435
import com.mojang.blaze3d.pipeline.RenderTarget;
3536
import com.mojang.blaze3d.platform.DestFactor;
3637
import com.mojang.blaze3d.platform.SourceFactor;
37-
import com.mojang.blaze3d.platform.Window;
3838
import com.mojang.blaze3d.systems.GpuDevice;
3939
import com.mojang.blaze3d.systems.RenderSystem;
40-
import com.mojang.blaze3d.textures.FilterMode;
4140
import com.mojang.blaze3d.textures.GpuTexture;
4241
import com.mojang.blaze3d.textures.GpuTextureView;
4342
import com.mojang.blaze3d.textures.TextureFormat;
44-
import com.mojang.blaze3d.vertex.VertexConsumer;
43+
import com.mojang.blaze3d.vertex.*;
4544
import lombok.experimental.UtilityClass;
4645
import net.minecraft.client.Minecraft;
4746
import net.minecraft.client.gui.GuiGraphics;
4847
import net.minecraft.client.gui.navigation.ScreenRectangle;
4948
import net.minecraft.client.gui.render.TextureSetup;
5049
import net.minecraft.client.gui.render.state.GuiElementRenderState;
50+
import net.minecraft.client.renderer.CachedPerspectiveProjectionMatrixBuffer;
5151
import net.minecraft.client.renderer.RenderPipelines;
52+
import net.minecraft.resources.ResourceLocation;
5253
import net.minecraft.util.ARGB;
5354
import net.minecraft.util.Mth;
5455
import org.jetbrains.annotations.NotNull;
5556
import org.jetbrains.annotations.Nullable;
5657
import org.joml.Matrix3x2f;
58+
import org.joml.Matrix4fStack;
5759
import org.lwjgl.opengl.GL11;
58-
import org.lwjgl.opengl.GL30;
60+
import org.lwjgl.opengl.GL30C;
5961
import org.visuals.legacy.animatium.Animatium;
6062

6163
@UtilityClass
6264
// Ported code of the old <=1.12.2 panorama renderer (w/ blur)
6365
public class PanoramaRendererUtility {
66+
private final BlendFunction PANORAMA_BLEND = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO);
67+
68+
private final RenderPipeline PANORAMA =
69+
RenderPipeline.builder(RenderPipelines.MATRICES_PROJECTION_SNIPPET)
70+
.withLocation(Animatium.location("pipeline/panorama"))
71+
.withVertexShader("core/position_tex_color")
72+
.withFragmentShader("core/position_tex_color")
73+
.withCull(false)
74+
.withDepthWrite(false)
75+
.withBlend(PANORAMA_BLEND)
76+
.withColorWrite(true, false)
77+
.withSampler("Sampler0")
78+
.withVertexFormat(DefaultVertexFormat.POSITION_TEX_COLOR, VertexFormat.Mode.QUADS)
79+
.build();
80+
81+
private final ResourceLocation[] PANORAMA_LOCATIONS = new ResourceLocation[]{
82+
ResourceLocation.withDefaultNamespace("textures/gui/title/background/panorama_0.png"),
83+
ResourceLocation.withDefaultNamespace("textures/gui/title/background/panorama_1.png"),
84+
ResourceLocation.withDefaultNamespace("textures/gui/title/background/panorama_2.png"),
85+
ResourceLocation.withDefaultNamespace("textures/gui/title/background/panorama_3.png"),
86+
ResourceLocation.withDefaultNamespace("textures/gui/title/background/panorama_4.png"),
87+
ResourceLocation.withDefaultNamespace("textures/gui/title/background/panorama_5.png")
88+
};
89+
90+
private CachedPerspectiveProjectionMatrixBuffer projectionMatrixBuffer = null;
6491
private GpuTextureView backgroundTextureView = null;
6592
private float spin = 0.0F;
6693

67-
/**
68-
* In PanoramaRenderer, call this method before ``cubeMap.render``
69-
*/
70-
public void setup(final RenderTarget renderTarget) {
94+
static {
95+
setup();
96+
}
97+
98+
private void setup() {
99+
final int width = 256;
100+
final int height = 256;
71101
if (backgroundTextureView == null) {
72102
final GpuDevice device = RenderSystem.getDevice();
73-
final GpuTexture backgroundTexture = device.createTexture(() -> "Background texture", 15, TextureFormat.RGBA8, 256, 256, 1, 1);
103+
final GpuTexture backgroundTexture = device.createTexture(() -> "Background texture", 15, TextureFormat.RGBA8, width, height, 1, 1);
74104
backgroundTextureView = device.createTextureView(backgroundTexture);
75105
}
76106

77-
renderTarget.resize(256, 256);
107+
if (projectionMatrixBuffer == null) {
108+
projectionMatrixBuffer = new CachedPerspectiveProjectionMatrixBuffer("panorama", 0.05F, 10.0F);
109+
}
78110
}
79111

80-
/**
81-
* In PanoramaRenderer, call this method after ``cubeMap.render``
82-
*
83-
* @param guiGraphics The GuiGraphics
84-
* @param width Screen width
85-
* @param height Screen Height
86-
*/
87112
public void render(final GuiGraphics guiGraphics, final RenderTarget renderTarget, final int width, final int height) {
88-
for (int i = 0; i < 7; ++i) {
89-
guiGraphics.guiRenderState.submitGuiElement(new BlurTextureBlit(guiGraphics.pose(), renderTarget, backgroundTextureView, width, height));
113+
renderPanorama(renderTarget, width, height);
114+
for (int layer = 0; layer < 7; ++layer) {
115+
final GlTexture texture = (GlTexture) backgroundTextureView.texture();
116+
117+
final int prevFbo = GL11.glGetInteger(GL30C.GL_FRAMEBUFFER_BINDING);
118+
final int prevTex = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
119+
GlStateManager._glBindFramebuffer(GL30C.GL_FRAMEBUFFER, ((GlTexture) renderTarget.getColorTexture()).getFbo(((GlDevice) RenderSystem.getDevice()).directStateAccess(), renderTarget.getDepthTexture()));
120+
GlStateManager._bindTexture(texture.glId());
121+
GlStateManager._texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
122+
GlStateManager._texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
123+
GL11.glCopyTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, 0, 0, 256, 256);
124+
GlStateManager._bindTexture(prevTex);
125+
GlStateManager._glBindFramebuffer(GL30C.GL_FRAMEBUFFER, prevFbo);
126+
127+
guiGraphics.guiRenderState.submitGuiElement(new BlitBlurSkybox(guiGraphics.pose(), backgroundTextureView, width, height));
128+
}
129+
130+
guiGraphics.guiRenderState.submitGuiElement(new BlitFinalTexture(guiGraphics.pose(), backgroundTextureView, width, height));
131+
}
132+
133+
private void renderPanorama(final RenderTarget renderTarget, final int width, final int height) {
134+
RenderSystem.setProjectionMatrix(projectionMatrixBuffer.getBuffer(width, height, 120.0F), ProjectionType.PERSPECTIVE);
135+
final Matrix4fStack modelViewStack = RenderSystem.getModelViewStack();
136+
modelViewStack.pushMatrix();
137+
modelViewStack.identity();
138+
modelViewStack.rotateX((float) Math.toRadians(180.0F));
139+
modelViewStack.rotateZ((float) Math.toRadians(90.0F));
140+
for (int i4 = 0; i4 < 64; i4++) {
141+
modelViewStack.pushMatrix();
142+
float f2 = (i4 % 8 / 8.0F - 0.5F) / 64.0F;
143+
float f3 = ((float) i4 / 8 / 8.0F - 0.5F) / 64.0F;
144+
modelViewStack.translate(f2, f3, 0.0F);
145+
modelViewStack.rotateX((float) Math.toRadians(getXRot()));
146+
modelViewStack.rotateY((float) Math.toRadians(getYRot()));
147+
for (int panoramaIdx = 0; panoramaIdx < 6; panoramaIdx++) {
148+
modelViewStack.pushMatrix();
149+
if (panoramaIdx == 1) {
150+
modelViewStack.rotateY((float) Math.toRadians(90.0F));
151+
} else if (panoramaIdx == 2) {
152+
modelViewStack.rotateY((float) Math.toRadians(180.0F));
153+
} else if (panoramaIdx == 3) {
154+
modelViewStack.rotateY((float) Math.toRadians(-90.0F));
155+
} else if (panoramaIdx == 4) {
156+
modelViewStack.rotateX((float) Math.toRadians(90.0F));
157+
} else if (panoramaIdx == 5) {
158+
modelViewStack.rotateX((float) Math.toRadians(-90.0F));
159+
}
160+
161+
final GpuTextureView panoramaTexture = Minecraft.getInstance().getTextureManager().getTexture(PANORAMA_LOCATIONS[panoramaIdx]).getTextureView();
162+
final RenderPipeline pipeline = PANORAMA;
163+
try (ByteBufferBuilder byteBufferBuilder = ByteBufferBuilder.exactlySized(pipeline.getVertexFormat().getVertexSize() * 4)) {
164+
final BufferBuilder builder = new BufferBuilder(byteBufferBuilder, pipeline.getVertexFormatMode(), pipeline.getVertexFormat());
165+
final int color = ARGB.white(255.0F / (i4 + 1.0F));
166+
builder.addVertex(-1.0F, -1.0F, 1.0F).setUv(0.0F, 0.0F).setColor(color);
167+
builder.addVertex(1.0F, -1.0F, 1.0F).setUv(1.0F, 0.0F).setColor(color);
168+
builder.addVertex(1.0F, 1.0F, 1.0F).setUv(1.0F, 1.0F).setColor(color);
169+
builder.addVertex(-1.0F, 1.0F, 1.0F).setUv(0.0F, 1.0F).setColor(color);
170+
final GpuBufferSlice dynamicTransforms = DynamicTransformsBuilder.of().withModelViewMatrix(modelViewStack).build();
171+
RenderUtils.drawBuffer(pipeline, renderTarget, builder.buildOrThrow(), dynamicTransforms, (pass) -> {
172+
pass.bindSampler("Sampler0", panoramaTexture);
173+
});
174+
}
175+
176+
modelViewStack.popMatrix();
177+
}
178+
179+
modelViewStack.popMatrix();
90180
}
91181

92-
final Window window = Minecraft.getInstance().getWindow();
93-
renderTarget.resize(window.getWidth(), window.getHeight());
94-
guiGraphics.guiRenderState.submitGuiElement(new FinalTextureBlit(guiGraphics.pose(), backgroundTextureView, width, height, 120.0F / (float) (Math.max(width, height))));
182+
modelViewStack.popMatrix();
183+
95184
}
96185

97-
/**
98-
* In PanoramaRenderer, call this method before ``cubeMap.render`` and after PanoramaRenderUtility#setup
99-
*
100-
* @param tickDelta The current game tick value
101-
*/
102186
public void update(float tickDelta) {
103187
spin += tickDelta;
104188
}
105189

106-
public float getXRot() {
190+
private float getXRot() {
107191
return Mth.sin(spin / 400.0F) * 25.0F + 20.0F;
108192
}
109193

110-
public float getYRot() {
194+
private float getYRot() {
111195
return -spin * 0.1F;
112196
}
113197

114-
private record BlurTextureBlit(Matrix3x2f pose, RenderTarget renderTarget, GpuTextureView textureView, int width, int height) implements GuiElementRenderState {
115-
public BlurTextureBlit {
116-
textureView.texture().setTextureFilter(FilterMode.LINEAR, FilterMode.LINEAR, false); // NOTE: Doesn't actually set the parameters till later on
117-
if (textureView instanceof GlTextureView glTextureView) {
118-
final int oldFbo = GL11.glGetInteger(GL30.GL_FRAMEBUFFER_BINDING);
119-
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, ((GlTexture) renderTarget.getColorTexture()).getFbo(((GlDevice) RenderSystem.getDevice()).directStateAccess(), renderTarget.getDepthTexture()));
120-
GlStateManager._bindTexture(glTextureView.texture().glId());
121-
GlStateManager._texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
122-
GlStateManager._texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
123-
GL11.glCopyTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, 0, 0, 256, 256);
124-
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, oldFbo);
125-
}
126-
}
127-
198+
private record BlitBlurSkybox(Matrix3x2f pose, GpuTextureView texture, int width,
199+
int height) implements GuiElementRenderState {
128200
@Override
129201
public void buildVertices(VertexConsumer consumer) {
130-
for (int i = 0; i < 3; ++i) {
131-
final float growth = (float) (i - 1) / 256.0F;
132-
final int color = ARGB.white(1.0F / (float) (i + 1));
133-
consumer.addVertexWith2DPose(this.pose, this.width, this.height).setUv(0.0F + growth, 1.0F).setColor(color);
134-
consumer.addVertexWith2DPose(this.pose, this.width, 0.0F).setUv(1.0F + growth, 1.0F).setColor(color);
202+
for (int cycle = 0; cycle < 3; cycle++) {
203+
final int color = ARGB.white(1.0F / (cycle + 1));
204+
final float growth = (cycle - 1) / 256.0F;
205+
consumer.addVertexWith2DPose(this.pose, width, height).setUv(0.0F + growth, 1.0F).setColor(color);
206+
consumer.addVertexWith2DPose(this.pose, width, 0.0F).setUv(1.0F + growth, 1.0F).setColor(color);
135207
consumer.addVertexWith2DPose(this.pose, 0.0F, 0.0F).setUv(1.0F + growth, 0.0F).setColor(color);
136-
consumer.addVertexWith2DPose(this.pose, 0.0F, this.height).setUv(0.0F + growth, 0.0F).setColor(color);
208+
consumer.addVertexWith2DPose(this.pose, 0.0F, height).setUv(0.0F + growth, 0.0F).setColor(color);
137209
}
138210
}
139211

140212
@Override
141213
public @NotNull RenderPipeline pipeline() {
142214
return RenderPipeline.builder(RenderPipelines.GUI_TEXTURED_SNIPPET)
143-
.withLocation(Animatium.location("pipeline/blur_texture"))
215+
.withLocation(Animatium.location("pipeline/panorama_blur"))
216+
.withBlend(PANORAMA_BLEND)
144217
.withColorWrite(true, false)
145-
.withBlend(new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO))
146218
.build();
147219
}
148220

149221
@Override
150222
public @NotNull TextureSetup textureSetup() {
151-
return TextureSetup.singleTexture(this.textureView);
223+
return TextureSetup.singleTexture(texture);
152224
}
153225

154226
@Override
@@ -158,16 +230,18 @@ public void buildVertices(VertexConsumer consumer) {
158230

159231
@Override
160232
public @NotNull ScreenRectangle bounds() {
161-
return new ScreenRectangle(0, 0, this.width, this.height).transformMaxBounds(pose);
233+
return new ScreenRectangle(0, 0, this.width, this.height).transformMaxBounds(this.pose);
162234
}
163235
}
164236

165-
private record FinalTextureBlit(Matrix3x2f pose, GpuTextureView textureView, int width, int height, float aspect) implements GuiElementRenderState {
237+
private record BlitFinalTexture(Matrix3x2f pose, GpuTextureView texture, int width,
238+
int height) implements GuiElementRenderState {
166239
@Override
167240
public void buildVertices(VertexConsumer consumer) {
241+
float aspect = 120.0F / (Math.max(this.width, this.height));
242+
float sw = this.width * aspect / 256.0F;
243+
float sh = this.height * aspect / 256.0F;
168244
final int color = ARGB.white(1.0F);
169-
final float sw = (float) this.width * this.aspect / 256.0F;
170-
final float sh = (float) this.height * this.aspect / 256.0F;
171245
consumer.addVertexWith2DPose(this.pose, 0.0F, this.height).setUv(0.5F - sh, 0.5F + sw).setColor(color);
172246
consumer.addVertexWith2DPose(this.pose, this.width, this.height).setUv(0.5F - sh, 0.5F - sw).setColor(color);
173247
consumer.addVertexWith2DPose(this.pose, this.width, 0.0F).setUv(0.5F + sh, 0.5F - sw).setColor(color);
@@ -177,13 +251,13 @@ public void buildVertices(VertexConsumer consumer) {
177251
@Override
178252
public @NotNull RenderPipeline pipeline() {
179253
return RenderPipeline.builder(RenderPipelines.GUI_TEXTURED_SNIPPET)
180-
.withLocation(Animatium.location("pipeline/basic_texture"))
254+
.withLocation(Animatium.location("pipeline/blit_texture"))
181255
.build();
182256
}
183257

184258
@Override
185259
public @NotNull TextureSetup textureSetup() {
186-
return TextureSetup.singleTexture(this.textureView);
260+
return TextureSetup.singleTexture(texture);
187261
}
188262

189263
@Override
@@ -193,7 +267,7 @@ public void buildVertices(VertexConsumer consumer) {
193267

194268
@Override
195269
public @NotNull ScreenRectangle bounds() {
196-
return new ScreenRectangle(0, 0, this.width, this.height).transformMaxBounds(pose);
270+
return new ScreenRectangle(0, 0, this.width, this.height).transformMaxBounds(this.pose);
197271
}
198272
}
199273
}

0 commit comments

Comments
 (0)