5 Commits

Author SHA1 Message Date
5c988108ef Fixed genergy conservation problem in specular lobe 2025-12-31 03:12:29 +09:00
84b2504a6f Updated api 2025-12-31 00:43:04 +09:00
f1d3dddb9a Change project structure;
Added new c# binding;
2025-12-30 20:54:05 +09:00
5f5404268c Added blas-tlas;
Added Multi-Scattering GGX;
2025-12-30 15:25:16 +09:00
bfd06bdd11 Refactor the codebase and add aov support. 2025-12-30 01:20:41 +09:00
398 changed files with 5334 additions and 361070 deletions

365
.gitignore vendored
View File

@@ -1 +1,366 @@
[Bb]uild/ [Bb]uild/
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
.vscode/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +0,0 @@
#ifndef PATH_TRACING_H
#define PATH_TRACING_H
#include "Algorithm/RayIntersection.h"
#include "Material/Material.h"
#include "Geometry/Triangle.h"
#include "Rendering/AOV.h"
#include "Rendering/Scene.h"
vec4s path_trace(const scene_t* scene, ray_t ray, uint32_t sample_index, uint16_t max_depth);
void render_aov(const scene_t* scene, ray_t ray, uint32_t sample_index, uint16_t max_depth, aov_output_t* aov_output);
#endif // PATH_TRACING_H

View File

