Last active
January 27, 2025 22:58
-
-
Save westonsoftware/a3fa982397fe1817ece4a27d3cbc5a89 to your computer and use it in GitHub Desktop.
Stride 3D rendered into Avalonia
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Stride.Core.Mathematics; | |
using Stride.Engine; | |
using Stride.Rendering; | |
using Stride.Graphics; | |
using System.IO; | |
namespace InfinityGame | |
{ | |
public class StartScript : SyncScript | |
{ | |
private Random random = new Random(); | |
public override void Start() | |
{ | |
var model = Content.Load<Model>("Sphere"); | |
var size = 100; | |
var count = 1000; | |
for (int i = 0; i < count; i++) | |
{ | |
var modelComponent = new ModelComponent(model); | |
var randomPosition = new Vector3(random.Next(-size, size), random.Next(0, size), random.Next(-size, size)); | |
var entity = new Entity(randomPosition, "NEW"); | |
Entity.Scene.Entities.Add(entity); | |
entity.Add(modelComponent); | |
} | |
Game.Window.Position = new Int2(0, 0); | |
} | |
public override void Update() | |
{ | |
var sprite = Entity.Get<SpriteComponent>(); | |
var texture = sprite.CurrentSprite.Texture; | |
using (var image = texture.GetDataAsImage(Game.GraphicsContext.CommandList)) | |
{ | |
using (var stream = new MemoryStream()) | |
{ | |
image.Save(stream, ImageFileType.Bmp); | |
GlobalEvents.FrameReadyEventKey.Broadcast(stream.ToArray()); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Avalonia.Controls; | |
using Avalonia.Markup.Xaml; | |
using InfinityGame; | |
using Stride.Engine.Events; | |
using System; | |
using System.IO; | |
using System.Windows.Threading; | |
namespace AvaloniaApplication1.Views | |
{ | |
public class UserControl1 : UserControl | |
{ | |
private readonly DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) }; | |
public UserControl1() | |
{ | |
this.InitializeComponent(); | |
} | |
private void InitializeComponent() | |
{ | |
AvaloniaXamlLoader.Load(this); | |
var strideImage = this.Find<Image>("StrideView"); | |
var frameReady = new EventReceiver<byte[]>(GlobalEvents.FrameReadyEventKey); | |
timer.Tick += (s,e) => | |
{ | |
if (frameReady.TryReceive(out byte[] bmp)) | |
{ | |
using var stream = new MemoryStream(bmp); | |
var bitmap = new Avalonia.Media.Imaging.Bitmap(stream); | |
strideImage.Source = bitmap; | |
} | |
}; | |
timer.Start(); | |
} | |
} | |
} |
Hi @westonsoftware @tebjan
I found this gist in Stride community resources, looking for AvaloniaUI integration.
I would like to run a Stride game inside an Avalonia app.
It seems to me that this gist just displays a texture inside an Avalonia image. Is that correct?
Is there a way to render a whole game, like it is documented for WPF?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If anyone is looking for the
GlobalEvents.FrameReadyEventKey
you simply add it to your global events file: https://doc.stride3d.net/4.2/en/manual/scripts/events.htmlFor example:
Also, note that downloading a texture from the GPU is a slow and blocking operation. Stride has a better
TextureReadback
class that at least doesn't block. However, the correct solution would be to create AvaloniaUI with a GPU context, if possible, and share a texture via a shared handle. This would be possible with Angle: AvaloniaUI/Avalonia#5432