From 269f8231e34ba5231d4f52e614c9cc0d40475a15 Mon Sep 17 00:00:00 2001 From: Kevin Turner <83819+keturn@users.noreply.github.com> Date: Fri, 18 Feb 2022 14:24:11 -0800 Subject: [PATCH] spike(rendering): factor out MutableChunkMesh --- .../rendering/world/ChunkMeshWorkerTest.java | 6 +- .../monitoring/chunk/ChunkMeshInfo.java | 7 +- .../typeHandling/TypeHandlerLibraryImpl.java | 6 +- .../extensionTypes/ChunkMeshTypeHandler.java | 11 ++- .../rendering/logic/ChunkMeshComponent.java | 8 +- .../primitives/BlockMeshGenerator.java | 6 +- .../BlockMeshGeneratorSingleShape.java | 4 +- .../rendering/primitives/ChunkMesh.java | 92 +----------------- .../rendering/primitives/ChunkMeshImpl.java | 4 +- .../primitives/ChunkTessellator.java | 8 +- .../primitives/MutableChunkMesh.java | 93 +++++++++++++++++++ .../rendering/world/ChunkMeshWorker.java | 13 +-- .../rendering/world/RenderableWorldImpl.java | 3 +- .../world/block/shapes/BlockMeshPart.java | 7 +- .../engine/world/chunks/LodChunkProvider.java | 8 +- .../engine/world/chunks/RenderableChunk.java | 6 +- 16 files changed, 149 insertions(+), 133 deletions(-) create mode 100644 engine/src/main/java/org/terasology/engine/rendering/primitives/MutableChunkMesh.java diff --git a/engine-tests/src/test/java/org/terasology/engine/rendering/world/ChunkMeshWorkerTest.java b/engine-tests/src/test/java/org/terasology/engine/rendering/world/ChunkMeshWorkerTest.java index 3e0e9c77dfb..4686d722ce4 100644 --- a/engine-tests/src/test/java/org/terasology/engine/rendering/world/ChunkMeshWorkerTest.java +++ b/engine-tests/src/test/java/org/terasology/engine/rendering/world/ChunkMeshWorkerTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; -import org.terasology.engine.rendering.primitives.ChunkMesh; +import org.terasology.engine.rendering.primitives.MutableChunkMesh; import org.terasology.engine.world.chunks.Chunk; import org.terasology.engine.world.chunks.RenderableChunk; import reactor.core.publisher.Mono; @@ -35,9 +35,9 @@ public class ChunkMeshWorkerTest { Comparator comparator; StepVerifier.FirstStep verifier; - static Mono> alwaysCreateMesh(Chunk chunk) { + static Mono> alwaysCreateMesh(Chunk chunk) { chunk.setDirty(false); - return Mono.just(Tuples.of(chunk, mock(ChunkMesh.class))); + return Mono.just(Tuples.of(chunk, mock(MutableChunkMesh.class))); } @BeforeEach diff --git a/engine/src/main/java/org/terasology/engine/monitoring/chunk/ChunkMeshInfo.java b/engine/src/main/java/org/terasology/engine/monitoring/chunk/ChunkMeshInfo.java index 487baf832aa..9d4df0abb90 100644 --- a/engine/src/main/java/org/terasology/engine/monitoring/chunk/ChunkMeshInfo.java +++ b/engine/src/main/java/org/terasology/engine/monitoring/chunk/ChunkMeshInfo.java @@ -1,8 +1,9 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.monitoring.chunk; import org.terasology.engine.rendering.primitives.ChunkMesh; +import org.terasology.engine.rendering.primitives.MutableChunkMesh; import static com.google.common.base.Preconditions.checkNotNull; @@ -14,7 +15,7 @@ public class ChunkMeshInfo { public final int totalTimeToGenerateBlockVertices; public final int totalTimeToGenerateOptimizedBuffers; - public ChunkMeshInfo(ChunkMesh mesh) { + public ChunkMeshInfo(MutableChunkMesh mesh) { checkNotNull(mesh, "The parameter 'mesh' must not be null"); int vertices = 0; @@ -22,7 +23,7 @@ public ChunkMeshInfo(ChunkMesh mesh) { if (mesh.hasVertexElements()) { for (ChunkMesh.RenderType type : ChunkMesh.RenderType.values()) { - final ChunkMesh.VertexElements element = mesh.getVertexElements(type); + final MutableChunkMesh.VertexElements element = mesh.getVertexElements(type); vertices += element.buffer.elements(); indices += element.indices.indices(); } diff --git a/engine/src/main/java/org/terasology/engine/persistence/typeHandling/TypeHandlerLibraryImpl.java b/engine/src/main/java/org/terasology/engine/persistence/typeHandling/TypeHandlerLibraryImpl.java index 1969f0361b3..dc71e47dadf 100644 --- a/engine/src/main/java/org/terasology/engine/persistence/typeHandling/TypeHandlerLibraryImpl.java +++ b/engine/src/main/java/org/terasology/engine/persistence/typeHandling/TypeHandlerLibraryImpl.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.persistence.typeHandling; @@ -53,7 +53,7 @@ import org.terasology.engine.persistence.typeHandling.mathTypes.Vector4icTypeHandler; import org.terasology.engine.persistence.typeHandling.reflection.ModuleEnvironmentSandbox; import org.terasology.engine.rendering.assets.texture.TextureRegion; -import org.terasology.engine.rendering.primitives.ChunkMesh; +import org.terasology.engine.rendering.primitives.MutableChunkMesh; import org.terasology.engine.world.block.BlockArea; import org.terasology.engine.world.block.BlockAreac; import org.terasology.engine.world.block.BlockRegion; @@ -115,7 +115,7 @@ private static void populateWithDefaultHandlers(TypeHandlerLibrary serialization serializationLibrary.addTypeHandler(Name.class, new NameTypeHandler()); serializationLibrary.addTypeHandler(TextureRegion.class, new TextureRegionTypeHandler()); serializationLibrary.addTypeHandler(UITextureRegion.class, new UITextureRegionTypeHandler()); - serializationLibrary.addTypeHandler(ChunkMesh.class, new ChunkMeshTypeHandler()); + serializationLibrary.addTypeHandler(MutableChunkMesh.class, new ChunkMeshTypeHandler()); serializationLibrary.addTypeHandlerFactory(new TextureRegionAssetTypeHandlerFactory()); diff --git a/engine/src/main/java/org/terasology/engine/persistence/typeHandling/extensionTypes/ChunkMeshTypeHandler.java b/engine/src/main/java/org/terasology/engine/persistence/typeHandling/extensionTypes/ChunkMeshTypeHandler.java index 4fbb3053f1a..d551f68c1e6 100644 --- a/engine/src/main/java/org/terasology/engine/persistence/typeHandling/extensionTypes/ChunkMeshTypeHandler.java +++ b/engine/src/main/java/org/terasology/engine/persistence/typeHandling/extensionTypes/ChunkMeshTypeHandler.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.persistence.typeHandling.extensionTypes; @@ -6,6 +6,7 @@ import org.lwjgl.BufferUtils; import org.terasology.engine.rendering.primitives.ChunkMesh; import org.terasology.engine.rendering.primitives.ChunkMeshImpl; +import org.terasology.engine.rendering.primitives.MutableChunkMesh; import org.terasology.persistence.typeHandling.PersistedData; import org.terasology.persistence.typeHandling.PersistedDataSerializer; import org.terasology.persistence.typeHandling.TypeHandler; @@ -15,9 +16,9 @@ import java.util.List; import java.util.Optional; -public class ChunkMeshTypeHandler extends TypeHandler { +public class ChunkMeshTypeHandler extends TypeHandler { @Override - protected PersistedData serializeNonNull(ChunkMesh value, PersistedDataSerializer serializer) { + protected PersistedData serializeNonNull(MutableChunkMesh value, PersistedDataSerializer serializer) { if (!value.hasVertexElements()) { throw new IllegalStateException("Attempting to serialize a ChunkMesh whose data has already been discarded."); } @@ -35,7 +36,7 @@ protected PersistedData serializeNonNull(ChunkMesh value, PersistedDataSerialize } @Override - public Optional deserialize(PersistedData data) { + public Optional deserialize(PersistedData data) { List asBuffers = new ArrayList<>(); for (PersistedData datum : data.getAsArray()) { ByteBuffer buffer = datum.getAsByteBuffer(); @@ -44,7 +45,7 @@ public Optional deserialize(PersistedData data) { directBuffer.rewind(); asBuffers.add(directBuffer); } - ChunkMesh result = new ChunkMeshImpl(); + MutableChunkMesh result = new ChunkMeshImpl(); for (ChunkMesh.RenderType renderType : ChunkMesh.RenderType.values()) { result.getVertexElements(renderType).buffer.replace(asBuffers.remove(0)); result.getVertexElements(renderType).indices.replace(asBuffers.remove(0)); diff --git a/engine/src/main/java/org/terasology/engine/rendering/logic/ChunkMeshComponent.java b/engine/src/main/java/org/terasology/engine/rendering/logic/ChunkMeshComponent.java index 7492301e928..582ddf63769 100644 --- a/engine/src/main/java/org/terasology/engine/rendering/logic/ChunkMeshComponent.java +++ b/engine/src/main/java/org/terasology/engine/rendering/logic/ChunkMeshComponent.java @@ -4,7 +4,7 @@ package org.terasology.engine.rendering.logic; import org.terasology.engine.network.Replicate; -import org.terasology.engine.rendering.primitives.ChunkMesh; +import org.terasology.engine.rendering.primitives.MutableChunkMesh; import org.terasology.joml.geom.AABBf; /** @@ -13,7 +13,7 @@ */ public class ChunkMeshComponent implements VisualComponent { @Replicate - public ChunkMesh mesh; + public MutableChunkMesh mesh; @Replicate public AABBf aabb; @Replicate @@ -21,12 +21,12 @@ public class ChunkMeshComponent implements VisualComponent { public ChunkMeshComponent() { } - public ChunkMeshComponent(ChunkMesh mesh, AABBf aabb) { + public ChunkMeshComponent(MutableChunkMesh mesh, AABBf aabb) { this.mesh = mesh; this.aabb = aabb; } - public synchronized void setMesh(ChunkMesh mesh) { + public synchronized void setMesh(MutableChunkMesh mesh) { if (this.mesh != null) { this.mesh.dispose(); } diff --git a/engine/src/main/java/org/terasology/engine/rendering/primitives/BlockMeshGenerator.java b/engine/src/main/java/org/terasology/engine/rendering/primitives/BlockMeshGenerator.java index 12425cbee9d..bd5e078f31b 100644 --- a/engine/src/main/java/org/terasology/engine/rendering/primitives/BlockMeshGenerator.java +++ b/engine/src/main/java/org/terasology/engine/rendering/primitives/BlockMeshGenerator.java @@ -1,10 +1,10 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.rendering.primitives; -import org.terasology.gestalt.module.sandbox.API; import org.terasology.engine.rendering.assets.mesh.Mesh; import org.terasology.engine.world.ChunkView; +import org.terasology.gestalt.module.sandbox.API; /** * This is used to generate Mesh data from a block in a chunk to a ChunkMesh output. @@ -21,7 +21,7 @@ public interface BlockMeshGenerator { * @param y Input position Y. * @param z Input position Z. */ - void generateChunkMesh(ChunkView view, ChunkMesh mesh, int x, int y, int z); + void generateChunkMesh(ChunkView view, MutableChunkMesh mesh, int x, int y, int z); /** * @return A standalone mesh used for items, inventory, etc... diff --git a/engine/src/main/java/org/terasology/engine/rendering/primitives/BlockMeshGeneratorSingleShape.java b/engine/src/main/java/org/terasology/engine/rendering/primitives/BlockMeshGeneratorSingleShape.java index 55f9fdf2a64..65d0c0948fe 100644 --- a/engine/src/main/java/org/terasology/engine/rendering/primitives/BlockMeshGeneratorSingleShape.java +++ b/engine/src/main/java/org/terasology/engine/rendering/primitives/BlockMeshGeneratorSingleShape.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.rendering.primitives; @@ -34,7 +34,7 @@ public ResourceUrn getBaseUrn() { @Override - public void generateChunkMesh(ChunkView view, ChunkMesh chunkMesh, int x, int y, int z) { + public void generateChunkMesh(ChunkView view, MutableChunkMesh chunkMesh, int x, int y, int z) { final BlockAppearance blockAppearance = block.getPrimaryAppearance(); if (!blockAppearance.hasAppearance()) { // perf: Skip mesh generation for blocks without appearance, e.g., air blocks. diff --git a/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkMesh.java b/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkMesh.java index c4a36c154af..351d6b6c103 100644 --- a/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkMesh.java +++ b/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkMesh.java @@ -1,49 +1,17 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 + package org.terasology.engine.rendering.primitives; -import org.joml.Vector2f; -import org.joml.Vector2fc; -import org.joml.Vector3f; import org.joml.Vector3fc; import org.terasology.engine.rendering.assets.material.Material; -import org.terasology.engine.rendering.assets.mesh.resource.GLAttributes; -import org.terasology.engine.rendering.assets.mesh.resource.IndexResource; -import org.terasology.engine.rendering.assets.mesh.resource.VertexAttributeBinding; -import org.terasology.engine.rendering.assets.mesh.resource.VertexByteAttributeBinding; -import org.terasology.engine.rendering.assets.mesh.resource.VertexFloatAttributeBinding; -import org.terasology.engine.rendering.assets.mesh.resource.VertexResource; -import org.terasology.engine.rendering.assets.mesh.resource.VertexResourceBuilder; import org.terasology.gestalt.module.sandbox.API; -import org.terasology.nui.Color; -import org.terasology.nui.Colorc; -/** - * Chunk meshes store, manipulate and render the vertex data of tessellated chunks. - */ public interface ChunkMesh { - VertexElements getVertexElements(ChunkMesh.RenderType renderType); - - /** - * has any vertex elements for is cleared from {@link #discardData()} - * - * @return if the vertex data is cleared - */ - boolean hasVertexElements(); - - /** - * update the mesh data - * - * @return true if the data has been updated - */ - boolean updateMesh(); - - void discardData(); - void updateMaterial(Material chunkMaterial, Vector3fc chunkPosition, boolean chunkIsAnimated); - int triangleCount(ChunkMesh.RenderPhase phase); + int triangleCount(RenderPhase phase); int getTimeToGenerateBlockVertices(); @@ -51,7 +19,7 @@ public interface ChunkMesh { void dispose(); - int render(ChunkMesh.RenderPhase type); + int render(RenderPhase type); /** * Possible rendering types. @@ -80,56 +48,4 @@ enum RenderPhase { REFRACTIVE, Z_PRE_PASS } - - class VertexElements { - - public static final int VERTEX_INDEX = 0; // vec3 - public static final int NORMAL_INDEX = 1; // vec3 - public static final int UV0_INDEX = 2; // vec3 - - public static final int FLAGS_INDEX = 3; // int - public static final int FRAME_INDEX = 4; // float - - public static final int SUNLIGHT_INDEX = 5; // float - public static final int BLOCK_INDEX = 6; // float - public static final int AMBIENT_OCCLUSION_INDEX = 7; // float - - public static final int COLOR_INDEX = 8; // vec4 - - public final VertexResource buffer; - public final IndexResource indices = new IndexResource(); - - public final VertexAttributeBinding position; - public final VertexAttributeBinding normals; - public final VertexAttributeBinding uv0; - - public final VertexAttributeBinding color; - - public final VertexByteAttributeBinding flags; - public final VertexByteAttributeBinding frames; - - public final VertexFloatAttributeBinding sunlight; // this could be changed to a single byte - public final VertexFloatAttributeBinding blockLight; // this could be changed to a single byte - public final VertexFloatAttributeBinding ambientOcclusion; // this could be changed to a single byte - public int vertexCount; - - - VertexElements() { - VertexResourceBuilder builder = new VertexResourceBuilder(); - position = builder.add(VERTEX_INDEX, GLAttributes.VECTOR_3_F_VERTEX_ATTRIBUTE); - normals = builder.add(NORMAL_INDEX, GLAttributes.VECTOR_3_F_VERTEX_ATTRIBUTE); - uv0 = builder.add(UV0_INDEX, GLAttributes.VECTOR_2_F_VERTEX_ATTRIBUTE); - - flags = builder.add(FLAGS_INDEX, GLAttributes.BYTE_1_VERTEX_ATTRIBUTE); - frames = builder.add(FRAME_INDEX, GLAttributes.BYTE_1_VERTEX_ATTRIBUTE); - - sunlight = builder.add(SUNLIGHT_INDEX, GLAttributes.FLOAT_1_VERTEX_ATTRIBUTE); - blockLight = builder.add(BLOCK_INDEX, GLAttributes.FLOAT_1_VERTEX_ATTRIBUTE); - ambientOcclusion = builder.add(AMBIENT_OCCLUSION_INDEX, GLAttributes.FLOAT_1_VERTEX_ATTRIBUTE); - - color = builder.add(COLOR_INDEX, GLAttributes.COLOR_4_F_VERTEX_ATTRIBUTE); - - buffer = builder.build(); - } - } } diff --git a/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkMeshImpl.java b/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkMeshImpl.java index 45777bf0a6e..c82be492462 100644 --- a/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkMeshImpl.java +++ b/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkMeshImpl.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.rendering.primitives; @@ -8,7 +8,7 @@ import org.terasology.engine.rendering.assets.material.Material; import org.terasology.engine.rendering.assets.mesh.resource.VertexResource; -public class ChunkMeshImpl implements ChunkMesh { +public class ChunkMeshImpl implements MutableChunkMesh { /* VERTEX DATA */ private final int[] vertexBuffers = new int[4]; diff --git a/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkTessellator.java b/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkTessellator.java index c6ca1835c58..5b7a2818fd8 100644 --- a/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkTessellator.java +++ b/engine/src/main/java/org/terasology/engine/rendering/primitives/ChunkTessellator.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.rendering.primitives; @@ -23,11 +23,11 @@ public ChunkTessellator() { } - public ChunkMesh generateMesh(ChunkView chunkView) { + public MutableChunkMesh generateMesh(ChunkView chunkView) { return generateMesh(chunkView, 1, 0); } - public ChunkMesh generateMesh(ChunkView chunkView, float scale, int border) { + public MutableChunkMesh generateMesh(ChunkView chunkView, float scale, int border) { PerformanceMonitor.startActivity("GenerateMesh"); ChunkMeshImpl mesh = new ChunkMeshImpl(); @@ -47,7 +47,7 @@ public ChunkMesh generateMesh(ChunkView chunkView, float scale, int border) { if (border != 0) { float totalScale = scale * Chunks.SIZE_X / (Chunks.SIZE_X - 2 * border); for (ChunkMesh.RenderType type : ChunkMesh.RenderType.values()) { - ChunkMesh.VertexElements elements = mesh.getVertexElements(type); + MutableChunkMesh.VertexElements elements = mesh.getVertexElements(type); Vector3f pos = new Vector3f(); for (int x = 0; x < elements.position.elements(); x++) { elements.position.get(x, pos); diff --git a/engine/src/main/java/org/terasology/engine/rendering/primitives/MutableChunkMesh.java b/engine/src/main/java/org/terasology/engine/rendering/primitives/MutableChunkMesh.java new file mode 100644 index 00000000000..8bbd5edc5c4 --- /dev/null +++ b/engine/src/main/java/org/terasology/engine/rendering/primitives/MutableChunkMesh.java @@ -0,0 +1,93 @@ +// Copyright 2022 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 +package org.terasology.engine.rendering.primitives; + +import org.joml.Vector2f; +import org.joml.Vector2fc; +import org.joml.Vector3f; +import org.joml.Vector3fc; +import org.terasology.engine.rendering.assets.mesh.resource.GLAttributes; +import org.terasology.engine.rendering.assets.mesh.resource.IndexResource; +import org.terasology.engine.rendering.assets.mesh.resource.VertexAttributeBinding; +import org.terasology.engine.rendering.assets.mesh.resource.VertexByteAttributeBinding; +import org.terasology.engine.rendering.assets.mesh.resource.VertexFloatAttributeBinding; +import org.terasology.engine.rendering.assets.mesh.resource.VertexResource; +import org.terasology.engine.rendering.assets.mesh.resource.VertexResourceBuilder; +import org.terasology.nui.Color; +import org.terasology.nui.Colorc; + +/** + * Chunk meshes store, manipulate and render the vertex data of tessellated chunks. + */ +public interface MutableChunkMesh extends ChunkMesh { + + VertexElements getVertexElements(MutableChunkMesh.RenderType renderType); + + /** + * has any vertex elements for is cleared from {@link #discardData()} + * + * @return if the vertex data is cleared + */ + boolean hasVertexElements(); + + /** + * update the mesh data + * + * @return true if the data has been updated + */ + boolean updateMesh(); + + void discardData(); + + class VertexElements { + + public static final int VERTEX_INDEX = 0; // vec3 + public static final int NORMAL_INDEX = 1; // vec3 + public static final int UV0_INDEX = 2; // vec3 + + public static final int FLAGS_INDEX = 3; // int + public static final int FRAME_INDEX = 4; // float + + public static final int SUNLIGHT_INDEX = 5; // float + public static final int BLOCK_INDEX = 6; // float + public static final int AMBIENT_OCCLUSION_INDEX = 7; // float + + public static final int COLOR_INDEX = 8; // vec4 + + public final VertexResource buffer; + public final IndexResource indices = new IndexResource(); + + public final VertexAttributeBinding position; + public final VertexAttributeBinding normals; + public final VertexAttributeBinding uv0; + + public final VertexAttributeBinding color; + + public final VertexByteAttributeBinding flags; + public final VertexByteAttributeBinding frames; + + public final VertexFloatAttributeBinding sunlight; // this could be changed to a single byte + public final VertexFloatAttributeBinding blockLight; // this could be changed to a single byte + public final VertexFloatAttributeBinding ambientOcclusion; // this could be changed to a single byte + public int vertexCount; + + + VertexElements() { + VertexResourceBuilder builder = new VertexResourceBuilder(); + position = builder.add(VERTEX_INDEX, GLAttributes.VECTOR_3_F_VERTEX_ATTRIBUTE); + normals = builder.add(NORMAL_INDEX, GLAttributes.VECTOR_3_F_VERTEX_ATTRIBUTE); + uv0 = builder.add(UV0_INDEX, GLAttributes.VECTOR_2_F_VERTEX_ATTRIBUTE); + + flags = builder.add(FLAGS_INDEX, GLAttributes.BYTE_1_VERTEX_ATTRIBUTE); + frames = builder.add(FRAME_INDEX, GLAttributes.BYTE_1_VERTEX_ATTRIBUTE); + + sunlight = builder.add(SUNLIGHT_INDEX, GLAttributes.FLOAT_1_VERTEX_ATTRIBUTE); + blockLight = builder.add(BLOCK_INDEX, GLAttributes.FLOAT_1_VERTEX_ATTRIBUTE); + ambientOcclusion = builder.add(AMBIENT_OCCLUSION_INDEX, GLAttributes.FLOAT_1_VERTEX_ATTRIBUTE); + + color = builder.add(COLOR_INDEX, GLAttributes.COLOR_4_F_VERTEX_ATTRIBUTE); + + buffer = builder.build(); + } + } +} diff --git a/engine/src/main/java/org/terasology/engine/rendering/world/ChunkMeshWorker.java b/engine/src/main/java/org/terasology/engine/rendering/world/ChunkMeshWorker.java index 20ba3ba9f8a..c33890fa9a7 100644 --- a/engine/src/main/java/org/terasology/engine/rendering/world/ChunkMeshWorker.java +++ b/engine/src/main/java/org/terasology/engine/rendering/world/ChunkMeshWorker.java @@ -10,8 +10,8 @@ import org.slf4j.LoggerFactory; import org.terasology.engine.core.GameScheduler; import org.terasology.engine.monitoring.chunk.ChunkMonitor; -import org.terasology.engine.rendering.primitives.ChunkMesh; import org.terasology.engine.rendering.primitives.ChunkTessellator; +import org.terasology.engine.rendering.primitives.MutableChunkMesh; import org.terasology.engine.rendering.world.viewDistance.ViewDistance; import org.terasology.engine.world.ChunkView; import org.terasology.engine.world.WorldProvider; @@ -56,10 +56,10 @@ public final class ChunkMeshWorker { private final Sinks.Many chunkMeshPublisher = Sinks.many().unicast().onBackpressureBuffer(); private final List chunksInProximityOfCamera = Lists.newArrayListWithCapacity(MAX_LOADABLE_CHUNKS); - private final Flux> chunksAndNewMeshes; + private final Flux> chunksAndNewMeshes; private final Flux completedChunks; - ChunkMeshWorker(Function>> workFunction, + ChunkMeshWorker(Function>> workFunction, Comparator frontToBackComparator, Scheduler parallelScheduler, Scheduler graphicsScheduler) { this.frontToBackComparator = frontToBackComparator; @@ -154,19 +154,20 @@ Flux getCompletedChunks() { return completedChunks; } - private static Chunk uploadNewMesh(Chunk chunk, ChunkMesh chunkMesh) { + private static Chunk uploadNewMesh(Chunk chunk, MutableChunkMesh chunkMesh) { chunkMesh.updateMesh(); // Does GL stuff, must be on main thread! chunkMesh.discardData(); chunk.setMesh(chunkMesh); return chunk; } - private static Function>> generateMeshFunc(ChunkTessellator chunkTessellator, WorldProvider worldProvider) { + private static Function>> generateMeshFunc( + ChunkTessellator chunkTessellator, WorldProvider worldProvider) { return (chunk -> { chunk.setDirty(false); ChunkView chunkView = worldProvider.getLocalView(chunk.getPosition()); if (chunkView != null && chunkView.isValidView()) { - ChunkMesh newMesh = chunkTessellator.generateMesh(chunkView); + MutableChunkMesh newMesh = chunkTessellator.generateMesh(chunkView); ChunkMonitor.fireChunkTessellated(chunk, newMesh); return Mono.just(Tuples.of(chunk, newMesh)); } diff --git a/engine/src/main/java/org/terasology/engine/rendering/world/RenderableWorldImpl.java b/engine/src/main/java/org/terasology/engine/rendering/world/RenderableWorldImpl.java index e513ac59243..b2ce5b705a3 100644 --- a/engine/src/main/java/org/terasology/engine/rendering/world/RenderableWorldImpl.java +++ b/engine/src/main/java/org/terasology/engine/rendering/world/RenderableWorldImpl.java @@ -18,6 +18,7 @@ import org.terasology.engine.rendering.logic.ChunkMeshRenderer; import org.terasology.engine.rendering.primitives.ChunkMesh; import org.terasology.engine.rendering.primitives.ChunkTessellator; +import org.terasology.engine.rendering.primitives.MutableChunkMesh; import org.terasology.engine.rendering.world.viewDistance.ViewDistance; import org.terasology.engine.world.ChunkView; import org.terasology.engine.world.WorldProvider; @@ -136,7 +137,7 @@ public boolean pregenerateChunks() { chunkProvider.update(); Chunk chunk; - ChunkMesh newMesh; + MutableChunkMesh newMesh; ChunkView localView; for (Vector3ic chunkCoordinates : calculateRenderableRegion(renderingConfig.getViewDistance())) { chunk = chunkProvider.getChunk(chunkCoordinates); diff --git a/engine/src/main/java/org/terasology/engine/world/block/shapes/BlockMeshPart.java b/engine/src/main/java/org/terasology/engine/world/block/shapes/BlockMeshPart.java index 1ff1bba9632..6f82f2c7556 100644 --- a/engine/src/main/java/org/terasology/engine/world/block/shapes/BlockMeshPart.java +++ b/engine/src/main/java/org/terasology/engine/world/block/shapes/BlockMeshPart.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.world.block.shapes; @@ -9,6 +9,7 @@ import org.terasology.engine.monitoring.PerformanceMonitor; import org.terasology.engine.rendering.primitives.ChunkMesh; import org.terasology.engine.rendering.primitives.ChunkVertexFlag; +import org.terasology.engine.rendering.primitives.MutableChunkMesh; import org.terasology.engine.world.ChunkView; import org.terasology.engine.world.block.Block; import org.terasology.math.TeraMath; @@ -80,9 +81,9 @@ public BlockMeshPart mapTexCoords(Vector2f offset, float width, int frames) { return new BlockMeshPart(vertices, normals, newTexCoords, indices, frames); } - public void appendTo(ChunkMesh chunk, ChunkView chunkView, int offsetX, int offsetY, int offsetZ, + public void appendTo(MutableChunkMesh chunk, ChunkView chunkView, int offsetX, int offsetY, int offsetZ, ChunkMesh.RenderType renderType, Colorc colorOffset, ChunkVertexFlag flags) { - ChunkMesh.VertexElements elements = chunk.getVertexElements(renderType); + MutableChunkMesh.VertexElements elements = chunk.getVertexElements(renderType); for (Vector2f texCoord : texCoords) { elements.uv0.put(texCoord); } diff --git a/engine/src/main/java/org/terasology/engine/world/chunks/LodChunkProvider.java b/engine/src/main/java/org/terasology/engine/world/chunks/LodChunkProvider.java index dc61fa4a5e8..87212db5a45 100644 --- a/engine/src/main/java/org/terasology/engine/world/chunks/LodChunkProvider.java +++ b/engine/src/main/java/org/terasology/engine/world/chunks/LodChunkProvider.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.world.chunks; @@ -8,6 +8,7 @@ import org.joml.Vector3ic; import org.terasology.engine.rendering.primitives.ChunkMesh; import org.terasology.engine.rendering.primitives.ChunkTessellator; +import org.terasology.engine.rendering.primitives.MutableChunkMesh; import org.terasology.engine.rendering.world.viewDistance.ViewDistance; import org.terasology.engine.world.ChunkView; import org.terasology.engine.world.block.Block; @@ -106,8 +107,9 @@ private void processReadyChunks() { int scale = chunk.scale; if (requiredScale != null && requiredScale <= scale) { // The relevant region may have been updated since // this chunk was requested. - chunk.getMesh().updateMesh(); - chunk.getMesh().discardData(); + MutableChunkMesh mesh = (MutableChunkMesh) chunk.getMesh(); // FIXME ASAP + mesh.updateMesh(); + mesh.discardData(); Vector3i subPos = new Vector3i(); if (scale > 0) { int subScale = 1 << (scale - 1); diff --git a/engine/src/main/java/org/terasology/engine/world/chunks/RenderableChunk.java b/engine/src/main/java/org/terasology/engine/world/chunks/RenderableChunk.java index 0391d6f0556..8dd0a7557bb 100644 --- a/engine/src/main/java/org/terasology/engine/world/chunks/RenderableChunk.java +++ b/engine/src/main/java/org/terasology/engine/world/chunks/RenderableChunk.java @@ -1,11 +1,11 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.world.chunks; import org.joml.Vector3f; -import org.terasology.joml.geom.AABBfc; -import org.terasology.gestalt.module.sandbox.API; import org.terasology.engine.rendering.primitives.ChunkMesh; +import org.terasology.gestalt.module.sandbox.API; +import org.terasology.joml.geom.AABBfc; /** * Anything that acts like a chunk for rendering purposes