mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-22 10:57:55 +01:00
Consists of inconsistency
- Make architecture of indirect engine and draw manager match that of other engines and draw managers
This commit is contained in:
parent
d3d5797fd3
commit
79464361d2
9 changed files with 169 additions and 195 deletions
|
@ -23,28 +23,24 @@ public class GlStateTracker {
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void _setBuffer(GlBufferType type, int buffer) {
|
public static void _setBuffer(GlBufferType type, int id) {
|
||||||
BUFFERS[type.ordinal()] = buffer;
|
BUFFERS[type.ordinal()] = id;
|
||||||
}
|
|
||||||
|
|
||||||
public static void _setProgram(int id) {
|
|
||||||
program = id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void _setVertexArray(int id) {
|
public static void _setVertexArray(int id) {
|
||||||
vao = id;
|
vao = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void _setProgram(int id) {
|
||||||
|
program = id;
|
||||||
|
}
|
||||||
|
|
||||||
public static State getRestoreState() {
|
public static State getRestoreState() {
|
||||||
return new State(BUFFERS.clone(), vao, program);
|
return new State(BUFFERS.clone(), vao, program);
|
||||||
}
|
}
|
||||||
|
|
||||||
public record State(int[] buffers, int vao, int program) implements AutoCloseable {
|
public record State(int[] buffers, int vao, int program) implements AutoCloseable {
|
||||||
public void restore() {
|
public void restore() {
|
||||||
if (program != GlStateTracker.program) {
|
|
||||||
GlStateManager._glUseProgram(program);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vao != GlStateTracker.vao) {
|
if (vao != GlStateTracker.vao) {
|
||||||
GlStateManager._glBindVertexArray(vao);
|
GlStateManager._glBindVertexArray(vao);
|
||||||
}
|
}
|
||||||
|
@ -56,6 +52,10 @@ public class GlStateTracker {
|
||||||
GlStateManager._glBindBuffer(values[i].glEnum, buffers[i]);
|
GlStateManager._glBindBuffer(values[i].glEnum, buffers[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (program != GlStateTracker.program) {
|
||||||
|
GlStateManager._glUseProgram(program);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,23 +1,66 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.indirect;
|
package com.jozufozu.flywheel.backend.instancing.indirect;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.core.model.Mesh;
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
import com.jozufozu.flywheel.util.Pair;
|
import com.jozufozu.flywheel.util.Pair;
|
||||||
|
|
||||||
public class IndirectDrawManager {
|
public class IndirectDrawManager {
|
||||||
|
|
||||||
public final Map<Pair<StructType<?>, VertexType>, IndirectCullingGroup<?>> lists = new HashMap<>();
|
private final List<UninitializedModel> uninitializedModels = new ArrayList<>();
|
||||||
|
private final List<IndirectInstancer<?>> allInstancers = new ArrayList<>();
|
||||||
|
public final Map<Pair<StructType<?>, VertexType>, IndirectCullingGroup<?>> renderLists = new HashMap<>();
|
||||||
|
|
||||||
|
public void create(IndirectInstancer<?> instancer, Model model) {
|
||||||
|
uninitializedModels.add(new UninitializedModel(instancer, model));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() {
|
||||||
|
for (var model : uninitializedModels) {
|
||||||
|
add(model.instancer(), model.model());
|
||||||
|
}
|
||||||
|
uninitializedModels.clear();
|
||||||
|
|
||||||
|
for (IndirectCullingGroup<?> value : renderLists.values()) {
|
||||||
|
value.beginFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
renderLists.values()
|
||||||
|
.forEach(IndirectCullingGroup::delete);
|
||||||
|
renderLists.clear();
|
||||||
|
|
||||||
|
allInstancers.forEach(IndirectInstancer::delete);
|
||||||
|
allInstancers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearInstancers() {
|
||||||
|
allInstancers.forEach(IndirectInstancer::clear);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <D extends InstancedPart> void add(IndirectInstancer<D> instancer, Material material, Mesh mesh) {
|
private <D extends InstancedPart> void add(IndirectInstancer<D> instancer, Model model) {
|
||||||
var indirectList = (IndirectCullingGroup<D>) lists.computeIfAbsent(Pair.of(instancer.type, mesh.getVertexType()), p -> new IndirectCullingGroup<>(p.first(), p.second()));
|
var meshes = model.getMeshes();
|
||||||
|
for (var entry : meshes.entrySet()) {
|
||||||
|
var material = entry.getKey();
|
||||||
|
var mesh = entry.getValue();
|
||||||
|
|
||||||
indirectList.drawSet.add(instancer, material, indirectList.meshPool.alloc(mesh));
|
var indirectList = (IndirectCullingGroup<D>) renderLists.computeIfAbsent(Pair.of(instancer.type, mesh.getVertexType()), p -> new IndirectCullingGroup<>(p.first(), p.second()));
|
||||||
|
|
||||||
|
indirectList.drawSet.add(instancer, material, indirectList.meshPool.alloc(mesh));
|
||||||
|
|
||||||
|
break; // TODO: support multiple meshes per model
|
||||||
|
}
|
||||||
|
allInstancers.add(instancer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private record UninitializedModel(IndirectInstancer<?> instancer, Model model) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.indirect;
|
package com.jozufozu.flywheel.backend.instancing.indirect;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -30,52 +30,55 @@ import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class IndirectEngine implements Engine {
|
public class IndirectEngine implements Engine {
|
||||||
|
|
||||||
public static int MAX_ORIGIN_DISTANCE = 100;
|
protected final IndirectDrawManager drawManager = new IndirectDrawManager();
|
||||||
|
protected final Map<StructType<?>, IndirectInstancerFactory<?>> factories = new HashMap<>();
|
||||||
protected BlockPos originCoordinate = BlockPos.ZERO;
|
|
||||||
|
|
||||||
protected final ContextShader context;
|
|
||||||
|
|
||||||
protected final Map<StructType<?>, IndirectFactory<?>> factories = new HashMap<>();
|
|
||||||
|
|
||||||
protected final List<IndirectModel<?>> uninitializedModels = new ArrayList<>();
|
|
||||||
protected final IndirectDrawManager indirectDrawManager = new IndirectDrawManager();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The set of instance managers that are attached to this engine.
|
* The set of instance managers that are attached to this engine.
|
||||||
*/
|
*/
|
||||||
private final WeakHashSet<InstanceManager<?>> instanceManagers;
|
private final WeakHashSet<InstanceManager<?>> instanceManagers = new WeakHashSet<>();
|
||||||
|
|
||||||
public IndirectEngine(ContextShader context) {
|
protected final ContextShader context;
|
||||||
|
protected final int sqrMaxOriginDistance;
|
||||||
|
|
||||||
|
protected BlockPos originCoordinate = BlockPos.ZERO;
|
||||||
|
|
||||||
|
public IndirectEngine(ContextShader context, int sqrMaxOriginDistance) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
this.sqrMaxOriginDistance = sqrMaxOriginDistance;
|
||||||
this.instanceManagers = new WeakHashSet<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public <D extends InstancedPart> IndirectFactory<D> factory(StructType<D> type) {
|
public <D extends InstancedPart> IndirectInstancerFactory<D> factory(StructType<D> type) {
|
||||||
return (IndirectFactory<D>) factories.computeIfAbsent(type, this::createFactory);
|
return (IndirectInstancerFactory<D>) factories.computeIfAbsent(type, this::createFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private <D extends InstancedPart> IndirectFactory<D> createFactory(StructType<D> type) {
|
private <D extends InstancedPart> IndirectInstancerFactory<D> createFactory(StructType<D> type) {
|
||||||
return new IndirectFactory<>(type, uninitializedModels::add);
|
return new IndirectInstancerFactory<>(type, drawManager::create);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginFrame(TaskEngine taskEngine, RenderContext context) {
|
||||||
|
try (var restoreState = GlStateTracker.getRestoreState()) {
|
||||||
|
drawManager.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) {
|
public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) {
|
||||||
try (var restoreState = GlStateTracker.getRestoreState()) {
|
try (var restoreState = GlStateTracker.getRestoreState()) {
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
for (var list : indirectDrawManager.lists.values()) {
|
for (var list : drawManager.renderLists.values()) {
|
||||||
list.submit(stage);
|
list.submit(stage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setup() {
|
protected void setup() {
|
||||||
GlTextureUnit.T2.makeActive();
|
GlTextureUnit.T2.makeActive();
|
||||||
Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer();
|
Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer();
|
||||||
|
|
||||||
|
@ -87,14 +90,31 @@ public class IndirectEngine implements Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public boolean maintainOriginCoordinate(Camera camera) {
|
||||||
factories.values()
|
Vec3 cameraPos = camera.getPosition();
|
||||||
.forEach(IndirectFactory::delete);
|
|
||||||
|
|
||||||
indirectDrawManager.lists.values()
|
double distanceSqr = Vec3.atLowerCornerOf(originCoordinate)
|
||||||
.forEach(IndirectCullingGroup::delete);
|
.subtract(cameraPos)
|
||||||
|
.lengthSqr();
|
||||||
|
|
||||||
factories.clear();
|
if (distanceSqr > sqrMaxOriginDistance) {
|
||||||
|
shiftListeners(Mth.floor(cameraPos.x), Mth.floor(cameraPos.y), Mth.floor(cameraPos.z));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shiftListeners(int cX, int cY, int cZ) {
|
||||||
|
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||||
|
|
||||||
|
drawManager.clearInstancers();
|
||||||
|
|
||||||
|
instanceManagers.forEach(InstanceManager::onOriginShift);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attachManagers(InstanceManager<?>... listener) {
|
||||||
|
Collections.addAll(instanceManagers, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -103,45 +123,9 @@ public class IndirectEngine implements Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void attachManagers(InstanceManager<?>... listener) {
|
public void delete() {
|
||||||
instanceManagers.addAll(List.of(listener));
|
factories.clear();
|
||||||
}
|
drawManager.delete();
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean maintainOriginCoordinate(Camera camera) {
|
|
||||||
Vec3 cameraPos = camera.getPosition();
|
|
||||||
|
|
||||||
double distanceSqr = Vec3.atLowerCornerOf(originCoordinate)
|
|
||||||
.subtract(cameraPos)
|
|
||||||
.lengthSqr();
|
|
||||||
|
|
||||||
if (distanceSqr > MAX_ORIGIN_DISTANCE * MAX_ORIGIN_DISTANCE) {
|
|
||||||
shiftListeners(Mth.floor(cameraPos.x), Mth.floor(cameraPos.y), Mth.floor(cameraPos.z));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beginFrame(TaskEngine taskEngine, RenderContext context) {
|
|
||||||
try (var restoreState = GlStateTracker.getRestoreState()) {
|
|
||||||
for (var model : uninitializedModels) {
|
|
||||||
model.init(indirectDrawManager);
|
|
||||||
}
|
|
||||||
uninitializedModels.clear();
|
|
||||||
|
|
||||||
for (IndirectCullingGroup<?> value : indirectDrawManager.lists.values()) {
|
|
||||||
value.beginFrame();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void shiftListeners(int cX, int cY, int cZ) {
|
|
||||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
|
||||||
|
|
||||||
factories.values().forEach(IndirectFactory::clear);
|
|
||||||
|
|
||||||
instanceManagers.forEach(InstanceManager::onOriginShift);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.indirect;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerFactory;
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
|
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
|
||||||
|
|
||||||
public class IndirectFactory<D extends InstancedPart> implements InstancerFactory<D> {
|
|
||||||
|
|
||||||
protected final Map<Model, IndirectModel<D>> models = new HashMap<>();
|
|
||||||
protected final StructType<D> type;
|
|
||||||
private final Consumer<IndirectModel<D>> creationListener;
|
|
||||||
|
|
||||||
public IndirectFactory(StructType<D> type, Consumer<IndirectModel<D>> creationListener) {
|
|
||||||
this.type = type;
|
|
||||||
this.creationListener = creationListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Instancer<D> model(Model modelKey) {
|
|
||||||
return models.computeIfAbsent(modelKey, this::createInstancer).getInstancer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
|
||||||
models.values().forEach(IndirectModel::delete);
|
|
||||||
models.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear all instance data without freeing resources.
|
|
||||||
*/
|
|
||||||
public void clear() {
|
|
||||||
models.values()
|
|
||||||
.stream()
|
|
||||||
.map(IndirectModel::getInstancer)
|
|
||||||
.forEach(AbstractInstancer::clear);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IndirectModel<D> createInstancer(Model model) {
|
|
||||||
var instancer = new IndirectModel<>(type, model);
|
|
||||||
this.creationListener.accept(instancer);
|
|
||||||
return instancer;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.jozufozu.flywheel.backend.instancing.indirect;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
|
import com.jozufozu.flywheel.api.instancer.InstancerFactory;
|
||||||
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
|
|
||||||
|
public class IndirectInstancerFactory<D extends InstancedPart> implements InstancerFactory<D> {
|
||||||
|
|
||||||
|
protected final StructType<D> type;
|
||||||
|
private final BiConsumer<IndirectInstancer<?>, Model> creationListener;
|
||||||
|
protected final Map<Model, IndirectInstancer<D>> models = new HashMap<>();
|
||||||
|
|
||||||
|
public IndirectInstancerFactory(StructType<D> type, BiConsumer<IndirectInstancer<?>, Model> creationListener) {
|
||||||
|
this.type = type;
|
||||||
|
this.creationListener = creationListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Instancer<D> model(Model modelKey) {
|
||||||
|
return models.computeIfAbsent(modelKey, this::createInstancer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndirectInstancer<D> createInstancer(Model model) {
|
||||||
|
var instancer = new IndirectInstancer<>(type);
|
||||||
|
creationListener.accept(instancer, model);
|
||||||
|
return instancer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,28 +1,28 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.indirect;
|
package com.jozufozu.flywheel.backend.instancing.indirect;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL46.*;
|
import static org.lwjgl.opengl.GL15.glDeleteBuffers;
|
||||||
|
import static org.lwjgl.opengl.GL44.GL_DYNAMIC_STORAGE_BIT;
|
||||||
|
import static org.lwjgl.opengl.GL45.glCreateBuffers;
|
||||||
|
import static org.lwjgl.opengl.GL45.glNamedBufferStorage;
|
||||||
|
import static org.lwjgl.opengl.GL45.nglNamedBufferSubData;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.backend.instancing.instancing.ElementBuffer;
|
|
||||||
import com.jozufozu.flywheel.backend.memory.MemoryBlock;
|
import com.jozufozu.flywheel.backend.memory.MemoryBlock;
|
||||||
import com.jozufozu.flywheel.core.model.Mesh;
|
import com.jozufozu.flywheel.core.model.Mesh;
|
||||||
|
|
||||||
public class IndirectMeshPool {
|
public class IndirectMeshPool {
|
||||||
|
private final VertexType vertexType;
|
||||||
|
|
||||||
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<>();
|
||||||
|
|
||||||
final VertexType vertexType;
|
|
||||||
|
|
||||||
final int vbo;
|
final int vbo;
|
||||||
private final MemoryBlock clientStorage;
|
private final MemoryBlock clientStorage;
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ public class IndirectMeshPool {
|
||||||
|
|
||||||
model.buffer(ptr);
|
model.buffer(ptr);
|
||||||
|
|
||||||
byteIndex += model.getByteSize();
|
byteIndex += model.size();
|
||||||
baseVertex += model.mesh.getVertexCount();
|
baseVertex += model.mesh.getVertexCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,38 +90,44 @@ public class IndirectMeshPool {
|
||||||
meshList.clear();
|
meshList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BufferedMesh {
|
public VertexType getVertexType() {
|
||||||
|
return vertexType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BufferedMesh {
|
||||||
public final Mesh mesh;
|
public final Mesh mesh;
|
||||||
private final int vertexCount;
|
private final int vertexCount;
|
||||||
private long byteIndex;
|
private long byteIndex;
|
||||||
private int baseVertex;
|
private int baseVertex;
|
||||||
|
|
||||||
public BufferedMesh(Mesh mesh) {
|
private BufferedMesh(Mesh mesh) {
|
||||||
this.mesh = mesh;
|
this.mesh = mesh;
|
||||||
|
|
||||||
vertexCount = mesh.getVertexCount();
|
vertexCount = mesh.getVertexCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buffer(long ptr) {
|
private void buffer(long ptr) {
|
||||||
this.mesh.write(ptr + byteIndex);
|
mesh.write(ptr + byteIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteSize() {
|
public Mesh getMesh() {
|
||||||
return IndirectMeshPool.this.vertexType.getLayout().getStride() * this.vertexCount;
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return mesh.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBaseVertex() {
|
public int getBaseVertex() {
|
||||||
return baseVertex;
|
return baseVertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getVertexCount() {
|
public int getIndexCount() {
|
||||||
return this.vertexCount;
|
return vertexCount * 6 / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIndexCount() {
|
public VertexType getVertexType() {
|
||||||
return this.vertexCount * 6 / 4;
|
return vertexType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.indirect;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
|
||||||
|
|
||||||
public class IndirectModel<D extends InstancedPart> {
|
|
||||||
|
|
||||||
private final Model model;
|
|
||||||
private final IndirectInstancer<D> instancer;
|
|
||||||
|
|
||||||
public IndirectModel(StructType<D> type, Model model) {
|
|
||||||
this.model = model;
|
|
||||||
this.instancer = new IndirectInstancer<>(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(IndirectDrawManager indirectDrawManager) {
|
|
||||||
var materialMeshMap = this.model.getMeshes();
|
|
||||||
for (var entry : materialMeshMap.entrySet()) {
|
|
||||||
var material = entry.getKey();
|
|
||||||
var mesh = entry.getValue();
|
|
||||||
indirectDrawManager.add(instancer, material, mesh);
|
|
||||||
|
|
||||||
return; // TODO: support multiple meshes per model
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IndirectInstancer<D> getInstancer() {
|
|
||||||
return instancer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Model getModel() {
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVertexCount() {
|
|
||||||
return model.getVertexCount() * instancer.instanceCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -80,7 +80,7 @@ public class InstancingEngine implements Engine {
|
||||||
|
|
||||||
try (var restoreState = GlStateTracker.getRestoreState()) {
|
try (var restoreState = GlStateTracker.getRestoreState()) {
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
render(drawSet);
|
render(drawSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class BackendTypes {
|
||||||
.properName("GL46 Compute Culling")
|
.properName("GL46 Compute Culling")
|
||||||
.shortName("indirect")
|
.shortName("indirect")
|
||||||
.engineMessage(new TextComponent("Using Indirect Engine").withStyle(ChatFormatting.GREEN))
|
.engineMessage(new TextComponent("Using Indirect Engine").withStyle(ChatFormatting.GREEN))
|
||||||
.engineSupplier(() -> new IndirectEngine(Components.WORLD))
|
.engineSupplier(() -> new IndirectEngine(Components.WORLD, 100 * 100))
|
||||||
.fallback(() -> BackendTypes.INSTANCING)
|
.fallback(() -> BackendTypes.INSTANCING)
|
||||||
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance()
|
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance()
|
||||||
.supportsIndirect())
|
.supportsIndirect())
|
||||||
|
|
Loading…
Reference in a new issue