RISC OS Open
A fast and easily customised operating system for ARM devices
ROOL
Home | News | Downloads | Bugs | Bounties | Forum | Documents | Photos | Contact us
Account
Forums → Bounties →

Bounty proposal: Paint

Subscribe to Bounty proposal: Paint 587 posts, 52 voices

Posts per page:

Pages: 1 ... 14 15 16 17 18 19 20 21 22 23 24

 
Aug 13, 2020 7:51am
Avatar Rick Murray (539) 10813 posts

A pixel translation table is an array with one entry for each source colour.

Except going to 32K modes where it is a guard word, a pointer to a table held elsewhere, and another guard word, and even more messy going to 16M modes.
There’s a table and description in PRM 5a on page 5a-120 (or p134 in the document).

but I wrongly thought a transfer function gets used in addition to the table lookup (for rendering)

This seems to imply that it can… https://www.riscosopen.org/wiki/documentation/show/Colour%20Mapping%20Descriptor

 
Aug 13, 2020 8:24am
Avatar Jeffrey Lee (213) 5870 posts
but I wrongly thought a transfer function gets used in addition to the table lookup (for rendering)

This seems to imply that it can… https://www.riscosopen.org/wiki/documentation/show/Colour%20Mapping%20Descriptor

When calling OS_SpriteOp, you can supply a transfer function or a lookup table, not both.

If you want to render using both a transfer function and a lookup table, you need to supply the transfer function to ColourTrans when it’s generating the table. This will generate a lookup table with the effects of the transfer function “baked in”. The generated table doesn’t contain any references to the original transfer function, so changing the properties of the transfer function after the table’s been generated will have no effect on that table.

I think there is one edge case to be aware of, which is that sometimes ColourTrans will decide not to return a translation table (e.g. if the source and dest are identical modes & palettes, or the source and dest are both true-colour), and that decision is made without looking at the transfer function. So if you pass a transfer function into ColourTrans, and ColourTrans doesn’t return a translation table, then you’ll have to instead pass the transfer function into each OS_SpriteOp call.

 
Aug 15, 2020 4:47pm
Avatar Andy S (2979) 426 posts

Here’s a new test build for the Brush Tool Enhancements.

As before:

It’s an ArcFS archive. The !Paint program is inside Paint.debug, built for IOMD (Risc PC / RPCEmu) but you can build from source if you want to. My code’s still a little messy as I haven’t ironed out all the issues yet.

  • I’ve fixed the issue where Shape / Stamp / Tint wasn’t working correctly with > 256 colour sprites (a Colour Mapping Descriptor is now used when necessary).
  • There should now be less flicker over the tools window when selecting a different brush (it no longer forces a redraw of the whole window).
  • Previously you could drag the mouse past the end of the opacity slider bar, making it hard to select full Opacity. This is now fixed.

By the way, sorry for putting these builds on a site that needs Javascript for you to download them!

 
Aug 15, 2020 5:31pm
Avatar Rick Murray (539) 10813 posts

sorry for putting these builds on a site that needs Javascript for you to download them!

Oh my god.

Firefox that makes it easy to look at every fetch that was made, so it’s usually possible to extract the actual download links (useful for Github, Drive, etc).
This one is https://public.boxcloud.com/d/1/[...]./download where the ‘…’ is about a thousand characters of random gibberish that probably encodes the filename, owner, your IP address, the time, the time in Martian, the Julian date, the phase of the moon, and the current number of people known to be infected by the modern plague.
Jeez.

 
Aug 16, 2020 2:44pm
Avatar Andy S (2979) 426 posts

I just got brush painting with the transparent colour working again.

I’ve noticed one downside of making use of blend tables / inverse tables for brush opacity. Draw some transparent strokes on the image. Then choose a solid colour and, with Opacity turned down, paint bands of it across the transparent strokes. When the temporary layer is merged down, the intersecting areas are the wrong colour. It’s obviously blending with the RGB colour of the bottom sprite, ignoring the fact that those pixels are masked as transparent. I don’t think there’s any easy way around that. To minimise the effect it might be worth seeing if we can paint the RGB colour in a neutral grey when painting areas with the transparent colour (at the moment Paint doesn’t care what colour it ends up).

 
Sep 2, 2020 3:32pm
Avatar Andy S (2979) 426 posts
I’ve noticed one downside of making use of blend tables / inverse tables for brush opacity. Draw some transparent strokes on the image. Then choose a solid colour and, with Opacity turned down, paint bands of it across the transparent strokes. When the temporary layer is merged down, the intersecting areas are the wrong colour. It’s obviously blending with the RGB colour of the bottom sprite, ignoring the fact that those pixels are masked as transparent. I don’t think there’s any easy way around that.

Talking to myself, there’s one way around it, but it adds a few extra steps to the merge which may introduce a delay.

The flood fill tool, when filling from transparent to a solid colour, works by temporarily inverting the sprite’s mask so it can then plot the transparent parts of the mask onto the sprite in the solid colour (afterwards it inverts the mask back to its normal state). We could do the same thing here to make sure any transparent pixels that are being painted over will be in the currently selected RGB colour. It would introduce two CLG operations and an extra plot. Maybe I can make use of OS_ChangedBox to cut down the size of the sprite being updated.

I think even this fix will have a side effect. Suppose the sprite has a white background, and you paint a green translucent line across the white background and across a transparent region. When the blending happens, the above fix would make the region that was transparent come out in a more saturated green than the area that was white. Still, when we’re not using alpha masks or channels I don’t think there’s a single right answer for this.

 
Dec 16, 2020 1:20pm
Avatar Andy S (2979) 426 posts

I’m taking another look at the alpha mask / alpha channel stuff. I know I said I’d probably leave it to the end but I think it’s about time I at least enabled the UI to create these sprites. As it’s been years since we discussed this, I’m refreshing my memory and I’ll paste a few relevant comments from Jeffrey here.

I’ve got the minimal functionality working for editing the alpha channel. It lets you edit it as a separate greyscale image which is then applied to the main colour image.

Yeah, I guess that’s the only real option for alpha channels at the moment.

In-place editing of alpha masks should be pretty straightforward – you can redirect screen output to them and they’ll be treated as a 256 grey image. However for alpha channels we currently don’t have any support for that (essentially we’d have to teach the OS about a whole set of new pixel formats, and all the rendering operations for those pixel formats would have to read-modify-write for each pixel… ouch)

I don’t think we have a builtin way of directly rendering an alpha channel or alpha mask to the screen (there are the “plot sprite mask” ops, but they haven’t been extended to work sensibly with alpha). But if you clear the screen to black and then plot the sprite using a colour mapping function which just returns white then it should have the desired effect (the colourmap function isn’t supplied the alpha of the pixel, but it is called before the alpha is applied – so by returning white and plotting on a black background you’ll get the desired gradient from black-white). Or for <=256 colour sprites you could supply a palette which maps everything to white.

However, I have just remembered that OS_SpriteOp (and the VDU in general) doesn’t support proper alpha blending!

The VDU plot operations have no concept of blending at all, they only support logical operations (aka GCOL actions).

Meanwhile, OS_SpriteOp will do RGB blending (using the ARGB channels of the sprite and the RGB channel of the destination). But it completely ignores the alpha channel of the destination – when it blends it acts as if the destination has an alpha of 1, and when it writes pixels it always does so with an alpha of 1. (You can copy the sprite alpha channel to the destination by disabling the blending flag (bit 3), but that will obviously disable the RGB blending as well).

I think the only bit of the OS which can blend properly with an alpha destination is the font manager (Font_Paint flag bit 14).

Potentially it wouldn’t be too hard to add proper alpha blending to OS_SpriteOp. But supporting it in the VDU would be a lot more work. And we’d only be able to support it for alpha-channel formats; if the alpha is in a separate mask plane then there’s no way it can work (the screen alpha value is needed during the RGB blend stage, but the VDU has no concept of the framebuffer having a separate plane containing the alpha data)

So I think the best course of action would be to design the feature set of Paint around the limitations of the current system. You can still have an opacity slider for the brush tool, and that will affect the blending of the RGB, but (outside of the special alpha/mask editing mode) the user will have little or no control over what the alpha/mask is set to.

For most plot operations you could potentially allow the user to specify a custom alpha value to set, but that would only really work with non-blending operations, or with blending operations where the sprite being edited uses an alpha mask (since the mask update is a separate step, allowing you to use a blending op for the RGB update and non-blending op for the mask update)

The main point to take away from my earlier discussions with Jeffrey is there’s no in-built support for alpha blending that takes the destination pixel’s alpha value into account. This matters especially where I want to support soft brushes that have their own alpha masks (so the brushes have translucent edges).

At the moment, as I understand it, relying on the built-in routines would mean there’d be no good way to calculate appropriate alpha values where the translucent edges of those brushes touch the sprite. We certainly don’t want such a brush turning opaque destination pixels translucent (well, except when using the Transparent colour) and conversely, particularly at low opacity selections, we don’t really want transparent areas of the sprite turned completely opaque.

