- Which methods are called in which order (only a coarse overview)?
- What are the parameters to these methods? In the headers I saw some void pointers going around in some methods. I assume that this is a HWND on Windows?
- Does the host provide the parent window that my VST GUI window needs to become a child of or does it provide the window that my VST can directly paint on?
- What's the type of the void pointer on Mac and Linux?
- How can I communicate to the host that my window size has changed / needs to be changed? Both approaches would work for me: providing some predefined sizes or using dynamic resizing with a handle.
How to instantiate a custom VST GUI (no JUCE, no IPlug)?
- KVRist
- 415 posts since 28 Nov, 2013 from Germany
I am currently experimenting with writing my own little GUI framework using Cairo with FreeType2 (and later perhaps Harfbuzz) as the paiting back end. Unfortunately, the documentation on VST2.4 is rather sparse so I have some questions with regards to the protocol between a host and a VST concerning the GUI creation:
Passed 303 posts. Next stop: 808.
- KVRAF
- 2470 posts since 25 Sep, 2014 from Specific Northwest
Look in aeffeditor.h for what to override. How you proceed from there is up to you.
Basically, you only need to provide the window size before opening the GUI window. To display the window, it's an HWND in Windows and an NSView on the Mac. It's passed as "void* parent" iirc, so you only need to add the needed cast to attach your GUI view.
Resizing is a pain. Before, I did it in my NSView class, but with adding Windows code in using a third-party utility, I gave up and am making the user close and reopen to get the new GUI size (I'm not a Windows programmer.) When resizing, you just send a message to the host asking if the size change is okay and get a yea or a nay back before resizing your view.
As an aside, I believe for the Mac AU, the plugin provides the NSView instance to the host to stuff into an NSWindow and display. I'm using a third-party wrapper to make my AU version.
Basically, you only need to provide the window size before opening the GUI window. To display the window, it's an HWND in Windows and an NSView on the Mac. It's passed as "void* parent" iirc, so you only need to add the needed cast to attach your GUI view.
Resizing is a pain. Before, I did it in my NSView class, but with adding Windows code in using a third-party utility, I gave up and am making the user close and reopen to get the new GUI size (I'm not a Windows programmer.) When resizing, you just send a message to the host asking if the size change is okay and get a yea or a nay back before resizing your view.
As an aside, I believe for the Mac AU, the plugin provides the NSView instance to the host to stuff into an NSWindow and display. I'm using a third-party wrapper to make my AU version.
I started on Logic 5 with a PowerBook G4 550Mhz. I now have a MacBook Air M1 and it's ~165x faster! So, why is my music not proportionally better? 
-
- KVRian
- 882 posts since 24 Jun, 2002 from Berlin
although you may not want to use IPlug, you might find it useful to know i've been updating it to allow any UI framework to sit on top.
https://github.com/olilarkin/wdl-ol/tree/iplugquake
haven't looked at window resizing yet. not looking forward to that
https://github.com/olilarkin/wdl-ol/tree/iplugquake
haven't looked at window resizing yet. not looking forward to that
- KVRist
- Topic Starter
- 415 posts since 28 Nov, 2013 from Germany
Hi syntonica, hi hibrasil,
thanks for your replies! I already got some empty window going by just instantiating an AEffEditor and I already checked how IPlug is doing some things to get a better understanding of the protocol / interfaces. So I assume that I will have something running soon.
With regards to IPlug: I already have some small projects implemented with it but currently it's a rather fragile thing because I use MinGW and some CMake scripts that I wrote myself to build them. So there is always an uncertainty whether updating or changing branches will break my projects. That's also part of the reason why I am thinking about writing my own little GUI framework using Cairo because I hope that a smaller code base will give me more control and that it will also enable simple ports to Linux.
I saw in Oli's other thread that it's planned to implement CMake support. This would really help in my case because then I would not have to rely on my own crude build system. I don't want to register at an account at patreon but if I get IPlug build at some point without my own band aids then I might perhaps help with some implementations if that's something that's wanted.
Why is the branch called "quake" by the way? Because it is intended to run and be ported to any computing device like Quake?
thanks for your replies! I already got some empty window going by just instantiating an AEffEditor and I already checked how IPlug is doing some things to get a better understanding of the protocol / interfaces. So I assume that I will have something running soon.
With regards to IPlug: I already have some small projects implemented with it but currently it's a rather fragile thing because I use MinGW and some CMake scripts that I wrote myself to build them. So there is always an uncertainty whether updating or changing branches will break my projects. That's also part of the reason why I am thinking about writing my own little GUI framework using Cairo because I hope that a smaller code base will give me more control and that it will also enable simple ports to Linux.
I saw in Oli's other thread that it's planned to implement CMake support. This would really help in my case because then I would not have to rely on my own crude build system. I don't want to register at an account at patreon but if I get IPlug build at some point without my own band aids then I might perhaps help with some implementations if that's something that's wanted.
Why is the branch called "quake" by the way? Because it is intended to run and be ported to any computing device like Quake?
Passed 303 posts. Next stop: 808.
-
- KVRian
- 882 posts since 24 Jun, 2002 from Berlin
no.. there was a jucequake, and now there's an iplugquake 
contributions to iplug, bug fixes, documentation, features are much appreciated just as valuable as patrons
contributions to iplug, bug fixes, documentation, features are much appreciated just as valuable as patrons
- KVRAF
- 8476 posts since 12 Feb, 2006 from Helsinki, Finland
Host should first call getRect(), then open(void*).BlitBit wrote: [*] Which methods are called in which order (only a coarse overview)?
You get HWND and NSView as parameter for open() depending on platform.[*] What are the parameters to these methods? In the headers I saw some void pointers going around in some methods. I assume that this is a HWND on Windows?
You want to use the window that you get as the parent (eg. superview or parent HWND) for the editor window (or "view" in Cocoa) that you create. You can then either build the UI into that editor window/view, or use it as a parent for further windows.[*] Does the host provide the parent window that my VST GUI window needs to become a child of or does it provide the window that my VST can directly paint on?
If you do everything in one window/view, then that's all you need, but in some hosts you can run into problems if you add more than one child to the host window, so if your editor code involves more than one window/view, you still want just one "editor" window/view that can then acts as the parent for rest of your GUI hierarchy.
NSView to use as a superview for the view you create.[*] What's the type of the void pointer on Mac and Linux?
In theory you just call resizeWindow() on the plugin (and in theory this works even if you do it in response to some mouse-dragging, but in practice I've noticed some issues doing this). In practice it works "most of the time" in "most hosts" sometimes depending on weird stuff like whether the plugin editor has it's own window or embedded into another window (eg. Reaper can do both and IIRC resize only works reliably when it's on it's own window). Usually closing and reopening the editor will work even in hosts having problems though.[*] How can I communicate to the host that my window size has changed / needs to be changed? Both approaches would work for me: providing some predefined sizes or using dynamic resizing with a handle.[/list]
You might also want to update the rectangle as returned by getRect() so that the window will reopen with the correct size and also resize the actual window you've created (eg. SetWindowPos() on windows), since host will normally only resize the parent that contains the editor, not the editor itself.
- KVRist
- Topic Starter
- 415 posts since 28 Nov, 2013 from Germany
Thanks for all the help! I managed to get something running this weekend. 
Here's the current state with some prototypical test renderings:
Here's the current state with some prototypical test renderings:
You do not have the required permissions to view the files attached to this post.
Passed 303 posts. Next stop: 808.
-
- KVRian
- 882 posts since 24 Jun, 2002 from Berlin
- KVRist
- Topic Starter
- 415 posts since 28 Nov, 2013 from Germany
No, I don't use the OpenGL backend. Currently I perform the following steps during the rendering:hibrasil wrote:cool! are you using the opengl backend?
- Take the device context of the window and create a compatible copy of it.
- Create a bitmap that the copied context can use to draw on.
- Let Cairo draw on the copied context.
- Blit the copy to the widget context and destroy all the extra resources.
Passed 303 posts. Next stop: 808.
- KVRAF
- 8476 posts since 12 Feb, 2006 from Helsinki, Finland
While this scene probably doesn't use a huge amount of CPU, make sure you're not looking a the host "CPU meter" because it's usually not really a CPU meter at all (even if it said "CPU" next to it), but rather an audio performance meter that shows the percentage of the audio block time that was spent actually processing it (both of which are real-time units, not CPU time).BlitBit wrote: But right now I render the full window at 50 Hz and the CPU in REAPER still shows 0.0%. The three circles are rotating but it's still a very simple scene of course.
The goal of such a meter is to try to give you an estimate of how much more you can do before you start to get audio glitches. If you make your plugin sleep() in the audio process() callback, it won't spend any actual CPU but still max out the host meters. If your audio code returns quickly while your GUI is spending 100% of all the cores on the system, the host meter should still show essentially 0%.
If you are already looking at some real CPU meter (eg. task manager or process explorer or whatever) then ignore what I just said... but if you're looking at the host meter, you're probably not seeing any of the GUI impact in it at all.