@@ -1,26 +0,0 @@
#ifndef SCENE_H
#define SCENE_H
#include "Algorithm/BVH.h"
#include "Camera.h"
#include "Lighting/Light.h"
#include "Material/Material.h"
#include "Geometry/Triangle.h"
#include "Rendering/RenderTarget.h"
#include "Rendering/Texture.h"
typedef struct
{
camera_t camera;
bvh_tree_t bvh_tree;
triangle_collection_t triangles;
material_collection_t materials;
texture_collection_t textures;
light_collection_t lights;
} scene_t;
bool scene_init(scene_t* scene, uint64_t triangle_count, uint16_t texture_count, uint8_t material_count, uint32_t punctual_light_count);
bool scene_build_bvh(scene_t* scene);
void scene_free(scene_t* scene);
#endif // SCENE_H

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Application
x:Class="SimpleRayTracer.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SimpleRayTracer">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.UI.Xaml.Shapes;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace SimpleRayTracer
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : Application
{
private Window? _window;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
InitializeComponent();
}
/// <summary>
/// Invoked when the application is launched.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
_window = new MainWindow();
_window.Activate();
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,147 @@
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
namespace SimpleRayTracer.Interop;
internal sealed partial class InteropSmokeTest : IDisposable
{
private SrtScene? _scene;
private SrtRenderJob? _job;
private WriteableBitmap? _bitmap;
private byte[]? _scratchBgra;
public WriteableBitmap Bitmap => _bitmap ?? throw new InvalidOperationException("Not started");
private static Quaternion FromEulerDegrees(Vector3 degrees)
{
var radians = degrees * (MathF.PI / 180f);
var cy = MathF.Cos(radians.Z * 0.5f);
var sy = MathF.Sin(radians.Z * 0.5f);
var cp = MathF.Cos(radians.Y * 0.5f);
var sp = MathF.Sin(radians.Y * 0.5f);
var cr = MathF.Cos(radians.X * 0.5f);
var sr = MathF.Sin(radians.X * 0.5f);
return new Quaternion
{
W = cr * cp * cy + sr * sp * sy,
X = sr * cp * cy - cr * sp * sy,
Y = cr * sp * cy + sr * cp * sy,
Z = cr * cp * sy - sr * sp * cy,
};
}
public void StartAsync(uint width = 640, uint height = 360)
{
if (_scene is not null || _job is not null)
throw new InvalidOperationException("Already started");
_scene = SrtScene.Create(triangleCount: 0, textureCount: 1, materialCount: 8, punctualLightCount: 1);
// Camera similar to native defaults: at (0,0,5) looking towards -Z.
_scene.SetCamera(position: new Vector3(-7.5f, 2.5f, 0.0f), rotation: FromEulerDegrees(new Vector3(10, -90, 0)), focalLength: 0.025f, sizeX: 0.036f, aspectRatio: width / (float)height);
// Basic sky so we don't render into black/undefined environment.
_scene.SetSky(SrtSky.Constant(new Vector3(1, 1, 1), intensity: 1.0f));
// Directional light
var lightDir = Vector3.Normalize(new Vector3(0.6f, 1.0f, 0.25f));
_scene.AddDirectionalLight(direction: lightDir, color: new Vector3(1.0f, 0.93f, 0.87f), intensity: 2.0f, angularDiameter: 0.53f);
_scene.LoadMeshFromFile("F:/c/SimpleRayTracer/native/assets/sponza.fbx");
_scene.Commit();
_job = _scene.CreateRenderJob(width: width, height: height, sampleCount: 64, maxDepth: 4, bucketSize: 64, seed: 1);
_bitmap = new WriteableBitmap((int)width, (int)height);
// Run renderer on background thread.
_ = Task.Run(() =>
{
try
{
_job.StartBlocking();
}
catch (Exception ex)
{
// No UI exception throwing from background thread; this is a smoke test.
System.Diagnostics.Debug.WriteLine($"Native render failed: {ex}");
}
});
}
public unsafe void CopyLatestToBitmap()
{
if (_job is null || _bitmap is null)
return;
// Ensure we have enough capacity
var res = SrtNative.srt_render_job_get_aov_desc(_job.Handle, SrtNative.SRT_AOV_BEAUTY_INDEX, out var w, out var h, out _);
if (res != SrtNative.Result.Ok)
return;
if ((uint)_bitmap.PixelWidth != w || (uint)_bitmap.PixelHeight != h)
{
// Bitmap size mismatch (shouldn't happen in this smoke test).
return;
}
var pixelBuffer = _bitmap.PixelBuffer;
var expectedBytes = checked(w * h * 4u);
if (pixelBuffer.Length < expectedBytes)
{
// Unexpected: WriteableBitmap pixel buffer is smaller than required.
return;
}
// Fast path: try raw pointer write (true zero-copy into PixelBuffer).
if (WinRtBufferByteAccess.TryGetPointer(pixelBuffer, out var dst) && dst != null)
{
_job.CopyBeautyBgra8(dst, w * 4);
}
else
{
// Fallback: stream write. Still avoids per-frame allocations by reusing a scratch buffer.
int n = checked((int)expectedBytes);
_scratchBgra ??= new byte[n];
if (_scratchBgra.Length != n)
{
_scratchBgra = new byte[n];
}
fixed (byte* tmp = _scratchBgra)
{
_job.CopyBeautyBgra8(tmp, w * 4);
}
using var stream = pixelBuffer.AsStream();
stream.Position = 0;
stream.Write(_scratchBgra, 0, _scratchBgra.Length);
}
_bitmap.Invalidate();
}
public bool IsDone
{
get
{
if (_job is null)
return true;
return _job.IsDone;
}
}
public void Dispose()
{
_job?.Dispose();
_job = null;
_scene?.Dispose();
_scene = null;
}
}

View File

