Bartlomiej Bazior wrote:
Hi,
Sorry for bothering you guys again, but I need some helping hand :-)
Today I spent some more time experimenting your libraries (mostly
trying different widgets and going into the depths of nui code).
I didn't expect it, but it was quiteinspiring experience, because
I come up with a lot of ideas about new widgets, and controlling vst
plugins with console :-), but unfortunately I've got some "technical"
problems here :-(
Very cool! I'll try to help.
1. It seems that my inability to build static debug versions of
vst-plugins is caused by VisualC++ Toolkit or PlatformSDK.
When I use only VisualStudio .NET I can build whatever I want,
but the free version libs are propably "crippled" or something -
always when I want to build debug version of plugin I get tons of
these when linking:
unresolved external symbol "public:
void __thiscall std::_String_base::_Xran(void)const "
I never had this problem. I googled a bit about this problem and it
seems that people having this problem are using libraries compiled with
older versions of visual studio (v6.x?) that uses the STL. I'm unsure
how this can be fixed. They seem to say that pasting that in your own
code fixes the problem:
_STD_BEGIN
// report a length_error
__declspec(dllexport) *void* __cdecl _Xlen()
{_THROW(length_error, "string too long"); }
// report an out_of_range error
__declspec(dllexport) *void* __cdecl _Xran()
{_THROW(out_of_range, "invalid string position"); }
_STD_END
(check out
http://groups.google.fr/group/microsoft.public.vc.stl/browse_thread/thread/c8ff6d50023fa1/7dc7801133c7e60c?q=void+__thiscall+std::_String_base::_Xran(void)const&rnum=5&hl=en#7dc7801133c7e60c)
Anyway to avoid this I decided to use STLPort, but I can't build nui/ngl
with it. I used version 4.6.2 and when compiling I get:
nglString.h(237) : error C2039: 'string' : is not a member of '_STL'
nglString.h(237) : error C2146: syntax error : missing ';' before
identifier 'GetStdString'
nglString.h(237) : error C2501: 'nglString::string' : missing
storage-class or type specifiers
I never used STLPort before, and don't know what to do with this :-(
Interesting. I haven't checked STLport compatilibity with ngl in more
than a year and a half. I remember that STLport like to rename the std::
namespace to something else. I also remember that there was some
settings about this in the project configuration box. I personally have
given up using STLPort on win32 because the STL provided with VC7 and
7.1 started to really be good enough that I could stop having yet
another dependency...
2. What should I do to avoid that font bug in vst-plugin that I
mentioned few days ago (when reopening editor, instead of normal fonts
some black rectangles appear)?
Ok, here is the init/uninint code we use in our own audio plugin framework:
// Main plugin class:
#ifdef _WIN32_
extern HINSTANCE g_hInst; // You'll need to get hold of the HINSTANCE in
the DLL init code (DllMain function).
#else
static void* g_hInst = NULL; // Just a dummy void* to get a simple API
on all platforms.
#endif
//////////////////////////////////////////////////////////////////////////////
//! My Plugin
class MyPlugin
{
public:
MyPlugin()
{
// nuiInit and nuiUninit should be called only once. You may want
to move these calls to DllMain on windows or to a singleton... Whatever
suits you.
nuiInit(g_hInst);
}
virtual ~MyPlugin()
{
nuiUninit();
}
};
// The UI handling class:
class MainWindow
{
public:
// Typical constructor/destructor and stuff goes here...
// ...
private:
nuiMainWindow* mpWindow; // This is our real plugin window where we
can put nui widget & handle all the UI of the plugin.
static nglWindow* mpHiddenContext; //< This is a hidden window that
will only be used to hold on to the graphical resources. This object
will be created as long as there will be an instance of MainWindow
alive. (it is created by the first instance of MainWindow and destroyed
by the last).
static uint mWindowRef; // a simple reference counter to keep track
of the number of MainWindow alive.
};
MainWindow::MainWindow(WindowHandle hwnd, const Point&
posNativeWindowOffset)
{
// WindowHandle hwnd is a HWND on Win32 and a WindowRef on the Mac.
// const Point& posNativeWindowOffset is the offset in the hwnd window
where we are supposed to put our own window (mac only IIRC).
nuiRenderer Renderer = eOpenGL;
nglContextInfo ContextInfo; // Use the default context
nglWindowInfo Info;
if (!mpHiddenContext)
{
mpHiddenContext = new nglWindow(10,10);
nuiTexture::SetSharedContext(mpHiddenContext);
nglString version((nglChar*)glGetString(GL_VERSION));
if (version == "1.0" || version == "1.1" ) // This is a simple check
to avoid tryint to GL on too old hardware.
Renderer = eSoftware;
}
mWindowRef++;
nglPath ResPath = nglPath(ePathCurrent);
Info.OSInfo.Parent = m_hwnd;
Info.Pos = nglWindowInfo::ePosUser;
Info.XPos = posNativeWindowOffset.GetX();
Info.YPos = posNativeWindowOffset.GetY();
Info.Width = 640; // Whatever sive suits you :).
Info.Height = 400;
nuiTopLevel::SetRenderer(Renderer);
mpWindow = new nuiMainWindow(ContextInfo, Info, mpHiddenContext, ResPath);
mpWindow->nglWindow::SetState(nglWindow::eShow);
mpWindow->SetDebugMode(true);
mpWindow->GetDrawContext()->PermitAntialiasing(true);
mpWindow->EnablePartialRedraw(true);
}
MainWindow::~MainWindow()
{
delete mpWindow;
mWindowRef--;
if (!mWindowRef)
{
delete mpHiddenContext;
mpHiddenContext = NULL;
nuiTexture::SetSharedContext(NULL);
}
}
//////////
This is a bit complicated I guess but it works like a charm on both Mac
and Win32.
I'll try and explain the reasoning behind the mess :-).
When we use nui the engine creates OpenGL textures to store the bitmaps,
the fonts and some other helpful things (for example there is a texture
to permit line antialiasing that is not dependent on hardware support
for that feature). Each texture is stored in the global resource manager
as nuiTexture. Each nuiTexture holds a handle to an OpenGL texture. The
problem is that when we close the window we have to destroy the OpenGL
context where all these textures are stored and we don't really want to
have to upload them again the next time the UI is opened. There is also
the problem where we need multiple windows using the same textures. If
you don't do anything special about this, an OpenGL context keeps all
its resources to itself (display lists, texture objects, etc...) but
there is a way to share these objects in between contexts. Once we can
share those we are free to create a hidden OpenGL context that will
always be created, and that will share its resources with the other
"real" opengl windows. I'm not sure I gave a decent explanation... Sorry
:-).
I'll have to adapt that code to the VSTPlugin example one of these days.
It should be really easy, probably just some copy and paste in the right
places...
3. And a last thing (propably very silly) I wanted to use my own
nuiMainWindow. For a quick start I just wrote the following class:
class FEVWindow : public nuiMainWindow
{
public:
FEVWindow(const nglContextInfo& rContextInfo,
const nglWindowInfo& rInfo,
const nglContext* pShared = NULL,
const nglPath& mResPath = NULL);
~FEVWindow() {};
};
FEVWindow::FEVWindow(const nglContextInfo& rContextInfo,
const nglWindowInfo& rInfo, const nglContext* pShared,
const nglPath& mResPath) :
nuiMainWindow(rContextInfo, rInfo, NULL, NULL)
{
}
Then instead of creating mpWindow out of nuiMainWindow (I used vst
example as a base) I create new FEVWindow, but as soon as I call:
mpWindow->nglWindow::SetState(nglWindow::eShow);
a runtime exception is thrown, and the plugin is "killed".
Right now I can't build debug version, so I couldn't check
this in debugger :-( But maybe I'm doing something wrong (or
more propably - I'm not doing something at all)?
Ok, I think the error should go away if you do this:
FEVWindow::FEVWindow(const nglContextInfo& rContextInfo,
const nglWindowInfo& rInfo, const nglContext* pShared,
const nglPath& rResPath) :
nuiMainWindow(rContextInfo, rInfo, NULL, rResPath)
{
}
If it doesn't go away with that fix I'll need you to tell me where
exactely the crash occurs (and may be part of the call stack).
Thanks in advance for any help, and once again sorry if I'm
being obtrusive.
Not at all! I hope you'll soon enjoy working on things more constructive
than trying to find fixes for stupid bugs and compiler problems :).
cheers,
Bart
Cheers, Sebastien