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" 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/engine_kernel.rs b/core-rust/natives/src/engine_kernel.rs index b2f072d..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; @@ -25,13 +25,13 @@ pub struct EngineKernel { pub user_interface: RefCell, pub frame_encoder: Mutex>> - } 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/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/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/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..2b55eed 100644 --- a/core-rust/natives/src/lib.rs +++ b/core-rust/natives/src/lib.rs @@ -5,6 +5,8 @@ mod ui; mod resource; mod jni; mod math; - +mod index_pool; #[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 new file mode 100644 index 0000000..2528c36 --- /dev/null +++ b/core-rust/natives/src/resource/chunk_mesh_resource.rs @@ -0,0 +1,232 @@ +use bytemuck::{Pod, Zeroable}; +use smallvec::SmallVec; +use std::sync::{Arc, Mutex}; +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], +}; + + +#[derive(PartialEq, Clone, Copy)] +pub enum MeshRenderType { + Opaque, + Translucent, + Billboard, + WaterAndIce +} + +pub struct ChunkMeshEntry { + render_type: MeshRenderType, + vertex_buffer: wgpu::Buffer, + index_buffer: wgpu::Buffer, + + num_elements: u64, + position_start: u64, + normal_start: u64, + uv_start: u64, + color_start: u64, + attribute_start: u64 +} + +impl ChunkMeshEntry { + 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 { + meshes: SmallVec<[ChunkMeshEntry; 5]>, +} + +impl ChunkMeshResource { + pub fn new() -> Self { + Self { + meshes: SmallVec::new() + } + } + + pub fn set_mesh_resource( + &mut self, + device: &wgpu::Device, + queue: &wgpu::Queue, + render_type: MeshRenderType, + indexes: &[u32], + position: &[ChunkPosition], + normal: &[ChunkNormal], + uv: &[ChunkUV], + color: &[ChunkColor], + attributes: &[ChunkAttributes] + ) { + + let num_elements: u64 = position.len() as u64; + let vertex_buffer = device.create_buffer( + &wgpu::BufferDescriptor { + 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 + ), + usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false + } + ); + + 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); + }, + _ => {} + } + } + + pub 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/scene.rs b/core-rust/natives/src/scene.rs new file mode 100644 index 0000000..4b88876 --- /dev/null +++ b/core-rust/natives/src/scene.rs @@ -0,0 +1,82 @@ +use glam::u32; +use jni::sys::jlong; +use crate::id_pool::IDPool; +use crate::resource::chunk_mesh_resource::ChunkMeshResource; +use crate::ui::{JavaHandle, arc_from_handle, arc_to_handle, arc_dispose_handle}; +use std::sync::{Weak,Arc, Mutex}; + +pub struct SceneChunk { + pub transform: glam::Mat4, + pub mesh: Option>> +} + +impl SceneChunk { +} + +impl JavaHandle> for SceneChunk { + fn from_handle(ptr: jlong) -> Option> { + arc_from_handle(ptr) + } + + fn to_handle(from: Arc) -> jlong { + arc_to_handle(from) + } + + fn drop_handle(ptr: jlong) { + arc_dispose_handle::(ptr); + } +} + +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 +// } +// } + +} + + + 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/src/main/java/org/terasology/engine/rust/EngineKernel.java b/core/src/main/java/org/terasology/engine/rust/EngineKernel.java index 0822b05..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,16 +3,54 @@ 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; + final long rawRustPtr; + + private final Cleaner.Cleanable cleanable; + + static { + NativeSupport.load("core_rust"); + } + + public EngineKernel(EngineKernelBuild builder) { + long kernelPtr = JNI.create(builder); + this.rawRustPtr = kernelPtr; + this.ui = new UIRenderer(this); + this.resource = new ResourceManager(this); + this.cleanable = CLEANER.register(this, () -> { + JNI.drop(kernelPtr); + }); + } + + public void resizeSurface(int width, int height) { + JNI.resizeSurface(rawRustPtr, width, height); + } + + public void cmdPrepare() { + JNI.cmdPrepare(rawRustPtr); + } + + public void cmdDispatch() { + JNI.cmdDispatch(rawRustPtr); + } + + @Override + public long getHandle() { + return rawRustPtr; + } + + @Override + public void dispose() { + this.cleanable.clean(); + } public static final class EngineKernelBuild { private long displayHandle; @@ -39,46 +77,16 @@ public EngineKernelBuild configureWin32Window(long windowHandle, long displayHan } } - public EngineKernel(EngineKernelBuild builder) { - long kernelPtr = JNI.create(builder); - rustKernelPtr = kernelPtr; - this.ui = new UIRenderer(this); - this.resource = new ResourceManager(this); - this.cleanable = CLEANER.register(this, () -> { - JNI.drop(kernelPtr); - }); - } - - static { - NativeSupport.load("core_rust"); - } - - - public void resizeSurface(int width, int height) { - JNI.resizeSurface(rustKernelPtr, width, height); - } - public void cmdPrepare() { - JNI.cmdPrepare(rustKernelPtr); - } - public void cmdDispatch() { - JNI.cmdDispatch(rustKernelPtr); - } - - @Override - public void dispose() { - this.cleanable.clean(); - } - 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); } }