@@ -0,0 +1,295 @@
using System;
using System.Numerics;
using System.IO;
namespace SimpleRayTracer.Interop;
internal sealed class SrtScene : IDisposable
{
internal IntPtr Handle { get; private set; }
public static SrtScene Create(ulong triangleCount, ushort textureCount, byte materialCount, uint punctualLightCount)
{
var h = SrtNative.srt_scene_create(triangleCount, textureCount, materialCount, punctualLightCount);
if (h == IntPtr.Zero)
throw new InvalidOperationException("srt_scene_create failed (native DLL not found or init failed)");
return new SrtScene(h);
}
private SrtScene(IntPtr handle) => Handle = handle;
public void SetCamera(Vector3 position, Quaternion rotation, float focalLength, float sizeX, float aspectRatio)
{
unsafe
{
var cam = new SrtNative.CameraParams
{
position = SrtNative.Vec3.Of(position.X, position.Y, position.Z),
rotation = new SrtNative.Quat { x = rotation.X, y = rotation.Y, z = rotation.Z, w = rotation.W },
focal_length = focalLength,
size_x = sizeX,
aspect_ratio = aspectRatio,
};
ThrowIfNotOk(SrtNative.srt_scene_camera_set(Handle, &cam));
}
}
public void SetSky(SrtSky sky)
{
if (sky is null) throw new ArgumentNullException(nameof(sky));
sky.Apply(this);
}
public uint AddDirectionalLight(Vector3 direction, Vector3 color, float intensity, float angularDiameter)
{
unsafe
{
var l = new SrtNative.DirectionalLight
{
direction = SrtNative.Vec3.Of(direction.X, direction.Y, direction.Z),
color = SrtNative.Vec3.Of(color.X, color.Y, color.Z),
intensity = intensity,
angular_diameter = angularDiameter,
};
ThrowIfNotOk(SrtNative.srt_scene_add_directional_light(Handle, &l, out var id));
return id;
}
}
public SrtNative.MaterialHandle CreateStandardLitMaterial(Vector3 albedo, float roughness, float diffuseRoughness, float metallic,
SrtNative.TextureHandle albedoTexture, SrtNative.TextureHandle normalTexture, SrtNative.TextureHandle roughnessTexture, SrtNative.TextureHandle metallicTexture,
Vector3 emission)
{
unsafe
{
var props = new SrtNative.StandardLitProperties
{
albedo = SrtNative.Vec3.Of(albedo.X, albedo.Y, albedo.Z),
roughness = roughness,
diffuse_roughness = diffuseRoughness,
metallic = metallic,
albedo_texture = albedoTexture,
normal_texture = normalTexture,
roughness_texture = roughnessTexture,
metallic_texture = metallicTexture,
};
ThrowIfNotOk(SrtNative.srt_scene_create_standard_lit_material(
Handle,
&props,
SrtNative.Vec3.Of(emission.X, emission.Y, emission.Z),
out var mat));
return mat;
}
}
public uint AddMeshModel(ulong triangleReserve)
{
ThrowIfNotOk(SrtNative.srt_scene_add_mesh_model(Handle, triangleReserve, out var id));
return id;
}
public void SetMeshTriangles(uint modelId, ReadOnlySpan<SrtNative.Triangle> triangles)
{
unsafe
{
fixed (SrtNative.Triangle* p = triangles)
{
ThrowIfNotOk(SrtNative.srt_scene_mesh_model_set_triangles(Handle, modelId, p, (uint)triangles.Length));
}
}
}
public uint AddMeshInstance(uint modelId, in SrtNative.Mat4 localToWorld)
{
unsafe
{
fixed (SrtNative.Mat4* p = &localToWorld)
{
ThrowIfNotOk(SrtNative.srt_scene_add_mesh_instance(Handle, modelId, p, out var instanceId));
return instanceId;
}
}
}
public void Commit() => ThrowIfNotOk(SrtNative.srt_scene_commit(Handle));
public SrtNative.TextureHandle LoadTextureFromFile(string path, bool srgb = true, bool mipmap = true, SrtNative.TextureStride stride = SrtNative.TextureStride.UInt8)
{
if (path is null) throw new ArgumentNullException(nameof(path));
path = ResolveAssetPath(path);
ThrowIfNotOk(SrtNative.srt_scene_texture_load(
Handle,
path,
srgb: (byte)(srgb ? 1 : 0),
mipmap: (byte)(mipmap ? 1 : 0),
stride: (uint)stride,
out var tex));
return tex;
}
public SrtNative.MeshHandle LoadMeshFromFile(string path)
{
if (path is null) throw new ArgumentNullException(nameof(path));
path = ResolveAssetPath(path);
ThrowIfNotOk(SrtNative.srt_scene_load_mesh(Handle, path, out var mesh));
return mesh;
}
private static string ResolveAssetPath(string path)
{
if (Path.IsPathRooted(path))
return path;
// Prefer app base directory (WinUI packaged/unpackaged), then fall back to CWD.
var baseDir = AppContext.BaseDirectory;
var candidate = Path.GetFullPath(Path.Combine(baseDir, path));
if (File.Exists(candidate))
return candidate;
candidate = Path.GetFullPath(path);
return candidate;
}
public SrtRenderJob CreateRenderJob(uint width, uint height, uint sampleCount, byte maxDepth, uint bucketSize, uint seed,
uint aovFlags = SrtNative.SRT_AOV_BEAUTY, uint renderingMode = SrtNative.SRT_RENDER_TILE_BASED)
{
unsafe
{
var cfg = new SrtNative.RenderingConfig
{
width = width,
height = height,
sample_count = sampleCount,
max_depth = maxDepth,
bucket_size = bucketSize,
};
ThrowIfNotOk(SrtNative.srt_render_job_create(Handle, &cfg, aovFlags, renderingMode, seed, out var job));
return new SrtRenderJob(job);
}
}
public void Dispose()
{
if (Handle != IntPtr.Zero)
{
SrtNative.srt_scene_destroy(Handle);
Handle = IntPtr.Zero;
}
}
internal static void ThrowIfNotOk(SrtNative.Result r)
{
if (r != SrtNative.Result.Ok)
throw new InvalidOperationException($"Native call failed: {r}");
}
}
internal sealed class SrtRenderJob : IDisposable
{
public IntPtr Handle { get; private set; }
internal SrtRenderJob(IntPtr handle) => Handle = handle;
public void StartBlocking() => SrtScene.ThrowIfNotOk(SrtNative.srt_render_job_start(Handle));
public bool IsDone
{
get
{
var r = SrtNative.srt_render_job_is_done(Handle, out var done);
return r == SrtNative.Result.Ok && done != 0;
}
}
public unsafe void CopyBeautyBgra8(byte* dst, uint dstStrideBytes)
{
_ = SrtNative.srt_render_job_copy_aov_bgra8(Handle, SrtNative.SRT_AOV_BEAUTY_INDEX, dst, dstStrideBytes);
}
public void Dispose()
{
if (Handle != IntPtr.Zero)
{
SrtNative.srt_render_job_request_stop(Handle);
SrtNative.srt_render_job_destroy(Handle);
Handle = IntPtr.Zero;
}
}
}
internal abstract class SrtSky
{
internal abstract unsafe void Apply(SrtScene scene);
public static SrtSky None() => new NoneSky();
public static SrtSky Constant(Vector3 color, float intensity) => new ConstantSky(color, intensity);
public static SrtSky Hdr(SrtNative.TextureHandle hdri, float intensity) => new HdrSky(hdri, intensity);
private sealed class NoneSky : SrtSky
{
internal override unsafe void Apply(SrtScene scene)
{
var desc = new SrtNative.SkyDesc { kind = (uint)SrtNative.SkyKind.None, data_size = 0, data = null };
SrtScene.ThrowIfNotOk(SrtNative.srt_scene_set_sky(scene.Handle, &desc));
}
}
private sealed class ConstantSky : SrtSky
{
private readonly Vector3 _color;
private readonly float _intensity;
public ConstantSky(Vector3 color, float intensity)
{
_color = color;
_intensity = intensity;
}
internal override unsafe void Apply(SrtScene scene)
{
var cd = new SrtNative.SkyConstantDesc
{
color = SrtNative.Vec3.Of(_color.X, _color.Y, _color.Z),
intensity = _intensity,
};
var desc = new SrtNative.SkyDesc
{
kind = (uint)SrtNative.SkyKind.Constant,
data_size = (uint)sizeof(SrtNative.SkyConstantDesc),
data = &cd,
};
SrtScene.ThrowIfNotOk(SrtNative.srt_scene_set_sky(scene.Handle, &desc));
}
}
private sealed class HdrSky : SrtSky
{
private readonly SrtNative.TextureHandle _hdri;
private readonly float _intensity;
public HdrSky(SrtNative.TextureHandle hdri, float intensity)
{
_hdri = hdri;
_intensity = intensity;
}
internal override unsafe void Apply(SrtScene scene)
{
var hd = new SrtNative.SkyHdrDesc { hdri = _hdri, intensity = _intensity };
var desc = new SrtNative.SkyDesc
{
kind = (uint)SrtNative.SkyKind.Hdr,
data_size = (uint)sizeof(SrtNative.SkyHdrDesc),
data = &hd,
};
SrtScene.ThrowIfNotOk(SrtNative.srt_scene_set_sky(scene.Handle, &desc));
}
}
}

