Skip to content

Conversation

@hydra
Copy link

@hydra hydra commented Dec 13, 2025

Hi, i tried out BlueEngine today and had some success, but was met with quite a few failures too.

This PR shows the changes I made in order to create a headless_loop example.

However, there were issues:

  1. it didn't seem possible to exit the main update_loop, I fixed this by adjusting the return type of the closure that's passed to update_loop so it returns ControlFlow, thus there was no way to exit gracefully from the application.
  2. the colors of the shapes are not as expected, the results don't match the values passed to the set_color according to method signatures.
  3. the rotating triangle disappears from the output on some frames.
image
  1. rotation on the cube doesn't apply till the 4th frame.

log (from raspberry pi 5):

/home/makerpnp/.cargo/bin/cargo run --color=always --example headless_loop --no-default-features --features "static_link headless" --profile release
    Finished `release` profile [optimized] target(s) in 0.35s
     Running `target/release/examples/headless_loop`
rotation: 12.000001deg
frame 1, elapsed: 56ms, frame_duration: 56ms
rotation: 24.000002deg
frame 2, elapsed: 98ms, frame_duration: 41ms
rotation: 36deg
frame 3, elapsed: 137ms, frame_duration: 38ms
rotation: 48.000004deg
frame 4, elapsed: 167ms, frame_duration: 30ms
rotation: 60deg
frame 5, elapsed: 197ms, frame_duration: 30ms
rotation: 72deg
frame 6, elapsed: 230ms, frame_duration: 32ms
rotation: 84deg
frame 7, elapsed: 270ms, frame_duration: 40ms
rotation: 96.00001deg
frame 8, elapsed: 305ms, frame_duration: 34ms
rotation: 108.00001deg
frame 9, elapsed: 351ms, frame_duration: 46ms
rotation: 120deg
frame 10, elapsed: 396ms, frame_duration: 45ms
rotation: 132deg
frame 11, elapsed: 422ms, frame_duration: 25ms
rotation: 144deg
frame 12, elapsed: 446ms, frame_duration: 24ms
rotation: 156deg
frame 13, elapsed: 476ms, frame_duration: 29ms
rotation: 168deg
frame 14, elapsed: 507ms, frame_duration: 31ms
rotation: 180deg
frame 15, elapsed: 534ms, frame_duration: 26ms
rotation: 192.00002deg
frame 16, elapsed: 566ms, frame_duration: 32ms
rotation: 204deg
frame 17, elapsed: 592ms, frame_duration: 26ms
rotation: 216.00002deg
frame 18, elapsed: 617ms, frame_duration: 24ms
rotation: 228deg
frame 19, elapsed: 642ms, frame_duration: 25ms
rotation: 240deg
frame 20, elapsed: 667ms, frame_duration: 24ms
rotation: 252deg
frame 21, elapsed: 695ms, frame_duration: 28ms
rotation: 264deg
frame 22, elapsed: 720ms, frame_duration: 24ms
rotation: 276deg
frame 23, elapsed: 746ms, frame_duration: 26ms
rotation: 288deg
frame 24, elapsed: 775ms, frame_duration: 29ms
rotation: 300deg
frame 25, elapsed: 801ms, frame_duration: 26ms
rotation: 312deg
frame 26, elapsed: 827ms, frame_duration: 25ms
rotation: 324deg
frame 27, elapsed: 853ms, frame_duration: 26ms
rotation: 336deg
frame 28, elapsed: 880ms, frame_duration: 27ms
rotation: 348deg
frame 29, elapsed: 907ms, frame_duration: 26ms
rotation: 360deg
frame 30, elapsed: 933ms, frame_duration: 26ms
Done!, took 934ms

log from Windows 11 (AMD 5950X + NVidia 4090)

