gmod-title-screen/src/main/java/zone/oat/gmodtitlescreen/screen/SlideshowBackground.java

104 lines
4.1 KiB
Java

package zone.oat.gmodtitlescreen.screen;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.util.math.Vector2f;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3f;
import zone.oat.gmodtitlescreen.ModIdentifier;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import static net.minecraft.client.gui.DrawableHelper.drawTexture;
@Environment(EnvType.CLIENT)
public class SlideshowBackground {
private static final Identifier[] BACKGROUNDS = {
new ModIdentifier("textures/gui/title/background/background_0.png"),
new ModIdentifier("textures/gui/title/background/background_1.png"),
new ModIdentifier("textures/gui/title/background/background_2.png"),
new ModIdentifier("textures/gui/title/background/background_3.png"),
new ModIdentifier("textures/gui/title/background/background_4.png"),
new ModIdentifier("textures/gui/title/background/background_5.png"),
new ModIdentifier("textures/gui/title/background/background_6.png"),
};
private static final Integer[][] BACKGROUND_SIZES = {
{960, 528},
{960, 528},
{960, 528},
{960, 528},
{960, 528},
{960, 528},
{960, 528},
};
private static final float SLIDESHOW_IMAGE_LENGTH = 400f;
private static final float TRANSITION_LENGTH = 30f;
private static float t = TRANSITION_LENGTH;
public static CompletableFuture<Void> loadBackgroundTexturesAsync(TextureManager textureManager, Executor executor) {
CompletableFuture<?>[] completableFutures = new CompletableFuture[BACKGROUNDS.length];
for(int i = 0; i < completableFutures.length; ++i) {
completableFutures[i] = textureManager.loadTextureAsync(BACKGROUNDS[i], executor);
}
return CompletableFuture.allOf(completableFutures);
}
private static void renderBackground(MatrixStack matrices, float a, int backgroundIndex, float alpha, int width, int height) {
matrices.push();
Identifier bg = BACKGROUNDS[backgroundIndex];
Integer[] backgroundSize = BACKGROUND_SIZES[backgroundIndex];
float baseScale = Math.max(width / (float) backgroundSize[0], height / (float) backgroundSize[1]);
Vector2f overscan = new Vector2f(backgroundSize[0] * baseScale - width, backgroundSize[1] * baseScale - height);
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, bg);
RenderSystem.enableBlend();
RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, alpha);
float scale = MathHelper.lerp(a, 1.1f, 1.2f);
float angle = MathHelper.lerp(a, -1f, 3f);
matrices.translate(width / 2f, height / 2f, 0f);
matrices.scale(scale, scale, 1f);
matrices.multiply(Vec3f.POSITIVE_Z.getDegreesQuaternion(angle));
drawTexture(
matrices,
(int) Math.floor(-overscan.getX()/2f - width/2f),
(int) Math.floor(-overscan.getY()/2f - height/2f),
width + (int) Math.ceil(overscan.getX()),
height + (int) Math.ceil(overscan.getY()),
0.0F,
0.0F,
1, 1, 1, 1
);
matrices.translate(width / 2f, height / 2f, 0f);
matrices.pop();
}
public static void render(MatrixStack matrices, float delta, int width, int height) {
t += delta;
int index = (int) Math.floor(t / SLIDESHOW_IMAGE_LENGTH) % BACKGROUNDS.length;
int previousIndex = (index - 1 + BACKGROUNDS.length) % BACKGROUNDS.length;
float a = (t % SLIDESHOW_IMAGE_LENGTH) / SLIDESHOW_IMAGE_LENGTH;
float transition = MathHelper.clamp(a / (TRANSITION_LENGTH / SLIDESHOW_IMAGE_LENGTH), 0f, 1f);
if (transition < 1f) {
renderBackground(matrices, a + 1f, previousIndex, 1f, width, height);
}
renderBackground(matrices, a, index, transition, width, height);
}
}