View File

@@ -0,0 +1,277 @@
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;
}

View File

@@ -0,0 +1,93 @@
using System;
using System.Runtime.InteropServices;
using Windows.Storage.Streams;
using WinRT;
namespace SimpleRayTracer.Interop;
// Allows zero-copy access to WriteableBitmap.PixelBuffer.
internal static class WinRtBufferByteAccess
{
private static readonly Guid IID_IBufferByteAccess = new("905a0fef-bc53-11df-8c49-001e4fc686da");
public static unsafe bool TryGetPointer(IBuffer buffer, out byte* ptr)
{
ptr = null;
if (buffer is null)
{
return false;
}
var unk = IntPtr.Zero;
var releaseUnk = false;
var acc = IntPtr.Zero;
try
{
if (buffer is not IWinRTObject winrt)
{
return false;
}
unk = winrt.NativeObject.ThisPtr;
if (unk == IntPtr.Zero)
{
return false;
}
Marshal.AddRef(unk);
releaseUnk = true;
var iid = IID_IBufferByteAccess;
var hr = Marshal.QueryInterface(unk, in iid, out acc);
if (hr < 0 || acc == IntPtr.Zero)
{
return false;
}
// vtable: [0]=QI, [1]=AddRef, [2]=Release, [3]=Buffer
var vtbl = *(IntPtr*)acc;
var bufferFnPtr = *((IntPtr*)vtbl + 3);
if (bufferFnPtr == IntPtr.Zero)
{
return false;
}
// IMPORTANT: COM uses stdcall on Windows.
var bufferFn = (delegate* unmanaged[Stdcall]<IntPtr, IntPtr*, int>)bufferFnPtr;
var raw = IntPtr.Zero;
hr = bufferFn(acc, &raw);
if (hr < 0 || raw == IntPtr.Zero)
{
return false;
}
ptr = (byte*)raw;
return true;
}
finally
{
if (acc != IntPtr.Zero)
{
Marshal.Release(acc);
}
if (releaseUnk && unk != IntPtr.Zero)
{
Marshal.Release(unk);
}
}
}
public static unsafe byte* GetPointerOrThrow(IBuffer buffer)
{
if (!TryGetPointer(buffer, out var ptr))
{
throw new NotSupportedException("WriteableBitmap.PixelBuffer does not expose IBufferByteAccess in this configuration.");
}
return ptr;
}
}

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="SimpleRayTracer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SimpleRayTracer"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="SimpleRayTracer">
<Window.SystemBackdrop>
<MicaBackdrop />
</Window.SystemBackdrop>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Spacing="12" Margin="12">
<Button x:Name="RunSmokeTestButton" Content="Run Interop Smoke Test" Click="RunSmokeTestButton_Click" />
<TextBlock x:Name="StatusText" VerticalAlignment="Center" />
</StackPanel>
<ScrollViewer Grid.Row="1" Margin="12">
<Image x:Name="RenderImage" Stretch="Uniform" />
</ScrollViewer>
</Grid>
</Window>

