Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
DAY 009:_PutImage
#21
Thumbs Up 
(11-15-2022, 04:43 PM)Pete Wrote: Thanks for _SMOOTHing things over.

Pete

Yes thankyou, Steve for checking into Smooth. I now have foggy memory or notion of trying out Smooth long ago and not getting anything noticeable happening.
b = b + ...
Reply
#22
Trying to understand from the wiki about how _CopyImage somehow makes software images into hardware images if using mode 33.

Quote:newhandle& = _COPYIMAGE(imageHandle&[, mode%])


Mode 32 is fine, but 33 doesn't seem to be doing anything.

Code: (Select All)
'mode 33 copyimage test

Screen _NewImage(800, 600, 32)

Dim h1&, h2&
h1& = _LoadImage("qb64pe.png", 32)
w1 = _Width(h1&): h1 = _Height(h1&)

_PutImage (1, 1)-(400, 300), h1&, 0, (1, 1)-(w1, h1)


h2& = _CopyImage(0, 32) '<------    works in mode 32 but blank if mode 33
Sleep

Cls
_PutImage (1, 1), h2&
Sleep
End

Maybe a certain variable type will work?   No idea
Reply
#23
Try this for your first demo into hardware images:

Code: (Select All)
'mode 33 copyimage test

SCREEN _NEWIMAGE(800, 600, 32)

LINE (100, 100)-(200, 200), -1, BF 'white box to keep things simple


h2& = _COPYIMAGE(0, 33) '<------    make a copy of the screen and make it a hardware copy
SLEEP

CLS
_PUTIMAGE , h2& 'put the hardware image over the screen  (they're separate layers, so you can overlap them)
_DISPLAY 'hardware images require a DISPLAY statement to render
SLEEP
END 'notice how the hardware image disappeared?  It's not part of the software screen at all.
'    which is why you have to call _DISPLAY to have them appear.
Reply
#24
Thanks, I added the _Display and it works fine!
Reply
#25
_Smooth works!  I attached the small image file used for this.
[Image: monalisa-sm.png]



Code: (Select All)
'Smooth image test


Screen _NewImage(800, 600, 32)

Dim h1&, h2&
h1& = _LoadImage("monalisa-sm.png", 32)
w1 = _Width(h1&): h1 = _Height(h1&)
h2& = _CopyImage(h1&, 33)

_PutImage (1, 1)-(401, 401), h1&, 0, (1, 1)-(w1, h1)
Locate 30, 20
Print "Normal"
Sleep
Cls
_PutImage (1, 1)-(401, 401), h2&, 0, (1, 1)-(w1, h1), _Smooth
Locate 30, 20
Print "Smooth"
_Display
Sleep
End


Attached Files Image(s)
   
Reply
#26
Thumbs Up 
Oh that's how that's supposed to work, thanks guys!

I tried it on our Logo:
   

Sure it's blurry but it's not pixelated square tiles!  So this is hardware images only.
b = b + ...
Reply
#27
SMcNeill
And, let me share an example here, for WHY one might want to use hardware images.

Code: (Select All)
'mode 33 copyimage test

SCREEN _NEWIMAGE(800, 600, 32)
RANDOMIZE TIMER

FOR i = 1 TO 100

    LINE (RND * 800, RND * 600)-(RND * 800, RND * 600), _RGB32(RND * 256, RND * 256, RND * 256), BF
    CircleFill RND * 800, RND * 600, RND * 200, _RGB32(RND * 256, RND * 256, RND * 256)
    LINE (100, 100)-(200, 200), -1, BF 'white box to keep things simple
NEXT
PRINT "Let's take a moment and showcase WHY we might want to use hardware images."
PRINT
PRINT "First, let's start with an simple image, and let's copy it to hardware."

h2& = _COPYIMAGE(0)
h2hw& = _COPYIMAGE(0, 33) '<------    make a copy of the screen and make it a hardware copy
changedirection = -1
x = 400: y = 300
xchange = -1: ychange = 1
SLEEP
_DELAY .25
_KEYCLEAR

