Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upAdd UI framework #441
Conversation
Xaeroxe
added
diff: medium
project: rendering
status: working
type: feature
and removed
diff: medium
labels
Oct 22, 2017
| +const FRAG_SRC: &[u8] = include_bytes!("frag.glsl"); | ||
| + | ||
| +#[derive(Copy, Clone)] | ||
| +#[allow(dead_code)] // This is used by the shaders |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +/// | ||
| +/// TODO: Eventually this should be either replaced by a citrine type, or citrine may just | ||
| +/// populate it. | ||
| +pub struct UiTransform { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 22, 2017
Member
Maybe we should limit this to the size and take the position from Transform?
torkleyy
Oct 22, 2017
Member
Maybe we should limit this to the size and take the position from Transform?
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 22, 2017
Member
I feel it's probably important to keep the concepts separate as this is in pixels, whereas Transform uses unspecified units.
Xaeroxe
Oct 22, 2017
Member
I feel it's probably important to keep the concepts separate as this is in pixels, whereas Transform uses unspecified units.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 22, 2017
Member
Okay, true. But if we already have that advantage, we should really do
pub enum Dimension {
/// In pixels
Absolute(f32),
/// Multiplied with window width / height
Relative(f32),
}
torkleyy
Oct 22, 2017
Member
Okay, true. But if we already have that advantage, we should really do
pub enum Dimension {
/// In pixels
Absolute(f32),
/// Multiplied with window width / height
Relative(f32),
}
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Aceeri
Oct 22, 2017
Member
I'm thinking amethyst_ui might just be glue between citrine and our renderer, this could probably be replaced by just using Position and Bounds components and hooking those up to the amethyst renderer.
Aceeri
Oct 22, 2017
•
Member
I'm thinking amethyst_ui might just be glue between citrine and our renderer, this could probably be replaced by just using Position and Bounds components and hooking those up to the amethyst renderer.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 22, 2017
Member
@torkleyy I was mostly just trying to sidestep the design decisions we talked about on gitter before. This structure's purpose is to be replaced, it's meant to be slightly sub-optimal.
Xaeroxe
Oct 22, 2017
Member
@torkleyy I was mostly just trying to sidestep the design decisions we talked about on gitter before. This structure's purpose is to be replaced, it's meant to be slightly sub-optimal.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Example doesn't work yet, probably have to fix my broken shaders. |
| - light, | ||
| - ): ( | ||
| - Option<Fetch<'a, Camera>>, | ||
| + (active, camera, ambient, mesh_storage, tex_storage, material_defaults, |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 23, 2017
Member
That formatting was merged in from @Rhuagh 's PR, but I still have more code to write here so I'll give it a rustfmt pass again.
Xaeroxe
Oct 23, 2017
Member
That formatting was merged in from @Rhuagh 's PR, but I still have more code to write here so I'll give it a rustfmt pass again.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
So what's the current status of this PR @Xaeroxe ? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 25, 2017
Member
Still requires additional work, I won't have time to work on it for a few days though.
|
Still requires additional work, I won't have time to work on it for a few days though. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 25, 2017
Member
(If anyone wants to push this to completion I gladly accept PRs on my PR)
|
(If anyone wants to push this to completion I gladly accept PRs on my PR) |
Xaeroxe
and others
added some commits
Oct 21, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 28, 2017
Member
Z-ordering tested and works
Had to add resizing to blend targets to fix resize issue.
I'm now starting work on a text component.
|
Z-ordering tested and works I'm now starting work on a text component. |
Xaeroxe
added some commits
Oct 28, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Broken by upstream changes, fixing now. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 29, 2017
Member
So while there's a lot of things I want to add here and there's many improvements to be made, this is useful in its current form, so I'm going to remove the WIP. We can merge this as is, and I'll work on adding the features I want in subsequent PRs.
|
So while there's a lot of things I want to add here and there's many improvements to be made, this is useful in its current form, so I'm going to remove the WIP. We can merge this as is, and I'll work on adding the features I want in subsequent PRs. |
Xaeroxe
changed the title from
[WIP] UI
to
Add UI framework
Oct 29, 2017
Xaeroxe
added
status: ready
and removed
status: working
labels
Oct 29, 2017
Xaeroxe
added some commits
Oct 29, 2017
Xaeroxe
added some commits
Oct 29, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Aceeri
Oct 30, 2017
Member
@Xaeroxe Do we want to keep the placeholder position component for now and just integrate the citrine Position one later?
|
@Xaeroxe Do we want to keep the placeholder position component for now and just integrate the citrine Position one later? |
| + | ||
| +/// UI bundle | ||
| +/// | ||
| +/// Will register all necessary components and systems needed for UI, along with any resources. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 30, 2017
Member
We should really list the stuff here. (I know this hasn't been done in the past)
torkleyy
Oct 30, 2017
Member
We should really list the stuff here. (I know this hasn't been done in the past)
| +use specs::{Entities, Entity, Fetch, Join, ParJoin, ReadStorage}; | ||
| + | ||
| +use super::*; | ||
| +use amethyst_renderer::{Mesh, MeshHandle}; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
I'll give this a full review tomorrow. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 30, 2017
Member
@Aceeri Probably yes, since citrine has a little ways to go before integrating into here and this is better than the nothing we have in Amethyst right now.
|
@Aceeri Probably yes, since citrine has a little ways to go before integrating into here and this is better than the nothing we have in Amethyst right now. |
Aceeri
approved these changes
Oct 31, 2017
Awesome stuff! Now I just need to get off my ass and start working on the layout stuff again.
| @@ -164,6 +163,7 @@ where | ||
| { | ||
| fn run_now(&mut self, res: &'a Resources) { | ||
| self.do_asset_loading(AssetLoadingData::<'a>::fetch(res, 0)); | ||
| + self.do_window_management(WindowData::<'a>::fetch(res, 0)); | ||
| self.do_render(RenderData::<'a, P>::fetch(res, 0)); |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Aceeri
Oct 31, 2017
Member
Minor nitpicking but these methods should probably just be render and manage_window or something. do_... seems redundant given they are methods.
Aceeri
Oct 31, 2017
Member
Minor nitpicking but these methods should probably just be render and manage_window or something. do_... seems redundant given they are methods.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 31, 2017
Member
I was just following the convention set from before, but sure I can do that.
Xaeroxe
Oct 31, 2017
Member
I was just following the convention set from before, but sure I can do that.
torkleyy
self-requested a review
Oct 31, 2017
torkleyy
requested changes
Oct 31, 2017
Great work @Xaeroxe ! I looked into it very closely, which is why you'll have 26 comments to address now
| + type Storage = DenseVecStorage<Self>; | ||
| +} | ||
| + | ||
| +/// This system renders `UiTex`t. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + /// | ||
| + /// Do not try and replace this while the inner function is being called. Whatever you put | ||
| + /// here would be overwritten. | ||
| + pub resize_fn: Option<Box<FnMut(&mut UiTransform, (f32, f32)) + Send + Sync>>, |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 31, 2017
Member
It might be worth considering to move this into a separate component. Additionally, maybe we can make it an enum which includes standard strategies? Except @Aceeri provides some citrine stuff handling it, that is.
torkleyy
Oct 31, 2017
Member
It might be worth considering to move this into a separate component. Additionally, maybe we can make it an enum which includes standard strategies? Except @Aceeri provides some citrine stuff handling it, that is.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + resize_fn: None, | ||
| + }; | ||
| + let p2_size_fn = |transform: &mut UiTransform, (width, _height)| { | ||
| + transform.x = (width / 2.) + 100. - transform.width / 2.; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 31, 2017
Member
Yeah, this isn't very nice. I guess some sort of basic layouting would be nice; not suggesting to do it in this PR though.
torkleyy
Oct 31, 2017
Member
Yeah, this isn't very nice. I guess some sort of basic layouting would be nice; not suggesting to do it in this PR though.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 31, 2017
Member
Personally I like how flexible this approach is and how easy it makes prototyping but this particular implementation did end up kind of hairy.
Xaeroxe
Oct 31, 2017
Member
Personally I like how flexible this approach is and how easy it makes prototyping but this particular implementation did end up kind of hairy.
| @@ -34,10 +37,20 @@ impl<'s> System<'s> for WinnerSystem { | ||
| let did_hit = if ball_x <= ball.radius { | ||
| // Right player scored on the left side. | ||
| score_board.score_right += 1; | ||
| + for (transform, text) in (&ui_transform, &mut text).join() { | ||
| + if "P2" == transform.id { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 31, 2017
Member
Entities should be used for this. While having a name for entities (which I btw. planned to implement in Specs: you would be able to just do world.create_entity().name("Blah") then) is nice, I don't think we should recommend it for component identification purposes.
torkleyy
Oct 31, 2017
Member
Entities should be used for this. While having a name for entities (which I btw. planned to implement in Specs: you would be able to just do world.create_entity().name("Blah") then) is nice, I don't think we should recommend it for component identification purposes.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 31, 2017
Member
I guess I like the getElementById from JavaScript and I was trying to mimic that here. It's nice being able to just keep things in your head and request for static values rather than having to store the entity, but storing the entity is also more efficient, so I'll go with that.
Xaeroxe
Oct 31, 2017
Member
I guess I like the getElementById from JavaScript and I was trying to mimic that here. It's nice being able to just keep things in your head and request for static values rather than having to store the entity, but storing the entity is also more efficient, so I'll go with that.
| + | ||
| +const SPHERE_COLOUR: [f32; 4] = [0.0, 0.0, 1.0, 1.0]; // blue | ||
| +const AMBIENT_LIGHT_COLOUR: Rgba = Rgba(0.01, 0.01, 0.01, 1.0); // near-black | ||
| +const POINT_LIGHT_COLOUR: Rgba = Rgba(1.0, 1.0, 1.0, 1.0); // white |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 31, 2017
Member
This was copy pasted from the sphere example, should I change it there too?
Xaeroxe
Oct 31, 2017
Member
This was copy pasted from the sphere example, should I change it there too?
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + let proj_vec = vec2( | ||
| + 2. / screen_dimensions.width(), | ||
| + -2. / screen_dimensions.height(), | ||
| + ).extend(-2.) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 31, 2017
Member
Yeah I'm not sure using extend here was the best idea, so I'll fix this.
Xaeroxe
Oct 31, 2017
Member
Yeah I'm not sure using extend here was the best idea, so I'll fix this.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + vertex.position *= vec4(dimension, 1, 1); | ||
| + vertex.position += vec4(coord, 0, 0); | ||
| + vertex.position *= proj_vec; | ||
| + vertex.position += vec4(-1, 1, 0, 0); |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 31, 2017
Member
I'm not sure if we can measure GPU performance in terms of how often a multiplication is happening, but rather how typical and thus optimized it is for a certain situation. So I don't know what's more efficient here, it's just unconventional.
torkleyy
Oct 31, 2017
Member
I'm not sure if we can measure GPU performance in terms of how often a multiplication is happening, but rather how typical and thus optimized it is for a certain situation. So I don't know what's more efficient here, it's just unconventional.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 31, 2017
Member
So I did this because @omni-viral and @Rhuagh told me the projection matrix was excessive.
Xaeroxe
Oct 31, 2017
Member
So I did this because @omni-viral and @Rhuagh told me the projection matrix was excessive.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Rhuagh
Oct 31, 2017
Member
You can even reduce it further using vec2 and swizzle operators if you want.
Rhuagh
Oct 31, 2017
Member
You can even reduce it further using vec2 and swizzle operators if you want.
| + if let Some(mesh) = mesh_storage.get(unit_mesh) { | ||
| + let vbuf = match mesh.buffer(PosTex::ATTRIBUTES) { | ||
| + Some(vbuf) => vbuf.clone(), | ||
| + None => continue, |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 31, 2017
Member
The same applies for the check above, let's return and decrease the indention.
torkleyy
Oct 31, 2017
Member
The same applies for the check above, let's return and decrease the indention.
| + &mut self.text | ||
| + } | ||
| + | ||
| + /// The RGBA color with a maximum of 1.0 and a minimum of 0.0 for each channel of the text. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + ); | ||
| + | ||
| + fn run(&mut self, (transform, mut text, loader, tex_storage, font_storage): Self::SystemData) { | ||
| + for (transform, text) in (&transform, &mut text).join() { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 31, 2017
Member
I'm not sure if this is a more general problem, but if a text doesn't have a transform, it will be silently ignored. No need to fix it here, just wanted to note.
torkleyy
Oct 31, 2017
Member
I'm not sure if this is a more general problem, but if a text doesn't have a transform, it will be silently ignored. No need to fix it here, just wanted to note.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
r? @torkleyy |
| + // Populate and update the draw order cache. | ||
| + // TODO: Replace all of this with code taking advantage of specs::TrackedStorage. | ||
| + // TrackedStorage doesn't exist yet but it will in a later version of specs. | ||
| + cached_draw_order.retain(|&(_z, entity)| { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Rhuagh
Oct 31, 2017
Member
Is it really worth it to cache this data and not just recalculate it per frame ? The loop below is best case n^2, because position will potentially go through all items in the cache, plus a sort that's n*log(n). Wouldn't it be faster to use binary_search_by and do insertion sort and create the list from scratch every frame? That would be a guaranteed n*log(n).
Rhuagh
Oct 31, 2017
•
Member
Is it really worth it to cache this data and not just recalculate it per frame ? The loop below is best case n^2, because position will potentially go through all items in the cache, plus a sort that's n*log(n). Wouldn't it be faster to use binary_search_by and do insertion sort and create the list from scratch every frame? That would be a guaranteed n*log(n).
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 31, 2017
Member
@Rhuagh Yeah you're right this eventually turned out to be not quite what was desired. I have a couple ideas on how to fix it though. First is to introduce a private AtomicBool to the UiTransform indicating if it was added to the cache or not, taking our n^2 operation down to just n.
Caching the sorting is valuable imo because sorting an already sorted collection is very cheap.
Xaeroxe
Oct 31, 2017
•
Member
@Rhuagh Yeah you're right this eventually turned out to be not quite what was desired. I have a couple ideas on how to fix it though. First is to introduce a private AtomicBool to the UiTransform indicating if it was added to the cache or not, taking our n^2 operation down to just n.
Caching the sorting is valuable imo because sorting an already sorted collection is very cheap.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Rhuagh
Oct 31, 2017
Member
I agree, it's just when the cache update is more expensive than rebuilding the whole thing I get suspicious :P TrackedStorage and insertion sort on z would turn it into nlogn worst case
Rhuagh
Oct 31, 2017
Member
I agree, it's just when the cache update is more expensive than rebuilding the whole thing I get suspicious :P TrackedStorage and insertion sort on z would turn it into nlogn worst case
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 31, 2017
Member
r? @Rhuagh
I've tightened up the caching a lot, it uses bitset to be much more efficient now.
|
r? @Rhuagh I've tightened up the caching a lot, it uses bitset to be much more efficient now. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Much better, thanks |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Nov 1, 2017
Member
@torkleyy After adding the new and improved cache I've determined TrackedStorage would actually be a detriment here instead of an advantage as the new cache is actually faster, (mostly because it takes advantage of things we can only do with this particular setup)
|
@torkleyy After adding the new and improved cache I've determined TrackedStorage would actually be a detriment here instead of an advantage as the new cache is actually faster, (mostly because it takes advantage of things we can only do with this particular setup) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Nov 1, 2017
Member
You are cloning ui_transform's bitset 3 times, I think you could reduce that to 1.
|
You are cloning |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Nov 1, 2017
Member
What I don't like about FlaggedStorage is that components get flagged on iteration, not on change. That's my main motivation for TrackedStorage.
|
What I don't like about |
torkleyy
approved these changes
Nov 1, 2017
I commented on the commit which changes the caching, otherwise I think it's great.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Since bitset cloning is pretty cheap I'm going to bors r+ |
bot
added a commit
that referenced
this pull request
Nov 1, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
bors r- |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Canceled |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Nov 1, 2017
Member
@torkleyy has informed me that bit set clones are not cheap. I'll fix this in the morning
|
@torkleyy has informed me that bit set clones are not cheap. I'll fix this in the morning |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
bors r+ |
bot
added a commit
that referenced
this pull request
Nov 1, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bors
bot
merged commit b8d0103
into
amethyst:develop
Nov 1, 2017
Xaeroxe
deleted the
Xaeroxe:ui
branch
Nov 1, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
remram44
commented
Nov 1, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Nov 1, 2017
Member
Oh right, the blend targets still don't work on Mac. I forgot about that. I'll fix it before we release. That's not a problem with anything UI related, it's a problem with using a rendering pass with blending, interestingly this only occurs on OSX.
|
Oh right, the blend targets still don't work on Mac. I forgot about that. I'll fix it before we release. That's not a problem with anything UI related, it's a problem with using a rendering pass with blending, interestingly this only occurs on OSX. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
I wrote up #473 to address this. |



Xaeroxe commentedOct 22, 2017
•
edited
Edited 5 times
-
Xaeroxe
edited Oct 29, 2017 (most recent)
-
Xaeroxe
edited Oct 29, 2017
-
Xaeroxe
edited Oct 29, 2017
-
Xaeroxe
edited Oct 29, 2017
-
Xaeroxe
edited Oct 22, 2017
Work done in this PR: