using System; using System.Runtime.InteropServices; namespace SimpleRayTracer.Interop; internal static unsafe class SrtNative { private const string _DLL = "SimpleRayTracerNative"; internal enum Result : int { Ok = 0, Error = 1, InvalidArgument = 2, OutOfRange = 3, OutOfCapacity = 4, NotFound = 5, } [StructLayout(LayoutKind.Sequential)] internal struct Vec2 { public float x, y; public static Vec2 Of(float x, float y) => new() { x = x, y = y }; } [StructLayout(LayoutKind.Sequential)] internal struct Vec3 { public float x, y, z; public static Vec3 Of(float x, float y, float z) => new() { x = x, y = y, z = z }; } [StructLayout(LayoutKind.Sequential)] internal struct Quat { public float x, y, z, w; public static Quat Identity() => new() { w = 1f }; } [StructLayout(LayoutKind.Sequential)] internal struct Mat4 { // Column-major float[16] public fixed float m[16]; public static Mat4 Identity() { var r = new Mat4(); r.m[0] = 1; r.m[5] = 1; r.m[10] = 1; r.m[15] = 1; return r; } } [StructLayout(LayoutKind.Sequential)] internal struct CameraParams { public Vec3 position; public Quat rotation; public float focal_length; public float size_x; public float aspect_ratio; } [StructLayout(LayoutKind.Sequential)] internal struct DirectionalLight { public Vec3 direction; public Vec3 color; public float intensity; public float angular_diameter; } [StructLayout(LayoutKind.Sequential)] internal struct TextureHandle { public ushort id; public static TextureHandle Invalid() => new() { id = 0xFFFF }; } [StructLayout(LayoutKind.Sequential)] internal struct MaterialHandle { public byte id; } [StructLayout(LayoutKind.Sequential)] internal struct StandardLitProperties { public Vec3 albedo; public float diffuse_roughness; public float roughness; public float metallic; public TextureHandle albedo_texture; public TextureHandle normal_texture; public TextureHandle roughness_texture; public TextureHandle metallic_texture; } internal enum TextureWrapMode : uint { Repeat = 0, Clamp = 1, } internal enum TextureFilterMode : uint { Nearest = 0, Linear = 1, } internal enum TextureStride : uint { UInt8 = 1, UInt16 = 2, Float32 = 4, } [StructLayout(LayoutKind.Sequential)] internal struct RenderingConfig { public uint width; public uint height; public uint sample_count; public byte max_depth; public uint bucket_size; } [StructLayout(LayoutKind.Sequential)] internal struct Vertex { public Vec3 position; public Vec3 normal; public Vec3 tangent; public Vec3 color; public Vec2 uv; } [StructLayout(LayoutKind.Sequential)] internal struct Triangle { public Vertex v0; public Vertex v1; public Vertex v2; public uint material_id; } [StructLayout(LayoutKind.Sequential)] internal struct MeshHandle { public uint model_id; public uint instance_id; public ulong triangle_id; public ulong triangle_count; public ushort material_id; public ushort material_count; } internal enum SkyKind : uint { None = 0, Constant = 1, Hdr = 2, } [StructLayout(LayoutKind.Sequential)] internal struct SkyDesc { public uint kind; public uint data_size; public void* data; } [StructLayout(LayoutKind.Sequential)] internal struct SkyConstantDesc { public Vec3 color; public float intensity; } [StructLayout(LayoutKind.Sequential)] internal struct SkyHdrDesc { public TextureHandle hdri; public float intensity; } [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr srt_scene_create(ulong triangle_count, ushort texture_count, byte material_count, uint punctual_light_count); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern void srt_scene_destroy(IntPtr scene); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_commit(IntPtr scene); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_camera_set(IntPtr scene, CameraParams* @params); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_add_directional_light(IntPtr scene, DirectionalLight* light, out uint id); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_create_standard_lit_material(IntPtr scene, StandardLitProperties* props, Vec3 emission, out MaterialHandle mat); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_texture_load(IntPtr scene, [MarshalAs(UnmanagedType.LPUTF8Str)] string filename, byte srgb, byte mipmap, uint stride, out TextureHandle texture); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_texture_set_sampler(IntPtr scene, TextureHandle texture, uint wrapMode, uint filterMode); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_set_sky_none(IntPtr scene); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_set_sky(IntPtr scene, SkyDesc* desc); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_set_sky_constant(IntPtr scene, Vec3 color, float intensity); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_set_sky_hdr(IntPtr scene, TextureHandle hdri, float intensity); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_add_mesh_model(IntPtr scene, ulong triangle_reserve, out uint model_id); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_mesh_model_set_triangles(IntPtr scene, uint model_id, Triangle* triangles, uint triangle_count); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_add_mesh_instance(IntPtr scene, uint model_id, Mat4* local_to_world, out uint instance_id); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_scene_load_mesh(IntPtr scene, [MarshalAs(UnmanagedType.LPUTF8Str)] string filename_utf8, out MeshHandle mesh); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_render_job_create( IntPtr scene, RenderingConfig* config, uint aov_flags, uint rendering_mode, uint seed, out IntPtr job); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern void srt_render_job_destroy(IntPtr job); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_render_job_start(IntPtr job); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern void srt_render_job_request_stop(IntPtr job); // C bool is 1 byte; use byte to avoid marshaling mismatches. [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_render_job_is_done(IntPtr job, out byte done); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_render_job_get_aov_desc(IntPtr job, uint aov_index, out uint width, out uint height, out uint strideBytes); [DllImport(_DLL, CallingConvention = CallingConvention.Cdecl)] internal static extern Result srt_render_job_copy_aov_bgra8(IntPtr job, uint aov_index, byte* dst, uint dstStrideBytes); internal const uint SRT_AOV_BEAUTY = 1u << 0; internal const uint SRT_RENDER_TILE_BASED = 1; internal const uint SRT_AOV_BEAUTY_INDEX = 0; }