Open NorthWindH opened 4 years ago
Thanks for getting in touch @NorthWindH, it's really nice to see people reading about my experiments/projects! Especially when they've done this sort of thing before.
You're 100% correct that RenderSystem::run()
will be called really frequently. It's essentially the top-level render()
function that'll be called whenever the drawing updates (or rather, the caller changed things and wants the canvas to be redrawn).
My "integration testing" so far has been to compile the library to WebAssembly (in debug mode :ROFL:) and hook it up to a HTML canvas, then make sure clicking on the canvas draws a dot under the cursor (it didn't... I'm guessing my maths for converting from HTML canvas coordinates with a zoomed/scaled viewport to drawing coordinates is buggy). I did pretty much the bare minimum to ensure z-order is accounted for, but I'll definitely want to use some of the tricks you mention once I start using the demo application on larger drawings.
How did you deal with situations where the viewport would change rapidly (e.g. scrolling in or out, or panning)? This is intended for a 2D CAD application so items will normally be created/removed to the world at "human" speeds, which is easy to keep up with, but when you zoom or pan it's quite easy to go from displaying 10 objects to 1000. I'm guessing under those circumstances you just need to take the cost of recomputing which items are within the viewport because there's no way out of it?
I'm also taking "render list" to be the list of items which are within the viewport and meant to be rendered, instead of something like a BSP or quad tree which is a data structure containing everything in the world organised by location, regardless of whether it would be rendered... Is that correct?
The specs
crate has a feature for detecting when a component is changed (inserted, deleted, or accessed via a mutable reference) and I was thinking of leveraging that to recalculate the render list with the latest changes on every tick. We currently do something similar to automatically recalculate an object's axis-aligned bounding box... I believe it will store changes in some sort of buffered channel so the runtime cost of detecting a change should amortize to adding and removing an Id
(u32
under the hood, I believe) from a ring buffer.
Hey just read the article that was on hacker news, linked to here I think: http://adventures.michaelfbryan.com/posts/ecs-outside-of-games/
Looked at the code, looks like these lines are likely what's slowing things down: https://github.com/Michael-F-Bryan/arcs/blob/42d5a77f461dc138de17a13823f8bfbdb0bbe7ce/arcs/src/render/renderer.rs#L253-L258
And it looks like this gets used here? https://github.com/Michael-F-Bryan/arcs/blob/42d5a77f461dc138de17a13823f8bfbdb0bbe7ce/arcs/src/render/renderer.rs#L151-L168
So it looks like that calculate function has a high likelihood of running in the hot loop. Apologies for the questions, I'm not very proficient in rust.
We have some experience with this in our graphics engine (C++). A few suggestions:
That's most of what comes to mind. Hopefully it helps. Happy to chat further. Cheers!