View File

@@ -0,0 +1,62 @@
using System;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using SimpleRayTracer.Interop;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace SimpleRayTracer
{
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainWindow : Window
{
private InteropSmokeTest? _smoke;
private DispatcherQueueTimer? _timer;
public MainWindow()
{
InitializeComponent();
}
private void RunSmokeTestButton_Click(object sender, RoutedEventArgs e)
{
RunSmokeTestButton.IsEnabled = false;
StatusText.Text = "Starting...";
try
{
_timer?.Stop();
_timer = null;
_smoke?.Dispose();
_smoke = new InteropSmokeTest();
_smoke.StartAsync(width: 640, height: 360);
RenderImage.Source = _smoke.Bitmap;
StatusText.Text = "Rendering...";
_timer = DispatcherQueue.CreateTimer();
_timer.Interval = TimeSpan.FromMilliseconds(33);
_timer.Tick += (_, _) =>
{
_smoke?.CopyLatestToBitmap();
if (_smoke?.IsDone == true)
{
StatusText.Text = "Done";
_timer?.Stop();
}
};
_timer.Start();
}
catch (Exception ex)
{
StatusText.Text = ex.Message;
RunSmokeTestButton.IsEnabled = true;
}
}
}
}

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="f3ab7e56-7fa5-4a20-a3e7-94cab61bcb0d"
Publisher="CN=Misaki"
Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="f3ab7e56-7fa5-4a20-a3e7-94cab61bcb0d" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>SimpleRayTracer</DisplayName>
<PublisherDisplayName>Misaki</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="SimpleRayTracer"
Description="SimpleRayTracer"
BackgroundColor="transparent"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

