Skip to content

Commit 665402f

Browse files
committed
experiment with material parameter handling
1 parent 218bd55 commit 665402f

4 files changed

Lines changed: 77 additions & 43 deletions

File tree

jme3-core/src/main/java/com/jme3/util/struct/Struct.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,13 @@ public void bind(Struct struct) {
8787
*
8888
* @param layout layout
8989
*/
90-
public void bind(StructLayout layout) {
90+
public <E extends Struct> E bind(StructLayout layout) {
9191
if (this.layout == layout) {
92-
return;
92+
return (E)this;
9393
}
9494
this.layout = layout;
9595
computeOffsets();
96+
return (E)this;
9697
}
9798

9899
/**

jme3-core/src/main/java/com/jme3/vulkan/material/experimental/Unlit.java

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,65 +2,53 @@
22

33
import com.jme3.math.ColorRGBA;
44
import com.jme3.texture.Texture;
5+
import com.jme3.util.struct.Struct;
56
import com.jme3.util.struct.StructLayout;
67
import com.jme3.util.struct.StructMapping;
7-
import com.jme3.vulkan.descriptors.CachedDescriptorSet;
8-
import com.jme3.vulkan.descriptors.DescriptorPool;
9-
import com.jme3.vulkan.descriptors.DescriptorSetLayout;
8+
import com.jme3.vulkan.JmePlatform;
9+
import com.jme3.vulkan.buffers.BufferUsage;
10+
import com.jme3.vulkan.buffers.MappableBuffer;
11+
import com.jme3.vulkan.buffers.saving.UpdateHint;
1012
import com.jme3.vulkan.material.structs.UnshadedParams;
11-
import com.jme3.vulkan.pipeline.PipelineLayout;
13+
import com.jme3.vulkan.util.Flag;
1214

15+
import java.util.HashMap;
1316
import java.util.IdentityHashMap;
1417
import java.util.Map;
1518

16-
public class Unlit implements ShaderInterface {
19+
public class Unlit {
1720

18-
private final Map<DescriptorSetLayout, CachedDescriptorSet> sets = new IdentityHashMap<>();
19-
private final UnshadedParams params = new UnshadedParams();
21+
private final Map<String, Object> parameters = new HashMap<>();
22+
private final Map<MappableBuffer, StructMapping> mappings = new IdentityHashMap<>();
23+
private final MappableBuffer visualBuffer = JmePlatform.allocateStandardBuffer(1, BufferUsage.Uniform, UpdateHint.Dynamic);
24+
private final UnshadedParams visuals = new UnshadedParams();
2025

2126
{
22-
params.bind(StructLayout.std140);
27+
visuals.bind(StructLayout.std140);
28+
visualBuffer.resize(visuals.getSize());
2329
}
2430

25-
public void update(PipelineLayout pipeline, DescriptorPool pool, ParameterPool parameters) {
26-
pipeline.allocate(pool, sets);
27-
pipeline.write(sets, "ColorMap", parameters.get("ColorMap"));
28-
try (StructMapping<UnshadedParams> m = parameters.mapBuffer("Params", params)) {
29-
params.color.compareAndSet(parameters.get("Color"));
31+
protected <T extends Struct> T map(MappableBuffer buffer, T struct) {
32+
StructMapping<T> map = mappings.get(buffer);
33+
if (map == null) {
34+
mappings.put(buffer, map = buffer.mapStruct(struct));
3035
}
36+
return map.get();
3137
}
3238

33-
@Override
34-
public void close() {
35-
36-
}
37-
38-
protected UnshadedParams getUnshaded() {
39-
return getStruct("Unshaded", UnshadedParams::new, StructLayout.std140);
40-
}
41-
42-
public void setBaseColor(ColorRGBA color) {
43-
getUnshaded().color.set(color);
39+
public void flush() {
40+
for (StructMapping m : mappings.values()) {
41+
m.close();
42+
}
43+
mappings.clear();
4444
}
4545

46-
public void setVertexColor(boolean vertexColor) {
47-
getUnshaded().vertexColor.set(true);
46+
public void setColor(ColorRGBA color) {
47+
map(visualBuffer, visuals).color.set(color);
4848
}
4949

5050
public void setColorMap(Texture texture) {
5151
parameters.put("ColorMap", texture);
5252
}
5353

54-
public ColorRGBA getBaseColor() {
55-
return getUnshaded().color.get();
56-
}
57-
58-
public boolean isVertexColor() {
59-
return getUnshaded().vertexColor.get();
60-
}
61-
62-
public Texture getColorMap() {
63-
return (Texture)parameters.get("ColorMap");
64-
}
65-
6654
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.jme3.vulkan.material.experimental;
2+
3+
import com.jme3.material.Material;
4+
import com.jme3.vulkan.buffers.MappableBuffer;
5+
import com.jme3.vulkan.buffers.saving.UpdateHint;
6+
import com.jme3.vulkan.material.structs.UnshadedParams;
7+
8+
import java.util.List;
9+
10+
public class UnshadedRenderer {
11+
12+
public void render(Material material) {
13+
/*
14+
There are 2 types of buffers:
15+
1. Buffers that are local to a material. Their contents don't change often
16+
so it's best to use more memory per material and keep their contents on the gpu.
17+
2. Buffers that are local to the renderer. Their contents change often, so it's
18+
best to save memory and use the same buffer for every material.
19+
3. Buffers that are shared among multiple renderers. Their content changes often,
20+
and renderers are likely to be using the same buffer layout.
21+
How do we identify which buffers fall into which category?
22+
1. Have the user/shader specify an update hint. For the camera buffer, this would
23+
be specified by the shader. For random stuff the user happens to want to update
24+
often, the hint would be specified by the user.
25+
2. For renderer-local and renderer-global buffers, I think these concepts can be
26+
merged into one, since the only difference is the formatting. The format can be
27+
identified via the struct type. So the renderer manager will store all renderer
28+
buffers by the struct used on them.
29+
Next, a buffer is a collection of parameters. How does the user specify the update
30+
hint when the user only has access to individual parameters?
31+
1. Treat as renderer managed if at least one hint is Stream.
32+
2. Treat as renderer managed if a majority of hints are Stream.
33+
3. Treat as renderer managed if all hints are Stream.
34+
*/
35+
UpdateHint hint = material.getParameter("Color").getUpdateHint();
36+
if (hint == UpdateHint.Stream) {
37+
MappableBuffer buffer = manager.getBuffer(new UnshadedParams());
38+
} else {
39+
MappableBuffer buffer = material.getBuffer(getClass(), new UnshadedParams());
40+
}
41+
}
42+
43+
}

