mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-01 01:46:39 +01:00
Instancers like suppliers
- Instancers accept model suppliers instead of models directly - gpu resource allocation is deferred until render time
This commit is contained in:
parent
7f2d8d8cb2
commit
6f06283f6f
2 changed files with 40 additions and 27 deletions
|
@ -59,7 +59,7 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
return models.size() > 0 && models.asMap()
|
return models.size() > 0 && models.asMap()
|
||||||
.values()
|
.values()
|
||||||
.stream()
|
.stream()
|
||||||
.allMatch(Instancer::empty);
|
.allMatch(Instancer::isEmpty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
@ -100,7 +100,7 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
|
|
||||||
public Instancer<D> get(Object key, Supplier<BufferedModel> supplier) {
|
public Instancer<D> get(Object key, Supplier<BufferedModel> supplier) {
|
||||||
try {
|
try {
|
||||||
return models.get(key, () -> new Instancer<>(supplier.get(), originCoordinate, spec));
|
return models.get(key, () -> new Instancer<>(supplier, originCoordinate, spec));
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -20,7 +20,8 @@ public class Instancer<D extends InstanceData> {
|
||||||
|
|
||||||
public final Supplier<Vector3i> originCoordinate;
|
public final Supplier<Vector3i> originCoordinate;
|
||||||
|
|
||||||
protected final BufferedModel model;
|
protected Supplier<BufferedModel> gen;
|
||||||
|
protected BufferedModel model;
|
||||||
|
|
||||||
protected final VertexFormat instanceFormat;
|
protected final VertexFormat instanceFormat;
|
||||||
protected final IInstanceFactory<D> factory;
|
protected final IInstanceFactory<D> factory;
|
||||||
|
@ -35,31 +36,15 @@ public class Instancer<D extends InstanceData> {
|
||||||
boolean anyToRemove;
|
boolean anyToRemove;
|
||||||
boolean anyToUpdate;
|
boolean anyToUpdate;
|
||||||
|
|
||||||
public Instancer(BufferedModel model, Supplier<Vector3i> originCoordinate, MaterialSpec<D> spec) {
|
public Instancer(Supplier<BufferedModel> model, Supplier<Vector3i> originCoordinate, MaterialSpec<D> spec) {
|
||||||
this.model = model;
|
this.gen = model;
|
||||||
this.factory = spec.getInstanceFactory();
|
this.factory = spec.getInstanceFactory();
|
||||||
this.instanceFormat = spec.getInstanceFormat();
|
this.instanceFormat = spec.getInstanceFormat();
|
||||||
this.originCoordinate = originCoordinate;
|
this.originCoordinate = originCoordinate;
|
||||||
|
|
||||||
if (model.getVertexCount() <= 0)
|
|
||||||
throw new IllegalArgumentException("Refusing to instance a model with no vertices.");
|
|
||||||
|
|
||||||
vao = new GlVertexArray();
|
|
||||||
instanceVBO = new GlBuffer(GlBufferType.ARRAY_BUFFER);
|
|
||||||
|
|
||||||
vao.bind();
|
|
||||||
|
|
||||||
// bind the model's vbo to our vao
|
|
||||||
model.setupState();
|
|
||||||
|
|
||||||
AttribUtil.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount());
|
|
||||||
|
|
||||||
vao.unbind();
|
|
||||||
|
|
||||||
model.clearState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
|
if (!isInitialized()) init();
|
||||||
if (deleted) return;
|
if (deleted) return;
|
||||||
|
|
||||||
vao.bind();
|
vao.bind();
|
||||||
|
@ -82,7 +67,33 @@ public class Instancer<D extends InstanceData> {
|
||||||
return instanceData;
|
return instanceData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean empty() {
|
private void init() {
|
||||||
|
model = gen.get();
|
||||||
|
gen = null;
|
||||||
|
|
||||||
|
if (model.getVertexCount() <= 0)
|
||||||
|
throw new IllegalArgumentException("Refusing to instance a model with no vertices.");
|
||||||
|
|
||||||
|
vao = new GlVertexArray();
|
||||||
|
instanceVBO = new GlBuffer(GlBufferType.ARRAY_BUFFER);
|
||||||
|
|
||||||
|
vao.bind();
|
||||||
|
|
||||||
|
// bind the model's vbo to our vao
|
||||||
|
model.setupState();
|
||||||
|
|
||||||
|
AttribUtil.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount());
|
||||||
|
|
||||||
|
vao.unbind();
|
||||||
|
|
||||||
|
model.clearState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return gen != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
return !anyToUpdate && !anyToRemove && glInstanceCount == 0;
|
return !anyToUpdate && !anyToRemove && glInstanceCount == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,17 +106,19 @@ public class Instancer<D extends InstanceData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free acquired resources. Attempting to use this after calling delete is undefined behavior.
|
* Free acquired resources. All other Instancer methods are undefined behavior after calling delete.
|
||||||
*/
|
*/
|
||||||
public void delete() {
|
public void delete() {
|
||||||
if (deleted) return;
|
if (deleted) return;
|
||||||
|
|
||||||
deleted = true;
|
deleted = true;
|
||||||
|
|
||||||
model.delete();
|
if (isInitialized()) {
|
||||||
|
model.delete();
|
||||||
|
|
||||||
instanceVBO.delete();
|
instanceVBO.delete();
|
||||||
vao.delete();
|
vao.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderSetup() {
|
protected void renderSetup() {
|
||||||
|
|
Loading…
Reference in a new issue