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 dd52a3c..af66c2e 100644 --- a/core-rust/natives/src/lib.rs +++ b/core-rust/natives/src/lib.rs @@ -5,3 +5,4 @@ mod ui; mod resource; mod jni; mod math; +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); } }