mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-07 12:56:31 +01:00
Blocks all the way down
- Instancing and indirect backends use the block format internally. - Remove layout shaders. - Do not compile against VertexType. - Do not sort draw calls by VertexType. - Remove VertexType#REGISTRY.
This commit is contained in:
parent
473e5e852f
commit
0e5617219b
25 changed files with 59 additions and 139 deletions
|
@ -28,8 +28,7 @@ public interface Mesh {
|
||||||
* The size in bytes that this mesh's data takes up.
|
* The size in bytes that this mesh's data takes up.
|
||||||
*/
|
*/
|
||||||
default int size() {
|
default int size() {
|
||||||
return vertexType().getLayout()
|
return vertexType().getStride() * vertexCount();
|
||||||
.getStride() * vertexCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,24 +1,16 @@
|
||||||
package com.jozufozu.flywheel.api.vertex;
|
package com.jozufozu.flywheel.api.vertex;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.api.registry.Registry;
|
|
||||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A vertex type containing metadata about a specific vertex layout.
|
* A vertex type containing metadata about a specific vertex layout.
|
||||||
*/
|
*/
|
||||||
public interface VertexType extends VertexListProvider {
|
public interface VertexType extends VertexListProvider {
|
||||||
static Registry<VertexType> REGISTRY = RegistryImpl.create();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The layout of this type of vertex when buffered.
|
* The layout of this type of vertex when buffered.
|
||||||
*/
|
*/
|
||||||
BufferLayout getLayout();
|
BufferLayout getLayout();
|
||||||
|
|
||||||
ResourceLocation layoutShader();
|
|
||||||
|
|
||||||
default int getStride() {
|
default int getStride() {
|
||||||
return getLayout().getStride();
|
return getLayout().getStride();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.backend.ShaderIndices;
|
import com.jozufozu.flywheel.backend.ShaderIndices;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent;
|
import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
||||||
|
@ -99,12 +98,9 @@ public class FlwPrograms {
|
||||||
|
|
||||||
private static ImmutableList<PipelineProgramKey> createPipelineKeys() {
|
private static ImmutableList<PipelineProgramKey> createPipelineKeys() {
|
||||||
ImmutableList.Builder<PipelineProgramKey> builder = ImmutableList.builder();
|
ImmutableList.Builder<PipelineProgramKey> builder = ImmutableList.builder();
|
||||||
// TODO: ubershader'd contexts?
|
|
||||||
for (Context context : Context.REGISTRY) {
|
for (Context context : Context.REGISTRY) {
|
||||||
for (InstanceType<?> instanceType : InstanceType.REGISTRY) {
|
for (InstanceType<?> instanceType : InstanceType.REGISTRY) {
|
||||||
for (VertexType vertexType : VertexType.REGISTRY) {
|
builder.add(new PipelineProgramKey(instanceType, context));
|
||||||
builder.add(new PipelineProgramKey(vertexType, instanceType, context));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
@ -9,7 +9,6 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
|
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
||||||
import com.jozufozu.flywheel.gl.GlCompat;
|
import com.jozufozu.flywheel.gl.GlCompat;
|
||||||
|
@ -89,8 +88,8 @@ public class IndirectPrograms {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlProgram getIndirectProgram(VertexType vertexType, InstanceType<?> instanceType, Context contextShader) {
|
public GlProgram getIndirectProgram(InstanceType<?> instanceType, Context contextShader) {
|
||||||
return pipeline.get(new PipelineProgramKey(vertexType, instanceType, contextShader));
|
return pipeline.get(new PipelineProgramKey(instanceType, contextShader));
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlProgram getCullingProgram(InstanceType<?> instanceType) {
|
public GlProgram getCullingProgram(InstanceType<?> instanceType) {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
||||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.glsl.ShaderSources;
|
import com.jozufozu.flywheel.glsl.ShaderSources;
|
||||||
|
@ -55,8 +54,8 @@ public class InstancingPrograms {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlProgram get(VertexType vertexType, InstanceType<?> instanceType, Context contextShader) {
|
public GlProgram get(InstanceType<?> instanceType, Context contextShader) {
|
||||||
return pipeline.get(new PipelineProgramKey(vertexType, instanceType, contextShader));
|
return pipeline.get(new PipelineProgramKey(instanceType, contextShader));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.compile;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.glsl.GLSLVersion;
|
import com.jozufozu.flywheel.glsl.GLSLVersion;
|
||||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ public record Pipeline(GLSLVersion glslVersion, ResourceLocation vertexShader, R
|
||||||
SourceComponent assemble(InstanceAssemblerContext context);
|
SourceComponent assemble(InstanceAssemblerContext context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public record InstanceAssemblerContext(VertexType vertexType, InstanceType<?> instanceType) {
|
public record InstanceAssemblerContext(int baseAttribute, InstanceType<?> instanceType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
||||||
import com.jozufozu.flywheel.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.gl.shader.ShaderType;
|
||||||
import com.jozufozu.flywheel.glsl.ShaderSources;
|
import com.jozufozu.flywheel.glsl.ShaderSources;
|
||||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||||
|
import com.jozufozu.flywheel.lib.vertex.BlockVertex;
|
||||||
|
|
||||||
public class PipelineCompiler {
|
public class PipelineCompiler {
|
||||||
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
|
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
|
||||||
|
@ -18,11 +19,9 @@ public class PipelineCompiler {
|
||||||
.link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.VERTEX)
|
.link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.VERTEX)
|
||||||
.withComponent(uniformComponent)
|
.withComponent(uniformComponent)
|
||||||
.withComponent(key -> pipeline.assembler()
|
.withComponent(key -> pipeline.assembler()
|
||||||
.assemble(new Pipeline.InstanceAssemblerContext(key.vertexType(), key.instanceType())))
|
.assemble(new Pipeline.InstanceAssemblerContext(BlockVertex.FORMAT.getAttributeCount(), key.instanceType())))
|
||||||
.withResource(pipeline.vertexAPI())
|
.withResource(pipeline.vertexAPI())
|
||||||
.withComponents(vertexComponents)
|
.withComponents(vertexComponents)
|
||||||
.withResource(key -> key.vertexType()
|
|
||||||
.layoutShader())
|
|
||||||
.withResource(key -> key.instanceType()
|
.withResource(key -> key.instanceType()
|
||||||
.instanceShader())
|
.instanceShader())
|
||||||
.withResource(key -> key.contextShader()
|
.withResource(key -> key.contextShader()
|
||||||
|
|
|
@ -2,14 +2,12 @@ package com.jozufozu.flywheel.backend.compile;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the entire context of a program's usage.
|
* Represents the entire context of a program's usage.
|
||||||
*
|
*
|
||||||
* @param vertexType The vertex type the program should be adapted for.
|
|
||||||
* @param instanceType The instance shader to use.
|
* @param instanceType The instance shader to use.
|
||||||
* @param contextShader The context shader to use.
|
* @param contextShader The context shader to use.
|
||||||
*/
|
*/
|
||||||
public record PipelineProgramKey(VertexType vertexType, InstanceType<?> instanceType, Context contextShader) {
|
public record PipelineProgramKey(InstanceType<?> instanceType, Context contextShader) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,7 @@ public class InstancedArraysComponent implements SourceComponent {
|
||||||
public InstancedArraysComponent(Pipeline.InstanceAssemblerContext ctx) {
|
public InstancedArraysComponent(Pipeline.InstanceAssemblerContext ctx) {
|
||||||
this.layoutItems = ctx.instanceType()
|
this.layoutItems = ctx.instanceType()
|
||||||
.getLayout().layoutItems;
|
.getLayout().layoutItems;
|
||||||
this.baseIndex = ctx.vertexType()
|
this.baseIndex = ctx.baseAttribute();
|
||||||
.getLayout()
|
|
||||||
.getAttributeCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,7 +10,6 @@ import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.model.Mesh;
|
import com.jozufozu.flywheel.api.model.Mesh;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
|
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
|
||||||
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
||||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||||
|
@ -29,7 +28,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
private boolean needsMemoryBarrier;
|
private boolean needsMemoryBarrier;
|
||||||
private int instanceCountThisFrame;
|
private int instanceCountThisFrame;
|
||||||
|
|
||||||
IndirectCullingGroup(InstanceType<I> instanceType, VertexType vertexType) {
|
IndirectCullingGroup(InstanceType<I> instanceType) {
|
||||||
objectStride = instanceType.getLayout()
|
objectStride = instanceType.getLayout()
|
||||||
.getStride() + IndirectBuffers.INT_SIZE;
|
.getStride() + IndirectBuffers.INT_SIZE;
|
||||||
|
|
||||||
|
@ -38,11 +37,11 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
buffers.createObjectStorage(128);
|
buffers.createObjectStorage(128);
|
||||||
buffers.createDrawStorage(2);
|
buffers.createDrawStorage(2);
|
||||||
|
|
||||||
meshPool = new IndirectMeshPool(vertexType);
|
meshPool = new IndirectMeshPool();
|
||||||
|
|
||||||
var indirectPrograms = IndirectPrograms.get();
|
var indirectPrograms = IndirectPrograms.get();
|
||||||
compute = indirectPrograms.getCullingProgram(instanceType);
|
compute = indirectPrograms.getCullingProgram(instanceType);
|
||||||
draw = indirectPrograms.getIndirectProgram(vertexType, instanceType, Contexts.WORLD);
|
draw = indirectPrograms.getIndirectProgram(instanceType, Contexts.WORLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(IndirectInstancer<I> instancer, RenderStage stage, Material material, Mesh mesh) {
|
public void add(IndirectInstancer<I> instancer, RenderStage stage, Material material, Mesh mesh) {
|
||||||
|
|
|
@ -7,13 +7,11 @@ import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
||||||
import com.jozufozu.flywheel.lib.util.Pair;
|
|
||||||
|
|
||||||
public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>> {
|
public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>> {
|
||||||
public final Map<Pair<InstanceType<?>, VertexType>, IndirectCullingGroup<?>> renderLists = new HashMap<>();
|
public final Map<InstanceType<?>, IndirectCullingGroup<?>> renderLists = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected <I extends Instance> IndirectInstancer<?> create(InstanceType<I> type) {
|
protected <I extends Instance> IndirectInstancer<?> create(InstanceType<I> type) {
|
||||||
|
@ -27,7 +25,7 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
|
||||||
var material = entry.getKey();
|
var material = entry.getKey();
|
||||||
var mesh = entry.getValue();
|
var mesh = entry.getValue();
|
||||||
|
|
||||||
var indirectList = (IndirectCullingGroup<I>) renderLists.computeIfAbsent(Pair.of(key.type(), mesh.vertexType()), p -> new IndirectCullingGroup<>(p.first(), p.second()));
|
var indirectList = (IndirectCullingGroup<I>) renderLists.computeIfAbsent(key.type(), IndirectCullingGroup::new);
|
||||||
|
|
||||||
indirectList.add((IndirectInstancer<I>) instancer, stage, material, mesh);
|
indirectList.add((IndirectInstancer<I>) instancer, stage, material, mesh);
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,11 @@ import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
||||||
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
import com.jozufozu.flywheel.lib.model.QuadIndexSequence;
|
import com.jozufozu.flywheel.lib.model.QuadIndexSequence;
|
||||||
|
import com.jozufozu.flywheel.lib.vertex.BlockVertexList;
|
||||||
|
import com.jozufozu.flywheel.lib.vertex.VertexTypes;
|
||||||
|
|
||||||
public class IndirectMeshPool {
|
public class IndirectMeshPool {
|
||||||
private final VertexType vertexType;
|
private static final VertexType VERTEX_TYPE = VertexTypes.BLOCK;
|
||||||
|
|
||||||
private final Map<Mesh, BufferedMesh> meshes = new HashMap<>();
|
private final Map<Mesh, BufferedMesh> meshes = new HashMap<>();
|
||||||
private final List<BufferedMesh> meshList = new ArrayList<>();
|
private final List<BufferedMesh> meshList = new ArrayList<>();
|
||||||
|
@ -32,20 +34,19 @@ public class IndirectMeshPool {
|
||||||
/**
|
/**
|
||||||
* Create a new mesh pool.
|
* Create a new mesh pool.
|
||||||
*/
|
*/
|
||||||
public IndirectMeshPool(VertexType type) {
|
public IndirectMeshPool() {
|
||||||
vertexType = type;
|
|
||||||
vbo = new GlBuffer();
|
vbo = new GlBuffer();
|
||||||
ebo = new GlBuffer();
|
ebo = new GlBuffer();
|
||||||
vertexArray = GlVertexArray.create();
|
vertexArray = GlVertexArray.create();
|
||||||
|
|
||||||
vertexArray.setElementBuffer(ebo.handle());
|
vertexArray.setElementBuffer(ebo.handle());
|
||||||
BufferLayout layout = vertexType.getLayout();
|
BufferLayout layout = VERTEX_TYPE.getLayout();
|
||||||
vertexArray.bindVertexBuffer(0, vbo.handle(), 0, layout.getStride());
|
vertexArray.bindVertexBuffer(0, vbo.handle(), 0, layout.getStride());
|
||||||
vertexArray.bindAttributes(0, 0, layout.attributes());
|
vertexArray.bindAttributes(0, 0, layout.attributes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public VertexType getVertexType() {
|
public VertexType getVertexType() {
|
||||||
return vertexType;
|
return VERTEX_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,6 +99,8 @@ public class IndirectMeshPool {
|
||||||
final long vertexPtr = vertexBlock.ptr();
|
final long vertexPtr = vertexBlock.ptr();
|
||||||
final long indexPtr = indexBlock.ptr();
|
final long indexPtr = indexBlock.ptr();
|
||||||
|
|
||||||
|
var target = new BlockVertexList();
|
||||||
|
|
||||||
int byteIndex = 0;
|
int byteIndex = 0;
|
||||||
int baseVertex = 0;
|
int baseVertex = 0;
|
||||||
int firstIndex = maxQuadIndexCount;
|
int firstIndex = maxQuadIndexCount;
|
||||||
|
@ -105,7 +108,8 @@ public class IndirectMeshPool {
|
||||||
mesh.byteIndex = byteIndex;
|
mesh.byteIndex = byteIndex;
|
||||||
mesh.baseVertex = baseVertex;
|
mesh.baseVertex = baseVertex;
|
||||||
|
|
||||||
mesh.buffer(vertexPtr);
|
target.ptr(vertexPtr + mesh.byteIndex);
|
||||||
|
mesh.mesh.write(target);
|
||||||
|
|
||||||
byteIndex += mesh.size();
|
byteIndex += mesh.size();
|
||||||
baseVertex += mesh.mesh.vertexCount();
|
baseVertex += mesh.mesh.vertexCount();
|
||||||
|
@ -156,17 +160,13 @@ public class IndirectMeshPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return mesh.size();
|
return mesh.vertexCount() * VERTEX_TYPE.getStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int indexCount() {
|
public int indexCount() {
|
||||||
return mesh.indexCount();
|
return mesh.indexCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buffer(long ptr) {
|
|
||||||
mesh.write(ptr + byteIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector4fc boundingSphere() {
|
public Vector4fc boundingSphere() {
|
||||||
return mesh.boundingSphere();
|
return mesh.boundingSphere();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class InstancedCrumbling {
|
||||||
.cutout(CutoutShaders.OFF);
|
.cutout(CutoutShaders.OFF);
|
||||||
|
|
||||||
var program = InstancingPrograms.get()
|
var program = InstancingPrograms.get()
|
||||||
.get(shader.vertexType(), shader.instanceType(), Contexts.CRUMBLING);
|
.get(shader.instanceType(), Contexts.CRUMBLING);
|
||||||
UniformBuffer.syncAndBind(program);
|
UniformBuffer.syncAndBind(program);
|
||||||
|
|
||||||
InstancingEngine.uploadMaterialIDUniform(program, crumblingMaterial);
|
InstancingEngine.uploadMaterialIDUniform(program, crumblingMaterial);
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.jozufozu.flywheel.backend.engine.instancing;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -16,7 +15,6 @@ import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.model.Mesh;
|
import com.jozufozu.flywheel.api.model.Mesh;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
||||||
|
|
||||||
|
@ -28,7 +26,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
|
||||||
/**
|
/**
|
||||||
* A map of vertex types to their mesh pools.
|
* A map of vertex types to their mesh pools.
|
||||||
*/
|
*/
|
||||||
private final Map<VertexType, InstancedMeshPool> meshPools = new HashMap<>();
|
private final InstancedMeshPool meshPool = new InstancedMeshPool();
|
||||||
private final EBOCache eboCache = new EBOCache();
|
private final EBOCache eboCache = new EBOCache();
|
||||||
|
|
||||||
public DrawSet get(RenderStage stage) {
|
public DrawSet get(RenderStage stage) {
|
||||||
|
@ -38,17 +36,13 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
|
||||||
public void flush() {
|
public void flush() {
|
||||||
super.flush();
|
super.flush();
|
||||||
|
|
||||||
for (var pool : meshPools.values()) {
|
meshPool.flush();
|
||||||
pool.flush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
super.invalidate();
|
super.invalidate();
|
||||||
|
|
||||||
meshPools.values()
|
meshPool.delete();
|
||||||
.forEach(InstancedMeshPool::delete);
|
|
||||||
meshPools.clear();
|
|
||||||
|
|
||||||
drawSets.values()
|
drawSets.values()
|
||||||
.forEach(DrawSet::delete);
|
.forEach(DrawSet::delete);
|
||||||
|
@ -58,8 +52,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstancedMeshPool.BufferedMesh alloc(Mesh mesh) {
|
private InstancedMeshPool.BufferedMesh alloc(Mesh mesh) {
|
||||||
return meshPools.computeIfAbsent(mesh.vertexType(), InstancedMeshPool::new)
|
return meshPool.alloc(mesh, eboCache);
|
||||||
.alloc(mesh, eboCache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -77,7 +70,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
|
||||||
for (var entry : meshes.entrySet()) {
|
for (var entry : meshes.entrySet()) {
|
||||||
var mesh = alloc(entry.getValue());
|
var mesh = alloc(entry.getValue());
|
||||||
|
|
||||||
ShaderState shaderState = new ShaderState(entry.getKey(), mesh.getVertexType(), instancer.type);
|
ShaderState shaderState = new ShaderState(entry.getKey(), instancer.type);
|
||||||
DrawCall drawCall = new DrawCall(instancer, mesh, shaderState);
|
DrawCall drawCall = new DrawCall(instancer, mesh, shaderState);
|
||||||
|
|
||||||
drawSet.put(shaderState, drawCall);
|
drawSet.put(shaderState, drawCall);
|
||||||
|
|
|
@ -18,9 +18,10 @@ import com.jozufozu.flywheel.gl.GlPrimitive;
|
||||||
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
||||||
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
||||||
import com.jozufozu.flywheel.gl.buffer.MappedBuffer;
|
import com.jozufozu.flywheel.gl.buffer.MappedBuffer;
|
||||||
|
import com.jozufozu.flywheel.lib.vertex.VertexTypes;
|
||||||
|
|
||||||
public class InstancedMeshPool {
|
public class InstancedMeshPool {
|
||||||
private final VertexType vertexType;
|
private static final VertexType VERTEX_TYPE = VertexTypes.BLOCK;
|
||||||
|
|
||||||
private final Map<Mesh, BufferedMesh> meshes = new HashMap<>();
|
private final Map<Mesh, BufferedMesh> meshes = new HashMap<>();
|
||||||
private final List<BufferedMesh> allBuffered = new ArrayList<>();
|
private final List<BufferedMesh> allBuffered = new ArrayList<>();
|
||||||
|
@ -35,15 +36,15 @@ public class InstancedMeshPool {
|
||||||
/**
|
/**
|
||||||
* Create a new mesh pool.
|
* Create a new mesh pool.
|
||||||
*/
|
*/
|
||||||
public InstancedMeshPool(VertexType vertexType) {
|
public InstancedMeshPool() {
|
||||||
this.vertexType = vertexType;
|
int stride = VERTEX_TYPE.getLayout()
|
||||||
int stride = vertexType.getLayout().getStride();
|
.getStride();
|
||||||
vbo = new GlBuffer();
|
vbo = new GlBuffer();
|
||||||
vbo.growthFunction(l -> Math.max(l + stride * 128L, (long) (l * 1.6)));
|
vbo.growthFunction(l -> Math.max(l + stride * 128L, (long) (l * 1.6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public VertexType getVertexType() {
|
public VertexType getVertexType() {
|
||||||
return vertexType;
|
return VERTEX_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,10 +56,6 @@ public class InstancedMeshPool {
|
||||||
*/
|
*/
|
||||||
public BufferedMesh alloc(Mesh mesh, EBOCache eboCache) {
|
public BufferedMesh alloc(Mesh mesh, EBOCache eboCache) {
|
||||||
return meshes.computeIfAbsent(mesh, m -> {
|
return meshes.computeIfAbsent(mesh, m -> {
|
||||||
if (m.vertexType() != vertexType) {
|
|
||||||
throw new IllegalArgumentException("Mesh has wrong vertex type");
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedMesh bufferedMesh = new BufferedMesh(m, byteSize, eboCache);
|
BufferedMesh bufferedMesh = new BufferedMesh(m, byteSize, eboCache);
|
||||||
byteSize += bufferedMesh.size();
|
byteSize += bufferedMesh.size();
|
||||||
allBuffered.add(bufferedMesh);
|
allBuffered.add(bufferedMesh);
|
||||||
|
@ -121,8 +118,12 @@ public class InstancedMeshPool {
|
||||||
try (MappedBuffer mapped = vbo.map()) {
|
try (MappedBuffer mapped = vbo.map()) {
|
||||||
long ptr = mapped.ptr();
|
long ptr = mapped.ptr();
|
||||||
|
|
||||||
|
var vertexList = VERTEX_TYPE.createVertexList();
|
||||||
|
|
||||||
for (BufferedMesh mesh : pendingUpload) {
|
for (BufferedMesh mesh : pendingUpload) {
|
||||||
mesh.buffer(ptr);
|
vertexList.ptr(ptr + mesh.byteIndex);
|
||||||
|
mesh.mesh.write(vertexList);
|
||||||
|
mesh.boundTo.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingUpload.clear();
|
pendingUpload.clear();
|
||||||
|
@ -140,7 +141,7 @@ public class InstancedMeshPool {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "InstancedMeshPool{" + "vertexType=" + vertexType + ", byteSize=" + byteSize + ", meshCount=" + meshes.size() + '}';
|
return "InstancedMeshPool{" + "vertexType=" + VERTEX_TYPE + ", byteSize=" + byteSize + ", meshCount=" + meshes.size() + '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BufferedMesh {
|
public class BufferedMesh {
|
||||||
|
@ -158,15 +159,16 @@ public class InstancedMeshPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return mesh.size();
|
return mesh.vertexCount() * VERTEX_TYPE.getStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
public VertexType getVertexType() {
|
public VertexType getVertexType() {
|
||||||
return vertexType;
|
return VERTEX_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAttributeCount() {
|
public int getAttributeCount() {
|
||||||
return vertexType.getLayout().getAttributeCount();
|
return VERTEX_TYPE.getLayout()
|
||||||
|
.getAttributeCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDeleted() {
|
public boolean isDeleted() {
|
||||||
|
@ -177,15 +179,9 @@ public class InstancedMeshPool {
|
||||||
return mesh.isEmpty() || isDeleted();
|
return mesh.isEmpty() || isDeleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buffer(long ptr) {
|
|
||||||
mesh.write(ptr + byteIndex);
|
|
||||||
|
|
||||||
boundTo.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setup(GlVertexArray vao) {
|
public void setup(GlVertexArray vao) {
|
||||||
if (boundTo.add(vao)) {
|
if (boundTo.add(vao)) {
|
||||||
BufferLayout type = vertexType.getLayout();
|
BufferLayout type = VERTEX_TYPE.getLayout();
|
||||||
vao.bindVertexBuffer(0, InstancedMeshPool.this.vbo.handle(), byteIndex, type.getStride());
|
vao.bindVertexBuffer(0, InstancedMeshPool.this.vbo.handle(), byteIndex, type.getStride());
|
||||||
vao.bindAttributes(0, 0, type.attributes());
|
vao.bindAttributes(0, 0, type.attributes());
|
||||||
vao.setElementBuffer(ebo);
|
vao.setElementBuffer(ebo);
|
||||||
|
|
|
@ -109,7 +109,7 @@ public class InstancingEngine extends AbstractEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
var program = InstancingPrograms.get()
|
var program = InstancingPrograms.get()
|
||||||
.get(shader.vertexType(), shader.instanceType(), Contexts.WORLD);
|
.get(shader.instanceType(), Contexts.WORLD);
|
||||||
UniformBuffer.syncAndBind(program);
|
UniformBuffer.syncAndBind(program);
|
||||||
|
|
||||||
uploadMaterialIDUniform(program, shader.material());
|
uploadMaterialIDUniform(program, shader.material());
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.jozufozu.flywheel.backend.engine.instancing;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
|
|
||||||
public record ShaderState(Material material, VertexType vertexType, InstanceType<?> instanceType) {
|
public record ShaderState(Material material, InstanceType<?> instanceType) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ import com.jozufozu.flywheel.api.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.lib.layout.CommonItems;
|
import com.jozufozu.flywheel.lib.layout.CommonItems;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public class BlockVertex implements VertexType {
|
public class BlockVertex implements VertexType {
|
||||||
public static final BufferLayout FORMAT = BufferLayout.builder()
|
public static final BufferLayout FORMAT = BufferLayout.builder()
|
||||||
.addItem(CommonItems.VEC3, "position")
|
.addItem(CommonItems.VEC3, "position")
|
||||||
|
@ -21,11 +19,6 @@ public class BlockVertex implements VertexType {
|
||||||
return FORMAT;
|
return FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation layoutShader() {
|
|
||||||
return VertexTypes.Files.BLOCK_LAYOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockVertexList createVertexList() {
|
public BlockVertexList createVertexList() {
|
||||||
return new BlockVertexList();
|
return new BlockVertexList();
|
||||||
|
|
|
@ -4,8 +4,6 @@ import com.jozufozu.flywheel.api.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.lib.layout.CommonItems;
|
import com.jozufozu.flywheel.lib.layout.CommonItems;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public class PosTexNormalVertex implements VertexType {
|
public class PosTexNormalVertex implements VertexType {
|
||||||
public static final BufferLayout FORMAT = BufferLayout.builder()
|
public static final BufferLayout FORMAT = BufferLayout.builder()
|
||||||
.addItem(CommonItems.VEC3, "position")
|
.addItem(CommonItems.VEC3, "position")
|
||||||
|
@ -18,11 +16,6 @@ public class PosTexNormalVertex implements VertexType {
|
||||||
return FORMAT;
|
return FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation layoutShader() {
|
|
||||||
return VertexTypes.Files.POS_TEX_NORMAL_LAYOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PosTexNormalVertexList createVertexList() {
|
public PosTexNormalVertexList createVertexList() {
|
||||||
return new PosTexNormalVertexList();
|
return new PosTexNormalVertexList();
|
||||||
|
|
|
@ -2,14 +2,9 @@ package com.jozufozu.flywheel.lib.vertex;
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public final class VertexTypes {
|
public final class VertexTypes {
|
||||||
public static final BlockVertex BLOCK = VertexType.REGISTRY.registerAndGet(new BlockVertex());
|
public static final BlockVertex BLOCK = new BlockVertex();
|
||||||
public static final PosTexNormalVertex POS_TEX_NORMAL = VertexType.REGISTRY.registerAndGet(new PosTexNormalVertex());
|
public static final PosTexNormalVertex POS_TEX_NORMAL = new PosTexNormalVertex();
|
||||||
|
|
||||||
private VertexTypes() {
|
private VertexTypes() {
|
||||||
}
|
}
|
||||||
|
@ -17,14 +12,4 @@ public final class VertexTypes {
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public static void init() {
|
public static void init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Files {
|
|
||||||
public static final ResourceLocation BLOCK_LAYOUT = Names.BLOCK.withSuffix(".vert");
|
|
||||||
public static final ResourceLocation POS_TEX_NORMAL_LAYOUT = Names.POS_TEX_NORMAL.withSuffix(".vert");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Names {
|
|
||||||
public static final ResourceLocation BLOCK = Flywheel.rl("layout/block");
|
|
||||||
public static final ResourceLocation POS_TEX_NORMAL = Flywheel.rl("layout/pos_tex_normal");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,6 @@ vec4 flw_var3;
|
||||||
|
|
||||||
/*const*/ FlwMaterial flw_material;
|
/*const*/ FlwMaterial flw_material;
|
||||||
|
|
||||||
// To be implemented by the layout shader.
|
|
||||||
void flw_layoutVertex();
|
|
||||||
|
|
||||||
// To be implemented by the instance shader.
|
// To be implemented by the instance shader.
|
||||||
void flw_transformBoundingSphere(in FlwInstance i, inout vec3 center, inout float radius);
|
void flw_transformBoundingSphere(in FlwInstance i, inout vec3 center, inout float radius);
|
||||||
void flw_instanceVertex(FlwInstance i);
|
void flw_instanceVertex(FlwInstance i);
|
||||||
|
|
|
@ -6,7 +6,7 @@ layout(location = 2) in vec2 _flw_v_texCoord;
|
||||||
layout(location = 3) in ivec2 _flw_v_light;
|
layout(location = 3) in ivec2 _flw_v_light;
|
||||||
layout(location = 4) in vec3 _flw_v_normal;
|
layout(location = 4) in vec3 _flw_v_normal;
|
||||||
|
|
||||||
void flw_layoutVertex() {
|
void _flw_layoutVertex() {
|
||||||
flw_vertexPos = vec4(_flw_v_pos, 1.0);
|
flw_vertexPos = vec4(_flw_v_pos, 1.0);
|
||||||
flw_vertexColor = _flw_v_color;
|
flw_vertexColor = _flw_v_color;
|
||||||
flw_vertexTexCoord = _flw_v_texCoord;
|
flw_vertexTexCoord = _flw_v_texCoord;
|
|
@ -1,6 +1,7 @@
|
||||||
#include "flywheel:internal/indirect/api/vertex.glsl"
|
#include "flywheel:internal/indirect/api/vertex.glsl"
|
||||||
#include "flywheel:internal/indirect/mesh.glsl"
|
#include "flywheel:internal/indirect/mesh.glsl"
|
||||||
#include "flywheel:internal/material.glsl"
|
#include "flywheel:internal/material.glsl"
|
||||||
|
#include "flywheel:internal/block.vert"
|
||||||
#include "flywheel:util/diffuse.glsl"
|
#include "flywheel:util/diffuse.glsl"
|
||||||
|
|
||||||
flat out uvec3 _flw_material;
|
flat out uvec3 _flw_material;
|
||||||
|
@ -33,7 +34,7 @@ void main() {
|
||||||
_flw_unpackMaterial(p, flw_material);
|
_flw_unpackMaterial(p, flw_material);
|
||||||
_flw_material = uvec3(drawCommands[batchID].fragmentMaterialID, drawCommands[batchID].packedFogAndCutout, p);
|
_flw_material = uvec3(drawCommands[batchID].fragmentMaterialID, drawCommands[batchID].packedFogAndCutout, p);
|
||||||
|
|
||||||
flw_layoutVertex();
|
_flw_layoutVertex();
|
||||||
flw_beginVertex();
|
flw_beginVertex();
|
||||||
flw_instanceVertex(i);
|
flw_instanceVertex(i);
|
||||||
flw_materialVertex();
|
flw_materialVertex();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "flywheel:internal/instancing/api/vertex.glsl"
|
#include "flywheel:internal/instancing/api/vertex.glsl"
|
||||||
#include "flywheel:internal/material.glsl"
|
#include "flywheel:internal/material.glsl"
|
||||||
|
#include "flywheel:internal/block.vert"
|
||||||
#include "flywheel:util/diffuse.glsl"
|
#include "flywheel:util/diffuse.glsl"
|
||||||
|
|
||||||
uniform uvec4 _flw_material_instancing;
|
uniform uvec4 _flw_material_instancing;
|
||||||
|
@ -11,7 +12,7 @@ void main() {
|
||||||
|
|
||||||
FlwInstance i = _flw_unpackInstance();
|
FlwInstance i = _flw_unpackInstance();
|
||||||
|
|
||||||
flw_layoutVertex();
|
_flw_layoutVertex();
|
||||||
flw_beginVertex();
|
flw_beginVertex();
|
||||||
flw_instanceVertex(i);
|
flw_instanceVertex(i);
|
||||||
flw_materialVertex();
|
flw_materialVertex();
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
#include "flywheel:api/vertex.glsl"
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 _flw_v_pos;
|
|
||||||
layout(location = 1) in vec2 _flw_v_texCoord;
|
|
||||||
layout(location = 2) in vec3 _flw_v_normal;
|
|
||||||
|
|
||||||
void flw_layoutVertex() {
|
|
||||||
flw_vertexPos = vec4(_flw_v_pos, 1.0);
|
|
||||||
flw_vertexColor = vec4(1.0);
|
|
||||||
flw_vertexTexCoord = _flw_v_texCoord;
|
|
||||||
flw_vertexOverlay = ivec2(0, 10);
|
|
||||||
flw_vertexLight = vec2(1.0);
|
|
||||||
flw_vertexNormal = _flw_v_normal;
|
|
||||||
}
|
|
Loading…
Reference in a new issue