Open jpcima opened 2 years ago
Did you have a particular implementation plan here already? Maybe myself or someone else in the community could help out.
EDIT: Nevermind, they map to this: https://github.com/jpcima/ysfx/blob/8ef69f9d6bef85b1b7da7cfe66b9f777f536cf4c/thirdparty/WDL/source/WDL/eel2/eel_lice.h
I think the REAPER JSFX likely use SWELL, the WDL "Simple Windows Emulation Layer"
This is the foundational cross-platform GFX and windowing lib that REAPER itself is built with.
IE, for gfx.rect()
, that might map to this:
https://github.com/justinfrankel/WDL/blob/master/WDL/swell/swell-gdi-generic.cpp#L279-L290
I am no expert though
For the JUCE example of using REAPER's embedded UI stuff, I had to figure out to draw the LICE bitmaps that REAPER hands to the render method into a JUCE component.
To do that is: https://github.com/juce-framework/JUCE/blob/master/examples/Plugins/ReaperEmbeddedViewPluginDemo.h#L329-L384
void doPaint (reaper::REAPER_FXEMBED_IBitmap* bitmap)
{
if (bitmap == nullptr || drawInfo == nullptr || bitmap->getWidth() <= 0 || bitmap->getHeight() <= 0)
return 0;
Image img (juce::Image::PixelFormat::ARGB, bitmap->getWidth(), bitmap->getHeight(), true);
Graphics g (img);
Image::BitmapData imgData { img, Image::BitmapData::readOnly };
const auto pixelsWidth = imgData.pixelStride * imgData.width;
auto* px = bitmap->getBits();
const auto rowSpan = bitmap->getRowSpan();
const auto numRows = bitmap->getHeight();
for (int y = 0; y < numRows; ++y)
std::memcpy (px + (y * rowSpan), imgData.getLinePointer (y), (size_t) pixelsWidth);
}
So maybe that eel_lice.h
header can be re-used, and then a method like this used to draw it on the JUCE Editor component?
(REAPER_FXEMBED_IBitmap
= LICE_IBitmap
)
Did you have a particular implementation plan here already?
Kind of yes, but it's not set in stone, there would be 2 ways to go at this problem.
to import SWELL+Lice+eel_lice.h which implements all of gfx as software renderer There's a bit of practical difficulty make it build it though, not entirely as trivial as it sounds.
to provide a library API which lets a user implement the entire graphics interface
only the method 2. would have the ability of accelerated rendering. (decent candidates for JUCE's graphics contexts, which can render both to GL and raster)
only the method 2. would have the ability of accelerated rendering. (decent candidates for JUCE's graphics contexts, which can render both to GL and raster)
Probably better to do the second one, I've noticed you've also kept the core of it decoupled from JUCE which is nice given the flexibility of re-using it in other environments/context
Probably better to do the second one, I've noticed you've also kept the core of it decoupled from JUCE which is nice given the flexibility of re-using it in other environments/context
It's a goal, given that this lib is not only for plugins but also for hosts, starting with Carla.
A thing about these graphics is they are modeled after Windows GDI software rendering. I'd really like to get Lice in if that's possible. Some parts of Swell give problems (eg. the windowing which pulls the Gdk dep and it's desired to avoid this) It might get away with it, if linking it with a Swell subset which is restricted to the GDI code only. That remains to verify.
There is success so far with getting Lice into the master branch. That means that drawing is going to be kept inside the library, which keeps the usage simple.
The library user should only provide the framebuffer of the window, and other information like mouse and key data, and Retina status.
The library user should only provide the framebuffer of the window, and other information like mouse and key data, and Retina status.
What exactly is a framebuffer?
Is it something you can get from a window pointer/handle, like HWND
on Windows or XID
(now called Window
I think) in X11 on Linux?
The framebuffer is an image that keeps the pixel data in RAM memory.
The current master has it implemented, and shows how to use it together with a juce::Image
.
This is checked working, which means the hardest work is done, next it will be about adding the graphics primitives. (which should be a copy-and-paste from eel_lice)
The framebuffer is an image that keeps the pixel data in RAM memory. The current master has it implemented, and shows how to use it together with a
juce::Image
.This is checked working, which means the hardest work is done, next it will be about adding the graphics primitives. (which should be a copy-and-paste from eel_lice)
We have liftoff! 🚀 Video clip below is incredible! Build was done ~5 minutes ago:
Yes, I've added a few more right now but there still remains to do some major ones. All I make so far is a tiny example, and not tried any actual plugins. Any elaborate ones which are worth testing?
desc:000 gfx2
out_pin:out
@sample
spl=0.0;
@gfx 600 400
gfx_r=rand(1);
gfx_g=rand(1);
gfx_b=rand(1);
cx=rand(gfx_w);
cy=rand(gfx_h);
cr=rand(10)+5;
gfx_circle(cx, cy, cr, 1);
n=n+1;
(n<500)?(gfx_clear=-1.0):(gfx_clear=0.0;n=0);
Any elaborate ones which are worth testing?
@JoepVanlier ("Saike") sets the bar for JSFX development IMO, his plugins are probably the golden standard as far as unit testing:
Big repo of them here:
The ones under the Basics
category would probably be good "first-goal" bars since they are more minimal in terms of UI than his other plugins:
BandSplitter
and BandJoiner
plugin UI's seem to work mostlyStereoBub
series can render the dial UI'sThere's also Geraint Luff's JSFX, which are fantastic:
ReEQ is another one. https://github.com/Justin-Johnson/ReJJ
Graphics are mostly working now, needs just these few features such as cursor and popup.
The status of gfx is supposed to be now implemented 100%.
The popup has needed a rewrite of gfx processing at plugin-side.
More precisely, the @gfx
is allowed to block indefinitely (by gfx_showmenu
), and so it can't happen on the main UI thread except by creating a modal loop; as a solution, @gfx
has been moved into a background thread.
https://www.reaper.fm/sdk/js/gfx.php
Note (1): this appears to be the default font https://int10h.org/oldschool-pc-fonts/fontlist/font?tandy1k-ii_200l
Note (2):
gfx_showmenu
is synchronous this blocks@gfx
from running, but not the entire host