View File

@@ -0,0 +1,10 @@
{
"profiles": {
"SimpleRayTracer (Package)": {
"commandName": "MsixPackage"
},
"SimpleRayTracer (Unpackaged)": {
"commandName": "Project"
}
}
}

View File

@@ -0,0 +1,77 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>SimpleRayTracer</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x86;x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<PublishProfile>win-$(Platform).pubxml</PublishProfile>
<UseWinUI>true</UseWinUI>
<WinUISDKReferences>false</WinUISDKReferences>
<EnableMsixTooling>true</EnableMsixTooling>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\Square150x150Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\StoreLogo.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251106002" />
<PackageReference Include="WinUIEx" Version="2.9.0" />
</ItemGroup>
<!--
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
Tools extension to be activated for this project even if the Windows App SDK Nuget
package has not yet been restored.
-->
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<ProjectCapability Include="Msix" />
</ItemGroup>
<!--
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
Explorer "Package and Publish" context menu entry to be enabled for this project even if
the Windows App SDK Nuget package has not yet been restored.
-->
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
</PropertyGroup>
<!-- Publish Properties -->
<PropertyGroup>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Content Include="..\..\build\bin\$(Configuration)\SimpleRayTracerNative.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="..\..\build\bin\$(Configuration)\cglm.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="..\..\build\bin\$(Configuration)\assimp-vc143-mt.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,13 @@
<Solution>
<Configurations>
<Platform Name="ARM64" />
<Platform Name="x64" />
<Platform Name="x86" />
</Configurations>
<Project Path="SimpleRayTracer.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
<Platform Solution="*|x86" Project="x86" />
<Deploy />
</Project>
</Solution>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="SimpleRayTracer.app"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- The ID below informs the system that this application is compatible with OS features first introduced in Windows 10.
It is necessary to support features in unpackaged applications, for example the custom titlebar implementation.
For more info see https://docs.microsoft.com/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time#declare-os-compatibility-in-your-application-manifest -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
</assembly>

View File