jme3-examples/src/main/java/jme3test/vulkan/TestJme4.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
import com.jme3.renderer.queue.TransparentComparator;
1414
import com.jme3.scene.Geometry;
1515
import com.jme3.scene.shape.Box;
16+
import com.jme3.util.struct.StructMapping;
1617
import com.jme3.vulkan.commands.StandardRenderSettings;
1718
import com.jme3.vulkan.material.NewMaterial;
1819
import com.jme3.vulkan.material.experimental.Unlit;
20+
import com.jme3.vulkan.material.structs.UnshadedParams;
1921
import com.jme3.vulkan.render.bucket.GeometryBucket;
2022
import com.sun.tools.javac.util.List;
2123

@@ -35,10 +37,10 @@ public void simpleInitApp() {
3537

3638
Geometry g = new Geometry("geom_jme4", new Box(1f, 1f, 1f));
3739
NewMaterial mat = (NewMaterial)engine.createMaterial("Common/MatDefs/Misc/Unshaded.j3md");
38-
try (Unlit u = new Unlit()) {
39-
u.setBaseColor(ColorRGBA.White);
40-
u.setColorMap(null);
40+
try (StructMapping<UnshadedParams> m = mat.getInterface(Unlit.class).mapVisuals()) {
41+
m.get().color.set(ColorRGBA.Blue);
4142
}
43+
mat.getInterface(Unlit.class).setColorMap(myTexture);
4244
g.setMaterial(mat);
4345
rootNode.attachChild(g);
4446

0 commit comments

Comments
 (0)