I’m therefore convinced that the only way to support soft brushes in a meaningful way is for Paint to have its own pixel by pixel alpha blending routine.

 
Feb 12, 2021 10:18pm
Avatar Andy S (2979) 426 posts

Oh yes! :D

3. There’s a very strange bug, when Opacity < 255, where the first click of the brush results in the brush sprite being plotted 8 pixels (usually) offset to the right. Subsequent plots always work normally (e.g. drag the mouse 1 pixel over and it will plot correctly, regardless of zoom level). I’m working on a test program to try and isolate the cause of this bug.

I’ve finally figured out the cause of the above bug.

Some experimentation revealed that swapping output between my layer sprite and the screen multiple times gave slightly different values for the start of screen memory (reading the VDU variable). Specifically, the first time output was switched to my sprite, the address was off by a small amount. Every time after that, the address was correct.

I noticed the amount of the sprite’s misalignment seemed to vary according to the number of colours of the brush sprite. I wondered if a palette or translation table was overflowing its memory and corrupting my sprite pointer (I couldn’t find anything obvious). I even began to wonder about a bug in the VDU code.

It turned out in the end that I got bitten by the flex memory management. I figured it out when I finally noticed the address of my sprite itself was changing inside the brush plot function. The change seemed to happen when the brush translation tables were being recreated. I confirmed it for sure by adding a Watchpoint to my sprite file struct in DDT and it alerted me that the pointers changed the moment one of the translation tables was flex-freed.

I’ll bear this in mind when I’m looking at the rest of the code as it could possibly have been a source of other crashes in Paint in the past.

Phew, onto the next issue! =)

 
Feb 13, 2021 10:03am
Avatar Chris (121) 447 posts

I’ve finally figured out the cause of the above bug.

Excellent!

Is this also likely to be the source of the longstanding crashes when using brush sprites in general?

 
Feb 13, 2021 1:49pm
Avatar Andy S (2979) 426 posts
Is this also likely to be the source of the longstanding crashes when using brush sprites in general?

This particular bug isn’t the source of those crashes because it was caused by code I wrote. It’s certainly possible that a similar set of circumstances could have made Paint crash in the past when painting with the brush, however so far I’ve not seen evidence of that in the code.

For flex to move the sprite far enough in memory for a plot to fall outside the sprite’s bounds and cause a crash, I suspect something large (like another sprite) would need to be deleted, unless you’re working with a small sprite when the crash happens or painting right at the edge of the sprite. In the latter case, it’s likely we’d have seen misaligned brush plots as well.

Are you still experiencing the crash?

 
Feb 15, 2021 10:33am
Avatar Chris (121) 447 posts

Are you still experiencing the crash?

Yes, although (as ever) it’s not clear exactly what circumstances provoke it. It’s only with the brush tool. From memory, sometimes pressing OK in the toolbox (to select the new brush sprite) crashes it, sometimes attempting to paint with the new sprite brings everything down. I’ll try to look into this, and see if I can narrow down when it’s happening.

 
Feb 16, 2021 9:09pm
Avatar Andy S (2979) 426 posts
Are you still experiencing the crash?

Yes, although (as ever) it’s not clear exactly what circumstances provoke it. It’s only with the brush tool.

At the risk of sounding like a broken record, when you catch it happening, please could you get me the output of the following commands?:

*where
*showregs
*memoryi pc -40 +80
*modules

The first two are the most important. If the machine’s unresponsive of course, at least writing down the error message would give some clue what’s going on.

Pages: 1 ... 14 15 16 17 18 19 20 21 22 23 24

Reply

To post replies, please first log in.

Forums → Bounties →

Search forums

Social

Follow us on and

ROOL Store

Buy RISC OS Open merchandise here, including SD cards for Raspberry Pi and more.

Donate! Why?

Help ROOL make things happen – please consider donating!

RISC OS IPR

RISC OS is an Open Source operating system owned by RISC OS Developments Ltd and licensed primarily under the Apache 2.0 license.

Description

Discussion of items in the bounty list.

Voices

  • Rick Murray (539)
  • Jeffrey Lee (213)
  • Andy S (2979)
  • Chris (121)

Options

  • Forums
  • Login
Site design © RISC OS Open Limited 2018 except where indicated
The RISC OS Open Beast theme is based on Beast's default layout

Valid XHTML 1.0  |  Valid CSS

Powered by Beast © 2006 Josh Goebel and Rick Olson
This site runs on Rails

Hosted by Arachsys