t# = TIMER
DO
    fps = fps + 1
    CLS
    IF changedirection THEN xchange = -1 * xchange: ychange = -1 * ychange: changedirection = 0
    x = x + xchange: y = y + ychange
    IF x < 0 OR x > _WIDTH OR y < 0 OR y > _HEIGHT THEN changedirection = -1
    _PUTIMAGE (x, y)-STEP(200, 200), h2& 'put the software image on the screen
    IF TIMER > t# + 1 THEN out1$ = STR$(fps): t# = TIMER: fps = 0
    PRINT "FPS:"; out1$; " with use of _PUTIMAGE with software screens and software "
    _DISPLAY 'hardware images require a DISPLAY statement to render
LOOP UNTIL _KEYHIT

_DELAY .25
_KEYCLEAR
t# = TIMER: fps = 0
DO
    fps = fps + 1
    CLS
    IF changedirection THEN xchange = -1 * xchange: ychange = -1 * ychange: changedirection = 0
    x = x + xchange: y = y + ychange
    IF x < 0 OR x > _WIDTH OR y < 0 OR y > _HEIGHT THEN changedirection = -1
    _PUTIMAGE (x, y)-STEP(200, 200), h2hw& 'put the hardware image over the screen  (they're separate layers, so you can overlap them)
    IF TIMER > t# + 1 THEN out2$ = STR$(fps): t# = TIMER: fps = 0
    PRINT "FPS:"; out1$; " with use of _PUTIMAGE with software screens and software images"
    PRINT "FPS:"; out2$; " with use of _PUTIMAGE with software screens and hardware images"
    _DISPLAY 'hardware images require a DISPLAY statement to render
LOOP UNTIL _KEYHIT

_DELAY .25
_KEYCLEAR

_DISPLAYORDER _HARDWARE 'notice I'm not using a software screen at all now.  The PRINT Statements below will NOT show.

t# = TIMER: fps = 0
DO
    fps = fps + 1
    CLS
    IF changedirection THEN xchange = -1 * xchange: ychange = -1 * ychange: changedirection = 0
    x = x + xchange: y = y + ychange
    IF x < 0 OR x > _WIDTH OR y < 0 OR y > _HEIGHT THEN changedirection = -1
    _PUTIMAGE (x, y)-STEP(200, 200), h2hw& 'put the hardware image over the screen  (they're separate layers, so you can overlap them)
    IF TIMER > t# + 1 THEN out3$ = STR$(fps): t# = TIMER: fps = 0
    PRINT "FPS:"; out1$; " with use of _PUTIMAGE with software screens and software images"
    PRINT "FPS:"; out2$; " with use of _PUTIMAGE with software screens and hardware images"
    _DISPLAY 'hardware images require a DISPLAY statement to render
LOOP UNTIL _KEYHIT

_DISPLAYORDER _SOFTWARE , _HARDWARE 'lets put the software screens back into our display
CLS

PRINT "FPS:"; out1$; " with use of _PUTIMAGE with software screens and software images"
PRINT "FPS:"; out2$; " with use of _PUTIMAGE with software screens and hardware images"
PRINT "FPS:"; out3$; " with use of _PUTIMAGE with hardware ONLY images and screens"





SUB CircleFill (CX AS LONG, CY AS LONG, R AS LONG, C AS LONG)
    DIM Radius AS LONG, RadiusError AS LONG
    DIM X AS LONG, Y AS LONG

    Radius = ABS(R)
    RadiusError = -Radius
    X = Radius
    Y = 0

    IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB

    ' Draw the middle span here so we don't draw it twice in the main loop,
    ' which would be a problem with blending turned on.
    LINE (CX - X, CY)-(CX + X, CY), C, BF

    WHILE X > Y
        RadiusError = RadiusError + Y * 2 + 1
        IF RadiusError >= 0 THEN
            IF X <> Y + 1 THEN
                LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
                LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
            END IF
            X = X - 1
            RadiusError = RadiusError - X * 2
        END IF
        Y = Y + 1
        LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
        LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
    WEND

END SUB

Now this is about as simple as a demo as I can imagine writing to showcase what needs to be shown here.  All we're doing in this example is drawing a screen of simple lines and circles, and then we're saving that screen as an image.  (Two images actually -- one software, one hardware, for comparison.)

