Shop OBEX P1 Docs P2 Docs Learn Events
Bitmaps and overlays — Parallax Forums

Bitmaps and overlays

I have to admit that I haven't payed much attention to all the graphics applications because I haven't needed it. I've seen some real cool graphics done on the P2 in the console emulation thread but tecnically the P2 emulates some special hardware (blitter, GPU...) and executes code origionally written for different platforms.

But is there a native graphics library that supports animated 2D graphics for the P2? It would be nice to have...

  • Bitmaps independent of the actual frame bufffer to support double buffering, overlays or sub-windows
  • copying of one bitmap into another with masking to make non-rectangular windows
  • transparent text to be able to display text labels on top of a background image

I think I could write this on my own if necessary. But I don't want to re-invent the wheel.

Comments

  • avsa242avsa242 Posts: 424
    edited 2022-07-23 13:58

    I have a library written in spin and spin2 that do some of those things, though they're not optimized - they're written in straight spin, currently. I wrote them in a generic way such that they are intended to be #included in an existing driver. It needs to provide it's own Plot() method (since this can vary a lot from one display type to another) in order for some of the others to work (like Line(), Box(), etc), as well as a few other support methods. The text routine can draw text with or without a background. It also itself #includes a common terminal library to provide things like printf(), str(), etc.
    If you have a VGA display, see https://github.com/avsa242/p2-spin-standard-library/blob/testing/library/demos/display/QVGA8BPP-Demo.spin2 for a 320x240 demo, and the driver at https://github.com/avsa242/p2-spin-standard-library/blob/testing/library/display.vga.bitmap-8bpp.spin2

    EDIT: Oops..just noticed I didn't have optional text background color drawing implemented in the library...was thinking of individual drivers that had it when building without the library. Fixed now.

  • Wuerfel_21Wuerfel_21 Posts: 4,374
    edited 2022-07-23 11:17

    Forget all about framebuffers if you want to do anything sensible.

    The console emulators use scanline buffers - the graphics are drawn some microseconds ahead of scanout.

    I guess VJET counts as a P2-native (or rather, P1-native and semi-hastily ported to P2) version of the concept, but that's really just does filled polygons (though nothing would stop you from putting in a bitmap object type).

    I've been thinking of making a more generally useful graphics driver, but haven't really had time nor reason to.

  • pik33pik33 Posts: 2,347

    Bitmaps independent of the actual frame bufffer to support double buffering, overlays or sub-windows

    In progress, using PSRAM. The progress is much slower as it can be as I have more to do than P2 programming and I also started to do FM synthesis toy. The topic is here: https://forums.parallax.com/discussion/173228/a-display-list-is-fun-0-50a-beta-0-07g-psram-command-list-used/p1

    The Prop2Play also uses several off-screen buffers to make a module file info scrolling window.

    copying of one bitmap into another with masking to make non-rectangular windows

    While I didn't do this with PSRAM based windows, my driver has sprites. They are HUB RAM based so they are limited with the memory capacity. They used wmlong to make color #0 transparent. Prop2Play uses them for visualisation.

    transparent text to be able to display text labels on top of a background image

    There are 2 methods: a text as a sprite ( so its color #0 is transparent) - this means these texts are independent from the rest of the screen and can be freely moved - I have 16 sprites up to 512 pixel width. Or - a procedure which draws the text on a background (outtextxycf) - only text pixels are drawn and no background, but then the text becomes a part of the picture and can not be "undone". Maybe I can add a procedure which saves the background somewhere before writing the text.

    The program which is the main test bench for the video driver is Prop2Play - https://forums.parallax.com/discussion/174334/prop2play-audio-player-for-a-p2-0-29-now-works-with-p2-ec32mb/p1

  • I don't need the top performace of a game engine. I don't need sprites, multi-layer parallax-scrolling or anything like that. I just want to implement some sort of virtual instruments like angular meters, gauges... Everything is quite simple and can be done with line drawing, filled polygons and text with an update rate of 1 to 10 fps.

    Most drivers for HDMI or LCDisplays already have built in functions to draw lines, rectangles and text (example here). But first, I'd like to be independent of the final decision which display I will eventually use and, second, draw into a hidden frame buffer and then copy everything to the actual display to avoid flickering.

    Writing a full blown graphics library that fits everyones needs is indeed a lot of work for which I also don't have the time I fear. So if I don't find something that fits I'll only implement a small subset of what would be desireable in a general library. But we could probably work towards an agreement for the interfaces and data type so that not everybody has to start totally from scratch...

  • pik33pik33 Posts: 2,347

    It seems what you need is a double buffer graphic driver and a blitting procedure with transparency. How to do it depends on the resolution you need. Anything like 800x480 eats too much memory to be usable without a PSRAM based environment, while 320x240 can fit in the hub, where you have wmlong to implement blitting.

  • @ManAtWork said:
    I don't need the top performace of a game engine. I don't need sprites, multi-layer parallax-scrolling or anything like that. I just want to implement some sort of virtual instruments like angular meters, gauges... Everything is quite simple and can be done with line drawing, filled polygons and text with an update rate of 1 to 10 fps.

    Most drivers for HDMI or LCDisplays already have built in functions to draw lines, rectangles and text (example here). But first, I'd like to be independent of the final decision which display I will eventually use and, second, draw into a hidden frame buffer and then copy everything to the actual display to avoid flickering.

    Writing a full blown graphics library that fits everyones needs is indeed a lot of work for which I also don't have the time I fear. So if I don't find something that fits I'll only implement a small subset of what would be desireable in a general library. But we could probably work towards an agreement for the interfaces and data type so that not everybody has to start totally from scratch...

    IMHO, for this kind of application, you can't go any wrong if you choose Eric Smith's FlesBasic as your main programming language; the whole Flex-environment seems to bring a lot of solid functionality, so you can spare your "forces", and deal with Spin2/Pasm2 only when absolutelly needed.

    Only my BRL 0.02 :smile:

  • @Wuerfel_21 said:
    Forget all about framebuffers if you want to do anything sensible.
    The console emulators use scanline buffers - the graphics are drawn some microseconds ahead of scanout.

    That's definitely the most efficient way if the largest part of the creen is re-drawn anyway. If there's no static background a frame buffer makes no sense and calculating pixels that are obscured by items in the front doesn't make sense either.

    For classical GUI applications where most of the screen stays the same and only small areas are animated a static frame buffer is still the better choice, I think. For EMI rigidity and reliability reasons I don't want an external memory bus and overclocking. So I'm limited to something around 480x640 and 1 byte/pixel or 800x600 and 4 bits/pixel.

    So if I wrote a genral graphics library with that restrictions it would probably not be useful to anybody else. A library that supports larger screens must be directly coupled to the memory driver for external RAM to be efficient. So it's probably unnecessary to worry about code re-use and it's better to just go ahead and implement it as simple as possible.

  • @ManAtWork said:

    @Wuerfel_21 said:
    Forget all about framebuffers if you want to do anything sensible.
    The console emulators use scanline buffers - the graphics are drawn some microseconds ahead of scanout.

    That's definitely the most efficient way if the largest part of the creen is re-drawn anyway. If there's no static background a frame buffer makes no sense and calculating pixels that are obscured by items in the front doesn't make sense either.

    For classical GUI applications where most of the screen stays the same and only small areas are animated a static frame buffer is still the better choice, I think. For EMI rigidity and reliability reasons I don't want an external memory bus and overclocking. So I'm limited to something around 480x640 and 1 byte/pixel or 800x600 and 4 bits/pixel.

    Line rendering is conceptually more efficient. In effect, you're trading storing the current frame as actualized pixels vs storing some kind of scene description that creates those pixels. For a GUI application mostly drawing shapes and text, the latter is much smaller and faster to create (in terms of main thread blocking time).

  • Hmm, memory seems in fact the most limiting factor. If I use a small LCD with SPI interface the frame buffer is in the display and I only need a buffer for the display area that actually changing in the P2. But if I use a VGA or HDMI scanline device I need memory for the full screen frame buffer plus every internal bitmaps I have to draw plus extra memory for the masks, the font and textures, symbols, icons and so on. And I still need some space for my application code. So more than 480x640 and 4bpp are not realistic.

    But come on... We are all spoiled by those memory-wasteful PCs nowadays. The original Amiga had only 256 or later 512kB of RAM and offered all that (at that time) amazing graphics. So 512kB of RAM should be plenty for any kind of industrial control panel, oszilloscope or general intrumentation display.

  • @pik33 Yes a display list would also be clever. It could be used to dynamically switch resolution or color depth between different display regions to save memory and bandwidth. This is why the Amiga had so called copper lists.

    With the P2 we could not only create scanline based switching but algorithmical decision for every single pixel. For example we could create a radar-type display with a round area in the center which is dynamically drawn on-the-fly and a tile buffer for more static text and symbols around it. But creating a general purpose library for that would probably be overkill for the simpler applications and too limited for gaming and hires imaging.

    So again, too much work unless you do it for fun.

  • I have a first, very limited but working test version of my bitmap driver. I decided to take one of my 320x240 LCDs as output device although the driver itself is not bound to this and could also be used for a VGA or HDMI display.

    The smaller resolution helps saving memory but to avoid the pixel-ish look and reduce aliasing/quantisation effects I use a 12:4 fixed point math for all coordinate calculations instead of simple integers.
    Short demo: https://youtu.be/UsBuGZLzQqE

    The left side uses standard integer rendering while on the right side fixed point math and pixel blending is used.

  • ManAtWorkManAtWork Posts: 2,049
    edited 2022-07-29 16:32

    Wow, the P2 even has an assembler instructions for converting 24 bit RGB pixel data to 16 bit 5:6:5 format and vice versa! (RGBSQZ and RGBEXP)
    B)
    I just discovered it while searching for the best fitting instruction of how to create a nibble mask out of a single bit mask.

    Edit:

                  movbyts tmp,#0    ' copy byte0 to all bytes, convert 8 bit %abcdefgh
                  mergeb  tmp       ' to 32 bit nibble mask %aaaabbbb..gggghhhh
    

    should do the job. :)

Sign In or Register to comment.