canvas.rs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. use std::sync::Arc;
  2. use dioxus::prelude::*;
  3. use dioxus_native::SharedNativeTexture;
  4. use wgpu::{
  5. core::instance, Extent3d, ImageCopyTexture, ImageCopyTextureBase, InstanceDescriptor, Origin3d,
  6. TextureAspect, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
  7. };
  8. fn main() {
  9. dioxus::launch(app);
  10. }
  11. fn app() -> Element {
  12. let width = 500;
  13. let height = 500;
  14. use_future(move || attach_egui(width, height));
  15. rsx! {
  16. div {
  17. h1 { "Hello native canvas" }
  18. canvas {
  19. id: "egui-demo",
  20. width: "{width}",
  21. height: "{height}",
  22. style: "border: 1px solid black;",
  23. }
  24. }
  25. }
  26. }
  27. async fn attach_egui(width: u32, height: u32) {
  28. let document = dioxus_native::document();
  29. let instance = wgpu::Instance::default();
  30. let surface = instance.create_surface(document.window_handle()).unwrap();
  31. let adapter = instance
  32. .request_adapter(&wgpu::RequestAdapterOptions {
  33. power_preference: wgpu::PowerPreference::default(),
  34. force_fallback_adapter: false,
  35. compatible_surface: Some(&surface),
  36. })
  37. .await
  38. .unwrap();
  39. let (device, _queue) = adapter
  40. .request_device(
  41. &wgpu::DeviceDescriptor {
  42. label: None,
  43. required_features: wgpu::Features::empty(),
  44. // Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain.
  45. required_limits: wgpu::Limits::downlevel_webgl2_defaults()
  46. .using_resolution(adapter.limits()),
  47. memory_hints: wgpu::MemoryHints::Performance,
  48. },
  49. None,
  50. )
  51. .await
  52. .expect("Failed to create device");
  53. let texture = device.create_texture(&TextureDescriptor {
  54. label: Some("egui-demo"),
  55. format: TextureFormat::Rgba32Float,
  56. usage: TextureUsages::RENDER_ATTACHMENT,
  57. size: Extent3d {
  58. width,
  59. height,
  60. depth_or_array_layers: 1,
  61. },
  62. mip_level_count: 1,
  63. sample_count: 1,
  64. dimension: TextureDimension::D2,
  65. view_formats: &[],
  66. });
  67. let copy_texture = ImageCopyTextureBase {
  68. texture: Arc::new(texture),
  69. mip_level: 1,
  70. origin: Origin3d { x: 0, y: 0, z: 0 },
  71. aspect: TextureAspect::All,
  72. };
  73. document.set_custom_texture(
  74. "egui-demo",
  75. SharedNativeTexture {
  76. inner: copy_texture,
  77. },
  78. );
  79. // todo - handle resize events!
  80. futures_util::future::pending::<()>().await;
  81. }