Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PCOPY use with hardware and software images
#1
I'm adding image layers to the library I'm working on. At first I was going to create an image array of multiple screens, draw each individual image to its designated screen (layer) then combine the images together.

TYPE TYPE_SCREENDB
    Image AS LONG
    ClearColor AS _UNSINGED LONG
    ...
    ... Yada, yada yada
    ....
END TYPE

REDIM ScreenDB(0) AS TYPE_SCREENDB

But I got to thinking, QB64 already does all the heavy lifting through the PCOPY statement. So I wrote the little test program below to see how this would work and to my my surprise hardware and software images are preserved and copied ... with a few quirks I'm having a hard time wrapping my head around.

On line 17 I draw a software sprite onto page 0 (the display page). Why is that image not preserved in the loop that follows?

On lines 37 and 38 I draw another software sprite onto page 0 which works. However, if I move these two lines of code to just under the _LIMIT 30 statement the image no longer appears.

At first I thought that perhaps pages 1 and 2 (and above) were not retaining the default _RGBA(0,0,0,0) transparent black color. But that can't be the case since line 30, PCOPY 2,0 , does not wipe out the previous PCOPY 1,0 in line 26 above it.

Does anyone have any insight as to why software images are not persisting as they should?

Code: (Select All)
DIM Sprite AS LONG '  software sprite
DIM HWSprite AS LONG ' hardware sprite

Sprite = _NEWIMAGE(64, 64, 32) '        software sprite
_DEST Sprite '                          draw on software sprite
CIRCLE (31, 31), 31
HWSprite = _COPYIMAGE(Sprite, 33) '      create hardware sprite

SCREEN _NEWIMAGE(640, 480, 32)

' ------------------------------------------------------------
'| Why is this software image not preserved in the loop below |
'| unless I draw it on the last page copied?                  |
' ------------------------------------------------------------

'SCREEN , , 2, 0 '                        draw on page 2 (only when this line active works?)
_PUTIMAGE (300, 300), Sprite '          draw software sprite

' ------------------------------------------------------------

DO
    _LIMIT 30 '                          30 FPS

    SCREEN , , 1, 0 '                    active page 1, display page 0
    _PUTIMAGE (100, 100), HWSprite '    draw hardware sprite on page 1
    PCOPY 1, 0 '                        copy page 1 to page 0

    SCREEN , , 2, 0 '                    active page 2, display page 0
    _PUTIMAGE (200, 200), HWSprite '    draw hardware sprite on page 2
    PCOPY 2, 0 '                        copy page 2 to page 0

    ' ----------------------------------------------------------------------
    '| Why do I need to draw software images last? When the two lines below |
    '| are moved under _LIMIT 30 above the software image is not seen?      |
    ' ----------------------------------------------------------------------

    SCREEN , , 0, 0 '                    active page 0, display page 0
    _PUTIMAGE (220, 220), Sprite '      draw software sprite

    ' ---------------------------------------------------------------------

    _DISPLAY '                          update screen with changes
LOOP UNTIL _KEYDOWN(27)
SYSTEM
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#2
After thinking about this a while I believe it is due to the fact that pages above 0 do not retain the _RGBA(0,0,0,0) transparent color. I forgot that the hardware layer and software layer are completely independent of each other.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#3
(08-13-2024, 05:25 PM)TerryRitchie Wrote: After thinking about this a while I believe it is due to the fact that pages above 0 do not retain the _RGBA(0,0,0,0) transparent color. I forgot that the hardware layer and software layer are completely independent of each other.
Yep, I was just about to respond with that Smile The `_PUTIMAGE` with hardware images doesn't care what the active or display page is, so even though your `PCOPY`s are wiping out the whole screen the hardware images still appear anyway when the screen gets rendered during `_Display`.

If you move one of the `_PutImage` calls with the hardware image out of the loop and just retain the `PCOPY` you can see that the page is actually blank.
Reply
#4
(08-13-2024, 05:33 PM)DSMan195276 Wrote:
(08-13-2024, 05:25 PM)TerryRitchie Wrote: After thinking about this a while I believe it is due to the fact that pages above 0 do not retain the _RGBA(0,0,0,0) transparent color. I forgot that the hardware layer and software layer are completely independent of each other.
Yep, I was just about to respond with that Smile The `_PUTIMAGE` with hardware images doesn't care what the active or display page is, so even though your `PCOPY`s are wiping out the whole screen the hardware images still appear anyway when the screen gets rendered during `_Display`.