We then throw that image onto a clean screen and move it in an unlimited loop, and count how many times it moves in a second.  Once we know our FPS, the user can hit any key they want and see the *exact* same code and process, and how fast it'd run if we swapped in a hardware image instead of a software image.  Once happy with seeing those results, the user can then hit any key they want and see that *exact* same code run with ONLY hardware support, and see what the difference is in performance.

I think the results, printed as a nice summery on the last page, speak for themselves as to why someone might want to start using hardware images over software.  Wink



And somehow, I posted this entirely in the wrong topic.  There's a copy of this in my CircleFill topic now as well, as I just copied our circlefiller for here from there, and then somehow posted this there instead of here.  LOL!
Reply
#28
This is really interesting.  (And all news to me, really).

So I realize I need to not just use _PUTIMAGE as a powerful image command, but I need to consider software vs hardware images.  And so this topic has been enlightening.

I just read this :  https://qb64phoenix.com/forum/showthread...are+images

And now I'm wondering how this all works...what exactly are hardware images and software images?  Why are they so different?  I mean what is the reason for such different speeds and performance?  Is this something that has been discussed or documented already so I can just find this info and start reading?  Or would anyone like to explain it in a simple way?  A couple of other related questions:  How exactly does _Display work?  I mean this as it relates to CLS, _DisplayOrder, and the which should go first in order to not cover or block the others?  And finally:  _FreeImage....is this something to be keeping close by in terms of not abusing memory or cpu usage? 

Sorry for so many questions  Big Grin
Reply
#29
@james2464 Lots of questions which are bleeding off into a lot of other keywords and all! Let me cover them here briefly, and if you have further questions, let's move the discussion for those other keywords elsewhere so as to not completely overwhelm this poor topic which should just be for _PUTIMAGE. Wink

Hardware images are basically completed screens that you send to your GPU to draw and render for you. They display for a single frame when _DISPLAY is called, and then they're gone. You can't edit them, change them, or do anything else with them, except just display them -- which is why they're so fast compared to software images. There's no such thing as PRINT displaying text on your hardware image. Hardware images are set in stone -- when you copy them, that's what they are! Forever and ever more!!

Software images are the screens that you're working on in the CPU. They're easy to manipulate and change. Print to them. Draw on them. Use Circle, Line, and PSET on them. These are the screens that you've always used, so you should be used to using them. They're malleable and easy to work with.

One important thing to keep in mind -- THE TWO SCREENS ARE COMPLETELY UNRELATED!! What you do with one has zero bearing with what happens to the other.

In fact.... dun dun de dun...

You can use hardware images with SCREEN 0 software screens! Overlay graphics over text screens! Who'da thunk it?



Since we now know a little about the screens, let's briefly hit on _DISPLAYORDER.

_DISPLAYORDER simply sets the order in which we layer our screens. Take a RED software screen, and a BLUE hardware screen. If both are solid colors, and they perfectly overlap each other, which one are we going to see displayed on our monitor?

To make this easy to understand and visualize, get two pieces of paper and write RED on one and BLUE on the other.

Put the RED (software) paper on the bottom, and the BLUE (hardware) page on top of it. Which can you see? The BLUE page! This is _DISPLAYORDER _SOFTWARE, _HARDWARE.

Now, pick those pieces of paper back up and put the BLUE (hardware) page down first, and then lay the RED (software) page on top of it. What can you see? The RED page! That's basically _DISPLAYORDER _HARDWARE, _SOFTWARE.

Now, pick those pages up once more, and this time you're going to toss the RED page completely away. Put the BLUE page down and what do you see? GASP!! The BLUE page!! That's what you get with just _DISPLAYORDER _HARDWARE.

_DISPLAYORDER basically just sets the order with which you stack those independent pages/screens on top of each other.



As for _DISPLAY, it basically just tells your program to sync up all your available pages and draw them all together, layered in the order you specified with _DISPLAYORDER.



And _FREEIMAGE, like always, should be used once you're finished with *any* image, to keep it from using up precious memory on your PC. (And maybe eventually leading to a program crash for "out of memory" glitches.)
Reply
#30
Brilliant...Thank you very much for this.

Sometimes new info leads to a bunch of questions so I appreciate you addressing them all.
Reply




Users browsing this thread: 2 Guest(s)