View File

@@ -14,14 +14,27 @@ set(HEADER_DIR "${CMAKE_SOURCE_DIR}/header")
set(LIBRARY_PATH "${CMAKE_SOURCE_DIR}/lib") set(LIBRARY_PATH "${CMAKE_SOURCE_DIR}/lib")
# Recursively find all .c files in the Sources directory # Recursively find all .c files in the Sources directory
file(GLOB_RECURSE SOURCES "${SOURCE_DIR}/*.c") file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "${SOURCE_DIR}/*.c")
add_executable(${PROJECT_NAME} WIN32 ${SOURCES}) # App sources (exclude interop exports; those live in the Native DLL)
set(APP_SOURCES ${SOURCES})
list(FILTER APP_SOURCES EXCLUDE REGEX ".*/Interop/SrtInterop\\.c$")
add_executable(${PROJECT_NAME} WIN32 ${APP_SOURCES})
# Native DLL for C# interop (keeps existing exe target intact)
set(NATIVE_SOURCES ${SOURCES})
# Exclude the app entrypoint from the DLL
list(FILTER NATIVE_SOURCES EXCLUDE REGEX ".*/[Mm]ain\\.c$")
add_library(${PROJECT_NAME}Native SHARED ${NATIVE_SOURCES})
# Include directories # Include directories
target_include_directories(${PROJECT_NAME} PRIVATE ${EXTERNAL_DIR}) target_include_directories(${PROJECT_NAME} PRIVATE ${EXTERNAL_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${HEADER_DIR}) target_include_directories(${PROJECT_NAME} PRIVATE ${HEADER_DIR})
target_include_directories(${PROJECT_NAME}Native PRIVATE ${EXTERNAL_DIR})
target_include_directories(${PROJECT_NAME}Native PRIVATE ${HEADER_DIR})
# Define imported target for cglm # Define imported target for cglm
add_library(cglm_shared SHARED IMPORTED) add_library(cglm_shared SHARED IMPORTED)
set_target_properties(cglm_shared PROPERTIES set_target_properties(cglm_shared PROPERTIES
@@ -43,17 +56,29 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
assimp_shared assimp_shared
) )
target_link_libraries(${PROJECT_NAME}Native PRIVATE
cglm_shared
assimp_shared
)
# target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBRARY_PATH}/cglm.lib) # target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBRARY_PATH}/cglm.lib)
# target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBRARY_PATH}/assimp-vc143-mt.lib) # target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBRARY_PATH}/assimp-vc143-mt.lib)
if(OpenMP_C_FOUND) if(OpenMP_C_FOUND)
target_link_libraries(${PROJECT_NAME} PRIVATE OpenMP::OpenMP_C) target_link_libraries(${PROJECT_NAME} PRIVATE OpenMP::OpenMP_C)
target_link_libraries(${PROJECT_NAME}Native PRIVATE OpenMP::OpenMP_C)
endif() endif()
set_target_properties(${PROJECT_NAME} PROPERTIES set_target_properties(${PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
) )
set_target_properties(${PROJECT_NAME}Native PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
target_compile_definitions(${PROJECT_NAME}Native PRIVATE SRT_INTEROP_BUILD=1)
if(WIN32) if(WIN32)
add_custom_command( add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD TARGET ${PROJECT_NAME} POST_BUILD
@@ -63,6 +88,15 @@ if(WIN32)
VERBATIM VERBATIM
COMMAND_EXPAND_LISTS COMMAND_EXPAND_LISTS
) )
add_custom_command(
TARGET ${PROJECT_NAME}Native POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_RUNTIME_DLLS:${PROJECT_NAME}Native>
$<TARGET_FILE_DIR:${PROJECT_NAME}Native>
VERBATIM
COMMAND_EXPAND_LISTS
)
endif() endif()
add_custom_command( add_custom_command(

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

View File

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Some files were not shown because too many files have changed in this diff Show More