Skip to content

Commit

Permalink
feat: wip implementation for passing chunk state fo wgpu layer
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Pollind <[email protected]>
  • Loading branch information
pollend committed Jul 25, 2023
1 parent d8de459 commit 4e18884
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.joml.Vector3i;
import org.joml.Vector3ic;
import org.terasology.engine.rendering.primitives.ChunkMesh;
import org.terasology.engine.rust.resource.ChunkGeometry;
import org.terasology.engine.world.block.Block;
import org.terasology.engine.world.block.BlockRegionc;
import org.terasology.engine.world.chunks.Chunk;
Expand All @@ -19,7 +20,7 @@
public class DummyChunk implements Chunk {
private final Vector3ic chunkPos;
private boolean dirty;
private ChunkMesh mesh;
private ChunkGeometry mesh;
private boolean ready;

public DummyChunk(Vector3ic position) {
Expand Down Expand Up @@ -147,7 +148,7 @@ public AABBfc getAABB() {
}

@Override
public void setMesh(ChunkMesh newMesh) {
public void setMesh(ChunkGeometry newMesh) {
this.mesh = newMesh;
}

Expand All @@ -167,7 +168,7 @@ public boolean hasMesh() {
}

@Override
public ChunkMesh getMesh() {
public ChunkGeometry getMesh() {
return mesh;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public int getVersion() {
return this.version;
}

ByteBuffer buffer() {
public ByteBuffer buffer() {
return this.buffer;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.terasology.engine.rendering.assets.texture.Texture;
import org.terasology.engine.rendering.assets.texture.TextureData;
import org.terasology.engine.rust.EngineKernel;
import org.terasology.engine.rust.TeraTexture;
import org.terasology.engine.rust.resource.TeraTexture;
import org.terasology.gestalt.assets.AssetType;
import org.terasology.gestalt.assets.DisposableResource;
import org.terasology.gestalt.assets.ResourceUrn;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.rendering.primitives;

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.VertexResource;
import org.terasology.engine.rendering.assets.mesh.resource.VertexResourceBuilder;
import org.terasology.engine.rust.resource.ChunkGeometry;
import org.terasology.gestalt.module.sandbox.API;
import org.terasology.engine.rendering.assets.mesh.Mesh;
import org.terasology.engine.world.ChunkView;
Expand All @@ -15,16 +23,43 @@ public interface BlockMeshGenerator {
/**
* Generates a block mesh at the defined location in the ChunkMesh.
*
* @param view The input hunk area to acquire the Block data from.
* @param mesh The output mesh that is being generated.
* @param x Input position X.
* @param y Input position Y.
* @param z Input position Z.
* @param view The input hunk area to acquire the Block data from.
* @param mesh The output mesh that is being generated.
* @param x Input position X.
* @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, ChunkMeshBufferGroup mesh, int x, int y, int z);

/**
* @return A standalone mesh used for items, inventory, etc...
*/
Mesh getStandaloneMesh();


final class ChunkMeshBuffer {
public final VertexResource positionBuffer;
public int cursor = 0;
public final VertexAttributeBinding<Vector3fc, Vector3f> position;
public final IndexResource indices = new IndexResource();
// public final VertexResource NormalBuffer;
// public final VertexResource uvBuffer;
// public final VertexResource ColroBuffer;
// public final VertexResource AttributeBuffer;

public ChunkMeshBuffer() {
// {
VertexResourceBuilder builder = new VertexResourceBuilder();
position = builder.add(0, GLAttributes.VECTOR_3_F_VERTEX_ATTRIBUTE);
positionBuffer = builder.build();
// }
}
}
final class ChunkMeshBufferGroup {
public final ChunkMeshBuffer opaque = new ChunkMeshBuffer();
public final ChunkMeshBuffer translucent = new ChunkMeshBuffer();
public final ChunkMeshBuffer billboard = new ChunkMeshBuffer();
public final ChunkMeshBuffer waterAndIce = new ChunkMeshBuffer();
}

}
Original file line number Diff line number Diff line change
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, ChunkMeshBufferGroup 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 Expand Up @@ -92,7 +92,7 @@ public void generateChunkMesh(ChunkView view, ChunkMesh chunkMesh, int x, int y,
.setGreen(colorSource.gf() * colorOffset.gf())
.setBlue(colorSource.bf() * colorOffset.bf())
.setAlpha(colorSource.af() * colorOffset.af());
blockMeshPart.appendTo(chunkMesh, view, x, y, z, renderType, colorCache, sideVertexFlag);
blockMeshPart.appendTo(chunkMesh, view, x, y, z, block, colorCache, sideVertexFlag);
}
}
}
Expand All @@ -104,7 +104,7 @@ public void generateChunkMesh(ChunkView view, ChunkMesh chunkMesh, int x, int y,
.setGreen(colorSource.gf() * colorOffset.gf())
.setBlue(colorSource.bf() * colorOffset.bf())
.setAlpha(colorSource.af() * colorOffset.af());
blockAppearance.getPart(BlockPart.CENTER).appendTo(chunkMesh, view, x, y, z, renderType, colorCache, vertexFlag);
blockAppearance.getPart(BlockPart.CENTER).appendTo(chunkMesh, view, x, y, z, block, colorCache, vertexFlag);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
package org.terasology.engine.rendering.primitives;

import com.google.common.base.Stopwatch;
import org.joml.Vector3f;
import org.terasology.engine.monitoring.PerformanceMonitor;
import org.terasology.engine.rust.EngineKernel;
import org.terasology.engine.rust.resource.ChunkGeometry;
import org.terasology.engine.world.ChunkView;
import org.terasology.engine.world.block.Block;
import org.terasology.engine.world.chunks.Chunks;

import java.util.concurrent.TimeUnit;

/**
* Generates tessellated chunk meshes from chunks.
*
Expand All @@ -25,45 +23,58 @@ public ChunkTessellator(EngineKernel kernel) {
this.kernel = kernel;
}

public ChunkMesh generateMesh(ChunkView chunkView) {
public ChunkGeometry generateMesh(ChunkView chunkView) {
return generateMesh(chunkView, 1, 0);
}

public ChunkMesh generateMesh(ChunkView chunkView, float scale, int border) {
public ChunkGeometry generateMesh(ChunkView chunkView, float scale, int border) {
PerformanceMonitor.startActivity("GenerateMesh");
ChunkMeshImpl mesh = new ChunkMeshImpl();
BlockMeshGenerator.ChunkMeshBufferGroup buffer = new BlockMeshGenerator.ChunkMeshBufferGroup();

final Stopwatch watch = Stopwatch.createStarted();

// The mesh extends into the borders in the horizontal directions, but not vertically upwards, in order to cover
// gaps between LOD chunks of different scales, but also avoid multiple overlapping ocean surfaces.
for (int y = 0; y < Chunks.SIZE_Y - border * 2; y++) {
for (int y = 0; y < Chunks.SIZE_Y * 2; y++) {
for (int z = 0; z < Chunks.SIZE_Z; z++) {
for (int x = 0; x < Chunks.SIZE_X; x++) {
Block block = chunkView.getBlock(x, y, z);
block.getMeshGenerator().generateChunkMesh(chunkView, mesh, x, y, z);
block.getMeshGenerator().generateChunkMesh(chunkView, buffer, x, y, z);
}
}
}

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);
Vector3f pos = new Vector3f();
for (int x = 0; x < elements.position.elements(); x++) {
elements.position.get(x, pos);
elements.position.set(x, pos.sub(border, 2 * border, border).mul(totalScale));
}
}
}
// 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);
// Vector3f pos = new Vector3f();
// for (int x = 0; x < elements.position.elements(); x++) {
// elements.position.get(x, pos);
// elements.position.set(x, pos.sub(border, 2 * border, border).mul(totalScale));
// }
// }
// }

watch.stop();
mesh.setTimeToGenerateBlockVertices((int) watch.elapsed(TimeUnit.MILLISECONDS));
// mesh.setTimeToGenerateBlockVertices((int) watch.elapsed(TimeUnit.MILLISECONDS));
statVertexArrayUpdateCount++;

ChunkGeometry geometry = this.kernel.resource.createChunkGeometry();
if (!buffer.opaque.positionBuffer.isEmpty()) {
geometry.setMeshResource(buffer.opaque.indices.buffer(),
buffer.opaque.positionBuffer.buffer(),
null,
null,
null,
null);
}
// for(BlockMeshGenerator.ChunkMeshBufferGroup.Geometry geom: buffer.geometries) {
//
// }

PerformanceMonitor.endActivity();
return mesh;
return geometry;
}

public static int getVertexArrayUpdateCount() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.joml.Vector3f;
import org.terasology.engine.math.Direction;
import org.terasology.engine.monitoring.PerformanceMonitor;
import org.terasology.engine.rendering.primitives.BlockMeshGenerator;
import org.terasology.engine.rendering.primitives.ChunkMesh;
import org.terasology.engine.rendering.primitives.ChunkVertexFlag;
import org.terasology.engine.world.ChunkView;
Expand Down Expand Up @@ -80,32 +81,38 @@ 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,
ChunkMesh.RenderType renderType, Colorc colorOffset, ChunkVertexFlag flags) {
ChunkMesh.VertexElements elements = chunk.getVertexElements(renderType);
for (Vector2f texCoord : texCoords) {
elements.uv0.put(texCoord);
}
public void appendTo(BlockMeshGenerator.ChunkMeshBufferGroup chunk, ChunkView chunkView, int offsetX, int offsetY, int offsetZ,
Block block, Colorc colorOffset, ChunkVertexFlag flags) {

BlockMeshGenerator.ChunkMeshBuffer opaque = chunk.opaque;
// if(!block.isTranslucent()) {
// chunk.opaque;
// }

// BlockMeshGenerator.ChunkMeshBufferGroup.Geometry geometry = chunk.geometries[renderType.ordinal()];
// for (Vector2f texCoord : texCoords) {
// elements.uv0.put(texCoord);
// }

int nextIndex = elements.vertexCount;
elements.buffer.reserveElements(nextIndex + vertices.length);
int nextIndex = opaque.cursor;
opaque.positionBuffer.reserveElements(nextIndex + vertices.length);
Vector3f pos = new Vector3f();
for (int vIdx = 0; vIdx < vertices.length; ++vIdx) {
elements.color.put(colorOffset);
elements.position.put(pos.set(vertices[vIdx]).add(offsetX, offsetY, offsetZ));
elements.normals.put(normals[vIdx]);
elements.flags.put((byte) (flags.getValue()));
elements.frames.put((byte) (texFrames - 1));
float[] lightingData = calcLightingValuesForVertexPos(chunkView, vertices[vIdx].add(offsetX, offsetY, offsetZ,
new Vector3f()), normals[vIdx]);
elements.sunlight.put(lightingData[0]);
elements.blockLight.put(lightingData[1]);
elements.ambientOcclusion.put(lightingData[2]);
// elements.color.put(colorOffset);
opaque.position.put(pos.set(vertices[vIdx]).add(offsetX, offsetY, offsetZ));
// elements.normals.put(normals[vIdx]);
// elements.flags.put((byte) (flags.getValue()));
// elements.frames.put((byte) (texFrames - 1));
// float[] lightingData = calcLightingValuesForVertexPos(chunkView, vertices[vIdx].add(offsetX, offsetY, offsetZ,
// new Vector3f()), normals[vIdx]);
// elements.sunlight.put(lightingData[0]);
// elements.blockLight.put(lightingData[1]);
// elements.ambientOcclusion.put(lightingData[2]);
}
elements.vertexCount += vertices.length;
opaque.cursor += vertices.length;

for (int index : indices) {
elements.indices.put(index + nextIndex);
opaque.indices.put(index + nextIndex);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package org.terasology.engine.world.chunks;

import org.joml.Vector3f;
import org.terasology.engine.rust.resource.ChunkGeometry;
import org.terasology.joml.geom.AABBfc;
import org.terasology.gestalt.module.sandbox.API;
import org.terasology.engine.rendering.primitives.ChunkMesh;
Expand All @@ -17,15 +18,15 @@ public interface RenderableChunk {

AABBfc getAABB();

void setMesh(ChunkMesh newMesh);
void setMesh(ChunkGeometry newMesh);

void setAnimated(boolean animated);

boolean isAnimated();

boolean hasMesh();

ChunkMesh getMesh();
ChunkGeometry getMesh();

void disposeMesh();

Expand Down

0 comments on commit 4e18884

Please sign in to comment.