Old 02-14-2018, 03:17 PM   #1
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default Q: GFX Red to Green Horizontal Gradient

Hi,

I don't get how rectgrad works,

How would you made a simple RED to GREEN horizontal gradient on full GFX width, in Lua ?

Thanks !

EDIT: Here is how close I get:


Code:
window_w = 600
window_h = 100

function init(window_w, window_h, window_x, window_y, docked)
  gfx.init("GFX" , window_w, window_h, docked, window_x, window_y)  -- name,w,h,dockstate,xpos,ypos
end

function Update()

  gfx.update()
  if gfx.getchar() ~= 27 then reaper.defer(run) else gfx.quit() end
end

-- DRAW IN GFX WINDOW
function run()
  


     x,y,w,h = 0, 0, gfx.w, gfx.h
     r,g,b,a = 1/gfx.w, 1/gfx.w, 0, 1
     drdx, dgdx, dbdx, dadx = 1-1/gfx.w, 1/gfx.w, 0, 1/gfx.w

    gfx.gradrect(x,y,w,h, r,g,b,a, drdx, dgdx, dbdx, dadx )

    gfx.update()
  
  --gfx.quit()
  Update()

end -- END DEFER


init(window_w, window_h)

run()

Last edited by X-Raym; 02-14-2018 at 03:30 PM.
X-Raym is offline   Reply With Quote
Old 02-14-2018, 04:17 PM   #2
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@Veto
Oh Thanks ! so we can put negarive value.



I don't understand the logic though ^^ very weird way to setup gradient (compare to CSS one for eg).

--
Also, the middle colors (red to brown to green instead of red to yellow to green) in this case seems match the Computer Color is Broken case explained by MinutePhysics.
https://www.youtube.com/watch?v=LKnqECcg6Gw
(the red to green exemple is shown in MP video).
EDIT: Oh non in fact it may be good. But I would still prefer bright yellow in middle ^^

Do you think we can go from Red to Green with nice yellow in the middle ?

Last edited by X-Raym; 02-14-2018 at 04:22 PM.
X-Raym is offline   Reply With Quote
Old 02-14-2018, 05:03 PM   #3
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@Veto
Perfect thank you !!

I'm experimenting a GFX progress bar system for scripts which take a long time to analysis and process things.



Don't know yet if the experiment will lead to successful results, but it worths the try.

I think it's pretty nice for the moment, thanks to you

I could add elapsed time, estimated time, or process step for eg too.
X-Raym is offline   Reply With Quote
Old 02-14-2018, 05:07 PM   #4
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Hmmm bad thing is that it takes way more time to process.

Above gradient was upgraded within a loop, 5000 times. It tooks about 3 seconds.

Without any GFX and feedback, it took 0.0037995456950739.

Maybe there is a way to optimized the drawing (like drawing only every second).

EDIT: I confirm, it is wayyyyy more quicker :P

Last edited by X-Raym; 02-14-2018 at 05:13 PM.
X-Raym is offline   Reply With Quote
Old 02-14-2018, 05:25 PM   #5
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@Veta
Quote:
Maybe it helps already if you draw it exactly gfx.w times?
Nice idea, it can be a way to keep progress bar smooth.

I need to find a the right balance between performance and smoothness :P

EDIT: redrawing every 0,01 (1/120 FPS approx) may be more performant in some cases than every gfx.w pixels, depending on the effectiveness of the loop.

Still, it is less effective than not having progress bar.

So maybe only for very long script.

Need a bit more testing :P

Last edited by X-Raym; 02-14-2018 at 05:34 PM.
X-Raym is offline   Reply With Quote
Old 02-14-2018, 07:24 PM   #6
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
Default

Draw gradient once to a blit buffer at script start.
mpl is offline   Reply With Quote
Old 02-15-2018, 02:09 AM   #7
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

I never use gfx.blit, I thought it was only for images.

I have to re-read lokasenna GUI tutorial, I'm a bit rusty with GFX :P

Last edited by X-Raym; 02-15-2018 at 02:48 AM.
X-Raym is offline   Reply With Quote
Old 02-15-2018, 02:55 AM   #8
IXix
Human being with feelings
 
Join Date: Jan 2007
Location: mcr:uk
Posts: 3,889
Default

Quote:
Originally Posted by X-Raym View Post
I never use gfx.blit, I thought it was only for images.

