Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER for Video Editing/Mangling

Reply
 
Thread Tools Display Modes
Old 02-10-2022, 06:24 AM   #1
papagirafe
Human being with feelings
 
papagirafe's Avatar
 
Join Date: Aug 2020
Location: Brasil
Posts: 679
Default gfx_img_alloc() ... transparent! (2022-06-16 update)

Hi folks,

I lost the page where I found this magical trick, but here is a code snippet I made to allocate an temporary image with an alpha plane (i.e. with transparent background).Of course you need to gfx_blit() with mode=0x10000. Hope it helps in your presets coding!

Code:
function gfx_img_alloc_transparent(w,h) 
(
  img=gfx_img_alloc();           // first, image handle only
  gfx_img_resize(img,-1,-1);     // incantation to summon alpha plane
  gfx_img_resize(img,w,h);       // real size now
  gfx_set(0,0,0,0,0x10000,img);  // 100% transparent "black"
  gfx_fillrect(0,0,w,h);         
  img;
);

Last edited by papagirafe; 06-16-2022 at 02:13 PM.
papagirafe is offline   Reply With Quote
Old 04-14-2022, 10:16 AM   #2
ashcat_lt
Human being with feelings
 
Join Date: Dec 2012
Posts: 7,271
Default

In messing with this, I think I've found that it's kind of not that complicated but also kind of sensitive to conditions. The initial resize just has to make it 0 or less in one direction or another, then the second can be to whatever size you want. _alloc itself seems to never really be necessary since the first resize accomplishes the same thing. It does however have to happen in RGBA colorspace. If the rest of your preset needs to be in RGBA or doesn't care anyway, there's no point in messing with that in the alloc function, but if we want it to be portable...

When we blit or draw into that transparent canvas, we also need to be in RGBA colorspace, and from what I can tell, it pretty much has to be mode 0.

When we blit from this transparent canvas, which colorspace we use doesn't really matter...except that some of the modes require a specific setting. Modes 17-19 always need YV12, and that works fine even with the transparency. Modes 1 and 3 don't care either way, except that 3 is said to be "very different" depending on which you choose. Mode 0 for whatever reason needs to be in RGBA mode. In other blend operations, it doesn't matter for this mode, but in this one case of the transparent source, it does seem to matter.

Here is a very simple preset that includes functions for allocating, blitting to, and blitting from the transparent canvas. Hope it helps. It seems to work, though honestly this whole process has been pretty hit or miss. If you have any issues, comments, or concerns, we'll try to figure it out.

Code:
//@param1:m_ 'mode' 0 0 19 10 1

colorspace = 'YV12';
function gfx_alloc_trans (img*, w, h)
  local (o_colorspace)
  (o_colorspace = colorspace; 
   colorspace ='RGBA';
   img = gfx_img_resize (img, 0, 0, 1);
   img = gfx_img_resize (img, w, h, 0);
   colorspace = o_colorspace;
   img;
  );
gfx_alloc_trans (trans, project_w, project_h);  
function gfx_blit_to_trans (src*, x, y, w, h, src_x, src_y, src_w, src_h)
  local (o_colorspace, o_mode)
  (o_colorspace = colorspace; 
   colorspace ='RGBA';
   o_mode = gfx_mode;
   gfx_mode = 0;
   gfx_blit (src, 0, x, y, w, h, src_x, src_y, src_w, src_h);
   colorspace = o_colorspace;
   gfx_mode = o_mode;
   dest;
  );
function gfx_blit_from_trans (src*, x, y, w, h, src_x, src_y, src_w, src_h)
  local (o_colorspace, o_mode)
  (o_colorspace = colorspace;
   o_mode = gfx_mode;
   gfx_mode == 0 ? 
     (colorspace = 'RGBA';
      gfx_mode = 0x10000;):gfx_mode = gfx_mode|0x10000;
   gfx_blit (src, 0, x, y, w, h, src_x, src_y, src_w, src_h);
   colorspace = o_colorspace;
   gfx_mode = o_mode;
  );
  
gfx_mode = m_;  
input = 0;
gfx_dest = trans;
gfx_blit_to_trans (input, i, i, 100, 100, 0, 0, project_w, project_h);
gfx_mode = 0;
gfx_dest = -1;
gfx_blit (0);
gfx_mode = m_;
gfx_blit_from_trans (trans, 0, 0, project_w, project_h, 0, 0, project_w, project_h);
i += 10;
i %= project_w - 100;
ashcat_lt is online now   Reply With Quote
Old 04-14-2022, 02:41 PM   #3
papagirafe
Human being with feelings
 
papagirafe's Avatar
 
Join Date: Aug 2020
Location: Brasil
Posts: 679
Default

Quote:
Originally Posted by ashcat_lt View Post
In messing with this, I think I've found that it's kind of not that complicated but also kind of sensitive to conditions. The initial resize just has to make it 0 or less in one direction or another, then the second can be to whatever size you want. _alloc itself seems to never really be necessary since the first resize accomplishes the same thing. It does however have to happen in RGBA colorspace. If the rest of your preset needs to be in RGBA or doesn't care anyway, there's no point in messing with that in the alloc function, but if we want it to be portable...

When we blit or draw into that transparent canvas, we also need to be in RGBA colorspace, and from what I can tell, it pretty much has to be mode 0.