If you move one of the `_PutImage` calls with the hardware image out of the loop and just retain the `PCOPY` you can see that the page is actually blank.
Right, so if I'm understanding this correctly all screen pages are software only and a separate hardware layer is not created for each page. When I call _DISPLAY all hardware images are simply drawn to a single hardware layer over the software images due to the default _DISPLAYORDER _SOFTWARE, _HARDWARE.

I just reversed _DISPLAYORDER and indeed the software images now overwrite the hardware images.

Hmm... What would be cool is if I could somehow convert each of the screen pages that get drawn to a hardware image.

It doesn't appear that I can control the _CLEARCOLOR of any of the screen pages either. I was hoping to overlay screen pages to create a master display page.

Here's something strange though. Change the _DISPLAYORDER in line 35 below to _HARDWARE, _SOFTWARE and the magenta background disappears?

Code: (Select All)
CONST RED~& = _RGB32(255, 0, 0)
CONST GREEN~& = _RGB32(0, 255, 0)
CONST BLUE~& = _RGB32(0, 0, 255)

DIM RedSprite AS LONG '  software sprite
DIM GreenSprite AS LONG
DIM BlueSprite AS LONG
DIM HWRedSprite AS LONG ' hardware sprite
DIM HWGreenSprite AS LONG ' hardware sprite
DIM HWBlueSprite AS LONG ' hardware sprite

RedSprite = _NEWIMAGE(64, 64, 32) '        software sprite
GreenSprite = _NEWIMAGE(64, 64, 32) '        software sprite
BlueSprite = _NEWIMAGE(64, 64, 32) '        software sprite

_DEST RedSprite '                              draw on software sprite
CIRCLE (31, 31), 31, RED
PAINT (31, 31), RED, RED
HWRedSprite = _COPYIMAGE(RedSprite, 33) '      create hardware sprite

_DEST GreenSprite '                              draw on software sprite
CIRCLE (31, 31), 31, GREEN
PAINT (31, 31), GREEN, GREEN
HWGreenSprite = _COPYIMAGE(GreenSprite, 33) '      create hardware sprite

_DEST BlueSprite '                              draw on software sprite
CIRCLE (31, 31), 31, BLUE
PAINT (31, 31), BLUE, BLUE
HWBlueSprite = _COPYIMAGE(BlueSprite, 33) '      create hardware sprite


SCREEN _NEWIMAGE(640, 480, 32)
_MOUSEHIDE

_DISPLAYORDER _SOFTWARE , _HARDWARE '    reverse this and the magenta background disappears?

DO
    _LIMIT 30 '                          30 FPS

    SCREEN , , 1, 0 '                    active page 1, display page 0
    PAINT (0, 0), _RGB32(255, 0, 255)
    _CLEARCOLOR _RGB32(255, 0, 255)
    _PUTIMAGE (100, 100), RedSprite '    draw sprite on page 1
    PCOPY 1, 0 '                        copy page 1 to page 0

    SCREEN , , 2, 0 '                    active page 2, display page 0
    PAINT (0, 0), _RGB32(255, 0, 255)
    _CLEARCOLOR _RGB32(255, 0, 255)
    _PUTIMAGE (120, 120), GreenSprite '  draw sprite on page 2
    PCOPY 2, 0 '                        copy page 2 to page 0

    ' Page 2 above simply overwrites page 1

    SCREEN , , 3, 0 '                    active page 2, display page 0
    PAINT (0, 0), _RGB32(255, 0, 255)
    _CLEARCOLOR _RGB32(255, 0, 255)
    _PUTIMAGE (140, 140), BlueSprite '  draw sprite on page 3
    PCOPY 3, 0 '                        copy page 3 to page 0

    ' Page 3 above simply overwrites page 2


    WHILE _MOUSEINPUT: WEND

    SCREEN , , 0, 0 '                            active page 0, display page 0
    _PUTIMAGE (_MOUSEX, _MOUSEY), HWRedSprite '  draw hardware sprite

    _DISPLAY '                                  update screen with changes
