From daf489b51ed9da05f50abea5b231be602b482add Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Mon, 25 Sep 2023 20:16:01 -0700 Subject: [PATCH 1/6] feat: add index pool Signed-off-by: Michael Pollind --- core-rust/natives/src/index_pool.rs | 85 +++++++++++++++++++++++++++++ core-rust/natives/src/lib.rs | 2 +- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 core-rust/natives/src/index_pool.rs diff --git a/core-rust/natives/src/index_pool.rs b/core-rust/natives/src/index_pool.rs new file mode 100644 index 0000000..21415b9 --- /dev/null +++ b/core-rust/natives/src/index_pool.rs @@ -0,0 +1,85 @@ + +pub struct Range { + start: u32, + end: u32 +} + +pub struct IDPool { + avaliable: Vec +} + +impl IDPool { + pub fn new(reserve: u32) -> Self { + Self { + avaliable: vec![ + Range { + start: 0, + end: reserve - 1 + }] + } + } + + pub fn fetch_id(&mut self) -> u32 { + match self.avaliable.last_mut() { + Some(range) => { + let res = range.end; + if range.end == range.start { + self.avaliable.pop(); + } else { + range.end -= 1; + } + res + }, + None => { + return u32::MAX + } + } + + } + + pub fn return_id(&mut self, index: u32) { + if self.avaliable.is_empty() { + self.avaliable.push(Range { start: id, end: id}); + return; + } + + let mut lower: usize = 0; + let mut upper: usize = self.avaliable.len() - 1; + let mut mid: usize = lower ; + while lower != upper { + mid = lower + ((upper - lower) / 2); + if index >= self.avaliable[mid].start && index <= self.avaliable[mid].end { + assert!(false) + //assert(false && "found within range"); + return; + } else if index < self.avaliable[mid].start { + upper = mid; + } else { + lower = mid + 1; + } + } + if index < self.avaliable[mid].start { + if self.avaliable[mid].start - index == 1 { + self.avaliable[mid].start -= 1; + if mid - 1 == 0 && + self.avaliable[mid - 1].end + 1 == self.avaliable[mid].start { + self.avaliable[mid - 1].end = self.avaliable[mid].end; + self.avaliable.remove(mid); + } + } else { + self.avaliable.insert(mid, Range {start: index, end: index}); + } + } else if index > self.avaliable[mid].end { + if index - self.avaliable[mid].end == 1 { + self.avaliable[mid].end += 1; + if (mid + 1 < self.avaliable.len() - 1) + && self.avaliable[mid + 1].start + 1 == self.avaliable[mid].end { + self.avaliable[mid + 1].start = self.avaliable[mid].start; + self.avaliable.remove(mid); + } + } else { + self.avaliable.insert(mid + 1, Range{start: index, end: index}); + } + } + } +} diff --git a/core-rust/natives/src/lib.rs b/core-rust/natives/src/lib.rs index ad5ece9..0dd9832 100644 --- a/core-rust/natives/src/lib.rs +++ b/core-rust/natives/src/lib.rs @@ -5,6 +5,6 @@ mod ui; mod resource; mod jni; mod math; - +mod index_pool; #[macro_use] extern crate log; From e13b69ef969eac0283b45f7685ec21e031d3eace Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Sun, 23 Jul 2023 22:40:59 -0700 Subject: [PATCH 2/6] feat: started working on chunk mesh resource Signed-off-by: Michael Pollind --- core-rust/natives/src/engine_kernel.rs | 1 - .../src/resource/.texture_resource.rs.rustfmt | 148 +++++++++++++++ .../src/resource/chunk_mesh_resource.rs | 172 ++++++++++++++++++ .../natives/src/resource/mesh_resource.rs | 4 +- core-rust/natives/src/resource/mod.rs | 1 + core-rust/natives/src/ui.rs | 1 - core-rust/natives/src/world.rs | 3 + .../terasology/engine/rust/EngineKernel.java | 1 - 8 files changed, 326 insertions(+), 5 deletions(-) create mode 100644 core-rust/natives/src/resource/.texture_resource.rs.rustfmt create mode 100644 core-rust/natives/src/resource/chunk_mesh_resource.rs create mode 100644 core-rust/natives/src/world.rs diff --git a/core-rust/natives/src/engine_kernel.rs b/core-rust/natives/src/engine_kernel.rs index b2f072d..6f60018 100644 --- a/core-rust/natives/src/engine_kernel.rs +++ b/core-rust/natives/src/engine_kernel.rs @@ -25,7 +25,6 @@ pub struct EngineKernel { pub user_interface: RefCell, pub frame_encoder: Mutex>> - } pub struct EngineKernelDesc { diff --git a/core-rust/natives/src/resource/.texture_resource.rs.rustfmt b/core-rust/natives/src/resource/.texture_resource.rs.rustfmt new file mode 100644 index 0000000..8c35aaa --- /dev/null +++ b/core-rust/natives/src/resource/.texture_resource.rs.rustfmt @@ -0,0 +1,148 @@ +use std::convert::From; +use std::sync::Arc; + +use glam::u32; +use jni::JNIEnv; +use jni::objects::{JObject}; +use jni::sys::{jint, jlong}; + + +use crate::java_util::{arc_dispose_handle, arc_from_handle, arc_to_handle, JavaHandle, set_joml_vector2f}; + +pub struct TextureResource { + pub texture: wgpu::Texture, +} + +impl TextureResource { + +} + +impl JavaHandle> for TextureResource { + fn from_handle(ptr: jni::sys::jlong) -> Option> { + arc_from_handle(ptr) + } + + fn to_handle(from: Arc) -> jni::sys::jlong { + arc_to_handle(from) + } + + fn drop_handle(ptr: jni::sys::jlong) { + arc_dispose_handle::(ptr); + } +} + +fn wgpu_texture_desc<'local, 'ret>(mut env: JNIEnv, obj: &JObject) -> wgpu::TextureDescriptor<'ret> { + let width = env.get_field(obj, "width", "I").unwrap().i().unwrap(); + let height = env.get_field(obj, "height", "I").unwrap().i().unwrap(); + let layer = env.get_field(obj, "layers", "I").unwrap().i().unwrap(); + let texture_dim = env.get_field(obj, "dim", "I").unwrap().i().unwrap(); + let format = env.get_field(obj, "format", "I").unwrap().i().unwrap(); + + let texture_format : wgpu::TextureFormat = unsafe { std::mem::transmute::(format) }.into(); + let texture_dim : wgpu::TextureDimension = unsafe { std::mem::transmute:: (texture_dim) }.into(); + + wgpu::TextureDescriptor { + size: wgpu::Extent3d { + width: width as u32, + height: height as u32, + depth_or_array_layers: layer as u32 + }, + mip_level_count: 1, + sample_count: 1, + dimension: texture_dim, + format: texture_format, + usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, + label: None, + view_formats: &[], + } +} + + + +#[repr(u32)] +enum JavaTextureDim { + DIM_1D, + DIM_2D, + DIM_3D +} + +impl From for wgpu::TextureDimension { + fn from(item: JavaTextureDim) -> Self { + match item { + JavaTextureDim::DIM_1D => wgpu::TextureDimension::D1, + JavaTextureDim::DIM_2D => wgpu::TextureDimension::D2, + JavaTextureDim::DIM_3D => wgpu::TextureDimension::D3, + } + } +} + +#[repr(u32)] +enum JavaImageFormat { + UNKNOWN, + R8_UNORM, + R8_SNORM, + R8_UINT, + R8_SINT, + R8G8_UNORM, + R8G8_SNORM, + R8G8_UINT, + R8G8_SINT, + R16_UNORM, + R16_SNORM, + R16_UINT, + R16_SINT, + R8G8B8A8_UNORM, + R8G8B8A8_SNORM, + R8G8B8A8_UINT, + R8G8B8A8_SINT, + R8G8B8A8_SRGB, +} + +trait TextureFormatExt { + fn bit_size_block(&self) -> u32; +} + +impl TextureFormatExt for wgpu::TextureFormat { + + fn bit_size_block(&self) -> u32 { + //TODO: incomplete + match self { + wgpu::TextureFormat::R8Unorm | + wgpu::TextureFormat::R8Sint | + wgpu::TextureFormat::R8Snorm => 8, + wgpu::TextureFormat::Rgba8Unorm | + wgpu::TextureFormat::Rgba8Sint | + wgpu::TextureFormat::Rgba8Uint | + wgpu::TextureFormat::Rgba8UnormSrgb => 32, + _ => 0 + } + } +} + +impl From for wgpu::TextureFormat { + fn from(item: JavaImageFormat) -> Self { + match item { + JavaImageFormat::R8_UNORM => wgpu::TextureFormat::R8Unorm, + JavaImageFormat::R8_SNORM => wgpu::TextureFormat::R8Snorm, + JavaImageFormat::R8_UINT => wgpu::TextureFormat::R8Uint, + JavaImageFormat::R8_SINT => wgpu::TextureFormat::R8Sint, + JavaImageFormat::R8G8_UNORM => wgpu::TextureFormat::Rg8Unorm, + JavaImageFormat::R8G8_SNORM => wgpu::TextureFormat::Rg8Snorm, + JavaImageFormat::R8G8_UINT => wgpu::TextureFormat::Rg8Uint, + JavaImageFormat::R8G8_SINT => wgpu::TextureFormat::Rg8Sint, + + JavaImageFormat::R16_UNORM => wgpu::TextureFormat::R16Unorm, + JavaImageFormat::R16_SNORM => wgpu::TextureFormat::R16Snorm, + JavaImageFormat::R16_UINT => wgpu::TextureFormat::R16Uint, + JavaImageFormat::R16_SINT => wgpu::TextureFormat::R16Sint, + + JavaImageFormat::R8G8B8A8_UNORM => wgpu::TextureFormat::Rgba8Unorm, + JavaImageFormat::R8G8B8A8_SNORM => wgpu::TextureFormat::Rgba8Snorm, + JavaImageFormat::R8G8B8A8_UINT => wgpu::TextureFormat::Rgba8Uint, + JavaImageFormat::R8G8B8A8_SINT => wgpu::TextureFormat::Rgba8Sint, + JavaImageFormat::R8G8B8A8_SRGB => wgpu::TextureFormat::Rgba8UnormSrgb, + _ => panic!("invalid image format"), + } + } +} + diff --git a/core-rust/natives/src/resource/chunk_mesh_resource.rs b/core-rust/natives/src/resource/chunk_mesh_resource.rs new file mode 100644 index 0000000..40a01a3 --- /dev/null +++ b/core-rust/natives/src/resource/chunk_mesh_resource.rs @@ -0,0 +1,172 @@ +use bytemuck::{Pod, Zeroable}; +use futures::lock::Mutex; +use smallvec::SmallVec; +use std::sync::Arc; +use crate::ui::{JavaHandle, arc_from_handle, arc_to_handle, arc_dispose_handle}; + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +pub struct ChunkPosition([f32; 3]); +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +pub struct ChunkNormal([f32; 3]); +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +pub struct ChunkUV([f32; 2]); +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +pub struct ChunkColor(u32); + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +pub struct ChunkAttributes { + sunlight: u8, + block_light: u8, + ambient_occlusion: u8, + pad: u8, + flags: u8, + frames: u8 +} + +const POSTION_LAYOUT: wgpu::VertexBufferLayout = wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as u64, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &wgpu::vertex_attr_array![0 => Float32x3], +}; + +const NORMAL_LAYOUT: wgpu::VertexBufferLayout = wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as u64, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &wgpu::vertex_attr_array![0 => Float32x3], +}; + +const UV_LAYOUT: wgpu::VertexBufferLayout = wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as u64, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &wgpu::vertex_attr_array![0 => Float32x2], +}; + +const COLOR_LAYOUT: wgpu::VertexBufferLayout = wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as u64, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &wgpu::vertex_attr_array![0 => Unorm8x4], +}; + +const ATTRIBUTE_LAYOUT: wgpu::VertexBufferLayout = wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as u64, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &wgpu::vertex_attr_array![0 => Unorm8x4, 1 => Uint8x2], +}; + + +pub enum MeshRenderType { + Opaque, + Translucent, + Billboard, + WaterAndIce +} + +pub struct ChunkMeshEntry { + render_type: MeshRenderType, + vertex_buffer: wgpu::Buffer, + index_buffer: wgpu::Buffer, + + num_elements: u32, + position_start: u64, + normal_start: u32, + uv_start: u32, + color_start: u32, + attribute_start: u32 +} + +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::() 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 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 set_mesh_resource( + &mut self, + device: &wgpu::Device, + queue: &wgpu::Queue, + render_type: MeshRenderType, + index_buffer: &[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"); + + let num_elements: u64 = position.len() as u64; + + let buffer = device.create_buffer( + &wgpu::BufferDescriptor { + label: Some("Unit Square Vertex Buffer"), + size: num_elements * + ( + std::mem::size_of::() as u64 + + std::mem::size_of::() as u64 + + std::mem::size_of::() as u64 + + std::mem::size_of::() as u64 + + std::mem::size_of::() as u64 + ), + usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false + } + ); + } + + pub fn unset_mesh_resource(render_type: MeshRenderType) { + + } + + fn as_slice(&self) -> &[ChunkMeshEntry] { + return self.meshes.as_slice(); + } +} + +impl JavaHandle> for ChunkMeshResource { + fn from_handle(ptr: jni::sys::jlong) -> Option> { + arc_from_handle(ptr) + } + + fn to_handle(from: Arc) -> jni::sys::jlong { + arc_to_handle(from) + } + + fn drop_handle(ptr: jni::sys::jlong) { + arc_dispose_handle::(ptr); + } +} + diff --git a/core-rust/natives/src/resource/mesh_resource.rs b/core-rust/natives/src/resource/mesh_resource.rs index e7e1111..6c8d4f6 100644 --- a/core-rust/natives/src/resource/mesh_resource.rs +++ b/core-rust/natives/src/resource/mesh_resource.rs @@ -43,12 +43,12 @@ impl Semantic { } pub struct ResourceStream { - buf: Rc, + buf: wgpu::Buffer, semantic: Semantic } pub struct IndexStream { - buf: Rc + buf: wgpu::Buffer } pub struct GeometryResource { diff --git a/core-rust/natives/src/resource/mod.rs b/core-rust/natives/src/resource/mod.rs index 44688e0..bb1e242 100644 --- a/core-rust/natives/src/resource/mod.rs +++ b/core-rust/natives/src/resource/mod.rs @@ -1,2 +1,3 @@ pub mod mesh_resource; +pub mod chunk_mesh_resource; pub mod texture_resource; diff --git a/core-rust/natives/src/ui.rs b/core-rust/natives/src/ui.rs index f6c6274..f20ff68 100644 --- a/core-rust/natives/src/ui.rs +++ b/core-rust/natives/src/ui.rs @@ -205,7 +205,6 @@ impl UserInterface { UIDrawGroup::Texture(ref tex) => { queue.write_buffer(&tex.vertex_buffer.as_ref(), tex.vertex_offset_start, &tex.vertex_shadow_data); queue.write_buffer(&tex.index_buffer.as_ref(), tex.index_offset_start, &tex.index_shadow_data); - // update_bind_group(&mut texture_bind_groups, tex.texture_index); rpass.set_bind_group(1, &texture_bind_groups[tex.texture_index], &[]); rpass.set_pipeline(&self.gui_texture_pipeline); diff --git a/core-rust/natives/src/world.rs b/core-rust/natives/src/world.rs new file mode 100644 index 0000000..672c639 --- /dev/null +++ b/core-rust/natives/src/world.rs @@ -0,0 +1,3 @@ +struct Scene { + +} diff --git a/core/src/main/java/org/terasology/engine/rust/EngineKernel.java b/core/src/main/java/org/terasology/engine/rust/EngineKernel.java index 0822b05..b5f25ec 100644 --- a/core/src/main/java/org/terasology/engine/rust/EngineKernel.java +++ b/core/src/main/java/org/terasology/engine/rust/EngineKernel.java @@ -13,7 +13,6 @@ public final class EngineKernel implements Disposable { public final UIRenderer ui; public final ResourceManager resource; - public static final class EngineKernelBuild { private long displayHandle; private long windowHandle; From 056367427d9369a7763b09fa9928208eeea479a4 Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Sun, 23 Jul 2023 22:41:46 -0700 Subject: [PATCH 3/6] removed rustfmt files Signed-off-by: Michael Pollind --- core-rust/natives/src/.lib.rs.rustfmt | 241 ------------------ .../src/resource/.texture_resource.rs.rustfmt | 148 ----------- 2 files changed, 389 deletions(-) delete mode 100644 core-rust/natives/src/.lib.rs.rustfmt delete mode 100644 core-rust/natives/src/resource/.texture_resource.rs.rustfmt diff --git a/core-rust/natives/src/.lib.rs.rustfmt b/core-rust/natives/src/.lib.rs.rustfmt deleted file mode 100644 index b6ca51a..0000000 --- a/core-rust/natives/src/.lib.rs.rustfmt +++ /dev/null @@ -1,241 +0,0 @@ -use context::Core; -use jni::{sys::{JNIEnv, jlong}, objects::JClass}; -use raw_window_handle::{XlibDisplayHandle, XlibWindowHandle, HasRawWindowHandle, RawWindowHandle, HasRawDisplayHandle, RawDisplayHandle, Win32WindowHandle, WindowsDisplayHandle}; -use std::ffi::c_void; -use crate::context::CONTEXT; -use futures::executor::block_on; -use std::borrow::Cow; - -#[macro_use] -extern crate lazy_static; - -mod win_init; -mod context; - - -#[no_mangle] -pub extern "system" fn Java_org_terasology_engine_rust_TeraRusty_dispatch(_jni: JNIEnv, _class: JClass) { - let context = CONTEXT.read().unwrap(); - - let core = &context.core.as_ref().unwrap(); - - let frame = core.wgpu_surface - .get_current_texture() - .expect("Failed to acquire next swap chain texture"); - let view = frame - .texture - .create_view(&wgpu::TextureViewDescriptor::default()); - let mut encoder = - core.wgpu_device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - { - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), - store: true, - }, - })], - depth_stencil_attachment: None, - }); - rpass.set_pipeline(&context.test_pipeline.as_ref().unwrap()); - rpass.draw(0..3, 0..1); - } - - core.wgpu_graphics_queue.submit(Some(encoder.finish())); - frame.present(); - -} - -struct XWindow { - window: XlibWindowHandle, - display: XlibDisplayHandle -} - -unsafe impl HasRawWindowHandle for XWindow { - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - return RawWindowHandle::Xlib(self.window); - } -} - -unsafe impl HasRawDisplayHandle for XWindow { - fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { - return RawDisplayHandle::Xlib(self.display); - } -} - -async fn initialize(instance: wgpu::Instance, surface: wgpu::Surface) { - let mut context = CONTEXT.write().unwrap(); - let adapter = instance - .request_adapter(&wgpu::RequestAdapterOptions { - power_preference: wgpu::PowerPreference::default(), - force_fallback_adapter: false, - // Request an adapter which can render to our surface - compatible_surface: Some(&surface), - }).await - .expect("Failed to find an appropriate adapter"); - - // Create the logical device and command queue - let (device, queue) = adapter - .request_device( - &wgpu::DeviceDescriptor { - label: None, - features: wgpu::Features::empty(), - // Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain. - limits: wgpu::Limits::downlevel_webgl2_defaults() - .using_resolution(adapter.limits()), - }, - None, - ) - .await - .expect("Failed to create device"); - - let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: None, - source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), - }); - - let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: None, - bind_group_layouts: &[], - push_constant_ranges: &[], - }); - - let swapchain_capabilities = surface.get_capabilities(&adapter); - let swapchain_format = swapchain_capabilities.formats[0]; - - let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: None, - layout: Some(&pipeline_layout), - vertex: wgpu::VertexState { - module: &shader, - entry_point: "vs_main", - buffers: &[], - }, - fragment: Some(wgpu::FragmentState { - module: &shader, - entry_point: "fs_main", - targets: &[Some(swapchain_format.into())], - }), - primitive: wgpu::PrimitiveState::default(), - depth_stencil: None, - multisample: wgpu::MultisampleState::default(), - multiview: None, - }); - - let config = wgpu::SurfaceConfiguration { - usage: wgpu::TextureUsages::RENDER_ATTACHMENT, - format: swapchain_format, - width: 1920, - height: 1080, - present_mode: wgpu::PresentMode::Fifo, - alpha_mode: swapchain_capabilities.alpha_modes[0], - view_formats: vec![], - }; - - surface.configure(&device, &config); - let core = Core { - wgpu_graphics_queue: queue, - wgpu_device : device, - wgpu_adapter : adapter, - wgpu_instance : instance, - wgpu_surface : surface - }; - (*context).core = Some(core); - (*context).test_pipeline = Some(render_pipeline); -} - -#[no_mangle] -pub extern "system" fn Java_org_terasology_engine_rust_TeraRusty_initializeWindowX11(_jni: JNIEnv, _class: JClass, display_ptr: jlong, window_ptr: jlong) { - let mut win = XWindow { - window: XlibWindowHandle::empty(), - display: XlibDisplayHandle::empty() - }; - - print!("initializeWindowX11"); - - win.window.window = window_ptr as u64; - win.display.display = display_ptr as *mut c_void; - - let instance = wgpu::Instance::default(); - let surface_result = unsafe {instance.create_surface(&win) }; - let surface = match surface_result { - Ok(surface) => surface, - Err(err) => panic!("problem creating surface: {:?}", err), - }; - // let mut context = CONTEXT.write().unwrap(); - // context.wgpu_instance = Some(instance); - // context.wgpu_surface = Some(surface); - let future = initialize(instance, surface); - block_on(future); -} - -struct Win32Window { - window: Win32WindowHandle, - display: WindowsDisplayHandle -} - - -unsafe impl HasRawWindowHandle for Win32Window { - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - return RawWindowHandle::Win32(self.window); - } -} - -unsafe impl HasRawDisplayHandle for Win32Window { - fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { - return RawDisplayHandle::Windows(self.display); - } -} - -#[no_mangle] -pub extern "system" fn Java_org_terasology_engine_rust_TeraRusty_initializeWindowWin32(_jni: JNIEnv, _class: JClass, window_ptr: jlong) { - let mut win = Win32Window { - window: Win32WindowHandle::empty(), - display: WindowsDisplayHandle::empty() - }; - win.window.hwnd = window_ptr as *mut c_void; - - let instance = wgpu::Instance::default(); - let surface_result = unsafe {instance.create_surface(&win) }; - let surface = match surface_result { - Ok(surface) => surface, - Err(err) => panic!("problem creating surface: {:?}", err), - }; - let future = initialize(instance, surface); - block_on(future); -} -//struct XWindow { -// window: XlibWindowHandle, -// display: XlibDisplayHandle -//} -// -//unsafe impl HasRawWindowHandle for XWindow { -// fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { -// return RawWindowHandle::Xlib(self.window); -// } -//} -// -//unsafe impl HasRawDisplayHandle for XWindow { -// fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { -// return RawDisplayHandle::Xlib(self.display); -// } -//} -// -// -//#[no_mangle] -//pub extern "system" fn Java_org_terasology_engine_native_InitializeWindowX11(_jni: JNIEnv, _class: JClass, display_ptr: jlong, window_ptr: jlong) { -// let mut win = XWindow { -// window: XlibWindowHandle::empty(), -// display: XlibDisplayHandle::empty() -// }; -// win.window.window = window_ptr as u64; -// win.display.display = display_ptr as *mut c_void; -// -// let instance = wgpu::Instance::default(); -// let surface = unsafe { instance.create_surface(&win) }; -//} - - diff --git a/core-rust/natives/src/resource/.texture_resource.rs.rustfmt b/core-rust/natives/src/resource/.texture_resource.rs.rustfmt deleted file mode 100644 index 8c35aaa..0000000 --- a/core-rust/natives/src/resource/.texture_resource.rs.rustfmt +++ /dev/null @@ -1,148 +0,0 @@ -use std::convert::From; -use std::sync::Arc; - -use glam::u32; -use jni::JNIEnv; -use jni::objects::{JObject}; -use jni::sys::{jint, jlong}; - - -use crate::java_util::{arc_dispose_handle, arc_from_handle, arc_to_handle, JavaHandle, set_joml_vector2f}; - -pub struct TextureResource { - pub texture: wgpu::Texture, -} - -impl TextureResource { - -} - -impl JavaHandle> for TextureResource { - fn from_handle(ptr: jni::sys::jlong) -> Option> { - arc_from_handle(ptr) - } - - fn to_handle(from: Arc) -> jni::sys::jlong { - arc_to_handle(from) - } - - fn drop_handle(ptr: jni::sys::jlong) { - arc_dispose_handle::(ptr); - } -} - -fn wgpu_texture_desc<'local, 'ret>(mut env: JNIEnv, obj: &JObject) -> wgpu::TextureDescriptor<'ret> { - let width = env.get_field(obj, "width", "I").unwrap().i().unwrap(); - let height = env.get_field(obj, "height", "I").unwrap().i().unwrap(); - let layer = env.get_field(obj, "layers", "I").unwrap().i().unwrap(); - let texture_dim = env.get_field(obj, "dim", "I").unwrap().i().unwrap(); - let format = env.get_field(obj, "format", "I").unwrap().i().unwrap(); - - let texture_format : wgpu::TextureFormat = unsafe { std::mem::transmute::(format) }.into(); - let texture_dim : wgpu::TextureDimension = unsafe { std::mem::transmute:: (texture_dim) }.into(); - - wgpu::TextureDescriptor { - size: wgpu::Extent3d { - width: width as u32, - height: height as u32, - depth_or_array_layers: layer as u32 - }, - mip_level_count: 1, - sample_count: 1, - dimension: texture_dim, - format: texture_format, - usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, - label: None, - view_formats: &[], - } -} - - - -#[repr(u32)] -enum JavaTextureDim { - DIM_1D, - DIM_2D, - DIM_3D -} - -impl From for wgpu::TextureDimension { - fn from(item: JavaTextureDim) -> Self { - match item { - JavaTextureDim::DIM_1D => wgpu::TextureDimension::D1, - JavaTextureDim::DIM_2D => wgpu::TextureDimension::D2, - JavaTextureDim::DIM_3D => wgpu::TextureDimension::D3, - } - } -} - -#[repr(u32)] -enum JavaImageFormat { - UNKNOWN, - R8_UNORM, - R8_SNORM, - R8_UINT, - R8_SINT, - R8G8_UNORM, - R8G8_SNORM, - R8G8_UINT, - R8G8_SINT, - R16_UNORM, - R16_SNORM, - R16_UINT, - R16_SINT, - R8G8B8A8_UNORM, - R8G8B8A8_SNORM, - R8G8B8A8_UINT, - R8G8B8A8_SINT, - R8G8B8A8_SRGB, -} - -trait TextureFormatExt { - fn bit_size_block(&self) -> u32; -} - -impl TextureFormatExt for wgpu::TextureFormat { - - fn bit_size_block(&self) -> u32 { - //TODO: incomplete - match self { - wgpu::TextureFormat::R8Unorm | - wgpu::TextureFormat::R8Sint | - wgpu::TextureFormat::R8Snorm => 8, - wgpu::TextureFormat::Rgba8Unorm | - wgpu::TextureFormat::Rgba8Sint | - wgpu::TextureFormat::Rgba8Uint | - wgpu::TextureFormat::Rgba8UnormSrgb => 32, - _ => 0 - } - } -} - -impl From for wgpu::TextureFormat { - fn from(item: JavaImageFormat) -> Self { - match item { - JavaImageFormat::R8_UNORM => wgpu::TextureFormat::R8Unorm, - JavaImageFormat::R8_SNORM => wgpu::TextureFormat::R8Snorm, - JavaImageFormat::R8_UINT => wgpu::TextureFormat::R8Uint, - JavaImageFormat::R8_SINT => wgpu::TextureFormat::R8Sint, - JavaImageFormat::R8G8_UNORM => wgpu::TextureFormat::Rg8Unorm, - JavaImageFormat::R8G8_SNORM => wgpu::TextureFormat::Rg8Snorm, - JavaImageFormat::R8G8_UINT => wgpu::TextureFormat::Rg8Uint, - JavaImageFormat::R8G8_SINT => wgpu::TextureFormat::Rg8Sint, - - JavaImageFormat::R16_UNORM => wgpu::TextureFormat::R16Unorm, - JavaImageFormat::R16_SNORM => wgpu::TextureFormat::R16Snorm, - JavaImageFormat::R16_UINT => wgpu::TextureFormat::R16Uint, - JavaImageFormat::R16_SINT => wgpu::TextureFormat::R16Sint, - - JavaImageFormat::R8G8B8A8_UNORM => wgpu::TextureFormat::Rgba8Unorm, - JavaImageFormat::R8G8B8A8_SNORM => wgpu::TextureFormat::Rgba8Snorm, - JavaImageFormat::R8G8B8A8_UINT => wgpu::TextureFormat::Rgba8Uint, - JavaImageFormat::R8G8B8A8_SINT => wgpu::TextureFormat::Rgba8Sint, - JavaImageFormat::R8G8B8A8_SRGB => wgpu::TextureFormat::Rgba8UnormSrgb, - _ => panic!("invalid image format"), - } - } -} - From e50b4e905da1b420d55569a79be5c61251566882 Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Mon, 25 Sep 2023 20:18:05 -0700 Subject: [PATCH 4/6] feat: add chunk mesh Signed-off-by: Michael Pollind --- core-rust/natives/src/jni/jni_chunk_mesh.rs | 10 ++ core-rust/natives/src/jni/jni_resource.rs | 12 +- core-rust/natives/src/jni/jni_texture.rs | 6 +- core-rust/natives/src/jni/mod.rs | 1 + core-rust/natives/src/lib.rs | 1 + .../src/resource/chunk_mesh_resource.rs | 153 +++++++++++++----- core-rust/natives/src/scene.rs | 21 +++ core-rust/natives/src/world.rs | 3 - .../terasology/engine/rust/EngineKernel.java | 83 +++++----- .../engine/rust/EngineSubsystem.java | 11 -- .../org/terasology/engine/rust/RawHandle.java | 8 + .../org/terasology/engine/rust/Scene.java | 9 ++ .../terasology/engine/rust/UIRenderer.java | 13 +- .../engine/rust/resource/ChunkGeometry.java | 62 +++++++ .../Geometry.java} | 9 +- .../rust/{ => resource}/ResourceManager.java | 13 +- .../rust/{ => resource}/TeraTexture.java | 24 +-- 17 files changed, 315 insertions(+), 124 deletions(-) create mode 100644 core-rust/natives/src/jni/jni_chunk_mesh.rs create mode 100644 core-rust/natives/src/scene.rs delete mode 100644 core-rust/natives/src/world.rs delete mode 100644 core/src/main/java/org/terasology/engine/rust/EngineSubsystem.java create mode 100644 core/src/main/java/org/terasology/engine/rust/RawHandle.java create mode 100644 core/src/main/java/org/terasology/engine/rust/Scene.java create mode 100644 core/src/main/java/org/terasology/engine/rust/resource/ChunkGeometry.java rename core/src/main/java/org/terasology/engine/rust/{GeometryHandle.java => resource/Geometry.java} (61%) rename core/src/main/java/org/terasology/engine/rust/{ => resource}/ResourceManager.java (64%) rename core/src/main/java/org/terasology/engine/rust/{ => resource}/TeraTexture.java (75%) diff --git a/core-rust/natives/src/jni/jni_chunk_mesh.rs b/core-rust/natives/src/jni/jni_chunk_mesh.rs new file mode 100644 index 0000000..5ecd955 --- /dev/null +++ b/core-rust/natives/src/jni/jni_chunk_mesh.rs @@ -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); +} diff --git a/core-rust/natives/src/jni/jni_resource.rs b/core-rust/natives/src/jni/jni_resource.rs index d6c9437..7190943 100644 --- a/core-rust/natives/src/jni/jni_resource.rs +++ b/core-rust/natives/src/jni/jni_resource.rs @@ -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 { @@ -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 { @@ -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()))) +} diff --git a/core-rust/natives/src/jni/jni_texture.rs b/core-rust/natives/src/jni/jni_texture.rs index 367fcd7..e633685 100644 --- a/core-rust/natives/src/jni/jni_texture.rs +++ b/core-rust/natives/src/jni/jni_texture.rs @@ -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"); diff --git a/core-rust/natives/src/jni/mod.rs b/core-rust/natives/src/jni/mod.rs index 65f3e9e..7fd70c3 100644 --- a/core-rust/natives/src/jni/mod.rs +++ b/core-rust/natives/src/jni/mod.rs @@ -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; diff --git a/core-rust/natives/src/lib.rs b/core-rust/natives/src/lib.rs index ad5ece9..58980f9 100644 --- a/core-rust/natives/src/lib.rs +++ b/core-rust/natives/src/lib.rs @@ -8,3 +8,4 @@ mod math; #[macro_use] extern crate log; +mod scene; diff --git a/core-rust/natives/src/resource/chunk_mesh_resource.rs b/core-rust/natives/src/resource/chunk_mesh_resource.rs index 40a01a3..8417028 100644 --- a/core-rust/natives/src/resource/chunk_mesh_resource.rs +++ b/core-rust/natives/src/resource/chunk_mesh_resource.rs @@ -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)] @@ -59,6 +58,7 @@ const ATTRIBUTE_LAYOUT: wgpu::VertexBufferLayout = wgpu::VertexBufferLayout { }; +#[derive(PartialEq, Clone, Copy)] pub enum MeshRenderType { Opaque, Translucent, @@ -71,44 +71,36 @@ 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::() 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::() 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::() 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::() 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::() 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::() 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( @@ -116,57 +108,130 @@ impl ChunkMeshResource { 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::() as u64 + std::mem::size_of::() as u64 + std::mem::size_of::() as u64 + std::mem::size_of::() as u64 + - std::mem::size_of::() as u64 + std::mem::size_of::() 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::()) 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> for ChunkMeshResource { - fn from_handle(ptr: jni::sys::jlong) -> Option> { +impl JavaHandle>> for ChunkMeshResource { + fn from_handle(ptr: jni::sys::jlong) -> Option>> { arc_from_handle(ptr) } - fn to_handle(from: Arc) -> jni::sys::jlong { + fn to_handle(from: Arc>) -> jni::sys::jlong { arc_to_handle(from) } fn drop_handle(ptr: jni::sys::jlong) { - arc_dispose_handle::(ptr); + arc_dispose_handle::>(ptr); } } diff --git a/core-rust/natives/src/scene.rs b/core-rust/natives/src/scene.rs new file mode 100644 index 0000000..3fcdbb9 --- /dev/null +++ b/core-rust/natives/src/scene.rs @@ -0,0 +1,21 @@ +use crate::resource::chunk_mesh_resource::ChunkMeshResource; +use std::sync::Arc; + +pub struct Scene { + opaque_chunks: Vec> +} + +impl Scene { + + pub fn cmd_prepare(&mut self) { + + } + + pub fn cmd_dispatch(&mut self) { + + } + + pub fn cmd_queue_opaque_chunk() { + + } +} diff --git a/core-rust/natives/src/world.rs b/core-rust/natives/src/world.rs deleted file mode 100644 index 672c639..0000000 --- a/core-rust/natives/src/world.rs +++ /dev/null @@ -1,3 +0,0 @@ -struct Scene { - -} diff --git a/core/src/main/java/org/terasology/engine/rust/EngineKernel.java b/core/src/main/java/org/terasology/engine/rust/EngineKernel.java index b5f25ec..fb5c1c2 100644 --- a/core/src/main/java/org/terasology/engine/rust/EngineKernel.java +++ b/core/src/main/java/org/terasology/engine/rust/EngineKernel.java @@ -3,44 +3,26 @@ package org.terasology.engine.rust; -import java.lang.ref.Cleaner; +import org.terasology.engine.rust.resource.ResourceManager; -public final class EngineKernel implements Disposable { - static final Cleaner CLEANER = Cleaner.create(); +import java.lang.ref.Cleaner; - final long rustKernelPtr; - private final Cleaner.Cleanable cleanable; +public final class EngineKernel implements Disposable, RawHandle { + public static final Cleaner CLEANER = Cleaner.create(); public final UIRenderer ui; public final ResourceManager resource; - public static final class EngineKernelBuild { - private long displayHandle; - private long windowHandle; - private int windowType; + final long rawRustPtr; - public enum WindowType { - Win32, - X11 - } - - public EngineKernelBuild configureX11Window(long windowHandle, long displayHandle) { - this.windowType = WindowType.X11.ordinal(); - this.displayHandle = displayHandle; - this.windowHandle = windowHandle; - return this; - } + private final Cleaner.Cleanable cleanable; - public EngineKernelBuild configureWin32Window(long windowHandle, long displayHandle) { - this.windowType = WindowType.Win32.ordinal(); - this.displayHandle = displayHandle; - this.windowHandle = windowHandle; - return this; - } + static { + NativeSupport.load("core_rust"); } public EngineKernel(EngineKernelBuild builder) { long kernelPtr = JNI.create(builder); - rustKernelPtr = kernelPtr; + this.rawRustPtr = kernelPtr; this.ui = new UIRenderer(this); this.resource = new ResourceManager(this); this.cleanable = CLEANER.register(this, () -> { @@ -48,19 +30,21 @@ public EngineKernel(EngineKernelBuild builder) { }); } - static { - NativeSupport.load("core_rust"); - } - - public void resizeSurface(int width, int height) { - JNI.resizeSurface(rustKernelPtr, width, height); + JNI.resizeSurface(rawRustPtr, width, height); } + public void cmdPrepare() { - JNI.cmdPrepare(rustKernelPtr); + JNI.cmdPrepare(rawRustPtr); } + public void cmdDispatch() { - JNI.cmdDispatch(rustKernelPtr); + JNI.cmdDispatch(rawRustPtr); + } + + @Override + public long getHandle() { + return rawRustPtr; } @Override @@ -68,16 +52,41 @@ public void dispose() { this.cleanable.clean(); } + public static final class EngineKernelBuild { + private long displayHandle; + private long windowHandle; + private int windowType; + + public enum WindowType { + Win32, + X11 + } + + public EngineKernelBuild configureX11Window(long windowHandle, long displayHandle) { + this.windowType = WindowType.X11.ordinal(); + this.displayHandle = displayHandle; + this.windowHandle = windowHandle; + return this; + } + + public EngineKernelBuild configureWin32Window(long windowHandle, long displayHandle) { + this.windowType = WindowType.Win32.ordinal(); + this.displayHandle = displayHandle; + this.windowHandle = windowHandle; + return this; + } + } + private static final class JNI { private static native long create(EngineKernelBuild builder); private static native void drop(long rustPtr); private static native void resizeSurface(long kernel, int width, int height); - private static native void cmdPrepare(long kernel); - private static native void cmdDispatch(long kernel); + private static native void cmdPrepare(long kernel); + private static native void cmdDispatch(long kernel); } } diff --git a/core/src/main/java/org/terasology/engine/rust/EngineSubsystem.java b/core/src/main/java/org/terasology/engine/rust/EngineSubsystem.java deleted file mode 100644 index 076d447..0000000 --- a/core/src/main/java/org/terasology/engine/rust/EngineSubsystem.java +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2023 The Terasology Foundation -// SPDX-License-Identifier: Apache-2.0 - -package org.terasology.engine.rust; - -public abstract class EngineSubsystem { - protected final EngineKernel kernel; - EngineSubsystem(EngineKernel kernel, T ignoredOptions) { - this.kernel = kernel; - } -} diff --git a/core/src/main/java/org/terasology/engine/rust/RawHandle.java b/core/src/main/java/org/terasology/engine/rust/RawHandle.java new file mode 100644 index 0000000..2115085 --- /dev/null +++ b/core/src/main/java/org/terasology/engine/rust/RawHandle.java @@ -0,0 +1,8 @@ +// Copyright 2023 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + +package org.terasology.engine.rust; + +public interface RawHandle { + long getHandle(); +} diff --git a/core/src/main/java/org/terasology/engine/rust/Scene.java b/core/src/main/java/org/terasology/engine/rust/Scene.java new file mode 100644 index 0000000..b140b4b --- /dev/null +++ b/core/src/main/java/org/terasology/engine/rust/Scene.java @@ -0,0 +1,9 @@ +// Copyright 2023 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + +package org.terasology.engine.rust; + +public class Scene { + + +} diff --git a/core/src/main/java/org/terasology/engine/rust/UIRenderer.java b/core/src/main/java/org/terasology/engine/rust/UIRenderer.java index 8154b56..3e4b689 100644 --- a/core/src/main/java/org/terasology/engine/rust/UIRenderer.java +++ b/core/src/main/java/org/terasology/engine/rust/UIRenderer.java @@ -3,6 +3,7 @@ package org.terasology.engine.rust; +import org.terasology.engine.rust.resource.TeraTexture; import org.terasology.joml.geom.Rectanglef; import java.util.Optional; @@ -17,16 +18,16 @@ public UIRenderer(EngineKernel kernel) { public void cmdUISetCrop(Optional rect) { if (rect.isPresent()) { Rectanglef r = rect.get(); - UIRenderer.JNI.cmdUISetCrop(this.kernel.rustKernelPtr, r.minX(), r.minY(), r.maxX(), r.maxY()); + UIRenderer.JNI.cmdUISetCrop(this.kernel.rawRustPtr, r.minX(), r.minY(), r.maxX(), r.maxY()); } else { - UIRenderer.JNI.cmdUIClearCrop(this.kernel.rustKernelPtr); + UIRenderer.JNI.cmdUIClearCrop(this.kernel.rawRustPtr); } } public void cmdUIDrawTexture(TeraTexture tex, Rectanglef uv, Rectanglef pos, int tintColor) { UIRenderer.JNI.cmdUIDrawTexture( - this.kernel.rustKernelPtr, - tex.rustTexturePtr, + this.kernel.rawRustPtr, + tex.getHandle(), uv.minX(), uv.minY(), uv.maxX(), uv.maxY(), pos.minX(), pos.minY(), pos.maxX(), pos.maxY(), tintColor @@ -35,8 +36,8 @@ public void cmdUIDrawTexture(TeraTexture tex, Rectanglef uv, Rectanglef pos, int public void cmdUIDrawTexture(TeraTexture tex, Rectanglef uv, Rectanglef pos) { UIRenderer.JNI.cmdUIDrawTexture( - this.kernel.rustKernelPtr, - tex.rustTexturePtr, + this.kernel.rawRustPtr, + tex.getHandle(), uv.minX(), uv.minY(), uv.maxX(), uv.maxY(), pos.minX(), pos.minY(), pos.maxX(), pos.maxY(), 0xffffffff diff --git a/core/src/main/java/org/terasology/engine/rust/resource/ChunkGeometry.java b/core/src/main/java/org/terasology/engine/rust/resource/ChunkGeometry.java new file mode 100644 index 0000000..962e5a1 --- /dev/null +++ b/core/src/main/java/org/terasology/engine/rust/resource/ChunkGeometry.java @@ -0,0 +1,62 @@ +// Copyright 2023 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + +package org.terasology.engine.rust.resource; + +import org.terasology.engine.rust.EngineKernel; +import org.terasology.engine.rust.RawHandle; + +import java.lang.ref.Cleaner; + +public class ChunkGeometry implements RawHandle { + final long rustPtr; + final EngineKernel kernel; + private final Cleaner.Cleanable cleanable; + + public enum MeshRenderType { + Opaque, + Translucent, + Billboard, + WaterAndIce + } + + public ChunkGeometry(EngineKernel kernel, long rustPtr) { + this.rustPtr = rustPtr; + this.kernel = kernel; + this.cleanable = EngineKernel.CLEANER.register(this, () -> { + ChunkGeometry.JNI.drop(rustPtr); + }); + } + + public void setMeshResource( + java.nio.ByteBuffer index, + java.nio.ByteBuffer position, + java.nio.ByteBuffer normal, + java.nio.ByteBuffer uv, + java.nio.ByteBuffer color, + java.nio.ByteBuffer attributes + ) { + JNI.setMeshResource(this.kernel.getHandle(), rustPtr, index, position, normal, uv, color, attributes); + } + + @Override + public long getHandle() { + return rustPtr; + } + + private static final class JNI { + static native void drop(long rustPtr); + + static native void setMeshResource(long kernelPtr, long chunkPtr, + java.nio.ByteBuffer index, + java.nio.ByteBuffer position, + java.nio.ByteBuffer normal, + java.nio.ByteBuffer uv, + java.nio.ByteBuffer color, + java.nio.ByteBuffer attributes + ); + + static native void clearMeshResource(long kernelPtr, long chunkPtr); + + } +} diff --git a/core/src/main/java/org/terasology/engine/rust/GeometryHandle.java b/core/src/main/java/org/terasology/engine/rust/resource/Geometry.java similarity index 61% rename from core/src/main/java/org/terasology/engine/rust/GeometryHandle.java rename to core/src/main/java/org/terasology/engine/rust/resource/Geometry.java index 4272702..ea26dac 100644 --- a/core/src/main/java/org/terasology/engine/rust/GeometryHandle.java +++ b/core/src/main/java/org/terasology/engine/rust/resource/Geometry.java @@ -1,10 +1,12 @@ // Copyright 2023 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 -package org.terasology.engine.rust; +package org.terasology.engine.rust.resource; -public class GeometryHandle implements Disposable { - GeometryHandle() { +import org.terasology.engine.rust.Disposable; + +public class Geometry implements Disposable { + Geometry() { } @@ -13,7 +15,6 @@ public void dispose() { } private static final class JNI { - private static native long create(); private static native void drop(long rustPtr); } diff --git a/core/src/main/java/org/terasology/engine/rust/ResourceManager.java b/core/src/main/java/org/terasology/engine/rust/resource/ResourceManager.java similarity index 64% rename from core/src/main/java/org/terasology/engine/rust/ResourceManager.java rename to core/src/main/java/org/terasology/engine/rust/resource/ResourceManager.java index 4ecf82c..a588544 100644 --- a/core/src/main/java/org/terasology/engine/rust/ResourceManager.java +++ b/core/src/main/java/org/terasology/engine/rust/resource/ResourceManager.java @@ -1,7 +1,9 @@ // Copyright 2023 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 -package org.terasology.engine.rust; +package org.terasology.engine.rust.resource; + +import org.terasology.engine.rust.EngineKernel; public class ResourceManager { private final EngineKernel kernel; @@ -10,14 +12,19 @@ public ResourceManager(EngineKernel kernel) { } public TeraTexture createTexture(TeraTexture.TextureDesc desc) { - return new TeraTexture(this.kernel, ResourceManager.JNI.createTextureResource(this.kernel.rustKernelPtr, desc)); + return new TeraTexture(this.kernel, ResourceManager.JNI.createTextureResource(this.kernel.getHandle(), desc)); } public TeraTexture createTexture(TeraTexture.TextureDesc desc, java.nio.ByteBuffer buffer) { - return new TeraTexture(this.kernel, ResourceManager.JNI.createTextureResourceFromBuffer(this.kernel.rustKernelPtr, desc, buffer)); + return new TeraTexture(this.kernel, ResourceManager.JNI.createTextureResourceFromBuffer(this.kernel.getHandle(), desc, buffer)); + } + + public ChunkGeometry createChunkGeometry() { + return new ChunkGeometry(this.kernel, ResourceManager.JNI.createChunkResource(this.kernel.getHandle())); } private static class JNI { public static native long createTextureResourceFromBuffer(long kernelPtr, TeraTexture.TextureDesc desc, java.nio.ByteBuffer buffer); public static native long createTextureResource(long kernelPtr, TeraTexture.TextureDesc desc); + public static native long createChunkResource(long kernelPtr); } } diff --git a/core/src/main/java/org/terasology/engine/rust/TeraTexture.java b/core/src/main/java/org/terasology/engine/rust/resource/TeraTexture.java similarity index 75% rename from core/src/main/java/org/terasology/engine/rust/TeraTexture.java rename to core/src/main/java/org/terasology/engine/rust/resource/TeraTexture.java index 473b77e..a7f994b 100644 --- a/core/src/main/java/org/terasology/engine/rust/TeraTexture.java +++ b/core/src/main/java/org/terasology/engine/rust/resource/TeraTexture.java @@ -1,16 +1,17 @@ // Copyright 2023 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 -package org.terasology.engine.rust; +package org.terasology.engine.rust.resource; import org.joml.Vector2f; import org.joml.Vector2fc; +import org.terasology.engine.rust.Disposable; +import org.terasology.engine.rust.EngineKernel; +import org.terasology.engine.rust.RawHandle; import java.lang.ref.Cleaner; -import static org.terasology.engine.rust.EngineKernel.CLEANER; - -public class TeraTexture implements Disposable { +public class TeraTexture implements Disposable, RawHandle { final long rustTexturePtr; private final Cleaner.Cleanable cleanable; private final EngineKernel kernel; @@ -19,11 +20,16 @@ public class TeraTexture implements Disposable { TeraTexture(EngineKernel kernel, long texturePtr) { this.kernel = kernel; rustTexturePtr = texturePtr; - this.cleanable = CLEANER.register(this, () -> { + this.cleanable = EngineKernel.CLEANER.register(this, () -> { TeraTexture.JNI.drop(texturePtr); }); } + @Override + public long getHandle() { + return this.rustTexturePtr; + } + public enum TextureDimension { DIM_1D, DIM_2D, @@ -89,7 +95,7 @@ public TextureDesc setDim(TextureDimension dim) { public void writeTextureBuffer(java.nio.ByteBuffer buffer) { - JNI.writeTextureBuffer(kernel.rustKernelPtr, this.rustTexturePtr, buffer); + JNI.writeTextureBuffer(kernel.getHandle(), this.rustTexturePtr, buffer); } public Vector2fc getSize() { @@ -104,10 +110,10 @@ public void dispose() { private static final class JNI { - private static native void drop(long rustPtr); + static native void drop(long rustPtr); - public static native void getSize(long textureResourcePtr, Vector2f vec); - public static native void writeTextureBuffer(long kernelPtr, long textureResourcePtr, java.nio.ByteBuffer buffer); + static native void getSize(long textureResourcePtr, Vector2f vec); + static native void writeTextureBuffer(long kernelPtr, long textureResourcePtr, java.nio.ByteBuffer buffer); } } From ba0aea65eeacf96ff03abe6c3ffc6a605d685aae Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Mon, 24 Jul 2023 22:04:34 -0700 Subject: [PATCH 5/6] feat: add chunk mesh Signed-off-by: Michael Pollind --- core-rust/natives/Cargo.lock | 116 +++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/core-rust/natives/Cargo.lock b/core-rust/natives/Cargo.lock index 3025c5f..b48f2ba 100644 --- a/core-rust/natives/Cargo.lock +++ b/core-rust/natives/Cargo.lock @@ -28,6 +28,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "aho-corasick" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +dependencies = [ + "memchr", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -305,10 +314,12 @@ name = "core-rust" version = "0.1.0" dependencies = [ "bytemuck", + "env_logger", "futures", "glam", "image", "jni", + "log", "once_cell", "raw-window-handle 0.5.2", "slotmap", @@ -448,12 +459,46 @@ dependencies = [ "wio", ] +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "equivalent" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" +[[package]] +name = "errno" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "expat-sys" version = "2.1.6" @@ -759,12 +804,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + [[package]] name = "hexf-parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "ident_case" version = "1.0.1" @@ -818,6 +875,17 @@ dependencies = [ "web-sys", ] +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "jni" version = "0.21.1" @@ -898,6 +966,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" + [[package]] name = "lock_api" version = "0.4.10" @@ -1322,6 +1396,35 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "regex" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + [[package]] name = "renderdoc-sys" version = "1.0.0" @@ -1340,6 +1443,19 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustix" +version = "0.38.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + [[package]] name = "safe_arch" version = "0.5.2" From 4364e4ace1e420deb2d6b59eef75b172b0d553a3 Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Tue, 25 Jul 2023 22:14:47 -0700 Subject: [PATCH 6/6] feat: added chunk logic for scene Signed-off-by: Michael Pollind --- core-rust/natives/src/engine_kernel.rs | 3 +- core-rust/natives/src/id_pool.rs | 69 ++++++++++++++++ core-rust/natives/src/java_util.rs | 6 +- core-rust/natives/src/lib.rs | 1 + .../src/resource/chunk_mesh_resource.rs | 5 -- core-rust/natives/src/scene.rs | 79 ++++++++++++++++--- 6 files changed, 145 insertions(+), 18 deletions(-) create mode 100644 core-rust/natives/src/id_pool.rs diff --git a/core-rust/natives/src/engine_kernel.rs b/core-rust/natives/src/engine_kernel.rs index 6f60018..5be9a77 100644 --- a/core-rust/natives/src/engine_kernel.rs +++ b/core-rust/natives/src/engine_kernel.rs @@ -1,7 +1,7 @@ use futures::executor::block_on; use jni::sys::jlong; use std::sync::Arc; -use crate::{java_util::{arc_from_handle, arc_to_handle, arc_dispose_handle, JavaHandle}, window_surface::{WindowSurface, WindowSurfaceDesc}, ui::{UserInterface}, math::rect::Rect} ; +use crate::{java_util::{arc_from_handle, arc_to_handle, arc_dispose_handle, JavaHandle}, window_surface::{WindowSurface, WindowSurfaceDesc}, ui::{UserInterface}, math::rect::Rect, scene::{SceneChunk, Scene}} ; use std::cell::RefCell; use std::sync::Mutex; use std::cell::Cell; @@ -31,6 +31,7 @@ pub struct EngineKernelDesc { pub surface: WindowSurfaceDesc, } + impl EngineKernel { pub fn new(instance: wgpu::Instance, desc: &EngineKernelDesc) -> Self { let surface = block_on(WindowSurface::create(&instance, &desc.surface)); diff --git a/core-rust/natives/src/id_pool.rs b/core-rust/natives/src/id_pool.rs new file mode 100644 index 0000000..2b5150f --- /dev/null +++ b/core-rust/natives/src/id_pool.rs @@ -0,0 +1,69 @@ +use smallvec; + +pub struct Range { + start: u32, + end: u32 +} + +pub struct IDPool { + used: u32, + free: Vec +} + +impl IDPool { + pub fn fetch_id(&mut self) -> u32 { + match self.free.last_mut() { + Some(range) => { + let id = range.start; + range.start += 1; + if range.start > range.end { + self.free.pop(); + } + id + }, + None => { + let id = self.used; + self.used += 1; + id + } + } + + } + + + pub fn return_id(&mut self, id: u32) { + if self.free.is_empty() { + self.free.push(Range { start: id, end: id}) + } + + match self.free.binary_search_by(|probe| { + if id >= probe.start && id <= probe.end { + std::cmp::Ordering::Equal + } else { + probe.start.cmp(&id) + } + }) { + Ok(_index) => { + panic!("id returned multiple times to the pool"); + }, + Err(index) => { + let current_range = &mut self.free[index]; + if id + 1 == current_range.start { + current_range.start -= 1; + if index > 0 { + let update_end = current_range.end; + let previous_range = &mut self.free[index - 1]; + if previous_range.end + 1 == id { + previous_range.end = update_end; + self.free.remove(index); + } + } + } + + + + } + } + + } +} diff --git a/core-rust/natives/src/java_util.rs b/core-rust/natives/src/java_util.rs index ef8c486..b6e1b11 100644 --- a/core-rust/natives/src/java_util.rs +++ b/core-rust/natives/src/java_util.rs @@ -10,9 +10,9 @@ pub trait JavaHandle { fn drop_handle(ptr: jlong); } -pub trait JavaHandleContainer { - fn from_handle(&self, ptr: jlong) -> Option; - fn to_handle(&self, from: T) -> jlong; +pub trait JavaHandleContainer<'a, T> { + fn from_handle(&self, ptr: jlong) -> Option<&'a T>; + fn to_handle(&self, from: &'a T) -> jlong; } diff --git a/core-rust/natives/src/lib.rs b/core-rust/natives/src/lib.rs index 58980f9..a428432 100644 --- a/core-rust/natives/src/lib.rs +++ b/core-rust/natives/src/lib.rs @@ -9,3 +9,4 @@ mod math; #[macro_use] extern crate log; mod scene; +mod id_pool; diff --git a/core-rust/natives/src/resource/chunk_mesh_resource.rs b/core-rust/natives/src/resource/chunk_mesh_resource.rs index 8417028..2528c36 100644 --- a/core-rust/natives/src/resource/chunk_mesh_resource.rs +++ b/core-rust/natives/src/resource/chunk_mesh_resource.rs @@ -89,7 +89,6 @@ impl ChunkMeshEntry { 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::() 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::() 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::() as u64)))} - } pub struct ChunkMeshResource { @@ -115,10 +114,6 @@ impl ChunkMeshResource { 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"); let num_elements: u64 = position.len() as u64; let vertex_buffer = device.create_buffer( diff --git a/core-rust/natives/src/scene.rs b/core-rust/natives/src/scene.rs index 3fcdbb9..4b88876 100644 --- a/core-rust/natives/src/scene.rs +++ b/core-rust/natives/src/scene.rs @@ -1,21 +1,82 @@ +use glam::u32; +use jni::sys::jlong; +use crate::id_pool::IDPool; use crate::resource::chunk_mesh_resource::ChunkMeshResource; -use std::sync::Arc; +use crate::ui::{JavaHandle, arc_from_handle, arc_to_handle, arc_dispose_handle}; +use std::sync::{Weak,Arc, Mutex}; -pub struct Scene { - opaque_chunks: Vec> +pub struct SceneChunk { + pub transform: glam::Mat4, + pub mesh: Option>> } -impl Scene { +impl SceneChunk { +} - pub fn cmd_prepare(&mut self) { - +impl JavaHandle> for SceneChunk { + fn from_handle(ptr: jlong) -> Option> { + arc_from_handle(ptr) } - pub fn cmd_dispatch(&mut self) { + fn to_handle(from: Arc) -> jlong { + arc_to_handle(from) + } + fn drop_handle(ptr: jlong) { + arc_dispose_handle::(ptr); } +} - pub fn cmd_queue_opaque_chunk() { +pub struct Scene { + chunk_uniform_buffer: wgpu::Buffer, + + chunk_id_pool: IDPool, + chunk_pool: smallvec::SmallVec<[SceneChunk; 1024]> +} - } + +pub struct ChunkMutator<'a>{ + chunk: &'a SceneChunk, + scene: &'a Scene, + index: u32 } + +impl<'a> ChunkMutator<'a> { + +} + +pub type ChunkHandle = u32; +impl Scene { +// pub fn register_chunk<'a>(&mut self) -> ChunkHandle { +// let chunk_id = self.chunk_id_pool.fetch_id(); +// let new_chunk = SceneChunk { +// transform: glam::Mat4::IDENTITY, +// mesh: None +// }; +// +// match self.chunk_pool.get_mut(chunk_id as usize) { +// Some(view) => { +// (*view) = new_chunk; +// }, +// None => { +// self.chunk_pool.push(new_chunk); +// } +// } +// return chunk_id ; +// } +// +// pub fn return_chunk(&mut self, id: ChunkHandle) { +// self.chunk_id_pool.return_id(id); +// } +// pub fn fetch_chunk<'a>(&'a mut self, id: ChunkHandle) -> ChunkMutator<'a> { +// ChunkMutator { +// chunk: &self.chunk_pool[id as usize], +// scene: self, +// index: id +// } +// } + +} + + +