Add far fade
This commit is contained in:
+349
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.renderTest;
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.buffers.Std140Builder;
|
||||
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.platform.DepthTestFunction;
|
||||
import com.mojang.blaze3d.platform.PolygonMode;
|
||||
import com.mojang.blaze3d.shaders.UniformType;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.*;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcFarFadeRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcVanillaFadeRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Renders a TODO
|
||||
*/
|
||||
public class McFarFadeRenderer implements IMcFarFadeRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
|
||||
|
||||
public static final McFarFadeRenderer INSTANCE = new McFarFadeRenderer();
|
||||
|
||||
private VertexFormat vertexFormat;
|
||||
private RenderPipeline pipeline;
|
||||
private boolean init = false;
|
||||
|
||||
private GpuBuffer fragUniformBuffer;
|
||||
|
||||
private GpuBuffer vboGpuBuffer;
|
||||
|
||||
public GpuTexture fadeColorTexture;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private McFarFadeRenderer()
|
||||
{
|
||||
this.vertexFormat = VertexFormat.builder()
|
||||
.add("vPosition", DhVertexFormat.SCREEN_POS)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void tryInit()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
|
||||
|
||||
GpuDevice gpuDevice = RenderSystem.getDevice();
|
||||
CommandEncoder commandEncoder = gpuDevice.createCommandEncoder();
|
||||
|
||||
|
||||
|
||||
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
|
||||
{
|
||||
pipelineBuilder.withCull(false);
|
||||
pipelineBuilder.withDepthWrite(false);
|
||||
pipelineBuilder.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withoutBlend();
|
||||
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
|
||||
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:far_fade"));
|
||||
|
||||
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "fade/vert"));
|
||||
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "fade/dh_fade"));
|
||||
|
||||
pipelineBuilder.withSampler("uMcColorTexture");
|
||||
|
||||
pipelineBuilder.withSampler("uDhDepthTexture");
|
||||
pipelineBuilder.withSampler("uDhColorTexture");
|
||||
|
||||
pipelineBuilder.withUniform("fragUniformBlock", UniformType.UNIFORM_BUFFER);
|
||||
|
||||
pipelineBuilder.withVertexFormat(this.vertexFormat, VertexFormat.Mode.TRIANGLE_FAN);
|
||||
}
|
||||
this.pipeline = pipelineBuilder.build();
|
||||
|
||||
|
||||
// upload vertex data
|
||||
{
|
||||
// vertices for a full-screen quad
|
||||
float[] vertices = new float[]
|
||||
{
|
||||
// PosX,Y,
|
||||
-1f, -1f,
|
||||
1f, -1f,
|
||||
1f, 1f,
|
||||
-1f, 1f,
|
||||
};
|
||||
|
||||
|
||||
Supplier<String> labelSupplier = () -> "distantHorizons:McFadeRenderer";
|
||||
int usage = 8 | 32; // is this just using OpenGL VBO flags?, if so I can't find it, supposedly GlDevice on Mojang's side
|
||||
int size = vertices.length * Float.BYTES;
|
||||
this.vboGpuBuffer = gpuDevice.createBuffer(labelSupplier, usage, size);
|
||||
|
||||
{
|
||||
int offset = 0;
|
||||
int length = vertices.length * Float.BYTES;
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vboGpuBuffer, offset, length);
|
||||
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * Float.BYTES);
|
||||
// Fill buffer with vertices.
|
||||
byteBuffer.order(ByteOrder.nativeOrder());
|
||||
byteBuffer.asFloatBuffer().put(vertices);
|
||||
byteBuffer.rewind();
|
||||
|
||||
commandEncoder.writeToBuffer(bufferSlice, byteBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
@Override // TODO can probably just be DH mvm/proj matricies
|
||||
public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix)
|
||||
{
|
||||
this.tryInit();
|
||||
|
||||
|
||||
if (McLodRenderer.INSTANCE.dhDepthTexture == null
|
||||
|| McLodRenderer.INSTANCE.dhColorTexture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GpuDevice gpuDevice = RenderSystem.getDevice();
|
||||
CommandEncoder commandEncoder = gpuDevice.createCommandEncoder();
|
||||
|
||||
|
||||
|
||||
// textures
|
||||
if (this.fadeColorTexture == null
|
||||
|| this.fadeColorTexture.getWidth(0) != MC_RENDER.getTargetFramebufferViewportWidth()
|
||||
|| this.fadeColorTexture.getHeight(0) != MC_RENDER.getTargetFramebufferViewportHeight())
|
||||
{
|
||||
if (this.fadeColorTexture != null)
|
||||
{
|
||||
this.fadeColorTexture.close();
|
||||
}
|
||||
|
||||
// TODO USAGE_TEXTURE_BINDING = 4
|
||||
int usage = 4 | 8 | 32 | 128;
|
||||
this.fadeColorTexture = gpuDevice.createTexture("FadeColorTexture",
|
||||
usage,
|
||||
TextureFormat.RGBA8,
|
||||
MC_RENDER.getTargetFramebufferViewportWidth(), MC_RENDER.getTargetFramebufferViewportHeight(),
|
||||
1, 1
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putFloat() // uStartFadeBlockDistance
|
||||
.putFloat() // uEndFadeBlockDistance
|
||||
.putMat4f() // uDhInvMvmProj
|
||||
.get();
|
||||
|
||||
|
||||
// create data //
|
||||
|
||||
float dhFarClipDistance = RenderUtil.getFarClipPlaneDistanceInBlocks();
|
||||
float fadeStartDistance = dhFarClipDistance * 0.5f;
|
||||
float fadeEndDistance = dhFarClipDistance * 0.9f;
|
||||
|
||||
|
||||
Mat4f dhProjectionMatrix = RenderUtil.createLodProjectionMatrix(mcProjectionMatrix);
|
||||
Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(mcModelViewMatrix);
|
||||
|
||||
Mat4f inverseDhModelViewProjectionMatrix = new Mat4f(dhProjectionMatrix);
|
||||
inverseDhModelViewProjectionMatrix.multiply(dhModelViewMatrix);
|
||||
inverseDhModelViewProjectionMatrix.invert();
|
||||
Mat4f inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix;
|
||||
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
buffer = Std140Builder.intoBuffer(buffer)
|
||||
.putFloat(fadeStartDistance) // uStartFadeBlockDistance
|
||||
.putFloat(fadeEndDistance) // uEndFadeBlockDistance
|
||||
.putMat4f(inverseDhMvmProjMatrix.createJomlMatrix()) // uDhInvMvmProj
|
||||
.get()
|
||||
;
|
||||
|
||||
this.fragUniformBuffer = UniformHandler.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
commandEncoder.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
|
||||
|
||||
this.renderFadeToTexture();
|
||||
McCopyRenderer.INSTANCE.render(this.fadeColorTexture, McLodRenderer.INSTANCE.dhColorTexture);
|
||||
|
||||
}
|
||||
|
||||
private void renderFadeToTexture()
|
||||
{
|
||||
GpuDevice gpuDevice = RenderSystem.getDevice();
|
||||
CommandEncoder commandEncoder = gpuDevice.createCommandEncoder();
|
||||
|
||||
// create a render pass
|
||||
Supplier<String> debugLabelSupplier = () -> "distantHorizons:McFadeRenderer";
|
||||
GpuTextureView colorTexture = gpuDevice.createTextureView(this.fadeColorTexture);
|
||||
OptionalInt optionalClearColorAsInt = OptionalInt.empty();
|
||||
GpuTextureView depthTexture = null;
|
||||
OptionalDouble optionalDepthValueAsDouble = OptionalDouble.empty();
|
||||
|
||||
try (RenderPass renderPass = commandEncoder.createRenderPass(
|
||||
debugLabelSupplier,
|
||||
colorTexture,
|
||||
optionalClearColorAsInt,
|
||||
depthTexture, optionalDepthValueAsDouble))
|
||||
{
|
||||
//renderPass.pushDebugGroup();
|
||||
//renderPass.popDebugGroup();
|
||||
|
||||
|
||||
// render pass setup
|
||||
{
|
||||
// bind MC color texture
|
||||
{
|
||||
GpuTextureView textureView = gpuDevice.createTextureView(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
|
||||
GpuSampler gpuSampler = gpuDevice.createSampler(
|
||||
AddressMode.CLAMP_TO_EDGE, AddressMode.CLAMP_TO_EDGE, // U,V
|
||||
FilterMode.NEAREST, FilterMode.NEAREST, // minFilter, magFilter
|
||||
1, // maxAnisotropy
|
||||
OptionalDouble.empty() // maxLod
|
||||
);
|
||||
renderPass.bindTexture("uMcColorTexture", textureView, gpuSampler);
|
||||
}
|
||||
|
||||
|
||||
// bind DH depth texture
|
||||
{
|
||||
GpuTextureView textureView = gpuDevice.createTextureView(McLodRenderer.INSTANCE.dhDepthTexture);
|
||||
GpuSampler gpuSampler = gpuDevice.createSampler(
|
||||
AddressMode.CLAMP_TO_EDGE, AddressMode.CLAMP_TO_EDGE, // U,V
|
||||
FilterMode.NEAREST, FilterMode.NEAREST, // minFilter, magFilter
|
||||
1, // maxAnisotropy
|
||||
OptionalDouble.empty() // maxLod
|
||||
);
|
||||
renderPass.bindTexture("uDhDepthTexture", textureView, gpuSampler);
|
||||
}
|
||||
|
||||
// bind DH color texture
|
||||
{
|
||||
GpuTextureView textureView = gpuDevice.createTextureView(McLodRenderer.INSTANCE.dhColorTexture);
|
||||
GpuSampler gpuSampler = gpuDevice.createSampler(
|
||||
AddressMode.CLAMP_TO_EDGE, AddressMode.CLAMP_TO_EDGE, // U,V
|
||||
FilterMode.NEAREST, FilterMode.NEAREST, // minFilter, magFilter
|
||||
1, // maxAnisotropy
|
||||
OptionalDouble.empty() // maxLod
|
||||
);
|
||||
renderPass.bindTexture("uDhColorTexture", textureView, gpuSampler);
|
||||
}
|
||||
|
||||
|
||||
|
||||
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer);
|
||||
|
||||
// bind VBO
|
||||
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol
|
||||
|
||||
// set pipeline
|
||||
renderPass.setPipeline(this.pipeline);
|
||||
}
|
||||
|
||||
// draw render pass
|
||||
{
|
||||
int indexStart = 0;
|
||||
int indexCount = 4;
|
||||
renderPass.draw(indexStart, indexCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
-779
@@ -1,779 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.renderTest;
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.buffers.Std140Builder;
|
||||
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
||||
import com.mojang.blaze3d.pipeline.BlendFunction;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.platform.DepthTestFunction;
|
||||
import com.mojang.blaze3d.platform.PolygonMode;
|
||||
import com.mojang.blaze3d.shaders.UniformType;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.AddressMode;
|
||||
import com.mojang.blaze3d.textures.FilterMode;
|
||||
import com.mojang.blaze3d.textures.GpuSampler;
|
||||
import com.mojang.blaze3d.textures.GpuTextureView;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericObjectRenderEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericRenderCleanupEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericRenderSetupEvent;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
|
||||
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||
import com.seibel.distanthorizons.core.render.renderer.RenderParams;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.GenericRenderObjectFactory;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.InstancedVboContainer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.RenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.awt.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Handles rendering generic groups of {@link DhApiRenderableBox}.
|
||||
*
|
||||
* @see IDhApiCustomRenderRegister
|
||||
* @see DhApiRenderableBox
|
||||
*/
|
||||
public class McGenericObjectRenderer_Textures implements IMcGenericRenderer
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
|
||||
|
||||
private static final DhApiRenderableBoxGroupShading DEFAULT_SHADING = DhApiRenderableBoxGroupShading.getUnshaded();
|
||||
|
||||
/**
|
||||
* Can be used to troubleshoot the renderer.
|
||||
* If enabled several debug objects will render around (0,150,0).
|
||||
*/
|
||||
public static final boolean RENDER_DEBUG_OBJECTS = false;
|
||||
|
||||
/** A box from 0,0,0 to 1,1,1 */
|
||||
private static final float[] BOX_VERTICES = {
|
||||
//region
|
||||
// Pos x y z
|
||||
|
||||
// min X, vertical face
|
||||
0, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
// max X, vertical face
|
||||
0, 1, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 1,
|
||||
|
||||
// min Z, vertical face
|
||||
0, 0, 1,
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 1,
|
||||
// max Z, vertical face
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 1, 0,
|
||||
1, 0, 0,
|
||||
|
||||
// min Y, horizontal face
|
||||
0, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
// max Y, horizontal face
|
||||
0, 1, 1,
|
||||
1, 1, 1,
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
//endregion
|
||||
};
|
||||
|
||||
private static final int[] BOX_INDICES = {
|
||||
//region
|
||||
// min X, vertical face
|
||||
2, 1, 0,
|
||||
0, 3, 2,
|
||||
// max X, vertical face
|
||||
6, 5, 4,
|
||||
4, 7, 6,
|
||||
|
||||
// min Z, vertical face
|
||||
10, 9, 8,
|
||||
8, 11, 10,
|
||||
// max Z, vertical face
|
||||
14, 13, 12,
|
||||
12, 15, 14,
|
||||
|
||||
// min Y, horizontal face
|
||||
18, 17, 16,
|
||||
16, 19, 18,
|
||||
// max Y, horizontal face
|
||||
20, 21, 22,
|
||||
22, 23, 20,
|
||||
//endregion
|
||||
};
|
||||
|
||||
private final ConcurrentHashMap<Long, RenderableBoxGroup> boxGroupById = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
// rendering setup
|
||||
private boolean init = false;
|
||||
|
||||
private VertexFormat vertexFormat;
|
||||
|
||||
private RenderPipeline opaquePipeline;
|
||||
private RenderPipeline transparentPipeline;
|
||||
|
||||
private GpuBuffer boxVertexBuffer;
|
||||
private GpuBuffer boxIndexBuffer;
|
||||
|
||||
private GpuBuffer fragUniformBuffer;
|
||||
private GpuBuffer vertUniformBuffer;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
public McGenericObjectRenderer_Textures() { }
|
||||
|
||||
public void init()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
this.vertexFormat = VertexFormat.builder()
|
||||
.add("vPosition", DhVertexFormat.FLOAT_XYZ_POS)
|
||||
.build();
|
||||
|
||||
this.createPipelines();
|
||||
this.createBuffers();
|
||||
|
||||
if (RENDER_DEBUG_OBJECTS)
|
||||
{
|
||||
this.addGenericDebugObjects();
|
||||
}
|
||||
}
|
||||
private void createPipelines()
|
||||
{
|
||||
GpuDevice gpuDevice = RenderSystem.getDevice();
|
||||
CommandEncoder commandEncoder = gpuDevice.createCommandEncoder();
|
||||
|
||||
|
||||
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
|
||||
{
|
||||
pipelineBuilder.withCull(true);
|
||||
pipelineBuilder.withDepthWrite(true);
|
||||
pipelineBuilder.withDepthTestFunction(DepthTestFunction.LESS_DEPTH_TEST);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
|
||||
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:generic"));
|
||||
|
||||
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "generic/vert"));
|
||||
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "generic/frag"));
|
||||
|
||||
pipelineBuilder.withSampler("uColorMap");
|
||||
|
||||
pipelineBuilder.withSampler("uLightMap");
|
||||
|
||||
pipelineBuilder.withUniform("vertUniformBlock", UniformType.UNIFORM_BUFFER);
|
||||
|
||||
pipelineBuilder.withVertexFormat(this.vertexFormat, VertexFormat.Mode.TRIANGLES);
|
||||
}
|
||||
|
||||
// opaque
|
||||
{
|
||||
pipelineBuilder.withoutBlend();
|
||||
this.opaquePipeline = pipelineBuilder.build();
|
||||
}
|
||||
|
||||
// transparent
|
||||
{
|
||||
pipelineBuilder.withBlend(BlendFunction.TRANSLUCENT);
|
||||
this.transparentPipeline = pipelineBuilder.build();
|
||||
}
|
||||
|
||||
}
|
||||
private void createBuffers()
|
||||
{
|
||||
// box vertices
|
||||
ByteBuffer boxVerticesBuffer = MemoryUtil.memAlloc(BOX_VERTICES.length * Float.BYTES);
|
||||
boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES);
|
||||
boxVerticesBuffer.rewind();
|
||||
MemoryUtil.memFree(boxVerticesBuffer);
|
||||
|
||||
|
||||
GpuDevice gpuDevice = RenderSystem.getDevice();
|
||||
CommandEncoder commandEncoder = gpuDevice.createCommandEncoder();
|
||||
|
||||
// upload vertex data
|
||||
{
|
||||
Supplier<String> labelSupplier = () -> "distantHorizons:McGenericRenderer";
|
||||
int usage = 8 | 32; // is this just using OpenGL VBO flags?, if so I can't find it, supposedly GlDevice on Mojang's side
|
||||
int size = BOX_VERTICES.length * Float.BYTES;
|
||||
this.boxVertexBuffer = gpuDevice.createBuffer(labelSupplier, usage, size);
|
||||
|
||||
{
|
||||
int offset = 0;
|
||||
int length = BOX_VERTICES.length * Float.BYTES;
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.boxVertexBuffer, offset, length);
|
||||
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES);
|
||||
// Fill buffer with vertices.
|
||||
byteBuffer.order(ByteOrder.nativeOrder());
|
||||
byteBuffer.asFloatBuffer().put(BOX_VERTICES);
|
||||
byteBuffer.rewind();
|
||||
|
||||
commandEncoder.writeToBuffer(bufferSlice, byteBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// box vertex indexes
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(BOX_INDICES.length * Integer.BYTES);
|
||||
buffer.asIntBuffer().put(BOX_INDICES);
|
||||
buffer.rewind();
|
||||
|
||||
|
||||
// TODO
|
||||
// GpuBuffer.USAGE_UNIFORM = 128
|
||||
// GpuBuffer.USAGE_INDEX = 64
|
||||
int usage = 8 | 32 | 64 | 128; // is this just using OpenGL VBO flags?, if so I can't find it, supposedly GlDevice on Mojang's side
|
||||
this.boxIndexBuffer = gpuDevice.createBuffer(() -> "DH Generic Index Buffer", usage, buffer.capacity());
|
||||
|
||||
int offset = 0;
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.boxIndexBuffer, offset, buffer.capacity());
|
||||
commandEncoder.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
}
|
||||
private void addGenericDebugObjects()
|
||||
{
|
||||
GenericRenderObjectFactory factory = GenericRenderObjectFactory.INSTANCE;
|
||||
|
||||
|
||||
// single giant box
|
||||
IDhApiRenderableBoxGroup singleGiantBoxGroup = factory.createForSingleBox(
|
||||
ModInfo.NAME + ":CyanChunkBox",
|
||||
new DhApiRenderableBox(
|
||||
new DhApiVec3d(0,0,0), new DhApiVec3d(16,190,16),
|
||||
new Color(Color.CYAN.getRed(), Color.CYAN.getGreen(), Color.CYAN.getBlue(), 125),
|
||||
EDhApiBlockMaterial.WATER)
|
||||
);
|
||||
singleGiantBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
|
||||
singleGiantBoxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT);
|
||||
this.add(singleGiantBoxGroup);
|
||||
|
||||
|
||||
// single slender box
|
||||
IDhApiRenderableBoxGroup singleTallBoxGroup = factory.createForSingleBox(
|
||||
ModInfo.NAME + ":GreenBeacon",
|
||||
new DhApiRenderableBox(
|
||||
new DhApiVec3d(16,0,31), new DhApiVec3d(17,2000,32),
|
||||
new Color(Color.GREEN.getRed(), Color.GREEN.getGreen(), Color.GREEN.getBlue(), 125),
|
||||
EDhApiBlockMaterial.ILLUMINATED)
|
||||
);
|
||||
singleTallBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
|
||||
singleTallBoxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT);
|
||||
this.add(singleTallBoxGroup);
|
||||
|
||||
|
||||
// absolute box group
|
||||
ArrayList<DhApiRenderableBox> absBoxList = new ArrayList<>();
|
||||
for (int i = 0; i < 18; i++)
|
||||
{
|
||||
absBoxList.add(new DhApiRenderableBox(
|
||||
new DhApiVec3d(i,150+i,24), new DhApiVec3d(1+i,151+i,25),
|
||||
new Color(Color.ORANGE.getRed(), Color.ORANGE.getGreen(), Color.ORANGE.getBlue()),
|
||||
EDhApiBlockMaterial.LAVA
|
||||
)
|
||||
);
|
||||
}
|
||||
IDhApiRenderableBoxGroup absolutePosBoxGroup = factory.createAbsolutePositionedGroup(ModInfo.NAME + ":OrangeStairs", absBoxList);
|
||||
this.add(absolutePosBoxGroup);
|
||||
|
||||
|
||||
// relative box group
|
||||
ArrayList<DhApiRenderableBox> relBoxList = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i+=2)
|
||||
{
|
||||
relBoxList.add(new DhApiRenderableBox(
|
||||
new DhApiVec3d(0,i,0), new DhApiVec3d(1,1+i,1),
|
||||
new Color(Color.MAGENTA.getRed(), Color.MAGENTA.getGreen(), Color.MAGENTA.getBlue()),
|
||||
EDhApiBlockMaterial.METAL
|
||||
)
|
||||
);
|
||||
}
|
||||
IDhApiRenderableBoxGroup relativePosBoxGroup = factory.createRelativePositionedGroup(
|
||||
ModInfo.NAME + ":MovingMagentaGroup",
|
||||
new DhApiVec3d(24, 140, 24),
|
||||
relBoxList);
|
||||
relativePosBoxGroup.setPreRenderFunc((event) ->
|
||||
{
|
||||
DhApiVec3d pos = relativePosBoxGroup.getOriginBlockPos();
|
||||
pos.x += event.partialTicks / 2;
|
||||
pos.x %= 32;
|
||||
relativePosBoxGroup.setOriginBlockPos(pos);
|
||||
});
|
||||
this.add(relativePosBoxGroup);
|
||||
|
||||
|
||||
// massive relative box group
|
||||
ArrayList<DhApiRenderableBox> massRelBoxList = new ArrayList<>();
|
||||
for (int x = 0; x < 50*2; x+=2)
|
||||
{
|
||||
for (int z = 0; z < 50*2; z+=2)
|
||||
{
|
||||
massRelBoxList.add(new DhApiRenderableBox(
|
||||
new DhApiVec3d(-x, 0, -z), new DhApiVec3d(1-x, 1, 1-z),
|
||||
new Color(Color.RED.getRed(), Color.RED.getGreen(), Color.RED.getBlue()),
|
||||
EDhApiBlockMaterial.TERRACOTTA
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
IDhApiRenderableBoxGroup massRelativePosBoxGroup = factory.createRelativePositionedGroup(
|
||||
ModInfo.NAME + ":MassRedGroup",
|
||||
new DhApiVec3d(-25, 140, 0),
|
||||
massRelBoxList);
|
||||
massRelativePosBoxGroup.setPreRenderFunc((event) ->
|
||||
{
|
||||
DhApiVec3d blockPos = massRelativePosBoxGroup.getOriginBlockPos();
|
||||
blockPos.y += event.partialTicks / 4;
|
||||
if (blockPos.y > 150f)
|
||||
{
|
||||
blockPos.y = 140f;
|
||||
|
||||
Color newColor = (massRelativePosBoxGroup.get(0).color == Color.RED) ? Color.RED.darker() : Color.RED;
|
||||
massRelativePosBoxGroup.forEach((box) -> { box.color = newColor; });
|
||||
massRelativePosBoxGroup.triggerBoxChange();
|
||||
}
|
||||
|
||||
massRelativePosBoxGroup.setOriginBlockPos(blockPos);
|
||||
});
|
||||
this.add(massRelativePosBoxGroup);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// registration //
|
||||
//==============//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void add(IDhApiRenderableBoxGroup iBoxGroup) throws IllegalArgumentException
|
||||
{
|
||||
if (!(iBoxGroup instanceof RenderableBoxGroup))
|
||||
{
|
||||
throw new IllegalArgumentException("Box group must be of type ["+ RenderableBoxGroup.class.getSimpleName()+"], type received: ["+(iBoxGroup != null ? iBoxGroup.getClass() : "NULL")+"].");
|
||||
}
|
||||
RenderableBoxGroup boxGroup = (RenderableBoxGroup) iBoxGroup;
|
||||
|
||||
|
||||
long id = boxGroup.getId();
|
||||
if (this.boxGroupById.containsKey(id))
|
||||
{
|
||||
throw new IllegalArgumentException("A box group with the ID [" + id + "] is already present.");
|
||||
}
|
||||
|
||||
this.boxGroupById.put(id, boxGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDhApiRenderableBoxGroup remove(long id) { return this.boxGroupById.remove(id); }
|
||||
|
||||
public void clear() { this.boxGroupById.clear(); }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
//region
|
||||
|
||||
/**
|
||||
* @param renderingWithSsao
|
||||
* if true that means this render call is happening before the SSAO pass
|
||||
* and any objects rendered in this pass will have SSAO applied to them.
|
||||
*/
|
||||
@Override
|
||||
public void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao)
|
||||
{
|
||||
//==============//
|
||||
// render setup //
|
||||
//==============//
|
||||
//#region
|
||||
|
||||
profiler.push("setup");
|
||||
|
||||
this.init();
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
|
||||
|
||||
Vec3d camPos = MC_RENDER.getCameraExactPosition();
|
||||
|
||||
//#endregion
|
||||
|
||||
if (McLodRenderer.INSTANCE.dhColorTexture == null
|
||||
|| McLodRenderer.INSTANCE.dhDepthTexture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
//#region
|
||||
|
||||
GpuDevice gpuDevice = RenderSystem.getDevice();
|
||||
CommandEncoder commandEncoder = gpuDevice.createCommandEncoder();
|
||||
|
||||
Collection<RenderableBoxGroup> boxList = this.boxGroupById.values();
|
||||
for (RenderableBoxGroup boxGroup : boxList)
|
||||
{
|
||||
// validation //
|
||||
|
||||
// shouldn't happen, but just in case
|
||||
if (boxGroup == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip boxes that shouldn't render this pass
|
||||
if (boxGroup.ssaoEnabled != renderingWithSsao)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
profiler.popPush("render prep");
|
||||
boxGroup.preRender(renderEventParam); // called even if the group is inactive, so the group can be activate if desired
|
||||
|
||||
// ignore inactive groups
|
||||
if (!boxGroup.active)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// allow API users to cancel this object's rendering
|
||||
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, new DhApiBeforeGenericObjectRenderEvent.EventParam(renderEventParam, boxGroup));
|
||||
if (cancelRendering)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// update instanced data if needed
|
||||
{
|
||||
boxGroup.tryUpdateInstancedDataAsync();
|
||||
|
||||
// skip groups that haven't been uploaded yet
|
||||
if (boxGroup.instancedVbos.getState() != InstancedVboContainer.EState.RENDER)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DhApiRenderableBoxGroupShading shading = boxGroup.shading;
|
||||
if (shading == null)
|
||||
{
|
||||
shading = DEFAULT_SHADING;
|
||||
}
|
||||
|
||||
// uniforms
|
||||
{
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putIVec3() // uOffsetChunk
|
||||
.putVec3() // uOffsetSubChunk
|
||||
.putIVec3() // uCameraPosChunk
|
||||
.putVec3() // uCameraPosSubChunk
|
||||
|
||||
.putMat4f() // uProjectionMvm
|
||||
.putInt() // uSkyLight
|
||||
.putInt() // uBlockLight
|
||||
|
||||
.putFloat() // uNorthShading
|
||||
.putFloat() // uSouthShading
|
||||
.putFloat() // uEastShading
|
||||
.putFloat() // uWestShading
|
||||
.putFloat() // uTopShading
|
||||
.putFloat() // uBottomShading
|
||||
.get();
|
||||
|
||||
|
||||
// create data //
|
||||
|
||||
Mat4f projectionMvmMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
|
||||
projectionMvmMatrix.multiply(renderEventParam.dhModelViewMatrix);
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
buffer = Std140Builder.intoBuffer(buffer)
|
||||
.putIVec3(
|
||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
||||
) // uOffsetChunk
|
||||
.putVec3(
|
||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
||||
) // uOffsetSubChunk
|
||||
.putIVec3(
|
||||
LodUtil.getChunkPosFromDouble(camPos.x),
|
||||
LodUtil.getChunkPosFromDouble(camPos.y),
|
||||
LodUtil.getChunkPosFromDouble(camPos.z)
|
||||
) // uCameraPosChunk
|
||||
.putVec3(
|
||||
LodUtil.getSubChunkPosFromDouble(camPos.x),
|
||||
LodUtil.getSubChunkPosFromDouble(camPos.y),
|
||||
LodUtil.getSubChunkPosFromDouble(camPos.z)
|
||||
) // uCameraPosSubChunk
|
||||
|
||||
.putMat4f(projectionMvmMatrix.createJomlMatrix()) // uProjectionMvm
|
||||
.putInt(boxGroup.getSkyLight()) // uSkyLight
|
||||
.putInt(boxGroup.getBlockLight()) // uBlockLight
|
||||
|
||||
.putFloat(shading.north)
|
||||
.putFloat(shading.south)
|
||||
.putFloat(shading.east)
|
||||
.putFloat(shading.west)
|
||||
.putFloat(shading.top)
|
||||
.putFloat(shading.bottom)
|
||||
|
||||
.get()
|
||||
;
|
||||
|
||||
this.fragUniformBuffer = UniformHandler.createBuffer("vertUniformBlock", uniformBufferSize, this.fragUniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
commandEncoder.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// render //
|
||||
|
||||
profiler.popPush("rendering");
|
||||
profiler.push(boxGroup.getResourceLocationNamespace());
|
||||
profiler.push(boxGroup.getResourceLocationPath());
|
||||
|
||||
Supplier<String> debugLabelSupplier = () -> "distantHorizons:McTestRenderer";
|
||||
GpuTextureView colorTexture = gpuDevice.createTextureView(McLodRenderer.INSTANCE.dhColorTexture);
|
||||
OptionalInt optionalClearColorAsInt = OptionalInt.empty();
|
||||
GpuTextureView depthTexture = gpuDevice.createTextureView(McLodRenderer.INSTANCE.dhDepthTexture);
|
||||
OptionalDouble optionalDepthValueAsDouble = OptionalDouble.empty();
|
||||
|
||||
try (RenderPass renderPass = commandEncoder.createRenderPass(
|
||||
debugLabelSupplier,
|
||||
colorTexture,
|
||||
optionalClearColorAsInt,
|
||||
depthTexture, optionalDepthValueAsDouble))
|
||||
{
|
||||
this.renderBoxGroupInstanced(renderPass, renderEventParam, boxGroup, camPos, profiler);
|
||||
}
|
||||
|
||||
profiler.pop(); // resource path
|
||||
profiler.pop(); // resource namespace
|
||||
|
||||
boxGroup.postRender(renderEventParam);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
|
||||
//==========//
|
||||
// clean up //
|
||||
//==========//
|
||||
//region
|
||||
|
||||
profiler.popPush("cleanup");
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam);
|
||||
|
||||
profiler.pop();
|
||||
|
||||
//endregion
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=====================//
|
||||
// instanced rendering //
|
||||
//=====================//
|
||||
//region
|
||||
|
||||
private void renderBoxGroupInstanced(
|
||||
RenderPass renderPass, RenderParams renderEventParam,
|
||||
RenderableBoxGroup boxGroup, Vec3d camPos,
|
||||
IProfilerWrapper profiler)
|
||||
{
|
||||
// update instance data //
|
||||
|
||||
profiler.push("vertex setup");
|
||||
|
||||
GpuDevice gpuDevice = RenderSystem.getDevice();
|
||||
|
||||
McInstancedVboContainer_Textures container = (McInstancedVboContainer_Textures) boxGroup.instancedVbos;
|
||||
|
||||
|
||||
// bind MC Lightmap
|
||||
{
|
||||
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
|
||||
|
||||
GpuTextureView textureView = gpuDevice.createTextureView(lightMapWrapper.gpuTexture);
|
||||
GpuSampler gpuSampler = gpuDevice.createSampler(
|
||||
AddressMode.CLAMP_TO_EDGE, AddressMode.CLAMP_TO_EDGE, // U,V
|
||||
FilterMode.NEAREST, FilterMode.NEAREST, // minFilter, magFilter
|
||||
1, // maxAnisotropy
|
||||
OptionalDouble.empty() // maxLod
|
||||
);
|
||||
renderPass.bindTexture("uLightMap", textureView, gpuSampler);
|
||||
}
|
||||
|
||||
renderPass.setIndexBuffer(this.boxIndexBuffer, VertexFormat.IndexType.INT);
|
||||
|
||||
|
||||
|
||||
// Bind instance data //
|
||||
profiler.popPush("binding");
|
||||
{
|
||||
GpuTextureView colorView = gpuDevice.createTextureView(container.colorTexture);
|
||||
GpuSampler colorSampler = gpuDevice.createSampler(
|
||||
AddressMode.CLAMP_TO_EDGE, AddressMode.CLAMP_TO_EDGE, // U,V
|
||||
FilterMode.NEAREST, FilterMode.NEAREST, // minFilter, magFilter
|
||||
1, // maxAnisotropy
|
||||
OptionalDouble.empty() // maxLod
|
||||
);
|
||||
renderPass.bindTexture("uColorMap", colorView, colorSampler);
|
||||
|
||||
|
||||
renderPass.setVertexBuffer(0, this.boxVertexBuffer);
|
||||
}
|
||||
|
||||
renderPass.setUniform("vertUniformBlock", this.fragUniformBuffer);
|
||||
|
||||
// set pipeline
|
||||
renderPass.setPipeline(this.opaquePipeline); // TODO
|
||||
|
||||
// Draw instanced
|
||||
profiler.popPush("render");
|
||||
if (container.uploadedBoxCount > 0)
|
||||
{
|
||||
renderPass.drawIndexed(
|
||||
/*indexStart*/ 0,
|
||||
/*firstIndex*/0,
|
||||
/*indexCount*/BOX_INDICES.length,
|
||||
/*instanceCount*/container.uploadedBoxCount);
|
||||
|
||||
}
|
||||
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// F3 menu //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
public String getVboRenderDebugMenuString()
|
||||
{
|
||||
// get counts
|
||||
int totalGroupCount = this.boxGroupById.size();
|
||||
int totalBoxCount = 0;
|
||||
|
||||
int activeGroupCount = 0;
|
||||
int activeBoxCount = 0;
|
||||
|
||||
for (long key : this.boxGroupById.keySet())
|
||||
{
|
||||
RenderableBoxGroup renderGroup = this.boxGroupById.get(key);
|
||||
if (renderGroup.active)
|
||||
{
|
||||
activeGroupCount++;
|
||||
activeBoxCount += renderGroup.size();
|
||||
}
|
||||
totalBoxCount += renderGroup.size();
|
||||
}
|
||||
|
||||
|
||||
return "Generic Obj #: " + F3Screen.NUMBER_FORMAT.format(activeGroupCount) + "/" + F3Screen.NUMBER_FORMAT.format(totalGroupCount) + ", " +
|
||||
"Cube #: " + F3Screen.NUMBER_FORMAT.format(activeBoxCount) + "/" + F3Screen.NUMBER_FORMAT.format(totalBoxCount);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
-277
@@ -1,277 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.renderTest;
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.GpuTexture;
|
||||
import com.mojang.blaze3d.textures.TextureFormat;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.IInstancedVboContainer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.RenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
|
||||
import java.awt.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* For use by {@link RenderableBoxGroup}
|
||||
*
|
||||
* @see RenderableBoxGroup
|
||||
*/
|
||||
public class McInstancedVboContainer_Textures implements IInstancedVboContainer
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
|
||||
|
||||
public GpuTexture colorTexture;
|
||||
public GpuTexture scaleTexture;
|
||||
public GpuTexture chunkPosXTexture;
|
||||
public GpuTexture chunkPosYTexture;
|
||||
public GpuTexture chunkPosZTexture;
|
||||
public GpuTexture subChunkPosTexture;
|
||||
public GpuTexture materialTexture;
|
||||
|
||||
public int[] chunkPosData = new int[0];
|
||||
public float[] subChunkPosData = new float[0];
|
||||
public float[] scaleData = new float[0];
|
||||
public byte[] colorData = new byte[0];
|
||||
public int[] materialData = new int[0];
|
||||
|
||||
public int uploadedBoxCount = 0;
|
||||
|
||||
private EState state = EState.NEW;
|
||||
@Override
|
||||
public EState getState() { return this.state; }
|
||||
@Override
|
||||
public void setState(EState state) { this.state = state; }
|
||||
|
||||
|
||||
|
||||
//===========================//
|
||||
// render building/uploading //
|
||||
//===========================//
|
||||
//region
|
||||
|
||||
public void updateVertexData(List<DhApiRenderableBox> uploadBoxList)
|
||||
{
|
||||
int boxCount = uploadBoxList.size();
|
||||
|
||||
|
||||
// recreate the data arrays if their size is different
|
||||
if (this.uploadedBoxCount != boxCount)
|
||||
{
|
||||
this.uploadedBoxCount = boxCount;
|
||||
|
||||
this.chunkPosData = new int[boxCount * 3]; // 3 elements XYZ
|
||||
this.subChunkPosData = new float[boxCount * 3]; // 3 elements XYZ
|
||||
this.scaleData = new float[boxCount * 3]; // 3 elements XYZ
|
||||
|
||||
this.colorData = new byte[boxCount * 4]; // 4 elements, RGBA
|
||||
this.materialData = new int[boxCount];
|
||||
}
|
||||
|
||||
|
||||
// transformation / scaling //
|
||||
for (int i = 0; i < boxCount; i++)
|
||||
{
|
||||
DhApiRenderableBox box = uploadBoxList.get(i);
|
||||
|
||||
int dataIndex = i * 3;
|
||||
|
||||
this.chunkPosData[dataIndex] = LodUtil.getChunkPosFromDouble(box.minPos.x);
|
||||
this.chunkPosData[dataIndex + 1] = LodUtil.getChunkPosFromDouble(box.minPos.y);
|
||||
this.chunkPosData[dataIndex + 2] = LodUtil.getChunkPosFromDouble(box.minPos.z);
|
||||
|
||||
this.subChunkPosData[dataIndex] = LodUtil.getSubChunkPosFromDouble(box.minPos.x);
|
||||
this.subChunkPosData[dataIndex + 1] = LodUtil.getSubChunkPosFromDouble(box.minPos.y);
|
||||
this.subChunkPosData[dataIndex + 2] = LodUtil.getSubChunkPosFromDouble(box.minPos.z);
|
||||
|
||||
this.scaleData[dataIndex] = (float) (box.maxPos.x - box.minPos.x);
|
||||
this.scaleData[dataIndex + 1] = (float) (box.maxPos.y - box.minPos.y);
|
||||
this.scaleData[dataIndex + 2] = (float) (box.maxPos.z - box.minPos.z);
|
||||
}
|
||||
|
||||
|
||||
// colors/materials //
|
||||
for (int i = 0; i < boxCount; i++)
|
||||
{
|
||||
DhApiRenderableBox box = uploadBoxList.get(i);
|
||||
Color color = box.color;
|
||||
int colorIndex = i * 4;
|
||||
this.colorData[colorIndex] = (byte)color.getRed();
|
||||
this.colorData[colorIndex + 1] = (byte)color.getGreen();
|
||||
this.colorData[colorIndex + 2] = (byte)color.getBlue();
|
||||
this.colorData[colorIndex + 3] = (byte)color.getAlpha();
|
||||
|
||||
this.materialData[i] = box.material;
|
||||
}
|
||||
|
||||
this.state = EState.READY_TO_UPLOAD;
|
||||
}
|
||||
|
||||
public void uploadDataToGpu()
|
||||
{
|
||||
GpuDevice gpuDevice = RenderSystem.getDevice();
|
||||
CommandEncoder commandEncoder = gpuDevice.createCommandEncoder();
|
||||
|
||||
if (this.colorTexture == null
|
||||
|| this.colorTexture.getWidth(0) < this.uploadedBoxCount)
|
||||
{
|
||||
// TODO USAGE_COPY_DST = 1
|
||||
// TODO USAGE_TEXTURE_BINDING = 4
|
||||
int usage = 1 | 4 | 8 | 32 | 128;
|
||||
String texturePrefix = "DhGenericTexture_";
|
||||
|
||||
this.colorTexture = gpuDevice.createTexture(texturePrefix + "Color",
|
||||
usage,
|
||||
TextureFormat.RGBA8,
|
||||
this.uploadedBoxCount, 1,
|
||||
1, 1
|
||||
);
|
||||
|
||||
this.scaleTexture = gpuDevice.createTexture(texturePrefix + "Scale",
|
||||
usage,
|
||||
TextureFormat.RGBA8,
|
||||
this.uploadedBoxCount, 1,
|
||||
1, 1
|
||||
);
|
||||
|
||||
this.chunkPosXTexture = gpuDevice.createTexture(texturePrefix + "ChunkXPos",
|
||||
usage,
|
||||
TextureFormat.DEPTH32,
|
||||
this.uploadedBoxCount, 1,
|
||||
1, 1
|
||||
);
|
||||
this.chunkPosYTexture = gpuDevice.createTexture(texturePrefix + "ChunkYPos",
|
||||
usage,
|
||||
TextureFormat.DEPTH32,
|
||||
this.uploadedBoxCount, 1,
|
||||
1, 1
|
||||
);
|
||||
this.chunkPosZTexture = gpuDevice.createTexture(texturePrefix + "ChunkZPos",
|
||||
usage,
|
||||
TextureFormat.DEPTH32,
|
||||
this.uploadedBoxCount, 1,
|
||||
1, 1
|
||||
);
|
||||
|
||||
this.subChunkPosTexture = gpuDevice.createTexture(texturePrefix + "SubChunk",
|
||||
usage,
|
||||
TextureFormat.RGBA8,
|
||||
this.uploadedBoxCount, 1,
|
||||
1, 1
|
||||
);
|
||||
|
||||
//this.materialTexture = gpuDevice.createTexture(texturePrefix + "Material",
|
||||
// usage,
|
||||
// TextureFormat.RED8I, // TODO not valid?
|
||||
// this.uploadedBoxCount, 1,
|
||||
// 1, 1
|
||||
//);
|
||||
}
|
||||
|
||||
{
|
||||
// color
|
||||
{
|
||||
ByteBuffer colorBuffer = ByteBuffer.allocateDirect(this.colorData.length * Float.BYTES);
|
||||
colorBuffer.asFloatBuffer();
|
||||
|
||||
for (int i = 0; i < this.colorData.length; i++)
|
||||
{
|
||||
colorBuffer.put(this.colorData[i]);
|
||||
}
|
||||
colorBuffer.rewind();
|
||||
|
||||
commandEncoder.writeToTexture(
|
||||
this.colorTexture,
|
||||
colorBuffer,
|
||||
NativeImage.Format.RGBA, // holds bytes
|
||||
0, //mipLevel
|
||||
0, // depthOrLayer
|
||||
0, // destX
|
||||
0, // destY
|
||||
this.uploadedBoxCount, // width
|
||||
1 // height
|
||||
);
|
||||
}
|
||||
|
||||
// scale
|
||||
{
|
||||
ByteBuffer scaleBuffer = ByteBuffer.allocateDirect(this.scaleData.length * Float.BYTES);
|
||||
scaleBuffer.asFloatBuffer();
|
||||
|
||||
for (int i = 0; i < this.scaleData.length; i++)
|
||||
{ scaleBuffer.putFloat(this.scaleData[i]); }
|
||||
scaleBuffer.rewind();
|
||||
|
||||
commandEncoder.writeToTexture(
|
||||
this.scaleTexture,
|
||||
scaleBuffer,
|
||||
NativeImage.Format.RGB, // holds bytes
|
||||
0, //mipLevel
|
||||
0, // depthOrLayer
|
||||
0, // destX
|
||||
0, // destY
|
||||
this.uploadedBoxCount, // width
|
||||
1 // height
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//for (int i = 0; i < this.chunkPosData.length; i++)
|
||||
//{ buffer.putInt(this.chunkPosData[i]); }
|
||||
//
|
||||
//for (int i = 0; i < this.subChunkPosData.length; i++)
|
||||
//{ buffer.putFloat(this.subChunkPosData[i]); }
|
||||
//
|
||||
//for (int i = 0; i < this.colorData.length; i++)
|
||||
//{ buffer.putFloat(this.colorData[i]); }
|
||||
//
|
||||
//for (int i = 0; i < this.materialData.length; i++)
|
||||
//{ buffer.putInt(this.materialData[i]); }
|
||||
//
|
||||
//buffer.rewind();
|
||||
}
|
||||
|
||||
this.state = EState.RENDER;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// base overrides //
|
||||
//================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
GLProxy.queueRunningOnRenderThread(() ->
|
||||
{
|
||||
if (this.colorTexture != null)
|
||||
{
|
||||
this.colorTexture.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -34,18 +34,13 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.*;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcFadeRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcSsaoRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
+4
-5
@@ -33,7 +33,6 @@ import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.*;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
@@ -42,7 +41,7 @@ import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcFadeRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcVanillaFadeRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.Identifier;
|
||||
@@ -56,14 +55,14 @@ import java.util.function.Supplier;
|
||||
/**
|
||||
* Renders a TODO
|
||||
*/
|
||||
public class McFadeRenderer implements IMcFadeRenderer
|
||||
public class McVanillaFadeRenderer implements IMcVanillaFadeRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
|
||||
|
||||
public static final McFadeRenderer INSTANCE = new McFadeRenderer();
|
||||
public static final McVanillaFadeRenderer INSTANCE = new McVanillaFadeRenderer();
|
||||
|
||||
private VertexFormat vertexFormat;
|
||||
private RenderPipeline pipeline;
|
||||
@@ -82,7 +81,7 @@ public class McFadeRenderer implements IMcFadeRenderer
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private McFadeRenderer()
|
||||
private McVanillaFadeRenderer()
|
||||
{
|
||||
this.vertexFormat = VertexFormat.builder()
|
||||
.add("vPosition", DhVertexFormat.SCREEN_POS)
|
||||
+2
-1
@@ -75,10 +75,11 @@ public class DependencySetup
|
||||
public static void createRenderBindings()
|
||||
{
|
||||
SingletonInjector.INSTANCE.bind(IMcTestRenderer.class, McTestRenderer.INSTANCE);
|
||||
SingletonInjector.INSTANCE.bind(IMcFadeRenderer.class, McFadeRenderer.INSTANCE);
|
||||
SingletonInjector.INSTANCE.bind(IMcVanillaFadeRenderer.class, McVanillaFadeRenderer.INSTANCE);
|
||||
SingletonInjector.INSTANCE.bind(IMcLodRenderer.class, McLodRenderer.INSTANCE);
|
||||
SingletonInjector.INSTANCE.bind(IMcSsaoRenderer.class, McSsaoRenderer.INSTANCE);
|
||||
SingletonInjector.INSTANCE.bind(IMcFogRenderer.class, McFogRenderer.INSTANCE);
|
||||
SingletonInjector.INSTANCE.bind(IMcFarFadeRenderer.class, McFarFadeRenderer.INSTANCE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
Submodule coreSubProjects updated: 225c2df8df...c3dce412fa
Reference in New Issue
Block a user