LOOP UNTIL _KEYDOWN(27)
SYSTEM
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#5
Ok, more thinking. I could make this work if each screen page would retain alpha transparency information. The problem with a change like that would probably make a lot of legacy code that uses PCOPY have very strange results.

Oh well, looks like I'm back to manipulating individual images and overlaying them as needed.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#6
Hey Terry,

Late to the party, because I'm finalizing a 4,000 sq ft roofing project. Just past final inspection, now.

I see you've made your decision on how to proceed, but just food for thought, if you want to preserve that initial image, you'd have to PCOPY it to page 2. Here is a more simplified SCREEN 0 text example...

Code: (Select All)

Locate 1, 1: Print "P"
PCopy 0, 1 ' Needed to preserve "P" when flipping pages. Also PCOPY to page 2, if needed.
Sleep
Do
    _Limit 30 '                          30 FPS
    Screen , , 1, 0 '                    active page 1, display page 0
    Locate 2, 1: Print "W" '_PutImage (100, 100), HWSprite '    draw hardware sprite on page 1
    PCopy 1, 0 '
    Sleep '                        copy page 1 to page 0
    Screen , , 2, 0 '                    active page 2, display page 0
    Locate 3, 1: Print "T" '_PutImage (200, 200), HWSprite '    draw hardware sprite on page 2
    PCopy 2, 0 '
    Sleep '                      copy page 2 to page 0
    Screen , , 0, 0 '
    Locate 4, 1: Print "Z" '_PutImage (220, 220), Sprite '      draw software sprite
    Sleep
Loop Until _KeyDown(27)
System

Pete
Shoot first and shoot people who ask questions, later.
Reply
#7
(08-13-2024, 07:17 PM)Pete Wrote: Hey Terry,

Late to the party, because I'm finalizing a 4,000 sq ft roofing project. Just past final inspection, now.

I see you've made your decision on how to proceed, but just food for thought, if you want to preserve that initial image, you'd have to PCOPY it to page 2. Here is a more simplified SCREEN 0 text example...

Code: (Select All)

Locate 1, 1: Print "P"
PCopy 0, 1 ' Needed to preserve "P" when flipping pages. Also PCOPY to page 2, if needed.
Sleep
Do
    _Limit 30 '                          30 FPS
    Screen , , 1, 0 '                    active page 1, display page 0
    Locate 2, 1: Print "W" '_PutImage (100, 100), HWSprite '    draw hardware sprite on page 1
    PCopy 1, 0 '
    Sleep '                        copy page 1 to page 0
    Screen , , 2, 0 '                    active page 2, display page 0
    Locate 3, 1: Print "T" '_PutImage (200, 200), HWSprite '    draw hardware sprite on page 2
    PCopy 2, 0 '
    Sleep '                      copy page 2 to page 0
    Screen , , 0, 0 '
    Locate 4, 1: Print "Z" '_PutImage (220, 220), Sprite '      draw software sprite
    Sleep
Loop Until _KeyDown(27)
System

Pete
Yep, I was playing around with that same thing. I decided without screen pages being able to preserve alpha transparency it's going to be next to impossible to use PCOPY to implement layers the way I need.

At first I was just attaching a layer value to sprites then going through the sprite array looking for layer 8, draw first, layer 7, draw next, layer 6 ... this required too much overhead. I then decided just to make individual images to draw the sprites to and then at the end combine them into one image. Sped things up greatly. That's what got me thinking about PCOPY and how I could possibly use that instead. I thought that maybe each screen page also had it's own hardware layer as well ... until I came to my senses. Tongue
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#8
Agreed. With PCOPY and graphics you are flipping the entire screen, which is considerably more overhead than working with _PUTIMAGE and a portion of the screen. I learned this while working with a bird image for the Harris / Walz campaign. I wanted to use PCOPY, but I couldn't get it flipping them the bird as fast and frequent as was necessary.

Pete Big Grin
Shoot first and shoot people who ask questions, later.
Reply




Users browsing this thread: 1 Guest(s)