Skip to content

Commit 2e9fa5a

Browse files
committed
Uniform idea
1 parent 6e817df commit 2e9fa5a

3 files changed

Lines changed: 236 additions & 0 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package btw.lowercase.renderer.uniform;
2+
3+
import com.mojang.blaze3d.buffers.GpuBuffer;
4+
import com.mojang.blaze3d.buffers.GpuBufferSlice;
5+
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
6+
import com.mojang.blaze3d.systems.RenderSystem;
7+
import org.lwjgl.system.MemoryStack;
8+
import org.visuals.legacy.animatium.renderer.uniform.UniformKey;
9+
import org.visuals.legacy.animatium.renderer.uniform.UniformSerializer;
10+
11+
import java.nio.ByteBuffer;
12+
import java.util.ArrayList;
13+
import java.util.LinkedHashMap;
14+
import java.util.List;
15+
import java.util.Map;
16+
17+
public final class UniformStorage {
18+
private final GpuBuffer ubo;
19+
private final List<UniformKey<?>> keys;
20+
private final Map<UniformKey<?>, Object> values;
21+
private final int size;
22+
23+
private UniformStorage(final String name, final List<UniformKey<?>> keys, final int size) {
24+
this.ubo = RenderSystem.getDevice().createBuffer(() -> "Dynamic Uniform Storage (" + name + ")", GpuBuffer.USAGE_UNIFORM | GpuBuffer.USAGE_COPY_DST, size);
25+
this.keys = keys;
26+
this.values = new LinkedHashMap<>();
27+
this.size = size;
28+
}
29+
30+
public static Builder builder(final String name) {
31+
return new Builder(name);
32+
}
33+
34+
public <T> void set(final UniformKey<T> key, final T value) {
35+
if (!this.keys.contains(key)) {
36+
throw new UnsupportedOperationException("Uniform storage does not contain key '" + key.name() + "'!");
37+
} else {
38+
this.values.put(key, value);
39+
}
40+
}
41+
42+
public <T> T get(final UniformKey<T> key) {
43+
if (!this.keys.contains(key)) {
44+
return null;
45+
} else {
46+
return (T) this.values.get(key);
47+
}
48+
}
49+
50+
public void update() {
51+
final GpuBufferSlice slice = this.ubo.slice();
52+
try (final MemoryStack stack = MemoryStack.stackPush()) {
53+
final ByteBuffer buffer = stack.malloc(this.size);
54+
for (final Map.Entry<UniformKey<?>, Object> entry : this.values.entrySet()) {
55+
final UniformKey<?> key = entry.getKey();
56+
((UniformSerializer<Object>) key.serializer()).put(buffer, entry.getValue());
57+
}
58+
59+
RenderSystem.getDevice().createCommandEncoder().writeToBuffer(slice, buffer);
60+
}
61+
}
62+
63+
public GpuBufferSlice slice() {
64+
return this.ubo.slice();
65+
}
66+
67+
public static class Builder {
68+
private final String name;
69+
70+
private final List<UniformKey<?>> keys = new ArrayList<>();
71+
private final Std140SizeCalculator calculator = new Std140SizeCalculator();
72+
73+
private Builder(final String name) {
74+
this.name = name;
75+
}
76+
77+
public Builder with(final UniformKey<?> key) {
78+
this.keys.add(key);
79+
key.serializer().size(this.calculator);
80+
return this;
81+
}
82+
83+
public UniformStorage build() {
84+
return new UniformStorage(this.name, List.copyOf(this.keys), this.calculator.get());
85+
}
86+
}
87+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.visuals.legacy.animatium.renderer.uniform
2+
3+
import btw.lowercase.renderer.uniform.UniformSerializer
4+
import org.joml.*
5+
6+
interface UniformKey<T> {
7+
companion object {
8+
@JvmStatic
9+
fun Integer(name: String): UniformKey<Int> = Impl(name, UniformSerializer.INTEGER)
10+
11+
@JvmStatic
12+
fun Float(name: String): UniformKey<Float> = Impl(name, UniformSerializer.FLOAT)
13+
14+
@JvmStatic
15+
fun Matrix4f(name: String): UniformKey<Matrix4f> = Impl(name, UniformSerializer.MATRIX4F)
16+
17+
@JvmStatic
18+
fun Vector2f(name: String): UniformKey<Vector2f> = Impl(name, UniformSerializer.VECTOR2F)
19+
20+
@JvmStatic
21+
fun Vector2i(name: String): UniformKey<Vector2i> = Impl(name, UniformSerializer.VECTOR2I)
22+
23+
@JvmStatic
24+
fun Vector3f(name: String): UniformKey<Vector3f> = Impl(name, UniformSerializer.VECTOR3F)
25+
26+
@JvmStatic
27+
fun Vector3i(name: String): UniformKey<Vector3i> = Impl(name, UniformSerializer.VECTOR3I)
28+
29+
@JvmStatic
30+
fun Vector4f(name: String): UniformKey<Vector4f> = Impl(name, UniformSerializer.VECTOR4F)
31+
32+
@JvmStatic
33+
fun Vector4i(name: String): UniformKey<Vector4i> = Impl(name, UniformSerializer.VECTOR4I)
34+
}
35+
36+
fun name(): String
37+
38+
fun serializer(): UniformSerializer<T>
39+
40+
private data class Impl<T>(val name: String, val serializer: UniformSerializer<T>) : UniformKey<T> {
41+
override fun name(): String = this.name
42+
43+
override fun serializer(): UniformSerializer<T> = this.serializer
44+
}
45+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package org.visuals.legacy.animatium.renderer.uniform
2+
3+
import com.mojang.blaze3d.buffers.Std140SizeCalculator
4+
import org.joml.*
5+
import java.nio.ByteBuffer
6+
7+
abstract class UniformSerializer<T> {
8+
companion object {
9+
val INTEGER: UniformSerializer<Int> = object : UniformSerializer<Int>() {
10+
override fun put(buffer: ByteBuffer, value: Int) {
11+
buffer.putInt(value)
12+
}
13+
14+
override fun size(calculator: Std140SizeCalculator) {
15+
calculator.putInt()
16+
}
17+
}
18+
19+
val FLOAT: UniformSerializer<Float> = object : UniformSerializer<Float>() {
20+
override fun put(buffer: ByteBuffer, value: Float) {
21+
buffer.putFloat(value)
22+
}
23+
24+
override fun size(calculator: Std140SizeCalculator) {
25+
calculator.putFloat()
26+
}
27+
}
28+
29+
val MATRIX4F: UniformSerializer<Matrix4f> = object : UniformSerializer<Matrix4f>() {
30+
override fun put(buffer: ByteBuffer, value: Matrix4f) {
31+
value.get(buffer)
32+
}
33+
34+
override fun size(calculator: Std140SizeCalculator) {
35+
calculator.putInt()
36+
}
37+
}
38+
39+
val VECTOR2F: UniformSerializer<Vector2f> = object : UniformSerializer<Vector2f>() {
40+
override fun put(buffer: ByteBuffer, value: Vector2f) {
41+
value.get(buffer)
42+
}
43+
44+
override fun size(calculator: Std140SizeCalculator) {
45+
calculator.putInt()
46+
}
47+
}
48+
49+
val VECTOR2I: UniformSerializer<Vector2i> = object : UniformSerializer<Vector2i>() {
50+
override fun put(buffer: ByteBuffer, value: Vector2i) {
51+
value.get(buffer)
52+
}
53+
54+
override fun size(calculator: Std140SizeCalculator) {
55+
calculator.putInt()
56+
}
57+
}
58+
59+
val VECTOR3F: UniformSerializer<Vector3f> = object : UniformSerializer<Vector3f>() {
60+
override fun put(buffer: ByteBuffer, value: Vector3f) {
61+
value.get(buffer)
62+
}
63+
64+
override fun size(calculator: Std140SizeCalculator) {
65+
calculator.putInt()
66+
}
67+
}
68+
69+
val VECTOR3I: UniformSerializer<Vector3i> = object : UniformSerializer<Vector3i>() {
70+
override fun put(buffer: ByteBuffer, value: Vector3i) {
71+
value.get(buffer)
72+
}
73+
74+
override fun size(calculator: Std140SizeCalculator) {
75+
calculator.putInt()
76+
}
77+
}
78+
79+
val VECTOR4F: UniformSerializer<Vector4f> =
80+
object : UniformSerializer<Vector4f>() {
81+
override fun put(buffer: ByteBuffer, value: Vector4f) {
82+
value.get(buffer)
83+
}
84+
85+
override fun size(calculator: Std140SizeCalculator) {
86+
calculator.putInt()
87+
}
88+
}
89+
90+
val VECTOR4I: UniformSerializer<Vector4i> = object : UniformSerializer<Vector4i>() {
91+
override fun put(buffer: ByteBuffer, value: Vector4i) {
92+
value.get(buffer)
93+
}
94+
95+
override fun size(calculator: Std140SizeCalculator) {
96+
calculator.putInt()
97+
}
98+
}
99+
}
100+
101+
abstract fun put(buffer: ByteBuffer, value: T)
102+
103+
abstract fun size(calculator: Std140SizeCalculator)
104+
}

0 commit comments

Comments
 (0)