Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Transparency with Hardware Images
#1
I'm still messing around with tilting images and parallax and trying to use _PutImage to display a couple hardware screens so both are visible, but they overlap and, naturally, the second one put to screen blocks the first one. I believe the way to do it would be to make the second image transparent by using _ClearColor while it's still a software image, but I can't get it to work...

How do you make a hardware image transparent? I guess I could snip out the parts I want with _PutImage, but figured I should know how to do this too...
Thanks.

P.S. I did sniff around the forum and wiki for answers, but no luck so far.

Code: (Select All)
Option _Explicit
Dim As Long image, virt, label, font, a
Dim As Integer w, h: w = 260: h = 400
Screen _NewImage(1920, 1080, 32): _FullScreen
$Color:32
font = _LoadFont("futura.ttc", 20)
virt = _NewImage(w, h, 32) '    small virtual screen
image = _CopyImage(virt, 32) '      a copy of virt
label = _CopyImage(image, 33) '    a hardware version
' -----------------------------------------
' print to small "virt" software screen                ** GENERATE TILTED SHIP & TARGET LABELS **
_Dest virt: _Font font: Color Yellow
_PrintString (_Width(virt) \ 2 - _PrintWidth("SHIP:    ") \ 2, _Height(virt) \ 2 - 10), "SHIP:    " '
Color Red
_PrintString (_Width(virt) \ 2 - _PrintWidth("TARG:    ") \ 2, _Height(virt) \ 2 + 20), "TARG:    " ' adding virt as dest at EOL fails, must use _Dest virt instead
' convert virt to hardware "image"
image = _CopyImage(virt, 33) '
' tweak "image" with _MapTriangle to "label" hardware screen
_MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), label '
_MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), label '
' -----------------------------------------
font = _LoadFont("futura.ttc", 26) '                    ** GENERATE TILTED SHIP ANGLE NUMBERS **
Dim As Long virt2, image2, shipCard(359)
Dim As _Unsigned Long col
virt2 = _NewImage(w, h, 32) '
' -------------------
_Source (virt2): col = Point(0, 0) '      <<<< THIS ISN'T WORKING <<<<
_ClearColor col, virt2
' -------------------
image2 = _CopyImage(virt2, 32) '
For a = 0 To 359: shipCard(a) = _CopyImage(image2, 33): Next '
_Dest virt2 '
w = 260: h = 500
Cls: _Font font: Color Yellow
For a = 0 To 359
    _PrintString (_Width(virt2) \ 2, _Height(virt2) \ 2 - 10), Str$(a) + " " '
    image2 = _CopyImage(virt2, 33) '
    _MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image2 To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), shipCard(a) '
    _MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image2 To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), shipCard(a) '
Next
' -----------------------------------------
font = _LoadFont("futura.ttc", 21) '                    ** GENERATE TILTED TARGET ANGLE NUMBERS **
Dim As Long virt3, image3, targCard(359)
virt3 = _NewImage(w, h, 32) '
'_Source (virt3): col = Point(0, 0) '
'_ClearColor col, virt3
image3 = _CopyImage(virt3, 32) '
For a = 0 To 359: targCard(a) = _CopyImage(image3, 33): Next '
_Dest virt3 '
w = 260: h = 500
Cls: _Font font: Color Red
For a = 0 To 359
    _PrintString (_Width(virt3) \ 2, _Height(virt3) \ 2 - 10), Str$(a) + " " '
    image3 = _CopyImage(virt3, 33) '
    _MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image3 To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), targCard(a) '
    _MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image3 To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), targCard(a) '
Next
_Dest 0

For a = 0 To 359 '                                                                                                  ** PUT TO SCREEN **
    If a < 10 Then
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 10, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 10, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 '    <<<< TARGET NUMBERS BLOCK SHIP NUMBERS
    End If
    If a > 9 _AndAlso a < 100 Then
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 30, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 30, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 '
    End If
    If a >= 100 Then
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 50, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 45, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 '
    End If
    _PutImage (_Width \ 2 - _Width(label) \ 2 - 100, _Height \ 2 - _Height(label) \ 2), label, 0 '                  add label last
    _Display '
    _Delay .025 '
    If _KeyHit = 27 Then Exit For
Next
_Delay .5
_FreeImage virt: _FreeImage image: _FreeImage label
_FreeImage virt2: _FreeImage image2
_FreeImage virt3: _FreeImage image3
For a = 0 To 359: _FreeImage shipCard(a): _FreeImage targCard(a): Next
System
Reply
#2
It seems to me that it's working as it should, but it's not doing what you seem to expect it to do.

Try this:

Code: (Select All)
virt2 = _NewImage(320, 240, 32) '
' -------------------
_Source virt2: col = Point(0, 0) '      <<<< THIS ISN'T WORKING <<<<
Locate 2, 1
Print "On your newly created screen your color is going to be:"; col
_ClearColor col, virt2
col = Point(0, 0)
Print "And after you ClearColor that color, it's going to be:"; col

You create a new 32-bit screen.   It starts with a default color of 0 on it -- that's fully transparent black.  0 red, 0 green, 0 blue, 0 alpha.
You then get that value (0) from the POINT statement.
And you then replace the color 0 with... color 0 with the _ClearColor command.

I'm not thinking that's what you're trying to do here. Tongue

Unless I'm missing my guess, you want your text to print and slant, without affecting the background beneath it.  It seems to me that what you desire falls back to the printing part of the process on the initial software screen.

Printing, by default is ForeGround Color, BackGround Color  (Color Red, Green <-- for example).   If you don't specify either of those colors, it starts out BRIGHT WHITE, BLACK.   (Or COLOR _RGB32(255,255,255), _RGB32(0,0,0) -- both of which are full 255 alpha value colors)

Try _PRINTMODE _KEEPBACKGROUND to only print the letters and not print them on a black background.  

OR

Set the color yourself for exactly what you want:

Code: (Select All)
CONST Transparent~& = 0
COLOR Red, Transparent
PRINT "Foo"

Then you'll just have the text without the background, so you can rotate it and do stuff with and then display it and use it as an overlay, without squaring blocks out of your background.
Reply
#3
Exact same issue as is going on here: https://qb64phoenix.com/forum/showthread...9#pid34869
Reply
#4
Thanks, Steve! One _PrintMode _KeepBackGround was all it took. Duh! Sometimes I just lose perspective...  Confused  Huh
Reply
#5
@NakedApe  One thing you want to be careful of -- for each _LOAD or _NEW statement in your program, you ***MUST*** have a cooresponding _FREE statement to go with them.  (Well, you don't have to have one -- if you prefer a memory leak that uses more and more resources until your program explodes and melts down, I guess that's up to you...  Big Grin )

Let's look at the code line by line:

Option _Explicit
Dim As Long image, virt, label, font, a
Dim As Integer w, h: w = 260: h = 400
Screen _NewImage(1920, 1080, 32): _FullScreen
$Color:32
font = _LoadFont("futura.ttc", 20)
virt = _NewImage(w, h, 32) '    small virtual screen
image = _CopyImage(virt, 32) '      a copy of virt
label = _CopyImage(image, 33) '    a hardware version

At this point, you have now loaded one font and four images.  (Two _NewImage statements and two _CopyImage statements.)



' -----------------------------------------
' print to small "virt" software screen                ** GENERATE TILTED SHIP & TARGET LABELS **
_Dest virt: _Font font: Color Yellow
_PrintString (_Width(virt) \ 2 - _PrintWidth("SHIP:    ") \ 2, _Height(virt) \ 2 - 10), "SHIP:    " '
Color Red
_PrintString (_Width(virt) \ 2 - _PrintWidth("TARG:    ") \ 2, _Height(virt) \ 2 + 20), "TARG:    " ' adding virt as dest at EOL fails, must use _Dest virt instead
' convert virt to hardware "image"


Here, you still have that single font and 4 images in memory...

image = _CopyImage(virt, 33) '

But here, you just made a fifth image in memory, and overwrote your old image handle without freeing the old image.  How the heck are you ever going to free that old image now?  You have no reference handle pointing to it, so... ????    You've now trapped the old handle and image in memory forever.  HELLO MEMORY LEAK!!


' tweak "image" with _MapTriangle to "label" hardware screen
_MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), label '
_MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), label '
' -----------------------------------------

At this point there are now five images in memory and one font... Nothing has been freed.

font = _LoadFont("futura.ttc", 26) '                    ** GENERATE TILTED SHIP ANGLE NUMBERS **

And now, it's the same thing as before.  A second font is now loaded, without freeing the old font.  You now have two fonts in memory, and you have overwritten and lost the handle on the first one.  Once again, how do you ever expect to free that first font from memory??  You don't have the handle to it anymore...    ANOTHER MEMORY LEAK!!


Dim As Long virt2, image2, shipCard(359)
Dim As _Unsigned Long col

So we now have two fonts and five images loaded in memory....

virt2 = _NewImage(w, h, 32) '

Errr....  Make that two fonts and six images.


