Fuck fluids
This commit is contained in:
@@ -33,18 +33,6 @@ import java.util.*;
|
|||||||
//There is strict forward only dataflow
|
//There is strict forward only dataflow
|
||||||
//Ingest -> world engine -> raw render data -> render data
|
//Ingest -> world engine -> raw render data -> render data
|
||||||
public class VoxelCore {
|
public class VoxelCore {
|
||||||
private static final Set<Block> biomeTintableAllFaces = new HashSet<>(List.of(Blocks.OAK_LEAVES, Blocks.JUNGLE_LEAVES, Blocks.ACACIA_LEAVES, Blocks.DARK_OAK_LEAVES, Blocks.VINE, Blocks.MANGROVE_LEAVES,
|
|
||||||
Blocks.TALL_GRASS, Blocks.LARGE_FERN,
|
|
||||||
Blocks.SHORT_GRASS,
|
|
||||||
|
|
||||||
Blocks.SPRUCE_LEAVES,
|
|
||||||
Blocks.BIRCH_LEAVES,
|
|
||||||
Blocks.PINK_PETALS,
|
|
||||||
Blocks.FERN, Blocks.POTTED_FERN));
|
|
||||||
private static final Set<Block> biomeTintableUpFace = new HashSet<>(List.of(Blocks.GRASS_BLOCK));
|
|
||||||
private static final Set<Block> waterTint = new HashSet<>(List.of(Blocks.WATER));
|
|
||||||
|
|
||||||
|
|
||||||
private final WorldEngine world;
|
private final WorldEngine world;
|
||||||
private final DistanceTracker distanceTracker;
|
private final DistanceTracker distanceTracker;
|
||||||
private final RenderGenerationService renderGen;
|
private final RenderGenerationService renderGen;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import me.cortex.zenith.client.core.gl.GlBuffer;
|
|||||||
import me.cortex.zenith.client.core.gl.GlTexture;
|
import me.cortex.zenith.client.core.gl.GlTexture;
|
||||||
import me.cortex.zenith.client.core.rendering.util.UploadStream;
|
import me.cortex.zenith.client.core.rendering.util.UploadStream;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.FluidBlock;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.render.RenderLayer;
|
import net.minecraft.client.render.RenderLayer;
|
||||||
import net.minecraft.client.render.RenderLayers;
|
import net.minecraft.client.render.RenderLayers;
|
||||||
@@ -97,6 +98,9 @@ public class ModelManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: what i need to do is seperate out fluid states from blockStates
|
||||||
|
|
||||||
|
|
||||||
//TODO: so need a few things, per face sizes and offsets, the sizes should be computed from the pixels and find the minimum bounding pixel
|
//TODO: so need a few things, per face sizes and offsets, the sizes should be computed from the pixels and find the minimum bounding pixel
|
||||||
// while the depth is computed from the depth buffer data
|
// while the depth is computed from the depth buffer data
|
||||||
public int addEntry(int blockId, BlockState blockState) {
|
public int addEntry(int blockId, BlockState blockState) {
|
||||||
@@ -104,8 +108,9 @@ public class ModelManager {
|
|||||||
throw new IllegalArgumentException("Trying to add entry for duplicate id");
|
throw new IllegalArgumentException("Trying to add entry for duplicate id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isFluid = blockState.getBlock() instanceof FluidBlock;
|
||||||
int modelId = -1;
|
int modelId = -1;
|
||||||
var textureData = this.bakery.renderFaces(blockState, 123456);
|
var textureData = this.bakery.renderFaces(blockState, 123456, isFluid);
|
||||||
{//Deduplicate same entries
|
{//Deduplicate same entries
|
||||||
int possibleDuplicate = this.modelTexture2id.getInt(List.of(textureData));
|
int possibleDuplicate = this.modelTexture2id.getInt(List.of(textureData));
|
||||||
if (possibleDuplicate != -1) {//Duplicate found
|
if (possibleDuplicate != -1) {//Duplicate found
|
||||||
@@ -122,9 +127,18 @@ public class ModelManager {
|
|||||||
|
|
||||||
var colourProvider = MinecraftClient.getInstance().getBlockColors().providers.get(Registries.BLOCK.getRawId(blockState.getBlock()));
|
var colourProvider = MinecraftClient.getInstance().getBlockColors().providers.get(Registries.BLOCK.getRawId(blockState.getBlock()));
|
||||||
|
|
||||||
var blockRenderLayer = RenderLayers.getBlockLayer(blockState);
|
RenderLayer blockRenderLayer = null;
|
||||||
|
if (blockState.getBlock() instanceof FluidBlock) {
|
||||||
|
blockRenderLayer = RenderLayers.getFluidLayer(blockState.getFluidState());
|
||||||
|
} else {
|
||||||
|
blockRenderLayer = RenderLayers.getBlockLayer(blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int checkMode = blockRenderLayer==RenderLayer.getSolid()?TextureUtils.WRITE_CHECK_STENCIL:TextureUtils.WRITE_CHECK_ALPHA;
|
int checkMode = blockRenderLayer==RenderLayer.getSolid()?TextureUtils.WRITE_CHECK_STENCIL:TextureUtils.WRITE_CHECK_ALPHA;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//If it is the solid layer, it is _always_ going to occlude fully for all written pixels, even if they are 100% translucent, this should save alot of resources
|
//If it is the solid layer, it is _always_ going to occlude fully for all written pixels, even if they are 100% translucent, this should save alot of resources
|
||||||
// if it is cutout it might occlude might not, need to test
|
// if it is cutout it might occlude might not, need to test
|
||||||
// if it is translucent it will _never_ occlude
|
// if it is translucent it will _never_ occlude
|
||||||
@@ -183,6 +197,7 @@ public class ModelManager {
|
|||||||
metadata |= hasBiomeColourResolver?1:0;
|
metadata |= hasBiomeColourResolver?1:0;
|
||||||
metadata |= blockRenderLayer == RenderLayer.getTranslucent()?2:0;
|
metadata |= blockRenderLayer == RenderLayer.getTranslucent()?2:0;
|
||||||
metadata |= needsDoubleSidedQuads?4:0;
|
metadata |= needsDoubleSidedQuads?4:0;
|
||||||
|
metadata |= (!blockState.getFluidState().isEmpty())?8:0;//Has a fluid state accosiacted with it
|
||||||
|
|
||||||
//TODO: add a bunch of control config options for overriding/setting options of metadata for each face of each type
|
//TODO: add a bunch of control config options for overriding/setting options of metadata for each face of each type
|
||||||
for (int face = 5; face != -1; face--) {//In reverse order to make indexing into the metadata long easier
|
for (int face = 5; face != -1; face--) {//In reverse order to make indexing into the metadata long easier
|
||||||
@@ -285,6 +300,9 @@ public class ModelManager {
|
|||||||
return ((metadata>>(8*6))&2) != 0;
|
return ((metadata>>(8*6))&2) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean containsFluid(long metadata) {
|
||||||
|
return ((metadata>>(8*6))&8) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -316,7 +334,7 @@ public class ModelManager {
|
|||||||
public long getModelMetadata(int blockId) {
|
public long getModelMetadata(int blockId) {
|
||||||
int map = this.idMappings[blockId];
|
int map = this.idMappings[blockId];
|
||||||
if (map == -1) {
|
if (map == -1) {
|
||||||
throw new IllegalArgumentException("Id hasnt been computed yet");
|
throw new IllegalArgumentException("Id hasnt been computed yet: " + blockId);
|
||||||
}
|
}
|
||||||
return this.metadataCache[map];
|
return this.metadataCache[map];
|
||||||
}
|
}
|
||||||
@@ -324,7 +342,7 @@ public class ModelManager {
|
|||||||
public int getModelId(int blockId) {
|
public int getModelId(int blockId) {
|
||||||
int map = this.idMappings[blockId];
|
int map = this.idMappings[blockId];
|
||||||
if (map == -1) {
|
if (map == -1) {
|
||||||
throw new IllegalArgumentException("Id hasnt been computed yet");
|
throw new IllegalArgumentException("Id hasnt been computed yet: " + blockId);
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,16 +10,27 @@ import me.cortex.zenith.client.core.gl.shader.Shader;
|
|||||||
import me.cortex.zenith.client.core.gl.shader.ShaderLoader;
|
import me.cortex.zenith.client.core.gl.shader.ShaderLoader;
|
||||||
import me.cortex.zenith.client.core.gl.shader.ShaderType;
|
import me.cortex.zenith.client.core.gl.shader.ShaderType;
|
||||||
import me.jellysquid.mods.sodium.client.gl.shader.GlShader;
|
import me.jellysquid.mods.sodium.client.gl.shader.GlShader;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.FluidBlock;
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gl.GlUniform;
|
import net.minecraft.client.gl.GlUniform;
|
||||||
import net.minecraft.client.render.*;
|
import net.minecraft.client.render.*;
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.fluid.FluidState;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.RotationAxis;
|
import net.minecraft.util.math.RotationAxis;
|
||||||
import net.minecraft.util.math.random.LocalRandom;
|
import net.minecraft.util.math.random.LocalRandom;
|
||||||
|
import net.minecraft.world.BlockRenderView;
|
||||||
|
import net.minecraft.world.LightType;
|
||||||
|
import net.minecraft.world.biome.ColorResolver;
|
||||||
|
import net.minecraft.world.chunk.light.LightingProvider;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.lwjgl.opengl.GL11C;
|
import org.lwjgl.opengl.GL11C;
|
||||||
|
|
||||||
@@ -86,7 +97,7 @@ public class ModelTextureBakery {
|
|||||||
|
|
||||||
//TODO: For block entities, also somehow attempt to render the default block entity, e.g. chests and stuff
|
//TODO: For block entities, also somehow attempt to render the default block entity, e.g. chests and stuff
|
||||||
// cause that will result in ok looking micro details in the terrain
|
// cause that will result in ok looking micro details in the terrain
|
||||||
public ColourDepthTextureData[] renderFaces(BlockState state, long randomValue) {
|
public ColourDepthTextureData[] renderFaces(BlockState state, long randomValue, boolean renderFluid) {
|
||||||
var model = MinecraftClient.getInstance()
|
var model = MinecraftClient.getInstance()
|
||||||
.getBakedModelManager()
|
.getBakedModelManager()
|
||||||
.getBlockModels()
|
.getBlockModels()
|
||||||
@@ -108,7 +119,13 @@ public class ModelTextureBakery {
|
|||||||
glBindFramebuffer(GL_FRAMEBUFFER, this.framebuffer.id);
|
glBindFramebuffer(GL_FRAMEBUFFER, this.framebuffer.id);
|
||||||
|
|
||||||
|
|
||||||
var renderLayer = RenderLayers.getBlockLayer(state);
|
RenderLayer renderLayer = null;
|
||||||
|
if (!renderFluid) {
|
||||||
|
renderLayer = RenderLayers.getBlockLayer(state);
|
||||||
|
} else {
|
||||||
|
renderLayer = RenderLayers.getFluidLayer(state.getFluidState());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
renderLayer.startDrawing();
|
renderLayer.startDrawing();
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
@@ -133,13 +150,10 @@ public class ModelTextureBakery {
|
|||||||
//TODO: TRANSLUCENT, must sort the quad first, or something idk
|
//TODO: TRANSLUCENT, must sort the quad first, or something idk
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.getFluidState().isEmpty()) {
|
|
||||||
//TODO: render fluid
|
|
||||||
}
|
|
||||||
|
|
||||||
var faces = new ColourDepthTextureData[FACE_VIEWS.size()];
|
var faces = new ColourDepthTextureData[FACE_VIEWS.size()];
|
||||||
for (int i = 0; i < faces.length; i++) {
|
for (int i = 0; i < faces.length; i++) {
|
||||||
faces[i] = captureView(state, model, FACE_VIEWS.get(i), randomValue);
|
faces[i] = captureView(state, model, FACE_VIEWS.get(i), randomValue, i, renderFluid);
|
||||||
//glBlitNamedFramebuffer(this.framebuffer.id, oldFB, 0,0,16,16,300*(i%3),300*(i/3),300*(i%3)+256,300*(i/3)+256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
//glBlitNamedFramebuffer(this.framebuffer.id, oldFB, 0,0,16,16,300*(i%3),300*(i/3),300*(i%3)+256,300*(i/3)+256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,17 +169,78 @@ public class ModelTextureBakery {
|
|||||||
return faces;
|
return faces;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ColourDepthTextureData captureView(BlockState state, BakedModel model, MatrixStack stack, long randomValue) {
|
private ColourDepthTextureData captureView(BlockState state, BakedModel model, MatrixStack stack, long randomValue, int face, boolean renderFluid) {
|
||||||
var vc = Tessellator.getInstance().getBuffer();
|
var vc = Tessellator.getInstance().getBuffer();
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
vc.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE);
|
vc.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE);
|
||||||
renderQuads(vc, state, model, stack, randomValue);
|
|
||||||
|
if (!renderFluid) {
|
||||||
|
renderQuads(vc, state, model, new MatrixStack(), randomValue);
|
||||||
|
} else {
|
||||||
|
MinecraftClient.getInstance().getBlockRenderManager().renderFluid(BlockPos.ORIGIN, new BlockRenderView() {
|
||||||
|
@Override
|
||||||
|
public float getBrightness(Direction direction, boolean shaded) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LightingProvider getLightingProvider() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLightLevel(LightType type, BlockPos pos) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColor(BlockPos pos, ColorResolver colorResolver) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public BlockEntity getBlockEntity(BlockPos pos) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: make it so it returns air on some positions, e.g. so from UP,
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(BlockPos pos) {
|
||||||
|
//TODO:FIXME: Dont hardcode
|
||||||
|
if (pos.equals(Direction.byId(face).getVector())) {
|
||||||
|
return Blocks.AIR.getDefaultState();
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidState getFluidState(BlockPos pos) {
|
||||||
|
if (pos.equals(Direction.byId(face).getVector())) {
|
||||||
|
return Blocks.AIR.getDefaultState().getFluidState();
|
||||||
|
}
|
||||||
|
return state.getFluidState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHeight() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBottomY() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}, vc, state, state.getFluidState());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
float[] mat = new float[4*4];
|
float[] mat = new float[4*4];
|
||||||
RenderSystem.getProjectionMatrix().get(mat);
|
new Matrix4f(RenderSystem.getProjectionMatrix()).mul(stack.peek().getPositionMatrix()).get(mat);
|
||||||
glUniformMatrix4fv(1, false, mat);
|
glUniformMatrix4fv(1, false, mat);
|
||||||
BufferRenderer.draw(vc.end());
|
BufferRenderer.draw(vc.end());
|
||||||
|
|
||||||
|
|
||||||
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
|
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
|
||||||
int[] colourData = new int[this.width*this.height];
|
int[] colourData = new int[this.width*this.height];
|
||||||
int[] depthData = new int[this.width*this.height];
|
int[] depthData = new int[this.width*this.height];
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package me.cortex.zenith.client.core.rendering;
|
package me.cortex.zenith.client.core.rendering;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import me.cortex.zenith.client.core.gl.GlBuffer;
|
import me.cortex.zenith.client.core.gl.GlBuffer;
|
||||||
import me.cortex.zenith.client.core.gl.shader.Shader;
|
import me.cortex.zenith.client.core.gl.shader.Shader;
|
||||||
@@ -109,7 +110,7 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//this.models.addEntry(0, Blocks.OAK_FENCE.getDefaultState());
|
//this.models.addEntry(0, Blocks.STONE.getDefaultState());
|
||||||
|
|
||||||
|
|
||||||
RenderLayer.getCutoutMipped().startDrawing();
|
RenderLayer.getCutoutMipped().startDrawing();
|
||||||
@@ -169,6 +170,8 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
|
|||||||
RenderLayer.getTranslucent().startDrawing();
|
RenderLayer.getTranslucent().startDrawing();
|
||||||
glBindVertexArray(this.vao);
|
glBindVertexArray(this.vao);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.blendFuncSeparate(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SrcFactor.ONE, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
int oldActiveTexture = glGetInteger(GL_ACTIVE_TEXTURE);
|
int oldActiveTexture = glGetInteger(GL_ACTIVE_TEXTURE);
|
||||||
int oldBoundTexture = glGetInteger(GL_TEXTURE_BINDING_2D);
|
int oldBoundTexture = glGetInteger(GL_TEXTURE_BINDING_2D);
|
||||||
@@ -178,14 +181,18 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
|
|||||||
glBindTexture(GL_TEXTURE_2D, this.models.getTextureId());
|
glBindTexture(GL_TEXTURE_2D, this.models.getTextureId());
|
||||||
this.lodShader.bind();
|
this.lodShader.bind();
|
||||||
|
|
||||||
|
glDepthMask(false);
|
||||||
glMultiDrawElementsIndirectCountARB(GL_TRIANGLES, GL_UNSIGNED_SHORT, 400_000 * 4 * 5, 4, this.geometry.getSectionCount(), 0);
|
glMultiDrawElementsIndirectCountARB(GL_TRIANGLES, GL_UNSIGNED_SHORT, 400_000 * 4 * 5, 4, this.geometry.getSectionCount(), 0);
|
||||||
|
glDepthMask(true);
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
|
||||||
glBindSampler(0, 0);
|
glBindSampler(0, 0);
|
||||||
GL11C.glBindTexture(GL_TEXTURE_2D, oldBoundTexture);
|
GL11C.glBindTexture(GL_TEXTURE_2D, oldBoundTexture);
|
||||||
glActiveTexture(oldActiveTexture);
|
glActiveTexture(oldActiveTexture);
|
||||||
|
RenderSystem.disableBlend();
|
||||||
|
|
||||||
RenderLayer.getTranslucent().endDrawing();
|
RenderLayer.getTranslucent().endDrawing();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import me.cortex.zenith.common.util.MemoryBuffer;
|
|||||||
import me.cortex.zenith.common.world.WorldEngine;
|
import me.cortex.zenith.common.world.WorldEngine;
|
||||||
import me.cortex.zenith.common.world.WorldSection;
|
import me.cortex.zenith.common.world.WorldSection;
|
||||||
import me.cortex.zenith.common.world.other.Mapper;
|
import me.cortex.zenith.common.world.other.Mapper;
|
||||||
|
import net.minecraft.block.FluidBlock;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
@@ -210,6 +211,25 @@ public class RenderDataFactory {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: if the model has a fluid state, it should compute if a fluid face needs to be injected
|
||||||
|
// fluid face of type this.world.getMapper().getBlockStateFromId(self).getFluidState() and block type
|
||||||
|
// this.world.getMapper().getBlockStateFromId(self).getFluidState().getBlockState()
|
||||||
|
|
||||||
|
//If we are a fluid and the oposing face is also a fluid need to make a closer check
|
||||||
|
if (ModelManager.containsFluid(metadata) && ModelManager.containsFluid(facingMetadata)) {
|
||||||
|
//if (this.world.getMapper().getBlockStateFromId(self).getFluidState() != this.world.getMapper().getBlockStateFromId(facingState).getFluidState()) {
|
||||||
|
// TODO: need to inject a face here of type fluid, how? i have no god damn idea, probably add an auxilery mesher just for this
|
||||||
|
//}
|
||||||
|
|
||||||
|
//Hackfix
|
||||||
|
var selfBS = this.world.getMapper().getBlockStateFromId(self);
|
||||||
|
if (selfBS.getBlock() instanceof FluidBlock && selfBS.getFluidState().getBlockState().getBlock() == this.world.getMapper().getBlockStateFromId(facingState).getFluidState().getBlockState().getBlock()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int clientModelId = this.modelMan.getModelId(selfBlockId);
|
int clientModelId = this.modelMan.getModelId(selfBlockId);
|
||||||
long otherFlags = 0;
|
long otherFlags = 0;
|
||||||
otherFlags |= ModelManager.isTranslucent(metadata)?1L<<33:0;
|
otherFlags |= ModelManager.isTranslucent(metadata)?1L<<33:0;
|
||||||
|
|||||||
@@ -1,337 +0,0 @@
|
|||||||
package me.cortex.zenith.client.core.rendering.building;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
|
||||||
import me.cortex.zenith.common.util.MemoryBuffer;
|
|
||||||
import me.cortex.zenith.client.core.util.Mesher2D;
|
|
||||||
import me.cortex.zenith.common.world.WorldEngine;
|
|
||||||
import me.cortex.zenith.common.world.WorldSection;
|
|
||||||
import me.cortex.zenith.common.world.other.Mapper;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
|
||||||
|
|
||||||
|
|
||||||
public class RenderDataFactoryOld {
|
|
||||||
/*
|
|
||||||
private final Mesher2D mesher = new Mesher2D(5,15);//15
|
|
||||||
private final LongArrayList outData = new LongArrayList(1000);
|
|
||||||
private final WorldEngine world;
|
|
||||||
private final long[] sectionCache = new long[32*32*32];
|
|
||||||
private final long[] connectedSectionCache = new long[32*32*32];
|
|
||||||
private final QuadEncoder encoder;
|
|
||||||
public RenderDataFactoryOld(WorldEngine world) {
|
|
||||||
this.world = world;
|
|
||||||
this.encoder = new QuadEncoder(world.getMapper(), MinecraftClient.getInstance().getBlockColors(), MinecraftClient.getInstance().world);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: MAKE a render cache that caches each WorldSection directional face generation, cause then can just pull that directly
|
|
||||||
// instead of needing to regen the entire thing
|
|
||||||
|
|
||||||
|
|
||||||
//section is already acquired and gets released by the parent
|
|
||||||
|
|
||||||
//buildMask in the lower 6 bits contains the faces to build, the next 6 bits are whether the edge face builds against
|
|
||||||
// its neigbor or not (0 if it does 1 if it doesnt (0 is default behavior))
|
|
||||||
public void generateMesh(WorldSection section, int buildMask) {
|
|
||||||
//TODO: to speed it up more, check like section.isEmpty() and stuff like that, have masks for if a slice/layer is entirly air etc
|
|
||||||
|
|
||||||
//TODO: instead of having it check its neighbors with the same lod level, compare against 1 level lower, this will prevent cracks and seams from
|
|
||||||
// appearing between lods
|
|
||||||
|
|
||||||
|
|
||||||
//if (section.definitelyEmpty()) {//Fast path if its known the entire chunk is empty
|
|
||||||
// return new BuiltSectionGeometry(section.getKey(), null, null);
|
|
||||||
//}
|
|
||||||
|
|
||||||
section.copyDataTo(this.sectionCache);
|
|
||||||
var data = this.sectionCache;
|
|
||||||
|
|
||||||
long[] connectedData = null;
|
|
||||||
int dirId = Direction.UP.getId();
|
|
||||||
if ((buildMask&(1<<dirId))!=0) {
|
|
||||||
for (int y = 0; y < 32; y++) {
|
|
||||||
this.mesher.reset();
|
|
||||||
|
|
||||||
for (int z = 0; z < 32; z++) {
|
|
||||||
for (int x = 0; x < 32; x++) {
|
|
||||||
var self = data[WorldSection.getIndex(x, y, z)];
|
|
||||||
if (Mapper.isAir(self)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long up = -1;
|
|
||||||
if (y < 31) {
|
|
||||||
up = data[WorldSection.getIndex(x, y + 1, z)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (y == 31 && ((buildMask>>(6+dirId))&1) == 0) {
|
|
||||||
//Load and copy the data into a local cache, TODO: optimize so its not doing billion of copies
|
|
||||||
if (connectedData == null) {
|
|
||||||
var connectedSection = this.world.acquire(section.lvl, section.x, section.y + 1, section.z);
|
|
||||||
connectedSection.copyDataTo(this.connectedSectionCache);
|
|
||||||
connectedData = this.connectedSectionCache;
|
|
||||||
connectedSection.release();
|
|
||||||
}
|
|
||||||
up = connectedData[WorldSection.getIndex(x, 0, z)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Recodes the id to include the correct lighting
|
|
||||||
this.mesher.put(x, z, (self&~(0xFFL<<56))|(up&(0xFFL<<56)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var count = this.mesher.process();
|
|
||||||
var array = this.mesher.getArray();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
var quad = array[i];
|
|
||||||
this.outData.add(this.encoder.encode(this.mesher.getDataFromQuad(quad), 1, y, quad));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
connectedData = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirId = Direction.EAST.getId();
|
|
||||||
if ((buildMask&(1<<dirId))!=0) {
|
|
||||||
for (int x = 0; x < 32; x++) {
|
|
||||||
this.mesher.reset();
|
|
||||||
|
|
||||||
for (int y = 0; y < 32; y++) {
|
|
||||||
for (int z = 0; z < 32; z++) {
|
|
||||||
var self = data[WorldSection.getIndex(x, y, z)];
|
|
||||||
if (Mapper.isAir(self)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long up = -1;
|
|
||||||
if (x < 31) {
|
|
||||||
up = data[WorldSection.getIndex(x + 1, y, z)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (x == 31 && ((buildMask>>(6+dirId))&1) == 0) {
|
|
||||||
//Load and copy the data into a local cache, TODO: optimize so its not doing billion of copies
|
|
||||||
if (connectedData == null) {
|
|
||||||
var connectedSection = this.world.acquire(section.lvl, section.x + 1, section.y, section.z);
|
|
||||||
connectedSection.copyDataTo(this.connectedSectionCache);
|
|
||||||
connectedData = this.connectedSectionCache;
|
|
||||||
connectedSection.release();
|
|
||||||
}
|
|
||||||
up = connectedData[WorldSection.getIndex(0, y, z)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.mesher.put(y, z, (self&~(0xFFL<<56))|(up&(0xFFL<<56)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var count = this.mesher.process();
|
|
||||||
var array = this.mesher.getArray();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
var quad = array[i];
|
|
||||||
this.outData.add(this.encoder.encode(this.mesher.getDataFromQuad(quad), 5, x, quad));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
connectedData = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirId = Direction.SOUTH.getId();
|
|
||||||
if ((buildMask&(1<<dirId))!=0) {
|
|
||||||
for (int z = 0; z < 32; z++) {
|
|
||||||
this.mesher.reset();
|
|
||||||
|
|
||||||
for (int x = 0; x < 32; x++) {
|
|
||||||
for (int y = 0; y < 32; y++) {
|
|
||||||
var self = data[WorldSection.getIndex(x, y, z)];
|
|
||||||
if (Mapper.isAir(self)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long up = -1;
|
|
||||||
if (z < 31) {
|
|
||||||
up = data[WorldSection.getIndex(x, y, z + 1)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (z == 31 && ((buildMask>>(6+dirId))&1) == 0) {
|
|
||||||
//Load and copy the data into a local cache, TODO: optimize so its not doing billion of copies
|
|
||||||
if (connectedData == null) {
|
|
||||||
var connectedSection = this.world.acquire(section.lvl, section.x, section.y, section.z + 1);
|
|
||||||
connectedSection.copyDataTo(this.connectedSectionCache);
|
|
||||||
connectedData = this.connectedSectionCache;
|
|
||||||
connectedSection.release();
|
|
||||||
}
|
|
||||||
up = connectedData[WorldSection.getIndex(x, y, 0)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.mesher.put(x, y, (self&~(0xFFL<<56))|(up&(0xFFL<<56)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var count = this.mesher.process();
|
|
||||||
var array = this.mesher.getArray();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
var quad = array[i];
|
|
||||||
this.outData.add(this.encoder.encode(this.mesher.getDataFromQuad(quad), 3, z, quad));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
connectedData = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirId = Direction.WEST.getId();
|
|
||||||
if ((buildMask&(1<<dirId))!=0) {
|
|
||||||
for (int x = 31; x != -1; x--) {
|
|
||||||
this.mesher.reset();
|
|
||||||
|
|
||||||
for (int y = 0; y < 32; y++) {
|
|
||||||
for (int z = 0; z < 32; z++) {
|
|
||||||
var self = data[WorldSection.getIndex(x, y, z)];
|
|
||||||
if (Mapper.isAir(self)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long up = -1;
|
|
||||||
if (x != 0) {
|
|
||||||
up = data[WorldSection.getIndex(x - 1, y, z)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (x == 0 && ((buildMask>>(6+dirId))&1) == 0) {
|
|
||||||
//Load and copy the data into a local cache, TODO: optimize so its not doing billion of copies
|
|
||||||
if (connectedData == null) {
|
|
||||||
var connectedSection = this.world.acquire(section.lvl, section.x - 1, section.y, section.z);
|
|
||||||
connectedSection.copyDataTo(this.connectedSectionCache);
|
|
||||||
connectedData = this.connectedSectionCache;
|
|
||||||
connectedSection.release();
|
|
||||||
}
|
|
||||||
up = connectedData[WorldSection.getIndex(31, y, z)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.mesher.put(y, z, (self&~(0xFFL<<56))|(up&(0xFFL<<56)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var count = this.mesher.process();
|
|
||||||
var array = this.mesher.getArray();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
var quad = array[i];
|
|
||||||
this.outData.add(this.encoder.encode(this.mesher.getDataFromQuad(quad), 4, x, quad));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
connectedData = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirId = Direction.NORTH.getId();
|
|
||||||
if ((buildMask&(1<<dirId))!=0) {
|
|
||||||
for (int z = 31; z != -1; z--) {
|
|
||||||
this.mesher.reset();
|
|
||||||
|
|
||||||
for (int x = 0; x < 32; x++) {
|
|
||||||
for (int y = 0; y < 32; y++) {
|
|
||||||
var self = data[WorldSection.getIndex(x, y, z)];
|
|
||||||
if (Mapper.isAir(self)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long up = -1;
|
|
||||||
if (z != 0) {
|
|
||||||
up = data[WorldSection.getIndex(x, y, z - 1)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (z == 0 && ((buildMask>>(6+dirId))&1) == 0) {
|
|
||||||
//Load and copy the data into a local cache, TODO: optimize so its not doing billion of copies
|
|
||||||
if (connectedData == null) {
|
|
||||||
var connectedSection = this.world.acquire(section.lvl, section.x, section.y, section.z - 1);
|
|
||||||
connectedSection.copyDataTo(this.connectedSectionCache);
|
|
||||||
connectedData = this.connectedSectionCache;
|
|
||||||
connectedSection.release();
|
|
||||||
}
|
|
||||||
up = connectedData[WorldSection.getIndex(x, y, 31)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.mesher.put(x, y, (self&~(0xFFL<<56))|(up&(0xFFL<<56)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var count = this.mesher.process();
|
|
||||||
var array = this.mesher.getArray();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
var quad = array[i];
|
|
||||||
this.outData.add(this.encoder.encode(this.mesher.getDataFromQuad(quad), 2, z, quad));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
connectedData = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirId = Direction.DOWN.getId();
|
|
||||||
if ((buildMask&(1<<dirId))!=0) {
|
|
||||||
for (int y = 31; y != -1; y--) {
|
|
||||||
this.mesher.reset();
|
|
||||||
|
|
||||||
for (int x = 0; x < 32; x++) {
|
|
||||||
for (int z = 0; z < 32; z++) {
|
|
||||||
var self = data[WorldSection.getIndex(x, y, z)];
|
|
||||||
if (Mapper.isAir(self)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long up = -1;
|
|
||||||
if (y != 0) {
|
|
||||||
up = data[WorldSection.getIndex(x, y - 1, z)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (y == 0 && ((buildMask>>(6+dirId))&1) == 0) {
|
|
||||||
//Load and copy the data into a local cache, TODO: optimize so its not doing billion of copies
|
|
||||||
if (connectedData == null) {
|
|
||||||
var connectedSection = this.world.acquire(section.lvl, section.x, section.y - 1, section.z);
|
|
||||||
connectedSection.copyDataTo(this.connectedSectionCache);
|
|
||||||
connectedData = this.connectedSectionCache;
|
|
||||||
connectedSection.release();
|
|
||||||
}
|
|
||||||
up = connectedData[WorldSection.getIndex(x, 31, z)];
|
|
||||||
if (!Mapper.isTranslucent(up)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.mesher.put(x, z, (self&~(0xFFL<<56))|(up&(0xFFL<<56)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var count = this.mesher.process();
|
|
||||||
var array = this.mesher.getArray();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
var quad = array[i];
|
|
||||||
this.outData.add(this.encoder.encode(this.mesher.getDataFromQuad(quad), 0, y, quad));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
connectedData = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (this.outData.isEmpty()) {
|
|
||||||
//return new BuiltSectionGeometry(section.getKey(), null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
var output = new MemoryBuffer(this.outData.size()*8L);
|
|
||||||
for (int i = 0; i < this.outData.size(); i++) {
|
|
||||||
MemoryUtil.memPutLong(output.address + i * 8L, this.outData.getLong(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.outData.clear();
|
|
||||||
//return new BuiltSectionGeometry(section.getKey(), output, null);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user