I have to re-read lokasenna GUI tutorial, I'm a bit rusty with GFX :P
Use it as much as you can to avoid drawing the same thing over and over. Draw once to a dedicated buffer and then just blit it back to the screen where/when you need it. Much faster.
IXix is online now   Reply With Quote
Old 02-15-2018, 03:12 AM   #9
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Understood, nice trick.

Did I miss something ?
Declaration (outside main loop)
Code:
  gfx.dest = 1
  gfx.gradrect(        0, 0, gfx.w / 2, gfx.h,    1, 0, 0, 1,             0, 2 / gfx.w, 0, 0)
  gfx.gradrect(gfx.w / 2, 0, gfx.w / 2, gfx.h,    1, 1, 0, 1,    -2 / gfx.w,         0, 0, 0)
  gfx.dest = - 1
... and in the main loop:
Code:
--gfx.blit(source, scale, rotation, srcx,  srcy,  srcw,  srch, destx, desty, destw, desth, rotxoffs, rotyoffs )
gfx.blit(       1,     1,        0,    0,    0,  gfx.w, gfx.h,    0,     0,  gfx.w, gfx.h)
It is just pure black.

If I put the gradient code instead of gfx.blit, I got the gradient.

Probably a small newbie issue :P

Last edited by X-Raym; 02-15-2018 at 03:38 AM. Reason: wrong id but still dont work
X-Raym is offline   Reply With Quote
Old 02-15-2018, 03:31 AM   #10
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
Default

<< assuming that .lua scripts can load files >>

If it is a fixed colour gradient I would generate it as a .png file.

Then load the file and select which part of it you want to display.
__________________
DarkStar ... interesting, if true. . . . Inspired by ...
DarkStar is online now   Reply With Quote
Old 02-15-2018, 05:41 AM   #11
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

This works perfectly !

Thanks for your assistance, you definitely nailed it.

I'll see if it can be used in some real scripts, but at least, I learned things with your help, and maybe others tool !

As my code is basically yours at few lines close... Here is mine :P
Code:
-- Progress Bar test
-- X-Raym
-- Designed for very long actions.
-- 02-15-2018
-- https://forum.cockos.com/showthread.php?p=1954480#post1954480
-- Thanks, Veto!

window_w = 600
window_h = 100
local reaper = reaper
local gfx = gfx

function sleep(s)
  local ntime = reaper.time_precise() + s
  repeat until reaper.time_precise() > ntime
end

function init(window_w, window_h, window_x, window_y, docked)
  gfx.init("GFX", window_w, window_h, docked, window_x, window_y) -- name,w,h,dockstate,xpos,ypos
  gfx.dest = 1
  gfx.setimgdim(gfx.dest, -1, -1) -- reset
  gfx.setimgdim(gfx.dest, gfx.w, gfx.h)
  gfx.gradrect(        0, 0, gfx.w / 2, gfx.h,    1, 0, 0, 1,             0, 2 / gfx.w, 0, 0)
  gfx.gradrect(gfx.w / 2, 0, gfx.w / 2, gfx.h,    1, 1, 0, 1,    -2 / gfx.w,         0, 0, 0)
  gfx.dest = - 1
end

function Update()
  gfx.update()
  if gfx.getchar() ~= 27 then reaper.defer(run) else gfx.quit() end
end

-- DRAW IN GFX WINDOW
function run()
  gfx.dest = 0
  gfx.gradrect(        0, 0, gfx.w / 2, gfx.h,    1, 0, 0, 1,             0, 2 / gfx.w, 0, 0)
  gfx.gradrect(gfx.w / 2, 0, gfx.w / 2, gfx.h,    1, 1, 0, 1,    -2 / gfx.w,         0, 0, 0)
  gfx.dest = - 1
  gfx.set(0, 0, 0, 1)
  
  local time_loop = reaper.time_precise()
  local redraw = 0

  local val = 10
  for i = 0, val do
    local time_loop_start = reaper.time_precise()

    if time_loop_start - time_loop > 0.001 then -- 120 FPS screen refresh rate
      redraw = redraw + 1
      local time_loop = time_loop_start
      --gfx.blit(source, scale, rotation, srcx,  srcy,  srcw,  srch, destx, desty, destw, desth, rotxoffs, rotyoffs )
      gfx.blit(       1,     1,        0,    0,    0,  gfx.w, gfx.h,    0,     0,  gfx.w, gfx.h)
      gfx.rect(gfx.w * i / val, 0, gfx.w - gfx.w * i / val, gfx.h )
      gfx.update()
    end
    sleep(0.1)
  end

  local time_off = reaper.time_precise()
  reaper.ShowConsoleMsg(tostring(time_off - time_start))
  gfx.quit()
  -- Update()

