Skip to content

Commit

Permalink
feat: add chunk mesh
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 c2bfecc commit 6f49d81
Show file tree
Hide file tree
Showing 17 changed files with 315 additions and 124 deletions.
10 changes: 10 additions & 0 deletions core-rust/natives/src/jni/jni_chunk_mesh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use jni::{JNIEnv, objects::JClass, sys::jlong};

use crate::{resource::chunk_mesh_resource::ChunkMeshResource, ui::JavaHandle};



#[no_mangle]
pub extern "system" fn Java_org_terasology_engine_rust_resource_ChunkGeometry_00024JNI_drop<'local>(mut env: JNIEnv<'local>, _class: JClass, geom_ptr: jlong) {
ChunkMeshResource::drop_handle(geom_ptr);
}
12 changes: 8 additions & 4 deletions core-rust/natives/src/jni/jni_resource.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use jni::{sys::jlong, objects::{JClass, JByteBuffer, JObject}, JNIEnv};
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use wgpu::util::DeviceExt;
use crate::{resource::texture_resource::TextureResource, ui::JavaHandle, engine_kernel::EngineKernel};
use crate::{resource::{texture_resource::TextureResource, chunk_mesh_resource::ChunkMeshResource}, ui::JavaHandle, engine_kernel::EngineKernel};
use super::jni_texture::JavaTextureDesc;

#[no_mangle]
pub extern "system" fn Java_org_terasology_engine_rust_ResourceManager_00024JNI_createTextureResourceFromBuffer<'local>(mut env: JNIEnv<'local>, _class: JClass, kernel_ptr: jlong, desc: JObject<'local>, buffer: JByteBuffer<'local>) -> jlong {
pub extern "system" fn Java_org_terasology_engine_rust_resource_ResourceManager_00024JNI_createTextureResourceFromBuffer<'local>(mut env: JNIEnv<'local>, _class: JClass, kernel_ptr: jlong, desc: JObject<'local>, buffer: JByteBuffer<'local>) -> jlong {
let texture_desc = JavaTextureDesc::new(&mut env, desc);
let wgpu_texture_desc = wgpu::TextureDescriptor {
size: wgpu::Extent3d {
Expand Down Expand Up @@ -41,7 +41,7 @@ pub extern "system" fn Java_org_terasology_engine_rust_ResourceManager_00024JNI_
}

#[no_mangle]
pub extern "system" fn Java_org_terasology_engine_rust_ResourceManager_00024JNI_createTextureResource<'local>(mut env: JNIEnv<'local>, _class: JClass, kernel_ptr: jlong, desc: JObject<'local>) -> jlong {
pub extern "system" fn Java_org_terasology_engine_rust_resource_ResourceManager_00024JNI_createTextureResource<'local>(mut env: JNIEnv<'local>, _class: JClass, kernel_ptr: jlong, desc: JObject<'local>) -> jlong {
let texture_desc = JavaTextureDesc::new(&mut env, desc);
let wgpu_texture_desc = wgpu::TextureDescriptor {
size: wgpu::Extent3d {
Expand All @@ -67,3 +67,7 @@ pub extern "system" fn Java_org_terasology_engine_rust_ResourceManager_00024JNI_
}))
}

#[no_mangle]
pub extern "system" fn Java_org_terasology_engine_rust_resource_ResourceManager_00024JNI_createChunkResource<'local>(_env: JNIEnv<'local>, _class: JClass, _kernel_ptr: jlong) -> jlong {
return ChunkMeshResource::to_handle(Arc::new(Mutex::new(ChunkMeshResource::new())))
}
6 changes: 3 additions & 3 deletions core-rust/natives/src/jni/jni_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,19 @@ impl From<&JavaImageFormat> for wgpu::TextureFormat {
}

#[no_mangle]
pub extern "system" fn Java_org_terasology_engine_rust_TeraTexture_00024JNI_drop<'local>(mut _env: JNIEnv<'local>, _class: JClass, texture_ptr: jlong) {
pub extern "system" fn Java_org_terasology_engine_rust_resource_TeraTexture_00024JNI_drop<'local>(mut _env: JNIEnv<'local>, _class: JClass, texture_ptr: jlong) {
TextureResource::drop_handle(texture_ptr);
}

#[no_mangle]
pub extern "system" fn Java_org_terasology_engine_rust_TeraTexture_00024JNI_getSize<'local>(mut env: JNIEnv<'local>, _class: JClass, texture_ptr: jlong, mut vec2_obj: JObject<'local>) {
pub extern "system" fn Java_org_terasology_engine_rust_resource_TeraTexture_00024JNI_getSize<'local>(mut env: JNIEnv<'local>, _class: JClass, texture_ptr: jlong, mut vec2_obj: JObject<'local>) {
let texture = TextureResource::from_handle(texture_ptr).expect("texture invalid");
let size = texture.texture.size();
set_joml_vector2f(env, &mut vec2_obj, size.width as f32, size.height as f32);
}

#[no_mangle]
pub extern "system" fn Java_org_terasology_engine_rust_TeraTexture_00024JNI_writeTextureBuffer<'local>(mut env: JNIEnv<'local>, _class: JClass, kernel_ptr: jlong, texture_ptr: jlong, buffer: JByteBuffer<'local>) {
pub extern "system" fn Java_org_terasology_engine_rust_resource_TeraTexture_00024JNI_writeTextureBuffer<'local>(mut env: JNIEnv<'local>, _class: JClass, kernel_ptr: jlong, texture_ptr: jlong, buffer: JByteBuffer<'local>) {
let Some(kernel) = EngineKernel::from_handle(kernel_ptr) else { panic!("kernel invalid") };
let texture_resource = TextureResource::from_handle(texture_ptr).expect("texture invalid");

Expand Down
1 change: 1 addition & 0 deletions core-rust/natives/src/jni/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod jni_engine_kernel;
pub mod jni_ui;
pub mod jni_resource;
pub mod jni_texture;
pub mod jni_chunk_mesh;
1 change: 1 addition & 0 deletions core-rust/natives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ mod ui;
mod resource;
mod jni;
mod math;
mod scene;
153 changes: 109 additions & 44 deletions core-rust/natives/src/resource/chunk_mesh_resource.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use bytemuck::{Pod, Zeroable};
use futures::lock::Mutex;
use smallvec::SmallVec;
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use crate::ui::{JavaHandle, arc_from_handle, arc_to_handle, arc_dispose_handle};

#[repr(C)]
Expand Down Expand Up @@ -59,6 +58,7 @@ const ATTRIBUTE_LAYOUT: wgpu::VertexBufferLayout = wgpu::VertexBufferLayout {
};


#[derive(PartialEq, Clone, Copy)]
pub enum MeshRenderType {
Opaque,
Translucent,
Expand All @@ -71,102 +71,167 @@ pub struct ChunkMeshEntry {
vertex_buffer: wgpu::Buffer,
index_buffer: wgpu::Buffer,

num_elements: u32,
num_elements: u64,
position_start: u64,
normal_start: u32,
uv_start: u32,
color_start: u32,
attribute_start: u32
normal_start: u64,
uv_start: u64,
color_start: u64,
attribute_start: u64
}

impl ChunkMeshEntry {
pub fn num_elements(&self) -> u32 { self.num_elements }
pub fn vertex_buffer(&self) -> &wgpu::Buffer { &self.vertex_buffer }
pub fn positions_slice(&self) -> wgpu::BufferSlice { self.vertex_buffer.slice(self.position_start..(self.position_start + (self.num_elements as u64 * std::mem::size_of::<ChunkPosition>() as u64)))}
// pub fn normals(&self) -> &wgpu::Buffer { &self.vertex_buffer_pos }
// pub fn uvs(&self) -> &wgpu::Buffer { &self.vertex_buffer_pos }
// pub fn colors(&self) -> &wgpu::Buffer { &self.vertex_buffer_pos }
// pub fn attributes(&self) -> &wgpu::Buffer { &self.vertex_buffer_pos }
pub fn num_elements(&self) -> u64 { self.num_elements }
pub fn buf_vertex_buffer(&self) -> &wgpu::Buffer { &self.vertex_buffer }
pub fn buf_index_buffer(&self) -> &wgpu::Buffer { &self.index_buffer }

pub fn buf_positions_slice(&self) -> wgpu::BufferSlice { self.vertex_buffer.slice(self.position_start..(self.position_start + (self.num_elements as u64 * std::mem::size_of::<ChunkPosition>() as u64)))}
pub fn buf_normals_slice(&self) -> wgpu::BufferSlice { self.vertex_buffer.slice(self.normal_start..(self.normal_start + (self.num_elements as u64 * std::mem::size_of::<ChunkNormal>() as u64))) }
pub fn buf_uvs_slice(&self) -> wgpu::BufferSlice{ self.vertex_buffer.slice(self.uv_start..(self.uv_start + (self.num_elements as u64 * std::mem::size_of::<ChunkUV>() as u64))) }
pub fn buf_colors_slice(&self) -> wgpu::BufferSlice { self.vertex_buffer.slice(self.color_start..(self.color_start + (self.num_elements as u64 * std::mem::size_of::<ChunkColor>() as u64))) }
pub fn buf_attributes_slice(&self) -> wgpu::BufferSlice { self.vertex_buffer.slice(self.attribute_start..(self.attribute_start + (self.num_elements as u64 * std::mem::size_of::<ChunkAttributes>() as u64)))}

}

pub struct ChunkMeshResource {
data_lock: Mutex<()>,
meshes: SmallVec<[ChunkMeshEntry; 5]>,
}

impl ChunkMeshResource {
fn new(
device: &wgpu::Device,
queue: &wgpu::Queue,
position: &[ChunkPosition],
normal: &[ChunkNormal],
uv: &[ChunkUV],
color: &[ChunkColor],
attributes: &[ChunkAttributes]
) {
assert!(position.len() == normal.len(), "mismatch in the number of vertices");
assert!(position.len() == uv.len(), "mismatch in the number of vertices");
assert!(position.len() == color.len(), "mismatch in the number of vertices");
assert!(position.len() == attributes.len(), "mismatch in the number of vertices");
pub fn new() -> Self {
Self {
meshes: SmallVec::new()
}
}

pub fn set_mesh_resource(
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
render_type: MeshRenderType,
index_buffer: &[u32],
indexes: &[u32],
position: &[ChunkPosition],
normal: &[ChunkNormal],
uv: &[ChunkUV],
color: &[ChunkColor],
attributes: &[ChunkAttributes]
) {
assert!(position.len() == normal.len(), "mismatch in the number of vertices");
assert!(position.len() == uv.len(), "mismatch in the number of vertices");
assert!(position.len() == color.len(), "mismatch in the number of vertices");
assert!(position.len() == attributes.len(), "mismatch in the number of vertices");
// assert!(position.len() == normal.len(), "mismatch in the number of vertices");
// assert!(position.len() == uv.len(), "mismatch in the number of vertices");
// assert!(position.len() == color.len(), "mismatch in the number of vertices");
// assert!(position.len() == attributes.len(), "mismatch in the number of vertices");

let num_elements: u64 = position.len() as u64;

let buffer = device.create_buffer(
let vertex_buffer = device.create_buffer(
&wgpu::BufferDescriptor {
label: Some("Unit Square Vertex Buffer"),
label: Some("Chunk Vertex Buffer"),
size: num_elements *
(
std::mem::size_of::<ChunkPosition>() as u64 +
std::mem::size_of::<ChunkNormal>() as u64 +
std::mem::size_of::<ChunkUV>() as u64 +
std::mem::size_of::<ChunkColor>() as u64 +
std::mem::size_of::<ChunkAttributes >() as u64
std::mem::size_of::<ChunkAttributes>() as u64
),
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false
}
);
}

pub fn unset_mesh_resource(render_type: MeshRenderType) {
let index_buffer = device.create_buffer(
&wgpu::BufferDescriptor {
label: Some("Chunk Index Buffer"),
size: (indexes.len() * std::mem::size_of::<u32>()) as u64,
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false
}
);

let position_byte: &[u8] = bytemuck::cast_slice(position);
let normal_byte: &[u8] = bytemuck::cast_slice(normal);
let uv_byte: &[u8] = bytemuck::cast_slice(uv);
let color_byte: &[u8] = bytemuck::cast_slice(color);
let attribute_byte: &[u8] = bytemuck::cast_slice(attributes);

let mut cursor: u64 = 0;
let position_start = cursor;
if position_byte.len() > 0 {
queue.write_buffer(&vertex_buffer, position_start, position_byte);
}
cursor += position_byte.len() as u64;

let normal_start = cursor;
if normal_byte.len() > 0 {
queue.write_buffer(&vertex_buffer, normal_start , normal_byte);
}
cursor += normal_byte.len() as u64;

let uv_start = cursor;
if uv_byte.len() > 0 {
queue.write_buffer(&vertex_buffer, uv_start, uv_byte);
}
cursor += uv_byte.len() as u64;

let color_start = cursor;
if color_byte.len() > 0 {
queue.write_buffer(&vertex_buffer, color_start, color_byte);
}
cursor += normal_byte.len() as u64;

let attribute_start = cursor;
if attribute_byte.len() > 0 {
queue.write_buffer(&vertex_buffer, attribute_start, attribute_byte);
}
queue.write_buffer(&index_buffer, 0, bytemuck::cast_slice(indexes));

let chunk_mesh = ChunkMeshEntry {
render_type,
vertex_buffer,
index_buffer,
num_elements,
position_start,
normal_start,
uv_start,
color_start,
attribute_start
};

match self.meshes.iter_mut().find(|ref el| {
el.render_type == render_type
}) {
Some(entry) => {
(*entry) = chunk_mesh;
},
None => {
self.meshes.push(chunk_mesh);
}
};
}

pub fn unset_mesh_resource(&mut self, render_type: MeshRenderType) {
match self.meshes.iter().position(|ref el| el.render_type == render_type) {
Some(index) => {
self.meshes.remove(index);
},
_ => {}
}
}

fn as_slice(&self) -> &[ChunkMeshEntry] {
pub fn as_slice(&self) -> &[ChunkMeshEntry] {
return self.meshes.as_slice();
}
}

impl JavaHandle<Arc<ChunkMeshResource>> for ChunkMeshResource {
fn from_handle(ptr: jni::sys::jlong) -> Option<Arc<ChunkMeshResource>> {
impl JavaHandle<Arc<Mutex<ChunkMeshResource>>> for ChunkMeshResource {
fn from_handle(ptr: jni::sys::jlong) -> Option<Arc<Mutex<ChunkMeshResource>>> {
arc_from_handle(ptr)
}

fn to_handle(from: Arc<ChunkMeshResource>) -> jni::sys::jlong {
fn to_handle(from: Arc<Mutex<ChunkMeshResource>>) -> jni::sys::jlong {
arc_to_handle(from)
}

fn drop_handle(ptr: jni::sys::jlong) {
arc_dispose_handle::<ChunkMeshResource>(ptr);
arc_dispose_handle::<Mutex<ChunkMeshResource>>(ptr);
}
}

21 changes: 21 additions & 0 deletions core-rust/natives/src/scene.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use crate::resource::chunk_mesh_resource::ChunkMeshResource;
use std::sync::Arc;

pub struct Scene {
opaque_chunks: Vec<Arc<ChunkMeshResource>>
}

impl Scene {

pub fn cmd_prepare(&mut self) {

}

pub fn cmd_dispatch(&mut self) {

}

pub fn cmd_queue_opaque_chunk() {

}
}
3 changes: 0 additions & 3 deletions core-rust/natives/src/world.rs

This file was deleted.

Loading

0 comments on commit 6f49d81

Please sign in to comment.