rotation: 12.000001deg
frame 1, elapsed: 7ms, frame_duration: 7ms
rotation: 24.000002deg
frame 2, elapsed: 14ms, frame_duration: 6ms
rotation: 36deg
frame 3, elapsed: 20ms, frame_duration: 6ms
rotation: 48.000004deg
frame 4, elapsed: 26ms, frame_duration: 6ms
rotation: 60deg
frame 5, elapsed: 32ms, frame_duration: 6ms
rotation: 72deg
frame 6, elapsed: 39ms, frame_duration: 6ms
rotation: 84deg
frame 7, elapsed: 47ms, frame_duration: 7ms
rotation: 96.00001deg
frame 8, elapsed: 53ms, frame_duration: 6ms
rotation: 108.00001deg
frame 9, elapsed: 59ms, frame_duration: 5ms
rotation: 120deg
frame 10, elapsed: 66ms, frame_duration: 7ms
rotation: 132deg
frame 11, elapsed: 73ms, frame_duration: 6ms
rotation: 144deg
frame 12, elapsed: 80ms, frame_duration: 6ms
rotation: 156deg
frame 13, elapsed: 86ms, frame_duration: 6ms
rotation: 168deg
frame 14, elapsed: 93ms, frame_duration: 6ms
rotation: 180deg
frame 15, elapsed: 99ms, frame_duration: 6ms
rotation: 192.00002deg
frame 16, elapsed: 105ms, frame_duration: 6ms
rotation: 204deg
frame 17, elapsed: 112ms, frame_duration: 6ms
rotation: 216.00002deg
frame 18, elapsed: 119ms, frame_duration: 6ms
rotation: 228deg
frame 19, elapsed: 125ms, frame_duration: 5ms
rotation: 240deg
frame 20, elapsed: 131ms, frame_duration: 6ms
rotation: 252deg
frame 21, elapsed: 137ms, frame_duration: 6ms
rotation: 264deg
frame 22, elapsed: 144ms, frame_duration: 6ms
rotation: 276deg
frame 23, elapsed: 150ms, frame_duration: 6ms
rotation: 288deg
frame 24, elapsed: 157ms, frame_duration: 6ms
rotation: 300deg
frame 25, elapsed: 163ms, frame_duration: 6ms
rotation: 312deg
frame 26, elapsed: 170ms, frame_duration: 6ms
rotation: 324deg
frame 27, elapsed: 177ms, frame_duration: 6ms
rotation: 336deg
frame 28, elapsed: 183ms, frame_duration: 6ms
rotation: 348deg
frame 29, elapsed: 189ms, frame_duration: 6ms
rotation: 360deg
frame 30, elapsed: 196ms, frame_duration: 6ms
Done!, took 196ms

I'm providing this feedback in the form of a draft PR, I don't expect you to merge this directly, since addtional changes are required - feel free to fix this up or make other changes.

@Gipson62
Copy link
Contributor

Gipson62 commented Dec 13, 2025

Damn, crazy PR, very good work. And I would say the issue of object disappearing is partially happening in this loop. Potentially related to the bind group logic. The other potential issue would be the culling used by wgpu hiding the triangle, but I doubt that.

@ElhamAryanpur
Copy link
Collaborator

Amazing work! Thank you so much, I really appreciate this!

Gipson is right, the wgpu usualy culls backface by default hence why when triangle is rotated backwards, it disappears. This can be set in ObjectSettings, I'll look into it myself too since I was planning for an overhaul to them.

About the cube not moving, that is a good point, I should look into that. Thank you!

@ElhamAryanpur
Copy link
Collaborator

I should look into colors as well. The colors are passed directly, but it could also have been texture color formats as well causing it 👀

@ElhamAryanpur ElhamAryanpur added the enhancement New feature or request label Dec 14, 2025
@ElhamAryanpur
Copy link
Collaborator

I see that this is a breaking change by default since it requires a ControlFlow return. It may do good to have it optional instead. Let me investigate

@ElhamAryanpur
Copy link
Collaborator

After a lot of investigating, the best way in my opinion would be to remove it from the return type and rather set it in the engine as a field instead. This helps both not break backwards compatibility, but also allows users to not require to set it on every loop as well.

Closest thing that would've worked as return would've been a struct with From<()> implemented, but even then it'd require ().into() to be called every time.

@ElhamAryanpur
Copy link
Collaborator

679410d

Also fixed the triangle not displaying issue

@Gipson62
Copy link
Contributor

Maybe it's kind of stupid, but why not making it possible for everyone, be it headless or not, to break from the update loop? Why should it be restricted only to headless mode? What if I wanted to do it on a game? It wouldn't be that much of an issue to allow it globally

@ElhamAryanpur
Copy link
Collaborator

ElhamAryanpur commented Dec 14, 2025

non headless mode already has it, with engine.window.should_close I believe.

There are many reasons as to why theres a difference, but simplest reason is that the windowed version's loop is controlled by winit, hence why it is based on window to close itself

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants