-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add example on docs and /examples folder #66
Conversation
// Turn SPRITE into an array of pixels in the right colorspace | ||
let sprite: [Rgb565; 256] = SPRITE.map(|(r, g, b)| Rgb565::new(r, g, b)); | ||
|
||
// Draw the 16*16 sprite on the top left corner of the screen | ||
display.set_pixels(0, 0, 15, 15, sprite).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty inefficient, because the sprite
array needs to be build in RAM. I'm biased and would simply use embedded-graphics to draw an image, but if you want to demonstrate set_pixels
I would suggest to change the SPRITE
constant to be SPRITE: [Rgb565; 256]
instead.
In addition to that the SPRITE
constant seems to use values between 0 and 255 while Rgb565
expects 5 or 6 bit values depending on the channel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did want to demonstrate how map
can be used to turn a regular array into an array of RgbXYZ colors, but it does make more sense to just use embedded-graphics
I will change this.
I will also add more to the example, drawing a smily face or something similar to demonstrate the use of embedded-graphics
instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to make this an example of using set_pixels
I'm OK with that, but the example should make it clear that there are other options available. For more memory constrained targets the array in RAM could be a problem for larger images.
You don't need an array, because set_pixels
takes an iter: display.set_pixels(0, 0, 15, 15, SPRITE.map(|(r, g, b)| Rgb565::new(r, g, b))).unwrap();
should also work, without the memory overhead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opted to use const SPRITE: [Rgb565; 256] = [Rgb565::RED, Rgb565::ORANGE ...
instead with fill_contiguous
, since I just wanted to demonstrate how it is possible to use a custom sprite. If this is okay you can resolve the conversation. Otherwise do suggest something
src/lib.rs
Outdated
@@ -179,6 +179,23 @@ where | |||
/// * `ey` - y coordinate end | |||
/// * `colors` - anything that can provide `IntoIterator<Item = u16>` to iterate over pixel data | |||
/// | |||
/// # Example |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to improve the docs for set_pixel
further:
One thing that is important to document IMO is the behavior of set_pixels
if the colors
iterator contains more pixels than required by the rectangle bounds. If I remember correctly there is no bounds checking and the drawing operation would just wrap back to the top left of the rectangle.
This is different to embedded-graphics
's similar fill_contiguous
method and should be highlighted. Because this makes it impossible to just use something like display.set_pixel(0, 0, 10, 10, core::iter::repeat(Rgb565::RED))
, which works in e-g.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is different to embedded-graphics's similar
fill_contiguous
method and should be highlighted
I added a # Warning
here » mentioning that using fill_contiguous
instead is recommended. Does this sound good or should I highlight that in another way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move it to above the argument list and rephrase it a bit. It's quite important to know the behavior of and IMO it's harder to notice the warning if it is below the example.
Instead of a warning I would just describe the behavior of this method. A rough draft of a description:
No bounds checking is performed on the
colors
iterator, which can lead to unexpected behavior if the iterator returns more or less color values than the number of pixels in the given update region. Usefill_contiguous
fromembedded-graphics
as an alternative with bounds checking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One note here is that set_pixels
is essentially a driver primitive. It's not meant to be used directly and is exposed so frameworks other than embedded-graphics
can be used.
Changes included on the latest commit:
|
display.clear(Rgb565::BLACK).unwrap(); | ||
|
||
// draw the 16*16 sprite on the top left corner of the screen | ||
display.fill_contiguous(&sprite_rectangle, SPRITE).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't normally recommend to use the methods in DrawTarget
directly in user code, but I'm not sure what the best option is in this case. The "embedded-graphics way" of drawing an image would be to use ImageRaw
and Image
, but that wouldn't work with the way you initialize the SPRITE
constant, because ImageRaw
expects a byte array. Perhaps we just leave it is now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is best to make the examples as 'correct' on the usage as possible, since they're made to demonstrate how things are intended to be done.
Maybe this example can be left as a 'possibility', but I think an example using ImageRaw
and Image
is important, since drawing custom sprites to the screen is probably a common use for the crate.
To be fair though, this is done by embedded-graphics
so maybe it's out of scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would either remove the image drawing from this example or change it to something that is easy to use. Drawing pixels from an array that is manually added to the code isn't very common IMO.
Using the tinybmp
instead of ImageRaw
would make it much easier for a user to generate the necessary image data, because they can just export a BMP file from an image editor like Gimp. The BMP format does also natively support RGB565 colors, which makes it a good fit for the used display. See the tinybmp
for an example how to use it: https://github.com/embedded-graphics/tinybmp#draw-a-bmp-image-to-an-embedded-graphics-draw-target
Regardless of whether we decide to remove the image drawing or not, a link to the embedded-graphics
example would be a good idea to get an overview of the possible drawing operations: https://docs.rs/embedded-graphics/latest/embedded_graphics/examples/index.html
src/lib.rs
Outdated
@@ -179,6 +179,23 @@ where | |||
/// * `ey` - y coordinate end | |||
/// * `colors` - anything that can provide `IntoIterator<Item = u16>` to iterate over pixel data | |||
/// | |||
/// # Example |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move it to above the argument list and rephrase it a bit. It's quite important to know the behavior of and IMO it's harder to notice the warning if it is below the example.
Instead of a warning I would just describe the behavior of this method. A rough draft of a description:
No bounds checking is performed on the
colors
iterator, which can lead to unexpected behavior if the iterator returns more or less color values than the number of pixels in the given update region. Usefill_contiguous
fromembedded-graphics
as an alternative with bounds checking.
Changes included on the latest commit:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but I'll wait for @rfuest to +1 as well
src/lib.rs
Outdated
@@ -179,6 +179,23 @@ where | |||
/// * `ey` - y coordinate end | |||
/// * `colors` - anything that can provide `IntoIterator<Item = u16>` to iterate over pixel data | |||
/// | |||
/// # Example |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One note here is that set_pixels
is essentially a driver primitive. It's not meant to be used directly and is exposed so frameworks other than embedded-graphics
can be used.
display.clear(Rgb565::BLACK).unwrap(); | ||
|
||
// draw the 16*16 sprite on the top left corner of the screen | ||
display.fill_contiguous(&sprite_rectangle, SPRITE).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would either remove the image drawing from this example or change it to something that is easy to use. Drawing pixels from an array that is manually added to the code isn't very common IMO.
Using the tinybmp
instead of ImageRaw
would make it much easier for a user to generate the necessary image data, because they can just export a BMP file from an image editor like Gimp. The BMP format does also natively support RGB565 colors, which makes it a good fit for the used display. See the tinybmp
for an example how to use it: https://github.com/embedded-graphics/tinybmp#draw-a-bmp-image-to-an-embedded-graphics-draw-target
Regardless of whether we decide to remove the image drawing or not, a link to the embedded-graphics
example would be a good idea to get an overview of the possible drawing operations: https://docs.rs/embedded-graphics/latest/embedded_graphics/examples/index.html
I do agree with the fact that the Adding a link to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, except for a missing word in one of the comments. Thanks for your efforts to improve the examples and docs. It's sometimes hard to know what is missing if you are already very familiar with the create.
Both locations would make sense, some users might learn about the crate via the README while others read the docs first. The README already contains a reference to e-g with this sentence: "embedded-graphics-core is used to provide the drawing API.", but that isn't very useful for users of the crate IMO. The distinction between |
Co-authored-by: Ralf Fuest <[email protected]>
Why
As mentioned in #65, two improvements that could be made were adding another example project and expanding documentation on
set_pixels()
Changes included
Adds another example to the
/examples
folder.set_pixels()
can be usedAdds an example to the
set_pixels()
on the docs