Closed jblang closed 5 months ago
as commented on discord, adding in new bitmap formats is kinda costly... but it is doable
the VDP does already support a "mono/mask" bitmap format. this accepts a single colour value, which defines the pixel "on" colour when the bitmap is rendered to the screen. "off" pixels simply aren't rendered, so whatever had been on the screen where a bitmap off-pixel is positioned will remain when it is drawn. this format is essentially inherited from fab-gl
I guess the question is, should we aim to provide a two-colour bitmap format that requires two colours to be set against the bitmap, or should we have no colours set against the bitmap and instead pick the colours to use to draw at render-time, using the current "foreground" and "background" graphics colours
having no colours set against the bitmap is probably, overall, more powerful and useful. it may however be harder to implement, as the current bitmap drawing system inside vdp-gl doesn't allow for this additional information to be directly included. there is probably a way tho :grin:
as also discussed on discord, an alternative approach would be to have a buffered command call that can expand out a monochrome bitmap into RGBA2222 format
technically this wouldn't really be a bitmap operation - just a way of expanding data, which could then be used as a bitmap. the command would iterate through a buffer a bit at a time, expanding that single bit out to a whole byte, using a list of bytes to pick from
such a command could also potentially be extended to support multiple bits mapping to bytes - thus allowing the conversion of 2-bit colour bitmaps into RGBA2222 format. support for 3-bit, 4-bit, 5-bit (etc) could also be added
the advantage of this approach would be that no new bitmap renderers would need to be written. rendering RGBA2222 format bitmaps is probably the fastest format to render for every screen mode, so performance would likely be better too
or should we have no colours set against the bitmap and instead pick the colours to use to draw at render-time, using the current "foreground" and "background" graphics colours
It might be useful to have both options, but for the use case I've currently got in mind (my plasma program), the ability to select the bitmap, including the colors with only a single byte is important, so i do want to tie my bitmaps to a specific foreground/background color. This is how the color and pattern table worked on TMS9918's tile mode; however in it's pseudo bitmap mode it is closer to what you proposed. You can specify an 8 bit mono bitmap and foreground and background colors independently for each 1x8 strip of pixels. On the C64, I believe you could independently specify the fg/bg colors for each 8x8 tile on the screen rather than it being an inherent property of the tile itself. You could also set a mode where each tile was 4x8 (stretched to 8x8 horizontally), with 4 colors.
given the complexity involved in adding support for another bitmap format, I think my preferred solution for supporting other depths of bitmaps is to create RGBA2222 format bitmaps on the VDP from different formats of source data.
overall I feel that is likely the more useful approach, especially given that manipulating RGBA2222 format bitmaps on the VDP is much easier than formats with less bits per pixel. for instance, with existing buffered commands, it's easy to mirror an RGBA2222 format bitmap around the Y axis - essentially impossible to do that for a 1-bpp bitmap.
the challenge of course is coming up with a straightforward API for expanding out data. options will be needed to specify the width (in bits) of data in the source. bitmaps also may be byte-aligned at certain boundaries, such as the row of a bitmap, so that information needs to optionally be provided in an API call too. then there's the matter of how to provide the map of values those bits are getting expanded into. when expanding a monochrome bitmap just two values are needed, but more bits need more values. you may end up needing a map of 16 values, possibly even more. it may be useful to use a buffer as the source for the map to allow it to be re-used - although for expanding a mono image that would be overkill
short-term I think this just means that the API needs to support options, probably with bits in options bytes reserved for future use
PR #221 adds an "expand bitmap" command, which will allow for bitmaps that are of a pixel width from 1-bpp to 7-bpp to be mapped to 8-bit values. given suitable mapping, this allows the creation of RGBA2222 from arbitrary bitmaps
this function also includes support for setting a "width" for the bitmap - a point at which after having processed that number of pixels the mapping routine will align to the next byte, and then start again.
the expansion routine currently assumes that all bitmaps will start from the top-most bit in a byte. I'm not sure how image alignment within bitmap data usually works. this alignment assumption is based off how fonts are handled in vdp-gl
@jblang I think the new "expand bitmap" buffer command essentially addresses the underlying desire/need here
as a result I'll close this issue - please feel free to open up another issue if there's any extensions that would be useful
I am proposing a new bitmap format that will allow two-color bitmaps to be sent in a much more compact way. Many 8-bit systems allowed defining two-color bitmaps with a foreground and background specified for a certain run of pixels (usually an 8x8 tile, but this isn't a limitation we need to carry over). Having the VDP simulate this format would make it easier to reuse graphics assets designed for other systems (TMS9918, C64, etc).
This can be simulated using RGBA2222 bitmaps, for example, but requires a lot of prep work on the CPU side to convert the data to the proper format (see the tile routines in my gradient library for example). RGBA2222 format also requires sending a lot more bytes to the VDP than is strictly necessary, which means longer loading times. For example an 8x8 tile in RGBA2222 format is 64 bytes, but would be only 9 bytes in my proposed format: two RGBA2222 bytes specifying the foreground and background color, and 8 bytes containing the 8x8 monchrome bitmap to use. The savings in bytes goes up even more if larger bitmaps are used.