When we blit from this transparent canvas, which colorspace we use doesn't really matter...except that some of the modes require a specific setting. Modes 17-19 always need YV12, and that works fine even with the transparency. Modes 1 and 3 don't care either way, except that 3 is said to be "very different" depending on which you choose. Mode 0 for whatever reason needs to be in RGBA mode. In other blend operations, it doesn't matter for this mode, but in this one case of the transparent source, it does seem to matter.
<snip>
Wow! Thanks for pushing this analysis much further! So far I used mainly transparencies in my video compositions so I explored almost only RGBA colorspaces. I am in the process of creating a new library of modular presets (closer to the sound fx concept) that rely a lot on this "transparent" allocation. Your insight will help to make it more robust. More on this upcoming library after my current project deadline.
papagirafe is offline   Reply With Quote
Old 04-14-2022, 09:03 PM   #4
ashcat_lt
Human being with feelings
 
Join Date: Dec 2012
Posts: 7,271
Default

Quote:
Originally Posted by papagirafe View Post
...almost only RGBA colorspaces...
Well, I tend to abuse mode 19 (absolute difference) quite a bit, so...

In the example I posted above, it probably doesn't need as many colorspace changes as it has, but I put them in to show that it could work, and to give places to try changing it and see what happens. That example in itself is kind of nonsensical since to blit one rectangular image onto another doesn't really need transparent edges. If we wanted multiple rectangular images on one canvas with transparency in between for whatever reason, or wanted to do that nested rotoblit thing that I talked about in that other thread, we'd need this. Also, what if we want circles or polygons. Which....

It occurred to me today that in RGBA, mode 3 (multiply) can be used as a sort of transparency masking thing. Because, ya know, x * 0 = 0, and if x happens to be a for alpha... The first use I have for this is circles. We make a white circle (because 1 * x = x) on a transparent background. We multiply that onto whatever else. Now that thing is inside a circle. The hard part is making a good circle to begin with. I'm working on that. Then on to polygons.

Course, there's still no good way to pass transparency from one track - or even VP instance - to another. If you really wanted to be that guy, you could cram the whole thing into gmem to be read wherever. I have, in fact, passed a couple of pixels between a JSFX and the VP in that fashion. It's a stupid waste of every resource with a lot of limits, but it can be done in a pinch.

Definitely interested to see what you've got coming together!

Last edited by ashcat_lt; 04-14-2022 at 09:09 PM.
ashcat_lt is online now   Reply With Quote
Old 04-15-2022, 08:08 AM   #5
papagirafe
Human being with feelings
 
papagirafe's Avatar
 
Join Date: Aug 2020
Location: Brasil
Posts: 679
Default

Quote:
Originally Posted by ashcat_lt View Post
Well, I tend to abuse mode 19 (absolute difference) quite a bit, so...

In the example I posted above, it probably doesn't need as many colorspace changes as it has, but I put them in to show that it could work, and to give places to try changing it and see what happens. That example in itself is kind of nonsensical since to blit one rectangular image onto another doesn't really need transparent edges. If we wanted multiple rectangular images on one canvas with transparency in between for whatever reason, or wanted to do that nested rotoblit thing that I talked about in that other thread, we'd need this. Also, what if we want circles or polygons. Which....

It occurred to me today that in RGBA, mode 3 (multiply) can be used as a sort of transparency masking thing. Because, ya know, x * 0 = 0, and if x happens to be a for alpha... The first use I have for this is circles. We make a white circle (because 1 * x = x) on a transparent background. We multiply that onto whatever else. Now that thing is inside a circle. The hard part is making a good circle to begin with. I'm working on that. Then on to polygons.

Course, there's still no good way to pass transparency from one track - or even VP instance - to another. If you really wanted to be that guy, you could cram the whole thing into gmem to be read wherever. I have, in fact, passed a couple of pixels between a JSFX and the VP in that fashion. It's a stupid waste of every resource with a lot of limits, but it can be done in a pinch.

Definitely interested to see what you've got coming together!
Ok. Lots of stuff here and so little time to absorb it. I am definitely going to explore the RGBA mode 3 for masks. I do have in my upcoming library an extremely fast mask preset that uses the xformblit() alpha hability but it lacks precision.

For transparency across video tracks/item transforms, I found reliable way to do it but it's not ready for prime time yet, patience my friend...

For circle, an non optimal but very simple way is to draw a square instead of text with the method I used in my "text with outline/shadow". Unfortunately I got no time to test it for now.

Warning: communication between JSFX and VP has timing side effects as I found with my debug console. When sending to VP to JSFX, the JSFX receives the video prefetch buffer not what you see. The opposite should not be as problematic since the JSFX sends to the prefetch buffer. Also sustaining 30+ frame second is difficult.
papagirafe is offline   Reply With Quote
Old 06-16-2022, 02:02 PM   #6
papagirafe
Human being with feelings
 
papagirafe's Avatar
 
Join Date: Aug 2020
Location: Brasil
Posts: 679
Default New version based on new info

Hi!

Based on new information from Justin in this thread https://forum.cockos.com/showthread.php?t=267784 here is a new and more robust version of the transparent image allocation routine.

Code:
function gfx_img_alloc_alpha(w,h) 
(
  gfx_set(0,0,0,1,0,-1,0); // set black, transparent, clobber
  gfx_img_alloc(w,h,1); // allocate and clear image with above settings
);
papagirafe is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 10:08 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.