Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(rendering): factor out MutableChunkMesh #4998

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -35,9 +35,9 @@ public class ChunkMeshWorkerTest {
Comparator<RenderableChunk> comparator;
StepVerifier.FirstStep<Chunk> verifier;

static Mono<Tuple2<Chunk, ChunkMesh>> alwaysCreateMesh(Chunk chunk) {
static Mono<Tuple2<Chunk, MutableChunkMesh>> 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
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -14,15 +15,15 @@ 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;
int indices = 0;

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();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Copyright 2021 The Terasology Foundation
// Copyright 2022 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0

package org.terasology.engine.persistence.typeHandling.extensionTypes;

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;
Expand All @@ -15,9 +16,9 @@
import java.util.List;
import java.util.Optional;

public class ChunkMeshTypeHandler extends TypeHandler<ChunkMesh> {
public class ChunkMeshTypeHandler extends TypeHandler<MutableChunkMesh> {
@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.");
}
Expand All @@ -35,7 +36,7 @@ protected PersistedData serializeNonNull(ChunkMesh value, PersistedDataSerialize
}

@Override
public Optional<ChunkMesh> deserialize(PersistedData data) {
public Optional<MutableChunkMesh> deserialize(PersistedData data) {
List<ByteBuffer> asBuffers = new ArrayList<>();
for (PersistedData datum : data.getAsArray()) {
ByteBuffer buffer = datum.getAsByteBuffer();
Expand All @@ -44,7 +45,7 @@ public Optional<ChunkMesh> 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));
Copy link
Member

@pollend pollend Feb 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this probably should be changed. these are raw buffers for opengl so they follow the endiness of the machine if two machines have different endiness then it will be garbled. network order is little endian I believe

result.getVertexElements(renderType).indices.replace(asBuffers.remove(0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -13,20 +13,20 @@
*/
public class ChunkMeshComponent implements VisualComponent<ChunkMeshComponent> {
@Replicate
public ChunkMesh mesh;
public MutableChunkMesh mesh;
@Replicate
public AABBf aabb;
@Replicate
public boolean animated = true;

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();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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...
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,25 @@
// 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();

int getTimeToGenerateOptimizedBuffers();

void dispose();

int render(ChunkMesh.RenderPhase type);
int render(RenderPhase type);

/**
* Possible rendering types.
Expand Down Expand Up @@ -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<Vector3fc, Vector3f> position;
public final VertexAttributeBinding<Vector3fc, Vector3f> normals;
public final VertexAttributeBinding<Vector2fc, Vector2f> uv0;

public final VertexAttributeBinding<Colorc, Color> 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();
}
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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];
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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();

Expand All @@ -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);
Expand Down
Loading