02-10-2022, 06:24 AM | #1 |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
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. |
04-14-2022, 10:16 AM | #2 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,271
|
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;
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika |
04-14-2022, 02:41 PM | #3 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
Quote:
|
|
04-14-2022, 09:03 PM | #4 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,271
|
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!
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika Last edited by ashcat_lt; 04-14-2022 at 09:09 PM. |
04-15-2022, 08:08 AM | #5 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
Quote:
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. |
|
06-16-2022, 02:02 PM | #6 |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
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 ); |
Thread Tools | |
Display Modes | |
|
|