(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.
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.
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.
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!
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.
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?
@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.
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.)