mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Fix fancy portal rendering
This commit is contained in:
parent
3603819860
commit
6215252b57
1 changed files with 68 additions and 89 deletions
|
@ -6,7 +6,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Matrix4fStack;
|
import org.joml.Quaternionf;
|
||||||
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
|
@ -24,13 +24,11 @@ import com.minelittlepony.unicopia.mixin.client.MixinMinecraftClient;
|
||||||
import com.mojang.blaze3d.platform.GlConst;
|
import com.mojang.blaze3d.platform.GlConst;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.systems.VertexSorter;
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gl.SimpleFramebuffer;
|
import net.minecraft.client.gl.SimpleFramebuffer;
|
||||||
import net.minecraft.client.option.Perspective;
|
|
||||||
import net.minecraft.client.render.BackgroundRenderer;
|
import net.minecraft.client.render.BackgroundRenderer;
|
||||||
import net.minecraft.client.render.BufferBuilder;
|
import net.minecraft.client.render.BufferBuilder;
|
||||||
|
import net.minecraft.client.render.BufferRenderer;
|
||||||
import net.minecraft.client.render.Camera;
|
import net.minecraft.client.render.Camera;
|
||||||
import net.minecraft.client.render.Frustum;
|
import net.minecraft.client.render.Frustum;
|
||||||
import net.minecraft.client.render.Tessellator;
|
import net.minecraft.client.render.Tessellator;
|
||||||
|
@ -49,7 +47,7 @@ import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
class PortalFrameBuffer implements AutoCloseable {
|
class PortalFrameBuffer implements AutoCloseable {
|
||||||
private static final LoadingCache<UUID, PortalFrameBuffer> CACHE = CacheBuilder.newBuilder()
|
private static final LoadingCache<UUID, PortalFrameBuffer> CACHE = CacheBuilder.newBuilder()
|
||||||
.expireAfterAccess(10, TimeUnit.SECONDS)
|
.expireAfterAccess(1, TimeUnit.HOURS)
|
||||||
.<UUID, PortalFrameBuffer>removalListener(n -> n.getValue().close())
|
.<UUID, PortalFrameBuffer>removalListener(n -> n.getValue().close())
|
||||||
.build(CacheLoader.from(PortalFrameBuffer::new));
|
.build(CacheLoader.from(PortalFrameBuffer::new));
|
||||||
|
|
||||||
|
@ -67,12 +65,12 @@ class PortalFrameBuffer implements AutoCloseable {
|
||||||
@Nullable
|
@Nullable
|
||||||
private SimpleFramebuffer framebuffer;
|
private SimpleFramebuffer framebuffer;
|
||||||
@Nullable
|
@Nullable
|
||||||
private SimpleFramebuffer backgroundBuffer;
|
|
||||||
@Nullable
|
|
||||||
private WorldRenderer renderer;
|
private WorldRenderer renderer;
|
||||||
@Nullable
|
@Nullable
|
||||||
private ClientWorld world;
|
private ClientWorld world;
|
||||||
|
|
||||||
|
private final Camera camera = new Camera();
|
||||||
|
|
||||||
private boolean closed;
|
private boolean closed;
|
||||||
|
|
||||||
private final MinecraftClient client = MinecraftClient.getInstance();
|
private final MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
@ -87,11 +85,12 @@ class PortalFrameBuffer implements AutoCloseable {
|
||||||
public void draw(MatrixStack matrices, VertexConsumerProvider vertices) {
|
public void draw(MatrixStack matrices, VertexConsumerProvider vertices) {
|
||||||
matrices.translate(0, -0.001, 0);
|
matrices.translate(0, -0.001, 0);
|
||||||
|
|
||||||
|
RenderSystem.assertOnRenderThread();
|
||||||
|
GlStateManager._colorMask(true, true, true, false);
|
||||||
|
GlStateManager._enableDepthTest();
|
||||||
|
GlStateManager._disableCull();
|
||||||
|
|
||||||
if (!(closed || framebuffer == null)) {
|
if (!(closed || framebuffer == null)) {
|
||||||
RenderSystem.assertOnRenderThread();
|
|
||||||
GlStateManager._colorMask(true, true, true, false);
|
|
||||||
GlStateManager._enableDepthTest();
|
|
||||||
GlStateManager._disableCull();
|
|
||||||
Tessellator tessellator = RenderSystem.renderThreadTesselator();
|
Tessellator tessellator = RenderSystem.renderThreadTesselator();
|
||||||
float uScale = (float)framebuffer.viewportWidth / (float)framebuffer.textureWidth;
|
float uScale = (float)framebuffer.viewportWidth / (float)framebuffer.textureWidth;
|
||||||
float vScale = (float)framebuffer.viewportHeight / (float)framebuffer.textureHeight;
|
float vScale = (float)framebuffer.viewportHeight / (float)framebuffer.textureHeight;
|
||||||
|
@ -102,16 +101,17 @@ class PortalFrameBuffer implements AutoCloseable {
|
||||||
|
|
||||||
RenderSystem.setTextureMatrix(SphereModel.DISK.getTextureMatrix());
|
RenderSystem.setTextureMatrix(SphereModel.DISK.getTextureMatrix());
|
||||||
SphereModel.DISK.render(matrices, buffer, 1, 2F, Colors.WHITE);
|
SphereModel.DISK.render(matrices, buffer, 1, 2F, Colors.WHITE);
|
||||||
buffer.end();
|
BufferRenderer.drawWithGlobalProgram(buffer.end());
|
||||||
|
|
||||||
client.getTextureManager().bindTexture(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE);
|
client.getTextureManager().bindTexture(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE);
|
||||||
GlStateManager._enableCull();
|
|
||||||
GlStateManager._colorMask(true, true, true, true);
|
|
||||||
GlStateManager._depthMask(true);
|
|
||||||
} else {
|
} else {
|
||||||
Vec3d skyColor = client.world.getSkyColor(client.gameRenderer.getCamera().getPos(), client.getRenderTickCounter().getTickDelta(false));
|
Vec3d skyColor = client.world.getSkyColor(client.gameRenderer.getCamera().getPos(), client.getRenderTickCounter().getTickDelta(false));
|
||||||
SphereModel.DISK.render(matrices, vertices.getBuffer(RenderLayers.getMagicShield()), 0, 0, 2, Color.argbToHex(1, (float)skyColor.x, (float)skyColor.y, (float)skyColor.z));
|
SphereModel.DISK.render(matrices, vertices.getBuffer(RenderLayers.getMagicShield()), 0, 0, 2, Color.argbToHex(1, (float)skyColor.x, (float)skyColor.y, (float)skyColor.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GlStateManager._enableCull();
|
||||||
|
GlStateManager._colorMask(true, true, true, true);
|
||||||
|
GlStateManager._depthMask(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void build(PortalSpell spell, Caster<?> caster, EntityReference.EntityValues<Entity> target) {
|
public void build(PortalSpell spell, Caster<?> caster, EntityReference.EntityValues<Entity> target) {
|
||||||
|
@ -152,25 +152,19 @@ class PortalFrameBuffer implements AutoCloseable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fov = client.options.getFov();
|
|
||||||
int originalFov = fov.getValue();
|
|
||||||
fov.setValue(110);
|
|
||||||
|
|
||||||
Camera camera = client.gameRenderer.getCamera();
|
Camera camera = client.gameRenderer.getCamera();
|
||||||
|
|
||||||
Entity cameraEntity = UEntities.CAST_SPELL.create(caster.asWorld());
|
Entity cameraEntity = UEntities.CAST_SPELL.create(caster.asWorld());
|
||||||
Vec3d offset = new Vec3d(0, 0, -0.1F).rotateY(-spell.getTargetYaw() * MathHelper.RADIANS_PER_DEGREE);
|
Vec3d offset = new Vec3d(0, 1, -0.1F).rotateY(-spell.getTargetYaw() * MathHelper.RADIANS_PER_DEGREE);
|
||||||
|
|
||||||
float yaw = spell.getTargetYaw() + camera.getYaw() - spell.getYaw() + 180;
|
float yaw = spell.getTargetYaw() + camera.getYaw() - spell.getYaw();
|
||||||
float pitch = spell.getTargetPitch() + (camera.getPitch() - spell.getPitch()) * 1.65F;
|
float pitch = spell.getTargetPitch();//MathHelper.clamp(spell.getTargetPitch() + (camera.getPitch() - spell.getPitch()) * 0.65F, -90, 90) + 90;
|
||||||
|
|
||||||
cameraEntity.setPosition(target.pos().add(offset));
|
cameraEntity.setPosition(target.pos().add(offset));
|
||||||
cameraEntity.setPitch(90 + pitch);
|
cameraEntity.setPitch(pitch % 180);
|
||||||
cameraEntity.setYaw(yaw);
|
cameraEntity.setYaw((yaw + 180) % 360);
|
||||||
|
|
||||||
drawWorld(cameraEntity, 400, 400);
|
drawWorld(cameraEntity, 400, 400);
|
||||||
|
|
||||||
fov.setValue(originalFov);
|
|
||||||
} finally {
|
} finally {
|
||||||
recursionCount--;
|
recursionCount--;
|
||||||
}
|
}
|
||||||
|
@ -178,26 +172,16 @@ class PortalFrameBuffer implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawWorld(Entity cameraEntity, int width, int height) {
|
private void drawWorld(Entity cameraEntity, int width, int height) {
|
||||||
Entity oldCameraEntity = client.cameraEntity;
|
|
||||||
Window window = client.getWindow();
|
Window window = client.getWindow();
|
||||||
|
|
||||||
int i = window.getFramebufferWidth();
|
int globalFramebufferWidth = window.getFramebufferWidth();
|
||||||
int j = window.getFramebufferHeight();
|
int globalFramebufferHeight = window.getFramebufferHeight();
|
||||||
|
|
||||||
width = i;
|
width = globalFramebufferWidth;
|
||||||
height = j;
|
height = globalFramebufferHeight;
|
||||||
|
|
||||||
Perspective perspective = client.options.getPerspective();
|
|
||||||
Matrix4fStack view = RenderSystem.getModelViewStack();
|
|
||||||
|
|
||||||
Matrix4f proj = RenderSystem.getProjectionMatrix();
|
Matrix4f proj = RenderSystem.getProjectionMatrix();
|
||||||
|
|
||||||
int fbo = client.getFramebuffer().fbo;
|
|
||||||
Camera camera = client.gameRenderer.getCamera();
|
|
||||||
|
|
||||||
WorldRenderer globalRenderer = client.worldRenderer;
|
|
||||||
try {
|
try {
|
||||||
client.cameraEntity = cameraEntity;
|
|
||||||
client.getFramebuffer().endWrite();
|
client.getFramebuffer().endWrite();
|
||||||
|
|
||||||
if (framebuffer == null) {
|
if (framebuffer == null) {
|
||||||
|
@ -206,15 +190,8 @@ class PortalFrameBuffer implements AutoCloseable {
|
||||||
framebuffer.clear(MinecraftClient.IS_SYSTEM_MAC);
|
framebuffer.clear(MinecraftClient.IS_SYSTEM_MAC);
|
||||||
}
|
}
|
||||||
|
|
||||||
view.pushMatrix();
|
|
||||||
view.identity();
|
|
||||||
RenderSystem.applyModelViewMatrix();
|
|
||||||
|
|
||||||
window.setFramebufferWidth(width);
|
window.setFramebufferWidth(width);
|
||||||
window.setFramebufferHeight(height);
|
window.setFramebufferHeight(height);
|
||||||
client.getFramebuffer().fbo = framebuffer.fbo;
|
|
||||||
|
|
||||||
client.options.setPerspective(Perspective.FIRST_PERSON);
|
|
||||||
|
|
||||||
RenderSystem.clear(GlConst.GL_DEPTH_BUFFER_BIT | GlConst.GL_COLOR_BUFFER_BIT, MinecraftClient.IS_SYSTEM_MAC);
|
RenderSystem.clear(GlConst.GL_DEPTH_BUFFER_BIT | GlConst.GL_COLOR_BUFFER_BIT, MinecraftClient.IS_SYSTEM_MAC);
|
||||||
framebuffer.beginWrite(true);
|
framebuffer.beginWrite(true);
|
||||||
|
@ -224,17 +201,40 @@ class PortalFrameBuffer implements AutoCloseable {
|
||||||
if (renderer == null) {
|
if (renderer == null) {
|
||||||
renderer = new WorldRenderer(client, client.getEntityRenderDispatcher(), client.getBlockEntityRenderDispatcher(), client.getBufferBuilders());
|
renderer = new WorldRenderer(client, client.getEntityRenderDispatcher(), client.getBlockEntityRenderDispatcher(), client.getBufferBuilders());
|
||||||
}
|
}
|
||||||
if (client.world != world) {
|
if (cameraEntity.getWorld() != world) {
|
||||||
world = client.world;
|
world = (ClientWorld)cameraEntity.getWorld();
|
||||||
renderer.setWorld(client.world);
|
renderer.setWorld(world);
|
||||||
}
|
}
|
||||||
((MixinMinecraftClient)client).setWorldRenderer(renderer);
|
//((MixinMinecraftClient)client).setWorldRenderer(renderer);
|
||||||
|
|
||||||
renderer.scheduleBlockRenders((int)cameraEntity.getX() / 16, (int)cameraEntity.getY() / 16, (int)cameraEntity.getZ() / 16);
|
var tickCounter = client.getRenderTickCounter();
|
||||||
|
|
||||||
client.gameRenderer.setRenderHand(false);
|
camera.update(world, cameraEntity, false, false, 1);
|
||||||
|
|
||||||
client.gameRenderer.renderWorld(client.getRenderTickCounter());
|
double fov = 110;
|
||||||
|
Matrix4f projectionMatrix = client.gameRenderer.getBasicProjectionMatrix(fov);
|
||||||
|
Matrix4f cameraTransform = new Matrix4f().rotation(camera.getRotation().conjugate(new Quaternionf()));
|
||||||
|
|
||||||
|
client.gameRenderer.loadProjectionMatrix(projectionMatrix);
|
||||||
|
/*renderer.scheduleBlockRenders(
|
||||||
|
ChunkSectionPos.getSectionCoord((int)cameraEntity.getX()),
|
||||||
|
ChunkSectionPos.getSectionCoord((int)cameraEntity.getY()),
|
||||||
|
ChunkSectionPos.getSectionCoord((int)cameraEntity.getZ())
|
||||||
|
);*/
|
||||||
|
renderer.setupFrustum(
|
||||||
|
camera.getPos(),
|
||||||
|
cameraTransform,
|
||||||
|
client.gameRenderer.getBasicProjectionMatrix(Math.max(fov, this.client.options.getFov().getValue().intValue()))
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
renderer.render(tickCounter, false, camera, client.gameRenderer,
|
||||||
|
client.gameRenderer.getLightmapTextureManager(),
|
||||||
|
cameraTransform,
|
||||||
|
projectionMatrix
|
||||||
|
);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
// Strip transparency
|
// Strip transparency
|
||||||
RenderSystem.colorMask(false, false, false, true);
|
RenderSystem.colorMask(false, false, false, true);
|
||||||
|
@ -244,48 +244,27 @@ class PortalFrameBuffer implements AutoCloseable {
|
||||||
|
|
||||||
framebuffer.endWrite();
|
framebuffer.endWrite();
|
||||||
} finally {
|
} finally {
|
||||||
((MixinMinecraftClient)client).setWorldRenderer(globalRenderer);
|
|
||||||
|
|
||||||
client.getFramebuffer().fbo = fbo;
|
|
||||||
client.getFramebuffer().beginWrite(true);
|
client.getFramebuffer().beginWrite(true);
|
||||||
|
client.gameRenderer.loadProjectionMatrix(proj);
|
||||||
|
|
||||||
view.popMatrix();
|
window.setFramebufferWidth(globalFramebufferWidth);
|
||||||
RenderSystem.applyModelViewMatrix();
|
window.setFramebufferHeight(globalFramebufferHeight);
|
||||||
RenderSystem.setProjectionMatrix(proj, VertexSorter.BY_Z);
|
|
||||||
|
|
||||||
window.setFramebufferWidth(i);
|
|
||||||
window.setFramebufferHeight(j);
|
|
||||||
|
|
||||||
client.options.setPerspective(perspective);
|
|
||||||
client.cameraEntity = oldCameraEntity;
|
|
||||||
|
|
||||||
if (recursionCount <= 1) {
|
|
||||||
client.gameRenderer.setRenderHand(true);
|
|
||||||
camera.update(client.world,
|
|
||||||
client.getCameraEntity() == null ? client.player : client.getCameraEntity(),
|
|
||||||
perspective.isFirstPerson(),
|
|
||||||
perspective.isFrontView(),
|
|
||||||
1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
closed = true;
|
synchronized (client) {
|
||||||
if (framebuffer != null) {
|
closed = true;
|
||||||
SimpleFramebuffer fb = framebuffer;
|
if (framebuffer != null) {
|
||||||
framebuffer = null;
|
SimpleFramebuffer fb = framebuffer;
|
||||||
fb.delete();
|
framebuffer = null;
|
||||||
}
|
fb.delete();
|
||||||
if (backgroundBuffer != null) {
|
}
|
||||||
SimpleFramebuffer fb = backgroundBuffer;
|
if (renderer != null) {
|
||||||
backgroundBuffer = null;
|
renderer.getChunkBuilder().stop();
|
||||||
fb.delete();
|
renderer.close();
|
||||||
}
|
}
|
||||||
if (renderer != null) {
|
|
||||||
renderer.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue