QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: Raven_Singularity on April 17, 2019, 08:30:15 pm

Title: Understanding hardware images
Post by: Raven_Singularity on April 17, 2019, 08:30:15 pm
I can't post my whole program code, but I'm going crazy trying to figure this out.  I have a loop which calls my graphics drawing routines.  It was working fine until recently, after I made some changes in my graphics routine.  Now I am left with no graphics being drawn to the screen unless I add a CLS in the rendering loop, which I do not want.

Code: QB64: [Select]
  1.    DO
  2.  
  3.       CLS
  4.  
  5.       CALL Timer_Update
  6.       CALL Update_Objects
  7.       CALL Render_Objects
  8.  
  9.       _DISPLAY
  10.       _LIMIT FPS
  11.  
  12.  

With the CLS in the loop, things are drawn to the screen just fine.  If I remove the CLS then my screen is empty.  It used to work either way.  If I didn't use CLS and had no background image, it would leave trails behind the images as they moved around the screen (as expected).  But I have no idea why the screen is completely blank now.  My first thought was a rogue PRINT statement somewhere that is pushing the graphics off the top of the screen, but even if I manually issue the _PUTIMAGE then END during the loop, it still doesn't display anything on the screen.  Is there some way that the default output handle could be changed that CLS fixes?  I'm all out of ideas.

Any clues how not having a CLS statement could prevent images being drawn to the screen with _PUTIMAGE?
Title: Re: Why would not using CLS block image drawing?
Post by: SMcNeill on April 17, 2019, 08:38:09 pm
The _PUTIMAGE and END method, for testing, isn’t working because of _DISPLAY.  You’d at least want to _PUTIMAGE, _DISPLAY, and then END, so you’d display the changes to the screen.

If you think it’s a PRINT pushing things off the screen, simply change that CLS to a LOCATE 1,1, for testing.  It might help confirm the issue.
Title: Re: Why would not using CLS block image drawing?
Post by: Raven_Singularity on April 17, 2019, 08:41:25 pm
I have already tried LOCATE 1, 1 in the loop, and a _DISPLAY before the END, but neither made any difference.  I am able to read text I PRINT right before the END, without using _DISPLAY.  Is PRINT different than graphics?
Title: Re: Why would not using CLS block image drawing?
Post by: SMcNeill on April 17, 2019, 08:46:28 pm
I have already tried LOCATE 1, 1 in the loop, and a _DISPLAY before the END, but neither made any difference.  I am able to read text I PRINT right before the END, without using _DISPLAY.  Is PRINT different than graphics?

No. It probably just means the program is ending before the first _DISPLAY statement is reached.  ;)
Title: Re: Why would not using CLS block image drawing?
Post by: Raven_Singularity on April 17, 2019, 08:51:21 pm
Nah.  Even a few thousand cycles into the render loop it still behaves that way.  PRINT "Hello world": END is always displaying it for me.

Code: QB64: [Select]

Text is visible upon END.
Title: Re: Why would not using CLS block image drawing?
Post by: Raven_Singularity on April 17, 2019, 09:26:49 pm
So I've narrowed down the issue.  It is about how CLS and SCREEN work with translucent background colours, and I don't get it.


This code displays the spaceship fine:

Code: QB64: [Select]
  1. CLS 0, _RGBA(255, 0, 0, 0)
  2. CALL Render_Objects


This code displays a solid red screen and no spaceship:

Code: QB64: [Select]
  1. CLS 0, _RGBA(255, 0, 0, 255)
  2. CALL Render_Objects


And this code displays a half-translucent red screen obscuring the spaceship:

Code: QB64: [Select]
  1. CLS 0, _RGBA(255, 0, 0, 255)
  2. CALL Render_Objects


Why is the SCREEN background colour being rendered in front of _PUTIMAGE images?


Edit 1:

Note: Render_Objects does nothing but call _PUTIMAGE with the correct parameters.


Edit 2:

The part that's really confusing me is my app had no issues rendering onto an opaque dark blue-grey background up until recently.  Was there anything that changed between 1.2 and 1.3 that affects how translucency of the screen background is handled?  Hmmm.
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: FellippeHeitor on April 17, 2019, 09:53:26 pm
Have your images by any chance been converted into hardware images?

https://qb64.org/wiki/DISPLAYORDER
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: Raven_Singularity on April 17, 2019, 09:57:58 pm
Yes, though I don't exactly understand what that does to the images.  I think that means they render faster on the video card using OpenGL?

Code: QB64: [Select]

But that doesn't explain why the SCREEN background appears in front of my images, or does it?  How?
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: FellippeHeitor on April 17, 2019, 10:02:11 pm
With that command you are specifying the render order. If that line is in your code you are instructing QB64 to place hardware images below software rendering. Try it with _SOFTWARE first then _HARDWARE:

_DISPLAYORDER _SOFTWARE, _HARDWARE

The screen background is a software render, that's why.
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: Raven_Singularity on April 17, 2019, 10:05:13 pm
If that's the case, then I entirely misunderstood the purpose of _DISPLAYORDER.

I thought _DISPLAYORDER specifies which output renderer to use by default, and if not available to fall back to the next renderer.  The help pages for a lot of these things are really sparse and vague.

I will try poking around at it and see if I can get it to work.  Thank you for the help.


Edit 1:

Secondary question: why is the my screen background not a hardware image?

I set up the screen with the following:

Code: QB64: [Select]
  1.    Main_Screen = _NEWIMAGE(Screen_Width, Screen_Height, 32)
  2.    SCREEN Main_Screen, 33
  3.    _DEST Main_Screen
  4.    CLS 0, C_App_Background

Shouldn't that make my main screen a hardware image?
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: FellippeHeitor on April 17, 2019, 10:27:33 pm
No. Second parameter to SCREEN does nothing http://www.qb64.org/wiki/SCREEN

If you want to work solely with hardware images, use displayorder with only the hardware switch (also as per the wiki page) and make a hardware image for the bg, which you'll place before the other images.
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: Raven_Singularity on April 17, 2019, 10:30:45 pm
I wrote this just before you answered:


Looking at the help page for SCREEN, I'm not sure what that 33 I put in is supposed to be doing.

"The empty comma disables color when any value is used. DO NOT USE! Include the comma ONLY when using page flipping."

Apparently the 33 is in that "don't use" value, hmm.

I guess my question is, "How do I make my screen background a hardware image?"



So, if I only use _DISPLAYORDER _HARDWARE that forces everything to use hardware?  What happens at that point when I do CLS?
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: FellippeHeitor on April 17, 2019, 10:32:20 pm
Quote
So, if I only use _DISPLAYORDER _HARDWARE that forces everything to use hardware?

No. If you do that you prevent any software images from ever being rendered, BG included. In that scenario, CLS is useless too.
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: Raven_Singularity on April 17, 2019, 10:35:53 pm
Is text always rendered as SOFTWARE?

I don't see text if I use _HARDWARE only.
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: FellippeHeitor on April 17, 2019, 10:38:31 pm
Yes, text is always rendered as software.
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: Raven_Singularity on April 17, 2019, 10:40:04 pm
With "_DISPLAYORDER _SOFTWARE , _GLRENDER , _HARDWARE" it is now behaving like it used to behave for me.  I can now see images and text, with the background colour appearing behind everything.

Any idea why it was behaving differently before (on v1.2)?  I had the same _DISPLAYORDER with _HARDWARE at the bottom of the stack, but CLS, PRINT, and _PUTIMAGE all worked as expected.
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: FellippeHeitor on April 17, 2019, 10:41:36 pm
Were the images being converted to hardware before?

Another thing: You don't need _GLRENDER if you're not doing any GL rendering. That would happen in SUB _GL. If you ain't got one, you can remove the switch from _DISPLAYORDER safely.
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: Raven_Singularity on April 17, 2019, 11:07:47 pm
It's possible I added the 33 switch for hardware loading recently, but I thought I used that before.


This displays nothing but a black screen:
Code: QB64: [Select]
  1.                      _AUTODISPLAY
  2.                      _PUTIMAGE (0, 0), test_handle&, , , _SMOOTH
  3.                      _DELAY 1
  4.                      END
  5.  


This displays the spaceship image for 1 second:
Code: QB64: [Select]
  1.                      _PUTIMAGE (0, 0), test_handle&, , , _SMOOTH
  2.                      _DISPLAY
  3.                      _DELAY 1
  4.                      END
  5.  


Why is _AUTODISPLAY non-functional?
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: Raven_Singularity on April 17, 2019, 11:12:26 pm
My original problem that lead me to the CLS/_HARDWARE issue was that I can't use _COPYIMAGE on my loaded image.


This gives me an invalid handle error for the _COPYIMAGE:
Code: QB64: [Select]
  1.                      _PUTIMAGE (0, 0), test_handle&, , , _SMOOTH
  2.                      Fart& = _COPYIMAGE(test_handle&, 33)
  3.  

Same without the 33, invalid handle error.  Why?
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: FellippeHeitor on April 17, 2019, 11:54:28 pm
It's possible I added the 33 switch for hardware loading recently

There you have it. That's the change - not one from 1.2 to 1.3.



_COPYIMAGE will fail if you try to COPYIMAGE a hardware image into another. Use it with software images.



Now, about _AUTODISPLAY.

Quote
Why is _AUTODISPLAY non-functional?

Your actual question here is: Why isn't _AUTODISPLAY doing what I thought it would be doing?


This is another case of you misinterpreting what a feature does.

_AUTODISPLAY is the default method for rendering. Draw something, see something immediately. You interrupt that behaviour when you use _DISPLAY.

_DISPLAY not only refreshes the screen, displaying whatever was drawn until the moment it was called, but it also disables _AUTODISPLAY, which means that for whatever you drew after using _DISPLAY to be seen you'll need to call _DISPLAY again. That's the reason we have flicker-free drawing when we use it.

If you use neither, then it's _AUTODISPLAY that's at work, which has everything drawn immediately shown.

Back to your examples, try this:

Code: QB64: [Select]
  1.     _PUTIMAGE (0, 0), test_handle&, , , _SMOOTH
  2.     _LIMIT 30

Your image will be visible as it's being refreshed with enough speed for you to have time to see it. Hardware images are cleared/refreshed at ~60hz.
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: Raven_Singularity on April 18, 2019, 12:06:06 am
I'm asking why _AUTODISPLAY (after using _DISPLAY) followed by a _PUTIMAGE does not display a visible image on the screen?

It should no longer be buffering the output.  How am I not understanding the feature?


"_COPYIMAGE will fail if you try to COPYIMAGE a hardware image"

Why?  How then are you supposed to duplicate a hardware image?
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: FellippeHeitor on April 18, 2019, 12:22:37 am
Quote
I'm asking why _AUTODISPLAY (after using _DISPLAY) followed by a _PUTIMAGE does not display a visible image on the screen?
It's a hardware image. If you're not refreshing it on screen it'll show for a fraction of second and go away, that's their nature.

Quote
How then are you supposed to duplicate a hardware image?
You don't.

Hardware images are immutable. You don't draw on them. They are good for displaying, as they're faster and use up less CPU.

The usual practice is to draw on software, convert to hardware, display. Need to update? Redraw on software, convert to hardware, display.

If you really need more than one identical copy of an image in hardware mode, use _COPYIMAGE on the original software version - twice.
Title: Re: Why would _PUTIMAGE appear behind the CLS background colour?
Post by: Raven_Singularity on April 18, 2019, 01:25:49 am
I guess I still do not understand the difference between hardware and software images.  The wiki pages have not helped clarify it for me at all.

I also don't understand why QB64 wouldn't support copying a hardware image -- internally it should be just as simple as copying a software image, no?

Why would being immutable affect copying the image, when copying does not alter the original?

What does "refreshing it on screen" mean?

"it'll show for a fraction of second and go away"

Does this mean it will only display for the current screen refresh?

"If you really need more than one identical copy of an image in hardware mode, use _COPYIMAGE on the original software version - twice."

I am loading the images from disk as hardware images, there are no original software images to my knowledge.


My objective is to leave the original image alone, while applying alpha blending for screen display.


This is the code that I was going to be trying, but because of not being able to copy the hardware image I haven't been able to test if it actually works yet:
Code: QB64: [Select]
  1.                      Translucent_Copy = _COPYIMAGE(Objects(Object_ID).Handle)
  2.                      Image_Memory = _MEMIMAGE(Translucent_Copy)
  3.                      Offset_Current = Image_Memory.OFFSET
  4.                      Offset_End = Offset_Start + (Objects(Object_ID).Width_Orig * Objects(Object_ID).Height_Orig * 4)
  5.  
  6.                      IF Offset_Start = Offset_End THEN
  7.                         PRINT "FATAL IMAGE ERROR": ERROR 999: END
  8.                      END IF
  9.  
  10.                      DO
  11.                         Alpha_Original = _MEMGET(Image_Memory, Offset_Current + 3, _UNSIGNED _BYTE)
  12.                         _MEMPUT Image_Memory, Offset_Current + 3, CINT(Alpha_Original * Objects(Object_ID).Opacity) AS _UNSIGNED _BYTE
  13.                         Offset_Current = Offset_Current + 4
  14.                      LOOP UNTIL Offset_Current = Offset_End
  15.  
  16.                      _PUTIMAGE (Objects(Object_ID).X + Offset_X#(Objects(Object_ID).Width, Objects(Object_ID).Orient_X), Objects(Object_ID).Y + Offset_Y#(Objects(Object_ID).Height, Objects(Object_ID).Orient_Y))-(Objects(Object_ID).X + Objects(Object_ID).Width - 1 + Offset_X#(Objects(Object_ID).Width, Objects(Object_ID).Orient_X), Objects(Object_ID).Y + Objects(Object_ID).Height - 1 + Offset_Y#(Objects(Object_ID).Height, Objects(Object_ID).Orient_Y)), Translucent_Copy, , , _SMOOTH
  17.                      _MEMFREE Image_Memory
  18.                      _FREEIMAGE Translucent_Copy
  19.  


Should I be creating a new software image, then reading the hardware image pixel data from memory and writing the alpha blended version onto the software image, or how should I go about this?

Are there any OpenGL functions I can call directly for displaying a hardware image with proper alpha blending (respecting the original image's preexisting alpha values), i.e. display the original hardware image at 0.50 or 0.84 opacity?


Edit:

The wiki references Galleon's OpenGL demo from three pages with the link /gl_package.zip]http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/gl_package.zip (http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there), but this link doesn't work.  Any working link for the demo?  I was curious to see what OpenGL functionality there is.

Where can I read up on what library functions are internally available to QB64 cross-platform, for use with DECLARE?
Title: Re: Understanding hardware images
Post by: SMcNeill on April 18, 2019, 02:08:53 am
Think of hardware images like you would printing to a printer.  It goes out, never comes back.  You might LPRINT #1, text$, but you won’t ever see an LINPUT command to read input back from that printer.

In a very similar way, hardware images are sent out to your GPU, with that one-way communication.  You don’t read them back.

They basic way they work is in 3 steps:
1)  create the hardware image and send it to the GPU (_COPYIMAGE ,33 is the easiest way to do this)
2)  display the image with _DISPLAY
3)  purge the image from the GPU after display (done automatically)

Without _DISPLAY, hardware images won’t display; the GPU waits for the call to render them for you.



If you need to blend, or alter, an image, you want to keep it as a software image.  You can’t blend a picture once it’s printed, can you?  By the same token, you can’t blend the hardware image. 

Title: Re: Understanding hardware images
Post by: Raven_Singularity on April 23, 2019, 10:26:18 am
So the only way to use hardware images is to keep all the images as software, but also copy them as hardware for fast display?  That would double the RAM usage, I presume.  At least, use as much extra video RAM as the images in RAM.

But why can't the GPU images be read back to being software images?  Video cards are two-way, not one-way like your printing example.  There's no reason why they shouldn't be copyable.


Any clues on my other questions:

1. How can I find out what internal QB64 library functionality is available through DECLARE?

2. Is there OpenGL functionality available which can render hardware images with partial translucency (without changing the original hardware image)?
Title: Re: Understanding hardware images
Post by: Petr on April 23, 2019, 01:59:23 pm
Hi. For better understand OpenGL texturing in QB64 please look to your QB64 instalation folder to Programs/samples/open_gl/simple_example.bas   This program use texturing but not so directly as C, but with Galleon's functions writed in OpenGL / QB64. Specially look to SUB GLH_Select_Texture and FUNCTION DONT_USE_GLH_New_Texture_Handle.

Hardware images are images loaded into OpenGL in the same way, but then are in memory area reserved with OpenGL and not with QB64.
Title: Re: Understanding hardware images
Post by: Raven_Singularity on April 27, 2019, 07:05:06 pm
Why does the function name start with "DONT_USE_"?

Doesn't seem encouraging, lol.
Title: Re: Understanding hardware images
Post by: Ashish on April 28, 2019, 10:00:43 am

1. How can I find out what internal QB64 library functionality is available through DECLARE?

2. Is there OpenGL functionality available which can render hardware images with partial translucency (without changing the original hardware image)?
for first question,  functions which are available in libqb.cpp, glut, glu, glew are available. You can check them inside internal/c/.... folder.

for second one, you can use the following example to render software images using OpenGL in realtime. The advantage will be that you can also modify image whenever needed.

Code: QB64: [Select]
  1. _TITLE "Using OpenGL to Render partial translucent images"
  2. SCREEN _NEWIMAGE(600, 600, 32)
  3.  
  4. img& = _LOADIMAGE("rainbow.png")
  5.  
  6. glAllow = -1
  7.     mouseX = _MOUSEX: mouseY = _MOUSEY
  8.     _LIMIT 30
  9.  
  10. SUB _GL ()
  11.     SHARED glAllow, img&, mouseX, mouseY
  12.     STATIC glInit
  13.  
  14.     IF glAllow = 0 THEN EXIT SUB
  15.  
  16.     _glMatrixMode _GL_MODELVIEW
  17.  
  18.     putimageGL mouseX - 100, mouseY - 100, mouseX + 100, mouseY + 100, img&
  19.  
  20.  
  21. SUB putimageGL (x1, y1, x2, y2, img_handle&)
  22.     IF img_handle& < -1 THEN
  23.         DIM m AS _MEM
  24.         DIM glTex&
  25.         m = _MEMIMAGE(img_handle&)
  26.         _glGenTextures 1, _OFFSET(glTex&)
  27.         _glBindTexture _GL_TEXTURE_2D, glTex&
  28.  
  29.         _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_WRAP_S, _GL_CLAMP
  30.         _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_WRAP_T, _GL_CLAMP
  31.         _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  32.         _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_NEAREST
  33.  
  34.         _glTexImage2D _GL_TEXTURE_2D, 0, _GL_RGBA, _WIDTH(img_handle&), _HEIGHT(img_handle&), 0, _GL_BGRA_EXT, _GL_UNSIGNED_BYTE, m.OFFSET
  35.  
  36.         _MEMFREE m
  37.         'converting 2D coordinates into OpenGL 2D coordinates
  38.         px1 = map(x1, -_WIDTH * 0.5, 1.5 * _WIDTH, -2, 2)
  39.         px2 = map(x2, -_WIDTH * 0.5, 1.5 * _WIDTH, -2, 2)
  40.         py1 = map(y1, -_WIDTH * 0.5, 1.5 * _WIDTH, 2, -2)
  41.         py2 = map(y2, -_WIDTH * 0.5, 1.5 * _WIDTH, 2, -2)
  42.  
  43.         _glEnable _GL_TEXTURE_2D
  44.         _glEnable _GL_BLEND
  45.  
  46.         _glBindTexture _GL_TEXTURE_2D, glTex&
  47.  
  48.         _glBegin _GL_QUADS
  49.         _glTexCoord2f 0, 0
  50.         _glVertex2f px1, py1
  51.         _glTexCoord2f 1, 0
  52.         _glVertex2f px2, py1
  53.         _glTexCoord2f 1, 1
  54.         _glVertex2f px2, py2
  55.         _glTexCoord2f 0, 1
  56.         _glVertex2f px1, py2
  57.         _glEnd
  58.  
  59.         _glDeleteTextures 1, _OFFSET(glTex&)
  60.  
  61.     END IF
  62.  
  63. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  64.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  65.  
Title: Re: Understanding hardware images
Post by: Raven_Singularity on April 29, 2019, 02:54:30 pm
Thank you, Ashish.  I will investigate how this works later.  After converting my app to software images my code using _MEM for partial translucency is working.  It's fairly fast, but OpenGL accelleration should improve the speed, I imagine.

One question:

In your code example it appears to just be drawing the image as-is.  Is there a way to apply an opacity level when drawing the image to the screen?  Such as opacity = 0.500.
Title: Re: Understanding hardware images
Post by: Petr on April 30, 2019, 03:46:51 pm
Hi. Is this what you're looking for? Change the transparency by pressing + or - on the numeric keypad.

Code: QB64: [Select]
  1.  
  2. _TITLE "Using OpenGL to Render partial translucent images"
  3. SCREEN _NEWIMAGE(600, 600, 32)
  4.  
  5. img& = _LOADIMAGE("rainbow.png")
  6. glAllow = -1
  7. na = 127
  8.  
  9.     mouseX = _MOUSEX: mouseY = _MOUSEY
  10.     _LIMIT 30
  11.     k& = _KEYHIT
  12.     IF k& = 43 THEN na = na + 1 'numerical +
  13.     IF k& = 45 THEN na = na - 1 'numerical -
  14.     IF na > 255 THEN na = 255
  15.     IF na < 0 THEN na = 0
  16.     IF oldNA <> na THEN
  17.         _SETALPHA na, _RGBA32(0, 0, 0, 0) TO _RGBA32(255, 255, 255, 255), img&
  18.        oldNA = na    
  19. LOOP UNTIL k& = 27
  20.  
  21. SUB _GL ()
  22.     SHARED glAllow, img&, mouseX, mouseY
  23.     STATIC glInit
  24.  
  25.     IF glAllow = 0 THEN EXIT SUB
  26.  
  27.     _glMatrixMode _GL_MODELVIEW
  28.  
  29.     putimageGL mouseX - 100, mouseY - 100, mouseX + 100, mouseY + 100, img&
  30.  
  31.  
  32. SUB putimageGL (x1, y1, x2, y2, img_handle&)
  33.     IF img_handle& < -1 THEN
  34.         DIM m AS _MEM
  35.         DIM glTex&
  36.         m = _MEMIMAGE(img_handle&)
  37.         _glGenTextures 1, _OFFSET(glTex&)
  38.         _glBindTexture _GL_TEXTURE_2D, glTex&
  39.  
  40.         _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_WRAP_S, _GL_CLAMP
  41.         _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_WRAP_T, _GL_CLAMP
  42.         _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  43.         _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_NEAREST
  44.  
  45.         _glTexImage2D _GL_TEXTURE_2D, 0, _GL_RGBA, _WIDTH(img_handle&), _HEIGHT(img_handle&), 0, _GL_BGRA_EXT, _GL_UNSIGNED_BYTE, m.OFFSET
  46.  
  47.         _MEMFREE m
  48.         'converting 2D coordinates into OpenGL 2D coordinates
  49.         px1 = map(x1, -_WIDTH * 0.5, 1.5 * _WIDTH, -2, 2)
  50.         px2 = map(x2, -_WIDTH * 0.5, 1.5 * _WIDTH, -2, 2)
  51.         py1 = map(y1, -_WIDTH * 0.5, 1.5 * _WIDTH, 2, -2)
  52.         py2 = map(y2, -_WIDTH * 0.5, 1.5 * _WIDTH, 2, -2)
  53.  
  54.         _glEnable _GL_TEXTURE_2D
  55.         _glEnable _GL_BLEND
  56.  
  57.         _glBindTexture _GL_TEXTURE_2D, glTex&
  58.  
  59.         _glBegin _GL_QUADS
  60.         _glTexCoord2f 0, 0
  61.         _glVertex2f px1, py1
  62.         _glTexCoord2f 1, 0
  63.         _glVertex2f px2, py1
  64.         _glTexCoord2f 1, 1
  65.         _glVertex2f px2, py2
  66.         _glTexCoord2f 0, 1
  67.         _glVertex2f px1, py2
  68.         _glEnd
  69.  
  70.         _glDeleteTextures 1, _OFFSET(glTex&)
  71.  
  72.     END IF
  73.  
  74. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  75.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  76.  
  77.  
  78.  

Ashish wrote this program absolutely brilliantly, because as it did, you can using textured movies.
Title: Re: Understanding hardware images
Post by: Raven_Singularity on April 30, 2019, 05:58:15 pm
I'm not able to see what your example does at the moment, but I started this thread because _SETALPHA does not respect an image's pre-existing partially translucent pixels.
Title: Re: Understanding hardware images
Post by: Petr on May 01, 2019, 06:19:48 am
Hi. So ... first I wrote a program that confirms what you say. SETALPHA adds a layer with transparency over the original colors. This shows the first part of the program. Then press Esc, please be patient and press + and - to set the alpha channel to rainbow.png for each pixel. I suppose this will be what you're looking for. Gradually extinguish and light up pixels based on their original values. I used slow commands, it can be speeded up if  MEM functions are used.

After pressing minus, the alpha is increased everywhere, not to the same value, but by the previous value of a particular pixel. Note that the blackness of the background around the circle also increases (the number in the upper left corner disappears). Plus shrinks transparency.

Code: QB64: [Select]
  1. 'create transparent image
  2. om = _NEWIMAGE(400, 300, 32)
  3. FOR D = 100 TO 300 STEP 50
  4.     LINE (D, 100)-(D + 49, 200), _RGBA32(255, 255, 255, D - 50), BF
  5.  
  6.  
  7.  
  8.  
  9. nm = _COPYIMAGE(om, 32)
  10. _SETALPHA 25, _RGBA32(0, 0, 0, 0) TO _RGBA32(255, 255, 255, 255), nm
  11.  
  12. SCREEN _NEWIMAGE(800, 600, 32)
  13. _MOUSEMOVE 505, 104
  14. _PUTIMAGE (1, 1), om
  15. _PUTIMAGE (400, 1), nm
  16.  
  17.     PCOPY 1, _DISPLAY
  18.     _SOURCE 0
  19.     alpha1 = _ALPHA32(POINT(_MOUSEX - 400, _MOUSEY))
  20.     alpha2 = _ALPHA32(POINT(_MOUSEX, _MOUSEY))
  21.  
  22.     LOCATE 1, 1: PRINT "Left is original image. Right is image with applied SETALPHA 25 to original image."
  23.     LOCATE 2, 1: PRINT "Original Alpha: "; alpha1; "New Alpha: "; alpha2
  24.     LOCATE 3, 1: PRINT "Press ESC for quit."
  25.     IF _MOUSEX > 0 AND _MOUSEY > 0 THEN
  26.         IF _MOUSEX < 505 THEN _MOUSEMOVE 505, _MOUSEY
  27.         IF _MOUSEY > 200 THEN _MOUSEMOVE _MOUSEX, 200
  28.  
  29.         IF _MOUSEY < 104 THEN _MOUSEMOVE _MOUSEX, 104
  30.         IF _MOUSEX > 750 THEN _MOUSEMOVE 750, _MOUSEY
  31.     END IF
  32.     PSET (_MOUSEX - 400, _MOUSEY), _RGB32(255, 255, 255) - POINT(_MOUSEX - 400, _MOUSEY)
  33.     _DISPLAY
  34.  
  35.     LINE (0, 0)-(800, 100), _RGB32(0, 0, 0), BF
  36.  
  37. _FREEIMAGE om 'original alpha
  38. _FREEIMAGE nm 'new alpha
  39.  
  40.  
  41. im = _LOADIMAGE("rainbow.png", 32)
  42. W = _WIDTH(im)
  43. H = _HEIGHT(im)
  44. DIM Alpha(W, H) AS _UNSIGNED _BYTE
  45. 'DIM newAlpha AS _UNSIGNED _BYTE 'uncomment it for show how it works with owerflow QB64 solution
  46. FOR y = 0 TO H - 1
  47.     FOR x = 0 TO W - 1
  48.         Alpha(x, y) = _ALPHA32(POINT(x, y))
  49. NEXT x, y
  50. _PUTIMAGE (0, 0), im
  51.  
  52.  
  53. DO UNTIL i$ = CHR$(27)
  54.     CLS
  55.     i$ = INKEY$
  56.     SELECT CASE i$
  57.         CASE "+": A = A + 1
  58.         CASE "-": A = A - 1
  59.  
  60.     END SELECT
  61.     LOCATE 1, 1: PRINT A
  62.  
  63.     FOR y = 0 TO H - 1
  64.         FOR x = 0 TO W - 1
  65.             newAlpha = Alpha(x, y) + A
  66.             _SOURCE im
  67.             CurrentColor~& = POINT(x, y)
  68.             IF newAlpha < 0 THEN newAlpha = 0
  69.             NewColor~& = _RGBA32(_RED32(CurrentColor~&), _GREEN32(CurrentColor~&), _BLUE32(CurrentColor~&), newAlpha)
  70.             PSET (x, y), NewColor~&
  71.     NEXT x, y
  72.     i$ = ""
  73.     _DISPLAY
  74.