end -- END DEFER

reaper.ClearConsole()
time_start = reaper.time_precise()
init(window_w, window_h)

run()
Cheers !
X-Raym is offline   Reply With Quote
Old 12-19-2023, 04:23 PM   #12
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

For reference, I just made a function form this:




Code:
function DrawHorizontalGradient( x, y, w, h, r1, g1, b1, a1, r2, g2, b2, a2 )
  gfx.gradrect( x, y, w, h,  r1, g1, b1, a1,  (r2-r1)/w, (g2-g1)/w, (b2-b1)/w, (a2-a1)/w) 
end

function run()
  
  DrawHorizontalGradient( 0, 0, gfx.w, gfx.h,
    1, 0, 0, 1, -- Color 1
    0, 1, 1, 1 -- Color 2
  )
  
  gfx.update()
  if gfx.getchar() ~= 27 then reaper.defer(run) else gfx.quit() end

end -- END DEFER

gfx.init("GFX" , 640, 270)  -- name,w,h,dockstate,xpos,ypos
run()

it wasn't easy !




Note: this is the regular RGB gradient as seen in CSS, it is not the beaitful one as in veto trick (for which red to green pass through yellow, and not by some kind of desaturated smudgy color, though this is standard way to draw gradient).
X-Raym is offline   Reply With Quote
Old 12-20-2023, 10:13 AM   #13
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 957
Default

X-Raym,
Thank you! This topic helped me a long time ago.
I like to use a "gradient to transparency" to simulate glows, soft shadows, or any other elements.

I made a mod of your script to clearly show how it works. While this is missing two gradient directions, right now I don't know how to do it. However, this code may serve as a starting point for someone:


Code:
function DrawTransparentGradient( x, y, w, h, r1, g1, b1, a1, mode)

  if mode == 0 then  -- from left to right
     gfx.gradrect( x, y, w, h,     r1, g1, b1, 0,     0, 0, 0, a1/w)
     elseif mode == 1 then  -- from bottom to top
     gfx.gradrect( x, y, w, h,     r1, g1, b1, 0,     0, 0, 0, 0,     0, 0, 0, a1/h)
  end

end

function run()
  
  DrawTransparentGradient( 0, 0, gfx.w, gfx.h,
    0, 1, 0, 1, -- Color
    0 -- Mode (direction)
  )
  
  gfx.update()
  if gfx.getchar() ~= 27 then reaper.defer(run) else gfx.quit() end

end -- END DEFER

gfx.init("GFX" , 640, 270)  -- name,w,h,dockstate,xpos,ypos
run()
cool is online now   Reply With Quote
Old 12-20-2023, 11:25 AM   #14
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@cool
Glad it helped ?

And how would you made left to right gradient ?


--


I managed to make a full color gradient, by interpolating hues between two points, and draging a gfx.line at every pixel. It is a bit CPU heavy for what it is (just a gradrient of color), but here is a demo in action.







EDIT: it was hard. 😫
X-Raym is offline   Reply With Quote
Old 12-20-2023, 09:48 PM   #15
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 957
Default

Quote:
Originally Posted by X-Raym View Post
@cool
And how would you made left to right gradient ?
I have a working solution inside MKSlicer, but I couldn’t do it in the code above: when setting negative alpha value, the image simply disappears. I don't know why this is happening.

This is what the code looks like inside the Slicer. I've simplified some things, but you'll get the gist:

Code:
grad_w = 50 -- gradient width, px
gfx.gradrect(x-grad_w, y, grad_w, h,    r, g, b, 0,   0, 0, 0, a/grad_w) -- right to left
gfx.gradrect(x, y, grad_w, h,    r, g, b, a,    0, 0, 0, -a/grad_w) -- left to right
Quote:
Originally Posted by X-Raym View Post
EDIT: it was hard. 😫
It looks complicated even in the picture

Last edited by cool; 12-20-2023 at 09:53 PM.
cool is online now   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 01:40 PM.


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