' -------------------
_Source (virt2): col = Point(0, 0) '      <<<< THIS ISN'T WORKING <<<<
_ClearColor col, virt2
' -------------------
image2 = _CopyImage(virt2, 32) '

Two fonts and seven images....


For a = 0 To 359: shipCard(a) = _CopyImage(image2, 33): Next '
_Dest virt2 '
w = 260: h = 500
Cls: _Font font: Color Yellow

OH NOS!!! NOW WE GO INTO A LOOP!!!!!!!!!!


For a = 0 To 359
    _PrintString (_Width(virt2) \ 2, _Height(virt2) \ 2 - 10), Str$(a) + " " '
    image2 = _CopyImage(virt2, 33) '
    _MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image2 To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), shipCard(a) '
    _MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image2 To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), shipCard(a) '
Next


We now have two fonts and 367 images loaded in memory, with absolutely no way to reference those 360 image2 images that we just overwrote repeatedly!!!!!

' -----------------------------------------
font = _LoadFont("futura.ttc", 21) '                    ** GENERATE TILTED TARGET ANGLE NUMBERS **

Wait... Make that three fonts and 367 images....

Dim As Long virt3, image3, targCard(359)
virt3 = _NewImage(w, h, 32) '

Three fonts and 368 images in memory....

'_Source (virt3): col = Point(0, 0) '
'_ClearColor col, virt3

OMG!! ANOTHER LOOP!!! 

image3 = _CopyImage(virt3, 32) '
For a = 0 To 359: targCard(a) =  _CopyImage(image3, 33): Next '

Three fonts and now... a SHITLOAD of images in memory...


_Dest virt3 '
w = 260: h = 500
Cls: _Font font: Color Red

WHEE!! ANOTHER LOOP!!!

For a = 0 To 359
    _PrintString (_Width(virt3) \ 2, _Height(virt3) \ 2 - 10), Str$(a) + " " '
    image3 = _CopyImage(virt3, 33) '
    _MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image3 To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), targCard(a) '
    _MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image3 To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), targCard(a) '
Next
_Dest 0

Three fonts and ... a METRIC SHIT TON of images!!!!



For a = 0 To 359 '                                                                                                  ** PUT TO SCREEN **
    If a < 10 Then
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 10, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 10, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 '    <<<< TARGET NUMBERS BLOCK SHIP NUMBERS
    End If
    If a > 9 _AndAlso a < 100 Then
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 30, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 30, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 '
    End If
    If a >= 100 Then
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 50, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
        _PutImage (_Width \ 2 - _Width(label) \ 2 - 45, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 '
    End If
    _PutImage (_Width \ 2 - _Width(label) \ 2 - 100, _Height \ 2 - _Height(label) \ 2), label, 0 '                  add label last
    _Display '
    _Delay .025 '
    If _KeyHit = 27 Then Exit For
Next
_Delay .5
_FreeImage virt: _FreeImage image: _FreeImage label
_FreeImage virt2: _FreeImage image2
_FreeImage virt3: _FreeImage image3
For a = 0 To 359: _FreeImage shipCard(a): _FreeImage targCard(a): Next
System




So... How many resources are still floating around, never to be freed in the program, before that system call shuts it all down??  Did you keep track?

Seems to me like you have three fonts that are never _FREE and over 360+ images which are never _FREE... And, which you can't easily *EVER* free as you overwrote the handle which references them.

Perhaps you might want to consider writing your own SafeLoad commands such as something like this:

SUB SaveLoadImage (image As String, handle As LONG)
  IF handle <> 0 then _FREEIMAGE handle 'free the old image before shooting for a new one.
  handle = 0  'reset the handle to 0 to show that the image has been freed at this point
  temp_handle = _LOADIMAGE(image)
  IF temp_handle < -1 THEN 'it's a valid image
    handle = temp_handle
  END IF
END SUB

Now, with that little routine, you automatically free up the old handle before overwriting it with a new image.  You'd still need to free the handles once you're completely done with them and aren't using them any longer, but a simple routine like this would keep you from overwriting old handles and losing them forever.

It's the type of self/automatic maintenance which I strongly recommend folks get used to doing.  It'll catch a boatload of issues for you and can save you from a ton of memory leaks and issues in your code.
Reply
#6
See, this is why apes shouldn't program computers! Thanks for the smack upside the head. I did not realize that that's how _NewImage and _LoadFont work. I thought overwriting the handle worked the same way as a variable - just overwriting that spot in memory - and not creating a leak. Clearly I've got some gaps in my QB knowledge...

I'll put your SaveLoadImage sub to work for sure. Now I gotta go back and see if I've made the same mistake with other programs. Dodgy  Thnx!
Reply
#7
_LoadImage loads an image in memory, and it returns a handle so you can access that image.
_NewImage basically does the same, except it creates a blank image in memory at the size and color depth you specify.
All the handle is, is the pointer to that memory.  

Umm...  Let's see the easiest way to explain it, so everyone can follow along with the concept:

F = FREEFILE  <-- this would get you a file handle for you to access a file on your drive.   Right?
OPEN "temp.txt" FOR OUTPUT AS #f    <--- and this would open that file usin that file handle

F = FREEFILE  <-- this will now give you another file handle so you won't run into issues when trying to access the next file you need.
OPEN "foo.txt" FOR INPUT AS #F

Only thing is.... You now have the first file which you opened for OUTPUT *still* open for OUTPUT.  You also now have a file open for INPUT...   The issue here is now:
How would you close that first file that you opened for OUTPUT??   F doesn't point to it anymore.   If you issue a CLOSE F, it's not going to close the file opened for OUTPUT; it's just going to close the file which was opened last for input and assigned to that variable...

With the above, you have written yourself into a memory leak with an always opened file that you just can't close easily.   (Not without issuing a CLOSE statement by itself and closing *every* file you have opened for any access!)



It's the same type thing with all the _LOAD or _NEW type commands.

foo = _LOADIMAGE is very similar to F = FREEFILE, in the fact that it just gives you the *handle* pointing to the proper place in memory/disk to work from.  If you overwrite that variable, you're going to end up making it impossible to FREE that resource later once you're done with it.

Fonts, Images, Sounds, Mem, File access.... Doesn't matter.  They *ALL* follow this same style of rule set.  If you _LOAD them or create them, you need a corresponding _FREE for them.   If you reuse the same variable without freeing them first, you have a memory leak that will eventually come back and bite you in the arse.

I really think that everyone needs to get in this habit when it comes to resource management:

If handle <> 0 THEN _FREEwhatever handle
handle = _LOADwhatever("blah blah.bllah")

Check to see if the handle is in use (a non-zero value), and if so, then free it.  If you haven't used that handle, you're fine and life is golden (except in subs or something which erases variable values after exit -- code smartly around them with passed or global handles).  If the handle is in use, free it before you overwrite it.

Just be certain to have that IF check suitable for your type.  (I think valid images are all less than -1, with -1 being an error message, so a check for 0 there might not be what you want and could lead to issues.  I'm just spitballing on that though, and without checking the wiki, don't trust that 100%.  I reserve the right to get confuzzled as much as anyone, and to not always keep up with every change/fix/update.  Big Grin )

If you start adding those type checks in your code, it'll save you a lot of possible issues and memory leaks in the future.  Just be certain to zero out that handle if you ever manually free the image yourself, so it won't try to free something which has already been freed.

_FREEIMAGE handle: handle = 0 '  <<--- Just something as simple as this, and then if it goes back to that IF check above later, it won't try to free what's already been freed.
Reply
#8
(07-07-2025, 11:51 PM)NakedApe Wrote: How do you make a hardware image transparent? I guess I could snip out the parts I want with _PutImage, but figured I should know how to do this too...
Thanks.

P.S. I did sniff around the forum and wiki for answers, but no luck so far.

I could be wrong, but wasn't @Pete doing some of this hardware image transparency stuff on here not too long ago?
Reply
#9
Quote:I could be wrong, but wasn't Pete doing some of this hardware image transparency stuff on here not too long ago?


Attached Files Thumbnail(s)
   

.bas   ClearColor Example.bas (Size: 1.98 KB / Downloads: 73)
.bas   setalpha and clearcolor difference between graphics and text screens.bas (Size: 1.96 KB / Downloads: 68)
.bas   setalpha example with Screen 0 dim screen.bas (Size: 4.3 KB / Downloads: 68)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  about Hardware Images and _DisplayOrder,Help! qbfans 11 540 02-11-2026, 07:10 AM
Last Post: SMcNeill
  Nth problem with hardware images Ikerkaz 9 470 01-23-2026, 02:58 PM
Last Post: bplus
  Hardware images questions Dav 5 454 12-04-2025, 04:18 PM
Last Post: Pete
  Hardware images...Talk to me! Unseen Machine 5 721 09-22-2025, 11:12 PM
Last Post: TempodiBasic
  Unintended transparency krovit 3 520 08-26-2025, 12:33 AM
Last Post: Unseen Machine

Forum Jump:


Users browsing this thread: 1 Guest(s)