mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Improve rendering of field of view effects
This commit is contained in:
parent
8629cba3e9
commit
0d6c265845
2 changed files with 163 additions and 61 deletions
|
@ -0,0 +1,128 @@
|
||||||
|
package com.minelittlepony.unicopia.client.gui;
|
||||||
|
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.*;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
public interface GradientUtil {
|
||||||
|
|
||||||
|
static void fillVerticalGradient(MatrixStack matrices, int startX, int startY, int stopY, int endX, int endY, int colorStart, int colorStop, int colorEnd, int z) {
|
||||||
|
RenderSystem.disableTexture();
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.defaultBlendFunc();
|
||||||
|
RenderSystem.setShader(GameRenderer::getPositionColorProgram);
|
||||||
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
|
BufferBuilder bufferBuilder = tessellator.getBuffer();
|
||||||
|
fillVerticalGradient(matrices.peek().getPositionMatrix(), bufferBuilder, startX, startY, stopY, endX, endY, z, colorStart, colorStop, colorEnd);
|
||||||
|
tessellator.draw();
|
||||||
|
RenderSystem.disableBlend();
|
||||||
|
RenderSystem.enableTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fillVerticalGradient(Matrix4f matrix, BufferBuilder builder, int startX, int startY, int stopY, int endX, int endY, int z, int colorStart, int colorStop, int colorEnd) {
|
||||||
|
final float fromA = (colorStart >> 24 & 0xFF) / 255F;
|
||||||
|
final float fromR = (colorStart >> 16 & 0xFF) / 255F;
|
||||||
|
final float fromG = (colorStart >> 8 & 0xFF) / 255F;
|
||||||
|
final float fromB = (colorStart & 0xFF) / 255F;
|
||||||
|
|
||||||
|
final float stopA = (colorStop >> 24 & 0xFF) / 255F;
|
||||||
|
final float stopR = (colorStop >> 16 & 0xFF) / 255F;
|
||||||
|
final float stopG = (colorStop >> 8 & 0xFF) / 255F;
|
||||||
|
final float stopB = (colorStop & 0xFF) / 255F;
|
||||||
|
|
||||||
|
final float toA = (colorEnd >> 24 & 0xFF) / 255F;
|
||||||
|
final float toR = (colorEnd >> 16 & 0xFF) / 255F;
|
||||||
|
final float toG = (colorEnd >> 8 & 0xFF) / 255F;
|
||||||
|
final float toB = (colorEnd & 0xFF) / 255F;
|
||||||
|
|
||||||
|
builder.begin(VertexFormat.DrawMode.TRIANGLE_FAN, VertexFormats.POSITION_COLOR);
|
||||||
|
|
||||||
|
builder.vertex(matrix, endX, stopY, z).color(stopR, stopG, stopB, stopA).next();
|
||||||
|
builder.vertex(matrix, endX, startY, z).color(fromR, fromG, fromB, fromA).next();
|
||||||
|
builder.vertex(matrix, startX, startY, z).color(fromR, fromG, fromB, fromA).next();
|
||||||
|
builder.vertex(matrix, startX, stopY, z).color(stopR, stopG, stopB, stopA).next();
|
||||||
|
builder.vertex(matrix, startX, endY, z).color(toR, toG, toB, toA).next();
|
||||||
|
builder.vertex(matrix, endX, endY, z).color(stopR, toG, toB, toA).next();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fillRadialGradient(MatrixStack matrices, int startX, int startY, int endX, int endY, int colorStart, int colorEnd, int z, float radius) {
|
||||||
|
RenderSystem.disableTexture();
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.defaultBlendFunc();
|
||||||
|
RenderSystem.setShader(GameRenderer::getPositionColorProgram);
|
||||||
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
|
if (fillRadials(matrices.peek().getPositionMatrix(), tessellator.getBuffer(), startX, startY, endX, endY, z, colorStart, colorEnd, radius)) {
|
||||||
|
tessellator.draw();
|
||||||
|
}
|
||||||
|
RenderSystem.disableBlend();
|
||||||
|
RenderSystem.enableTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean fillRadials(Matrix4f matrix, BufferBuilder builder, int startX, int startY, int endX, int endY, int z, int colorStart, int colorEnd, float radius) {
|
||||||
|
final float fromA = (colorStart >> 24 & 0xFF) / 255F;
|
||||||
|
final float fromR = (colorStart >> 16 & 0xFF) / 255F;
|
||||||
|
final float fromG = (colorStart >> 8 & 0xFF) / 255F;
|
||||||
|
final float fromB = (colorStart & 0xFF) / 255F;
|
||||||
|
final float toA = (colorEnd >> 24 & 0xFF) / 255F;
|
||||||
|
final float toR = (colorEnd >> 16 & 0xFF) / 255F;
|
||||||
|
final float toG = (colorEnd >> 8 & 0xFF) / 255F;
|
||||||
|
final float toB = (colorEnd & 0xFF) / 255F;
|
||||||
|
|
||||||
|
double increment = DrawableUtil.TAU / 30D;
|
||||||
|
|
||||||
|
float width = endX - startX;
|
||||||
|
float height = endY - startY;
|
||||||
|
|
||||||
|
float outerRadius = MathHelper.sqrt((width * width) + (height * height)) / 2F;
|
||||||
|
|
||||||
|
float innerRadius = outerRadius * (1 - radius);
|
||||||
|
|
||||||
|
builder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
|
||||||
|
for (double angle = 0; angle < DrawableUtil.TAU; angle += increment) {
|
||||||
|
clampedVertex(builder, matrix, innerRadius, angle + increment, z, startX, endX, startY, endY).color(toR, toG, toB, toA).next();
|
||||||
|
clampedVertex(builder, matrix, innerRadius, angle, z, startX, endX, startY, endY).color(toR, toG, toB, toA).next();
|
||||||
|
clampedVertex(builder, matrix, outerRadius, angle, z, startX, endX, startY, endY).color(fromR, fromG, fromB, fromA).next();
|
||||||
|
clampedVertex(builder, matrix, outerRadius, angle + increment, z, startX, endX, startY, endY).color(fromR, fromG, fromB, fromA).next();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float getX(double radius, double angle) {
|
||||||
|
return (float)(radius * MathHelper.sin((float)angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
static float getY(double radius, double angle) {
|
||||||
|
return (float)(radius * MathHelper.cos((float)angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static VertexConsumer clampedVertex(BufferBuilder bufferBuilder, Matrix4f model, double radius, double angle, float z, int minX, int maxX, int minY, int maxY) {
|
||||||
|
float midX = (maxX - minX) / 2F;
|
||||||
|
float midY = (maxY - minY) / 2F;
|
||||||
|
|
||||||
|
float x = midX + getX(radius, angle);
|
||||||
|
float y = midY + getY(radius, angle);
|
||||||
|
|
||||||
|
float xPad = (maxX - minX) / 10F;
|
||||||
|
float yPad = (maxY - minY) / 20F;
|
||||||
|
|
||||||
|
if (x < minX + xPad) {
|
||||||
|
x = minX;
|
||||||
|
}
|
||||||
|
if (x > maxX - xPad) {
|
||||||
|
x = maxX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < minY + yPad) {
|
||||||
|
y = minY;
|
||||||
|
}
|
||||||
|
if (y > maxY - yPad) {
|
||||||
|
y = maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bufferBuilder.vertex(model, x, y, z);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ package com.minelittlepony.unicopia.client.gui;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.*;
|
import com.minelittlepony.unicopia.*;
|
||||||
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||||
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
||||||
|
@ -224,21 +223,21 @@ public class UHud extends DrawableHelper {
|
||||||
|
|
||||||
float strength = MathHelper.clamp(pulse + i, 0.3F, 1F);
|
float strength = MathHelper.clamp(pulse + i, 0.3F, 1F);
|
||||||
|
|
||||||
int alpha1 = (int)(strength * 205) << 24 & -16777216;
|
int alpha1 = (int)(strength * 205);
|
||||||
int alpha2 = (int)(alpha1 * 0.6F);
|
int alpha2 = (int)(alpha1 * 0.6F);
|
||||||
|
int color = 0xFFFFFF;
|
||||||
fillGradient(matrices, 0, 0, scaledWidth, scaledHeight / 2, 0xFFFFFF | alpha1, 0xFFFFFF | alpha2);
|
|
||||||
fillGradient(matrices, 0, scaledHeight / 2, scaledWidth, scaledHeight, 0xFFFFFF | alpha2, 0xFFFFFF | alpha1);
|
|
||||||
|
|
||||||
if (hasEffect) {
|
if (hasEffect) {
|
||||||
matrices.push();
|
GradientUtil.fillRadialGradient(matrices, 0, 0, scaledWidth, scaledHeight,
|
||||||
matrices.translate(scaledWidth, 0, 0);
|
color | (alpha1 << 24),
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(90));
|
color | (alpha2 << 24),
|
||||||
|
getZOffset(), 1);
|
||||||
fillGradient(matrices, 0, 0, scaledHeight, scaledWidth / 2, 0xFFFFFF | 0, 0xFFFFFF | alpha2);
|
} else {
|
||||||
fillGradient(matrices, 0, scaledWidth / 2, scaledHeight, scaledWidth, 0xFFFFFF | alpha2, 0xFFFFFF | 0);
|
GradientUtil.fillVerticalGradient(matrices, 0, 0, scaledHeight / 2, scaledWidth, scaledHeight,
|
||||||
|
color | (alpha1 << 24),
|
||||||
matrices.pop();
|
color | (alpha2 << 24),
|
||||||
|
color | (alpha1 << 24),
|
||||||
|
getZOffset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +270,12 @@ public class UHud extends DrawableHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float exhaustion = pony.getMagicalReserves().getExhaustion().getPercentFill();
|
if (UItems.ALICORN_AMULET.isApplicable(client.player)) {
|
||||||
|
float radius = (float)pony.getArmour().getTicks(UItems.ALICORN_AMULET) / (5 * ItemTracker.DAYS);
|
||||||
|
renderVignette(matrices, 0x000000, radius, radius, scaledWidth, scaledHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
float exhaustion = MathHelper.clamp(pony.getMagicalReserves().getExhaustion().getPercentFill(), 0, 0.6F);
|
||||||
|
|
||||||
if (exhaustion > 0) {
|
if (exhaustion > 0) {
|
||||||
if (exhaustion > 0.5F && (heartbeatSound == null || heartbeatSound.isDone())) {
|
if (exhaustion > 0.5F && (heartbeatSound == null || heartbeatSound.isDone())) {
|
||||||
|
@ -282,59 +286,29 @@ public class UHud extends DrawableHelper {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int color = 0x880000;
|
|
||||||
|
|
||||||
float rate = exhaustion > 0.5F ? 2.5F : 7F;
|
float rate = exhaustion > 0.5F ? 2.5F : 7F;
|
||||||
|
|
||||||
float radius = (1 + (float)Math.sin(client.player.age / rate)) / 2F;
|
float radius = (1 + (float)Math.sin(client.player.age / rate)) / 2F;
|
||||||
radius = 0.1F + radius * 0.1F;
|
|
||||||
|
|
||||||
int alpha1 = (int)(MathHelper.clamp(exhaustion * radius * 2, 0, 1) * 205) << 24 & -16777216;
|
renderVignette(matrices, 0x880000, exhaustion * radius, 0.1F + radius * 0.3F, scaledWidth, scaledHeight);
|
||||||
int alpha2 = 0;
|
|
||||||
|
|
||||||
int halfWidth = (int)(scaledWidth * radius);
|
|
||||||
int halfHeight = (int)(scaledHeight * radius);
|
|
||||||
|
|
||||||
fillGradient(matrices, 0, 0, scaledWidth, halfHeight, color | alpha1, color | alpha2);
|
|
||||||
fillGradient(matrices, 0, scaledHeight - halfHeight, scaledWidth, scaledHeight, color | alpha2, color | alpha1);
|
|
||||||
|
|
||||||
matrices.push();
|
|
||||||
matrices.translate(scaledWidth, 0, 0);
|
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(90));
|
|
||||||
|
|
||||||
fillGradient(matrices, 0, 0, scaledHeight, halfWidth, color | alpha1, color | alpha2);
|
|
||||||
fillGradient(matrices, 0, scaledWidth - halfWidth, scaledHeight, scaledWidth, color | alpha2, color | alpha1);
|
|
||||||
|
|
||||||
matrices.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UItems.ALICORN_AMULET.isApplicable(client.player)) {
|
|
||||||
int color = 0x000000;
|
|
||||||
|
|
||||||
long timer = pony.getArmour().getTicks(UItems.ALICORN_AMULET);
|
|
||||||
|
|
||||||
float radius = (float)timer / (5 * ItemTracker.DAYS);
|
|
||||||
|
|
||||||
int alpha1 = (int)(MathHelper.clamp(radius * 2, 0, 1) * 205) << 24 & -16777216;
|
|
||||||
int alpha2 = 0;
|
|
||||||
|
|
||||||
int halfWidth = (int)(scaledWidth * radius);
|
|
||||||
int halfHeight = (int)(scaledHeight * radius);
|
|
||||||
|
|
||||||
fillGradient(matrices, 0, 0, scaledWidth, halfHeight, color | alpha1, color | alpha2);
|
|
||||||
fillGradient(matrices, 0, scaledHeight - halfHeight, scaledWidth, scaledHeight, color | alpha2, color | alpha1);
|
|
||||||
|
|
||||||
matrices.push();
|
|
||||||
matrices.translate(scaledWidth, 0, 0);
|
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(90));
|
|
||||||
|
|
||||||
fillGradient(matrices, 0, 0, scaledHeight, halfWidth, color | alpha1, color | alpha2);
|
|
||||||
fillGradient(matrices, 0, scaledWidth - halfWidth, scaledHeight, scaledWidth, color | alpha2, color | alpha1);
|
|
||||||
|
|
||||||
matrices.pop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderVignette(MatrixStack matrices, int color, float alpha, float radius, int scaledWidth, int scaledHeight) {
|
||||||
|
if (radius <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
color &= 0xFFFFFF;
|
||||||
|
float alpha2 = MathHelper.clamp(radius - 1, 0, 1) * 255;
|
||||||
|
float alpha1 = Math.max(alpha2, MathHelper.clamp(alpha * 2, 0, 1) * 205);
|
||||||
|
GradientUtil.fillRadialGradient(matrices, 0, 0, scaledWidth, scaledHeight,
|
||||||
|
color | (int)alpha1 << 24,
|
||||||
|
color | (int)alpha2 << 24,
|
||||||
|
getZOffset(), Math.min(1, radius));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void setMessage(Text message) {
|
public void setMessage(Text message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.messageTime = 60;
|
this.messageTime = 60;
|
||||||
|
|
Loading…
Reference in a new issue