### Install Linux Libraries for Input
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.LinuxFramebuffer/README.md
Installs necessary libraries for keyboard/mouse input handling on Debian/Ubuntu systems. Ensure these are installed before running the program if input is required.
```bash
apt install libudev1 libinput10 libxkbcommon0
```
--------------------------------
### Install iOS Workload
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
Installs the necessary .NET workload for iOS development. This command is required before building and running iOS applications.
```bash
sudo dotnet workload install ios
```
--------------------------------
### Enable Detailed Build Diagnostics
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
Add these parameters to the `dotnet build` command to get more detailed error output and diagnostic information. This is useful for troubleshooting build issues.
```bash
dotnet build -v diag /p:WarningLevel=4 --tl:off
```
--------------------------------
### Install dotnet-xcsync Tool
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
Installs the dotnet-xcsync tool, which is used for generating and synchronizing Xcode projects for .NET MAUI iOS applications. Ensure you are using a compatible .NET version (e.g., .NET 9).
```bash
dotnet tool install dotnet-xcsync -g --prerelease --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json
```
--------------------------------
### Configure PATH for .NET Core SDK Tools
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
Appends the .NET Core SDK tools directory to the PATH environment variable in the user's zprofile. This ensures that tools like xcsync are accessible from the terminal. The path '/Users/abenedik/.dotnet/tools' should be adjusted if your .NET installation is in a different location.
```bash
cat << \EOF >> ~/.zprofile
# Add .NET Core SDK tools
export PATH="$PATH:/Users/abenedik/.dotnet/tools"
EOF
```
--------------------------------
### Blazor WebAssembly Project Configuration (.csproj)
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.BlazorWebAssembly/README.md
Configure your Blazor WebAssembly project's .csproj file to enable unsafe code, set Emscripten flags for WebGL, and enable SIMD instructions. This setup is crucial for Ab4d.SharpEngine.Web to function correctly.
```xml
true-lGL -s FULL_ES3=1 -sMAX_WEBGL_VERSION=2true
```
```xml
```
--------------------------------
### Generate Xcode Project with xcsync
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
Generates the Xcode project for a .NET iOS application for the first time. This command is typically run after installing and configuring the xcsync tool.
```bash
xcsync generate --target-framework-moniker net9.0-ios --open
```
--------------------------------
### Run macOS Sample
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
Execute a specific macOS project from the SharpEngine samples directory using the .NET CLI. The '--project' parameter can be omitted if there's only one project in the folder.
```bash
dotnet run --project Ab4d.SharpEngine.Samples.AvaloniaUI.macos.csproj
```
--------------------------------
### Initialize SharpEngine from JavaScript
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.AspNetCoreApp/README.md
This JavaScript code demonstrates the process of initializing the .NET WebAssembly runtime and then calling a .NET exported function to set up the SharpEngine and generate a 3D scene.
```javascript
var dotNetRuntime = null;
async function main() {
const { getAssemblyExports,嬋 } = await DotnetRuntime.loadWasm('output/Ab4d.SharpEngine.Samples.WebAssemblyDemo.dll');
dotNetRuntime =嬋;
const exports = getAssemblyExports('Ab4d.SharpEngine.Samples.WebAssemblyDemo.dll');
exports.JavaScriptInterop.InitSharpEngineJSExport();
}
main();
```
--------------------------------
### Image Asset File Naming Conventions
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.UnoPlatform/Ab4d.SharpEngine.Samples.UnoPlatform/Assets/SharedAssets.md
Illustrates common file naming patterns for images with different scale factors, suitable for various platforms. Ensure assets are placed in the 'Assets' directory and have a 'Content' build action.
```text
\Assets\Images\logo.scale-100.png
\Assets\Images\logo.scale-200.png
\Assets\Images\logo.scale-400.png
\Assets\Images\scale-100\logo.png
\Assets\Images\scale-200\logo.png
\Assets\Images\scale-400\logo.png
```
--------------------------------
### Generated Resource Class Structure
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.Android.Application/Resources/AboutResources.txt
This is an example of the 'Resource' class generated by the Android build system. It contains nested classes for different resource types (Drawable, Layout, Strings) with constants representing resource IDs.
```csharp
public class Resource {
public class Drawable {
public const int icon = 0x123;
}
public class Layout {
public const int main = 0x456;
}
public class Strings {
public const int first_string = 0xabc;
public const int second_string = 0xbcd;
}
}
```
--------------------------------
### Configure Debugging for Subfolder Deployment
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.BlazorWebAssembly/README.md
Add `commandLineArgs` and `launchUrl` to each profile in `Properties/launchSettings.json` to enable debugging the Blazor WebAssembly app when it's configured to run in a subfolder.
```json
"commandLineArgs": "--pathbase=/sharp-engine-browser-demo",
"launchUrl": "sharp-engine-browser-demo"
```
--------------------------------
### Include Raw Assets in .csproj
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.Maui/Resources/Raw/AboutAssets.txt
Use the `MauiAsset` build action in your .csproj file to include raw assets from the Resources\Raw directory and its subdirectories. The `LogicalName` ensures assets are deployed with their original directory structure and filename.
```xml
```
--------------------------------
### Run RenderFormSample
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.WinForms/Titles/RenderFormSample.md
Uncomment this code in Program.cs to run the RenderFormSample. Ensure SamplesForm is commented out.
```csharp
//Application.Run(new SamplesForm());
// Uncomment to run RenderFormSample:
using (var game = new RenderFormSample())
game.Run();
```
--------------------------------
### Configure .NET WebAssembly Project for Ab4d.SharpEngine
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.WebAssemblyDemo/README.md
Essential .csproj configurations for a .NET WebAssembly project targeting Ab4d.SharpEngine. Ensure these properties are set for WebGL support and unsafe code execution.
```xml
net9.0-browserbrowser-wasmExetrue-lGL -s FULL_ES3=1 -sMAX_WEBGL_VERSION=2true
```
--------------------------------
### Fog Shader - Main Function
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.Common/Resources/Shaders/txt/FogShader_Texture.frag.txt
This is the main entry point for the fragment shader. It sets up material properties, samples the diffuse texture, performs alpha clipping, calculates lighting, applies fog, and outputs the final color.
```glsl
#version 450
struct FogMaterial
{
vec4 diffuseColor;
float fogStart;
float fogFullColorStart;
vec3 fogColor;
float alphaClipThreshold;
};
struct Light
{
vec3 pos;
float phi;
vec3 dir;
float theta;
vec3 diffuse;
float falloff;
vec3 spec;
vec3 att;
float range;
};
layout(set = 3, binding = 0, std430) readonly buffer FogMaterialsBuffer
{
FogMaterial materials[];
} materialsBuffer;
layout(set = 0, binding = 0, std140) uniform sceneUniformBuffer
{
mat4 viewProjection;
vec3 eyePosW;
vec2 viewSize;
float dpiScale;
float superSampling;
vec3 ambientColor;
int dirLightStart;
int dirLightCount;
int pointLightStart;
int pointLightCount;
int spotLightStart;
int spotLightCount;
} scene;
layout(set = 1, binding = 0, std430) readonly buffer AllLightsBuffer
{
Light allLights[];
} allLightsBuffer;
layout(push_constant, std430) uniform indexSetup
{
layout(offset = 4) int materialIndex;
} pushConstants;
layout(set = 3, binding = 1) uniform sampler2D samplerDiffuseTexture;
layout(location = 2) in vec2 inUV;
layout(location = 1) in vec3 inNormalW;
layout(location = 0) in vec3 inPosW;
layout(location = 0) out vec4 outColor;
void main()
{
int materialIndex = pushConstants.materialIndex;
int usedMaterialIndex = abs(materialIndex);
FogMaterial material;
material.diffuseColor = materialsBuffer.materials[usedMaterialIndex].diffuseColor;
material.fogStart = materialsBuffer.materials[usedMaterialIndex].fogStart;
material.fogFullColorStart = materialsBuffer.materials[usedMaterialIndex].fogFullColorStart;
material.fogColor = materialsBuffer.materials[usedMaterialIndex].fogColor;
material.alphaClipThreshold = materialsBuffer.materials[usedMaterialIndex].alphaClipThreshold;
vec4 diffuseColor = material.diffuseColor;
diffuseColor *= texture(samplerDiffuseTexture, inUV);
bool _70 = material.alphaClipThreshold > 0.0;
bool _80;
if (_70)
{
_80 = diffuseColor.w < material.alphaClipThreshold;
}
else
{
_80 = _70;
}
if (_80)
{
discard;
}
float multiplyNormal = float(sign(materialIndex));
vec3 normal = normalize(inNormalW) * multiplyNormal;
vec3 toEye = normalize(scene.eyePosW - inPosW);
vec3 finalDiffuseColor = vec3(0.0);
Light oneLightInfo;
for (int iDir = 0; iDir < scene.dirLightCount; iDir++)
{
int _133 = iDir + scene.dirLightStart;
oneLightInfo.pos = allLightsBuffer.allLights[_133].pos;
oneLightInfo.phi = allLightsBuffer.allLights[_133].phi;
oneLightInfo.dir = allLightsBuffer.allLights[_133].dir;
oneLightInfo.theta = allLightsBuffer.allLights[_133].theta;
oneLightInfo.diffuse = allLightsBuffer.allLights[_133].diffuse;
oneLightInfo.falloff = allLightsBuffer.allLights[_133].falloff;
oneLightInfo.spec = allLightsBuffer.allLights[_133].spec;
oneLightInfo.att = allLightsBuffer.allLights[_133].att;
oneLightInfo.range = allLightsBuffer.allLights[_133].range;
vec3 lightVec = -oneLightInfo.dir;
float diffuseFactor = dot(lightVec, normal);
if (diffuseFactor > 0.0)
{
finalDiffuseColor = oneLightInfo.diffuse * diffuseFactor;
}
}
finalDiffuseColor = clamp(finalDiffuseColor + scene.ambientColor, vec3(0.0), vec3(1.0)) * diffuseColor.xyz;
float distanceW = length(scene.eyePosW - inPosW);
float fogFactor = clamp((distanceW - material.fogStart) / (material.fogFullColorStart - material.fogStart), 0.0, 1.0);
finalDiffuseColor = mix(finalDiffuseColor, material.fogColor, vec3(fogFactor));
outColor = clamp(vec4(finalDiffuseColor, diffuseColor.w), vec4(0.0), vec4(1.0));
}
```
--------------------------------
### Configure Blazor WebAssembly for Subfolder Debugging
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
Modify launchSettings.json to run a Blazor WebAssembly app in a subfolder during debugging.
```json
{
"commandLineArgs": "--pathbase=/sharp-engine-browser-demo",
"launchUrl": "sharp-engine-browser-demo"
}
```
--------------------------------
### Load Maui Asset at Runtime
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.Maui/Resources/Raw/AboutAssets.txt
Access deployed raw assets at runtime using `FileSystem.OpenAppPackageFileAsync`. This method returns a stream to the asset, which can then be read using a `StreamReader`.
```csharp
async Task LoadMauiAsset()
{
using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
using var reader = new StreamReader(stream);
var contents = reader.ReadToEnd();
}
```
--------------------------------
### Include libMoltenVK.dylib for macOS
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
This snippet shows how to include the MoltenVK dynamic library for macOS in a .NET project's ItemGroup. It ensures the library is copied to the output directory.
```xml
libMoltenVK.dylib
PreserveNewest
```
--------------------------------
### Include libMoltenVK.dylib for iOS
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
This snippet demonstrates how to include the MoltenVK dynamic library for iOS in a .NET project's ItemGroup. It specifies the path for the iOS build and ensures it's copied to the output.
```xml
libMoltenVK.dylib
PreserveNewest
```
--------------------------------
### Build and Run iOS App
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
Compiles and runs an iOS application on a connected device. Replace 'xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx' with the actual device identifier obtained from Xcode.
```bash
dotnet build -t:Run -p:Configuration=Debug -r ios-arm64 /p:_DeviceName=xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx
```
--------------------------------
### Linking Shared Files in csproj
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
This csproj snippet demonstrates how to link all .cs files from a shared directory and a specific custom file into the current project. Use this to include common code in multiple projects.
```xml
```
--------------------------------
### Enable Logging for Rendering Issues
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
Configure logging levels and destinations to diagnose rendering problems in Ab4d.SharpEngine. Set the desired log level and choose where to output the messages.
```csharp
Ab4d.SharpEngine.Utilities.Log.LogLevel = LogLevels.Warn;
```
```csharp
// Write log messages to the output window (for example, Visual Studio Debug window)
// Ab4d.SharpEngine.Utilities.Log.IsLoggingToDebugOutput = true;
```
```csharp
// Write log to a file
Ab4d.SharpEngine.Utilities.Log.LogFileName = @"c:\SharpEngine.log";
```
```csharp
// Write to a local StringBuilder
private System.Text.StringBuilder _logStringBuilder;
Ab4d.SharpEngine.Utilities.Log.AddLogListener((logLevel, message) => _logStringBuilder.AppendLine(message));
```
```csharp
Ab4d.SharpEngine.Utilities.Log.WriteSimplifiedLogMessage = true;
```
--------------------------------
### Defining Compiler Constants in csproj
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
This csproj snippet shows how to define compiler constants like VULKAN or WEB_GL within the root PropertyGroup. Ensure this definition is not overwritten by later configurations for Debug/Release builds.
```xml
VULKAN
```
```xml
$(DefineConstants);TRACE;DEBUG;
```
--------------------------------
### Razor Component: Creating the 3D Scene
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.BlazorWebAssembly/README.md
Implement the OnAfterRender method in your Razor component to create and initialize the 3D scene. This involves setting up the scene, camera, and event handlers for user interaction.
```csharp
@code {
private SharpEngineSceneView sharpEngineSceneView = null!;
///
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
CreateScene3D();
}
private void CreateScene3D()
{
var scene = sharpEngineSceneView.Scene;
var sceneView = sharpEngineSceneView.SceneView;
var boxModelNode = new BoxModelNode(centerPosition: new Vector3(0, 0, 0), size: new Vector3(100, 40, 80), material: StandardMaterials.Green);
scene.RootNode.Add(boxModelNode);
sceneView.BackgroundColor = Colors.SkyBlue;
sceneView.Camera = new TargetPositionCamera()
{
Heading = 30,
Attitude = -20,
Distance = 300
};
var pointerCameraController = new PointerCameraController(sceneView)
{
RotateCameraConditions = PointerAndKeyboardConditions.LeftPointerButtonPressed,
MoveCameraConditions = PointerAndKeyboardConditions.LeftPointerButtonPressed | PointerAndKeyboardConditions.ControlKey,
ZoomMode = CameraZoomMode.PointerPosition,
RotateAroundPointerPosition = true,
IsPinchZoomEnabled = true, // zoom with touch pinch gesture
IsPinchMoveEnabled = true // move camera with two fingers
};
}
}
```
--------------------------------
### Configure Avalonia Vulkan Backend with Dedicated GPU
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/doc/performance.md
Configures the Avalonia app to use the Vulkan rendering backend and attempts to prioritize the discrete GPU. This is useful for applications that render both UI and 3D graphics using Vulkan.
```csharp
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure()
.UsePlatformDetect()
.With(new Win32PlatformOptions
{
RenderingMode = new[]
{
Win32RenderingMode.Vulkan
}
})
.With(new X11PlatformOptions
{
RenderingMode = new[]
{
X11RenderingMode.Vulkan
}
})
.With(new Avalonia.Vulkan.VulkanOptions()
{
VulkanDeviceCreationOptions = new VulkanDeviceCreationOptions()
{
// When the following option is set, then on a laptop with multiple GPUs
// Avalonia and SharpEngine will use a discrete GPU even if the "High performance"
// is not selected for this app in the Windows Graphics Settings.
//
// It is still recommended to use "High performance" to prevent potential
// copying of the window's content to the primary graphics card.
//
// Comment this setting if you want to use integrated GPU and improve battery life.
PreferDiscreteGpu = true
},
//VulkanInstanceCreationOptions = new Avalonia.Vulkan.VulkanInstanceCreationOptions()
//{
// UseDebug = true // Use Vulkan debug layers for Avalonia UI operations
//}
});
```
--------------------------------
### Configure Base Path in index.html
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.BlazorWebAssembly/README.md
Modify the `` tag in `wwwroot/index.html` to specify the application's base path when deploying to a subfolder. This ensures correct routing and asset loading.
```html
```
--------------------------------
### Configure CodesignKey and CodesignProvision in Project File
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
Adds or updates the CodesignKey and CodesignProvision properties within the iOS project's .csproj file. This step is crucial for enabling automatic code signing when building for iOS.
```xml
Aple Development: axxxxxxk@xxxx.com (XXXXXXX)Automatic
```
--------------------------------
### Common Alias for Platform-Specific Devices
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/README.md
This C# code snippet shows how to use conditional compilation and common aliases (like GpuDevice) to refer to platform-specific device types (VulkanDevice or WebGLDevice) within a single file.
```csharp
#if VULKAN
using Ab4d.Vulkan;
using Ab4d.SharpEngine.Vulkan;
using GpuDevice = Ab4d.SharpEngine.Vulkan.VulkanDevice;
#endif
#if WEB_GL
using Ab4d.SharpEngine.WebGL;
using GpuDevice = Ab4d.SharpEngine.WebGL.WebGLDevice;
#endif
```
```csharp
private void RecreateIndexBuffer(GpuDevice gpuDevice)
```
--------------------------------
### Enable Standard Validation in MainActivity.cs
Source: https://github.com/ab4d/ab4d.sharpengine.samples/blob/main/Ab4d.SharpEngine.Samples.Android.Application/Resources/lib/Vulkan-validation-layers.txt
Set the 'enableStandardValidation' property to true in your MainActivity.cs to activate standard Vulkan validation layers.
```csharp
enableStandardValidation = true;
```