mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
This commit is contained in:
parent
adeafc5c71
commit
73257b4f4f
9 changed files with 1096 additions and 482 deletions
|
|
@ -2795,59 +2795,70 @@ Image* juce_createIconForFile (const File& file)
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
#if JUCE_OPENGL
|
#if JUCE_OPENGL
|
||||||
|
|
||||||
struct OpenGLContextInfo
|
|
||||||
|
//==============================================================================
|
||||||
|
class WindowedGLContext : public OpenGLContext
|
||||||
{
|
{
|
||||||
Window embeddedWindow;
|
public:
|
||||||
GLXContext renderContext;
|
WindowedGLContext (Component* const component,
|
||||||
};
|
const OpenGLPixelFormat& pixelFormat_,
|
||||||
|
GLXContext sharedContext)
|
||||||
void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext)
|
: renderContext (0),
|
||||||
{
|
embeddedWindow (0),
|
||||||
XSync (display, False);
|
pixelFormat (pixelFormat_)
|
||||||
jassert (component != 0);
|
|
||||||
|
|
||||||
if (component == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
LinuxComponentPeer* const peer
|
|
||||||
= dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer());
|
|
||||||
|
|
||||||
if (peer == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
GLint attribList[] =
|
|
||||||
{
|
{
|
||||||
GLX_RGBA,
|
jassert (component != 0);
|
||||||
GLX_DOUBLEBUFFER,
|
LinuxComponentPeer* const peer = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer());
|
||||||
GLX_RED_SIZE, 8,
|
if (peer == 0)
|
||||||
GLX_GREEN_SIZE, 8,
|
return;
|
||||||
GLX_BLUE_SIZE, 8,
|
|
||||||
GLX_ALPHA_SIZE, 8,
|
|
||||||
GLX_DEPTH_SIZE, 8,
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
XVisualInfo* const bestVisual = glXChooseVisual (display, DefaultScreen (display), attribList);
|
XSync (display, False);
|
||||||
|
|
||||||
if (bestVisual == 0)
|
GLint attribs [64];
|
||||||
return 0;
|
int n = 0;
|
||||||
|
attribs[n++] = GLX_RGBA;
|
||||||
|
attribs[n++] = GLX_DOUBLEBUFFER;
|
||||||
|
attribs[n++] = GLX_RED_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.redBits;
|
||||||
|
attribs[n++] = GLX_GREEN_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.greenBits;
|
||||||
|
attribs[n++] = GLX_BLUE_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.blueBits;
|
||||||
|
attribs[n++] = GLX_ALPHA_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.alphaBits;
|
||||||
|
attribs[n++] = GLX_DEPTH_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.depthBufferBits;
|
||||||
|
attribs[n++] = GLX_STENCIL_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.stencilBufferBits;
|
||||||
|
attribs[n++] = GLX_ACCUM_RED_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.accumulationBufferRedBits;
|
||||||
|
attribs[n++] = GLX_ACCUM_GREEN_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.accumulationBufferGreenBits;
|
||||||
|
attribs[n++] = GLX_ACCUM_BLUE_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.accumulationBufferBlueBits;
|
||||||
|
attribs[n++] = GLX_ACCUM_ALPHA_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.accumulationBufferAlphaBits;
|
||||||
|
|
||||||
OpenGLContextInfo* const oc = new OpenGLContextInfo();
|
// xxx not sure how to do fullSceneAntiAliasingNumSamples on linux..
|
||||||
|
|
||||||
oc->renderContext = glXCreateContext (display, bestVisual,
|
attribs[n++] = None;
|
||||||
(sharedContext != 0) ? ((OpenGLContextInfo*) sharedContext)->renderContext
|
|
||||||
: 0,
|
|
||||||
GL_TRUE);
|
|
||||||
|
|
||||||
Window windowH = (Window) peer->getNativeHandle();
|
XVisualInfo* const bestVisual = glXChooseVisual (display, DefaultScreen (display), attribs);
|
||||||
|
|
||||||
Colormap colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone);
|
if (bestVisual == 0)
|
||||||
XSetWindowAttributes swa;
|
return;
|
||||||
swa.colormap = colourMap;
|
|
||||||
swa.border_pixel = 0;
|
|
||||||
swa.event_mask = ExposureMask | StructureNotifyMask;
|
|
||||||
|
|
||||||
oc->embeddedWindow = XCreateWindow (display, windowH,
|
renderContext = glXCreateContext (display, bestVisual, sharedContext, GL_TRUE);
|
||||||
|
|
||||||
|
Window windowH = (Window) peer->getNativeHandle();
|
||||||
|
|
||||||
|
Colormap colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone);
|
||||||
|
XSetWindowAttributes swa;
|
||||||
|
swa.colormap = colourMap;
|
||||||
|
swa.border_pixel = 0;
|
||||||
|
swa.event_mask = ExposureMask | StructureNotifyMask;
|
||||||
|
|
||||||
|
embeddedWindow = XCreateWindow (display, windowH,
|
||||||
0, 0, 1, 1, 0,
|
0, 0, 1, 1, 0,
|
||||||
bestVisual->depth,
|
bestVisual->depth,
|
||||||
InputOutput,
|
InputOutput,
|
||||||
|
|
@ -2855,73 +2866,104 @@ void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext)
|
||||||
CWBorderPixel | CWColormap | CWEventMask,
|
CWBorderPixel | CWColormap | CWEventMask,
|
||||||
&swa);
|
&swa);
|
||||||
|
|
||||||
XSaveContext (display, (XID) oc->embeddedWindow, improbableNumber, (XPointer) peer);
|
XSaveContext (display, (XID) embeddedWindow, improbableNumber, (XPointer) peer);
|
||||||
|
|
||||||
XMapWindow (display, oc->embeddedWindow);
|
XMapWindow (display, embeddedWindow);
|
||||||
XFreeColormap (display, colourMap);
|
XFreeColormap (display, colourMap);
|
||||||
|
|
||||||
XFree (bestVisual);
|
XFree (bestVisual);
|
||||||
XSync (display, False);
|
XSync (display, False);
|
||||||
|
|
||||||
return oc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void juce_updateOpenGLWindowPos (void* context, Component* owner, Component* topComp)
|
|
||||||
{
|
|
||||||
jassert (context != 0);
|
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
|
||||||
|
|
||||||
XMoveResizeWindow (display, oc->embeddedWindow,
|
|
||||||
owner->getScreenX() - topComp->getScreenX(),
|
|
||||||
owner->getScreenY() - topComp->getScreenY(),
|
|
||||||
jmax (1, owner->getWidth()),
|
|
||||||
jmax (1, owner->getHeight()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void juce_deleteOpenGLContext (void* context)
|
|
||||||
{
|
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
|
||||||
|
|
||||||
if (oc != 0)
|
|
||||||
{
|
|
||||||
glXDestroyContext (display, oc->renderContext);
|
|
||||||
|
|
||||||
XUnmapWindow (display, oc->embeddedWindow);
|
|
||||||
XDestroyWindow (display, oc->embeddedWindow);
|
|
||||||
|
|
||||||
delete oc;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool juce_makeOpenGLContextCurrent (void* context)
|
~WindowedGLContext()
|
||||||
{
|
{
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
makeInactive();
|
||||||
|
|
||||||
if (oc != 0)
|
glXDestroyContext (display, renderContext);
|
||||||
return glXMakeCurrent (display, oc->embeddedWindow, oc->renderContext)
|
|
||||||
|
XUnmapWindow (display, embeddedWindow);
|
||||||
|
XDestroyWindow (display, embeddedWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool makeActive() throw()
|
||||||
|
{
|
||||||
|
jassert (renderContext != 0);
|
||||||
|
|
||||||
|
return glXMakeCurrent (display, embeddedWindow, renderContext)
|
||||||
&& XSync (display, False);
|
&& XSync (display, False);
|
||||||
else
|
}
|
||||||
return glXMakeCurrent (display, None, 0);
|
|
||||||
|
bool makeInactive() throw()
|
||||||
|
{
|
||||||
|
return (! isActive()) || glXMakeCurrent (display, None, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isActive() const throw()
|
||||||
|
{
|
||||||
|
return glXGetCurrentContext() == renderContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpenGLPixelFormat getPixelFormat() const
|
||||||
|
{
|
||||||
|
return pixelFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* getRawContext() const throw()
|
||||||
|
{
|
||||||
|
return renderContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateWindowPosition (int x, int y, int w, int h, int)
|
||||||
|
{
|
||||||
|
XMoveResizeWindow (display, embeddedWindow,
|
||||||
|
x, y, jmax (1, w), jmax (1, h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void swapBuffers()
|
||||||
|
{
|
||||||
|
glXSwapBuffers (display, embeddedWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void repaint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
juce_UseDebuggingNewOperator
|
||||||
|
|
||||||
|
GLXContext renderContext;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Window embeddedWindow;
|
||||||
|
OpenGLPixelFormat pixelFormat;
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
WindowedGLContext (const WindowedGLContext&);
|
||||||
|
const WindowedGLContext& operator= (const WindowedGLContext&);
|
||||||
|
};
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
OpenGLContext* OpenGLContext::createContextForWindow (Component* const component,
|
||||||
|
const OpenGLPixelFormat& pixelFormat,
|
||||||
|
const OpenGLContext* const contextToShareWith)
|
||||||
|
{
|
||||||
|
WindowedGLContext* c = new WindowedGLContext (component, pixelFormat,
|
||||||
|
contextToShareWith != 0 ? (GLXContext) contextToShareWith->getRawContext() : 0);
|
||||||
|
|
||||||
|
if (c->renderContext == 0)
|
||||||
|
deleteAndZero (c);
|
||||||
|
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool juce_isActiveOpenGLContext (void* context) throw()
|
void juce_glViewport (const int w, const int h)
|
||||||
{
|
{
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
glViewport (0, 0, w, h);
|
||||||
|
|
||||||
jassert (oc != 0);
|
|
||||||
return glXGetCurrentContext() == oc->renderContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void juce_swapOpenGLBuffers (void* context)
|
void OpenGLPixelFormat::getAvailablePixelFormats (OwnedArray <OpenGLPixelFormat>& results)
|
||||||
{
|
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
|
||||||
|
|
||||||
if (oc != 0)
|
|
||||||
glXSwapBuffers (display, oc->embeddedWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
void juce_repaintOpenGLWindow (void* context)
|
|
||||||
{
|
{
|
||||||
|
results.add (new OpenGLPixelFormat()); // xxx
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3292,92 +3292,190 @@ void AppleRemoteDevice::handleCallbackInternal()
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
#if JUCE_OPENGL
|
#if JUCE_OPENGL
|
||||||
|
|
||||||
struct OpenGLContextInfo
|
//==============================================================================
|
||||||
|
class WindowedGLContext : public OpenGLContext
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
WindowedGLContext (Component* const component,
|
||||||
|
const OpenGLPixelFormat& pixelFormat_,
|
||||||
|
AGLContext sharedContext)
|
||||||
|
: renderContext (0),
|
||||||
|
pixelFormat (pixelFormat_)
|
||||||
|
{
|
||||||
|
jassert (component != 0);
|
||||||
|
|
||||||
|
HIViewComponentPeer* const peer = dynamic_cast <HIViewComponentPeer*> (component->getTopLevelComponent()->getPeer());
|
||||||
|
if (peer == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLint attribs [64];
|
||||||
|
int n = 0;
|
||||||
|
attribs[n++] = AGL_RGBA;
|
||||||
|
attribs[n++] = AGL_DOUBLEBUFFER;
|
||||||
|
attribs[n++] = AGL_ACCELERATED;
|
||||||
|
attribs[n++] = AGL_RED_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.redBits;
|
||||||
|
attribs[n++] = AGL_GREEN_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.greenBits;
|
||||||
|
attribs[n++] = AGL_BLUE_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.blueBits;
|
||||||
|
attribs[n++] = AGL_ALPHA_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.alphaBits;
|
||||||
|
attribs[n++] = AGL_DEPTH_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.depthBufferBits;
|
||||||
|
attribs[n++] = AGL_STENCIL_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.stencilBufferBits;
|
||||||
|
attribs[n++] = AGL_ACCUM_RED_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.accumulationBufferRedBits;
|
||||||
|
attribs[n++] = AGL_ACCUM_GREEN_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.accumulationBufferGreenBits;
|
||||||
|
attribs[n++] = AGL_ACCUM_BLUE_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.accumulationBufferBlueBits;
|
||||||
|
attribs[n++] = AGL_ACCUM_ALPHA_SIZE;
|
||||||
|
attribs[n++] = pixelFormat.accumulationBufferAlphaBits;
|
||||||
|
|
||||||
|
// xxx not sure how to do fullSceneAntiAliasingNumSamples..
|
||||||
|
|
||||||
|
attribs[n++] = AGL_SAMPLE_BUFFERS_ARB;
|
||||||
|
attribs[n++] = 1;
|
||||||
|
attribs[n++] = AGL_SAMPLES_ARB;
|
||||||
|
attribs[n++] = 4;
|
||||||
|
attribs[n++] = AGL_CLOSEST_POLICY;
|
||||||
|
attribs[n++] = AGL_NO_RECOVERY;
|
||||||
|
attribs[n++] = AGL_NONE;
|
||||||
|
|
||||||
|
renderContext = aglCreateContext (aglChoosePixelFormat (0, 0, attribs),
|
||||||
|
sharedContext);
|
||||||
|
|
||||||
|
aglSetDrawable (renderContext, GetWindowPort (peer->windowRef));
|
||||||
|
}
|
||||||
|
|
||||||
|
~WindowedGLContext()
|
||||||
|
{
|
||||||
|
makeInactive();
|
||||||
|
aglSetDrawable (renderContext, 0);
|
||||||
|
aglDestroyContext (renderContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool makeActive() throw()
|
||||||
|
{
|
||||||
|
jassert (renderContext != 0);
|
||||||
|
|
||||||
|
return aglSetCurrentContext (renderContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool makeInactive() throw()
|
||||||
|
{
|
||||||
|
return (! isActive()) || aglSetCurrentContext (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isActive() const throw()
|
||||||
|
{
|
||||||
|
return aglGetCurrentContext() == renderContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpenGLPixelFormat getPixelFormat() const
|
||||||
|
{
|
||||||
|
return pixelFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* getRawContext() const throw()
|
||||||
|
{
|
||||||
|
return renderContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateWindowPosition (int x, int y, int w, int h, int outerWindowHeight)
|
||||||
|
{
|
||||||
|
GLint bufferRect[4];
|
||||||
|
bufferRect[0] = x;
|
||||||
|
bufferRect[1] = outerWindowHeight - (y + h);
|
||||||
|
bufferRect[2] = w;
|
||||||
|
bufferRect[3] = h;
|
||||||
|
|
||||||
|
aglSetInteger (renderContext, AGL_BUFFER_RECT, bufferRect);
|
||||||
|
aglEnable (renderContext, AGL_BUFFER_RECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swapBuffers()
|
||||||
|
{
|
||||||
|
aglSwapBuffers (renderContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
void repaint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
juce_UseDebuggingNewOperator
|
||||||
|
|
||||||
AGLContext renderContext;
|
AGLContext renderContext;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpenGLPixelFormat pixelFormat;
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
WindowedGLContext (const WindowedGLContext&);
|
||||||
|
const WindowedGLContext& operator= (const WindowedGLContext&);
|
||||||
};
|
};
|
||||||
|
|
||||||
void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext)
|
//==============================================================================
|
||||||
|
OpenGLContext* OpenGLContext::createContextForWindow (Component* const component,
|
||||||
|
const OpenGLPixelFormat& pixelFormat,
|
||||||
|
const OpenGLContext* const contextToShareWith)
|
||||||
{
|
{
|
||||||
jassert (component != 0);
|
WindowedGLContext* c = new WindowedGLContext (component, pixelFormat,
|
||||||
|
contextToShareWith != 0 ? (AGLContext) contextToShareWith->getRawContext() : 0);
|
||||||
|
|
||||||
HIViewComponentPeer* const peer = dynamic_cast <HIViewComponentPeer*> (component->getTopLevelComponent()->getPeer());
|
if (c->renderContext == 0)
|
||||||
|
deleteAndZero (c);
|
||||||
|
|
||||||
if (peer == 0)
|
return c;
|
||||||
return 0;
|
|
||||||
|
|
||||||
OpenGLContextInfo* const oc = new OpenGLContextInfo();
|
|
||||||
|
|
||||||
GLint attrib[] = { AGL_RGBA, AGL_DOUBLEBUFFER,
|
|
||||||
AGL_RED_SIZE, 8,
|
|
||||||
AGL_ALPHA_SIZE, 8,
|
|
||||||
AGL_DEPTH_SIZE, 24,
|
|
||||||
AGL_CLOSEST_POLICY, AGL_NO_RECOVERY,
|
|
||||||
AGL_SAMPLE_BUFFERS_ARB, 1,
|
|
||||||
AGL_SAMPLES_ARB, 4,
|
|
||||||
AGL_NONE };
|
|
||||||
|
|
||||||
oc->renderContext = aglCreateContext (aglChoosePixelFormat (0, 0, attrib),
|
|
||||||
(sharedContext != 0) ? ((OpenGLContextInfo*) sharedContext)->renderContext
|
|
||||||
: 0);
|
|
||||||
|
|
||||||
aglSetDrawable (oc->renderContext,
|
|
||||||
GetWindowPort (peer->windowRef));
|
|
||||||
|
|
||||||
return oc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void juce_updateOpenGLWindowPos (void* context, Component* owner, Component* topComp)
|
void juce_glViewport (const int w, const int h)
|
||||||
{
|
{
|
||||||
jassert (context != 0);
|
glViewport (0, 0, w, h);
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
|
||||||
|
|
||||||
GLint bufferRect[4];
|
|
||||||
|
|
||||||
bufferRect[0] = owner->getScreenX() - topComp->getScreenX();
|
|
||||||
bufferRect[1] = topComp->getHeight() - (owner->getHeight() + owner->getScreenY() - topComp->getScreenY());
|
|
||||||
bufferRect[2] = owner->getWidth();
|
|
||||||
bufferRect[3] = owner->getHeight();
|
|
||||||
|
|
||||||
aglSetInteger (oc->renderContext, AGL_BUFFER_RECT, bufferRect);
|
|
||||||
aglEnable (oc->renderContext, AGL_BUFFER_RECT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void juce_deleteOpenGLContext (void* context)
|
static int getAGLAttribute (AGLPixelFormat p, const GLint attrib)
|
||||||
{
|
{
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
GLint result = 0;
|
||||||
|
aglDescribePixelFormat (p, attrib, &result);
|
||||||
aglDestroyContext (oc->renderContext);
|
return result;
|
||||||
|
|
||||||
delete oc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool juce_makeOpenGLContextCurrent (void* context)
|
void OpenGLPixelFormat::getAvailablePixelFormats (OwnedArray <OpenGLPixelFormat>& results)
|
||||||
{
|
{
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
GLint attribs [64];
|
||||||
|
int n = 0;
|
||||||
|
attribs[n++] = AGL_RGBA;
|
||||||
|
attribs[n++] = AGL_DOUBLEBUFFER;
|
||||||
|
attribs[n++] = AGL_ACCELERATED;
|
||||||
|
attribs[n++] = AGL_NO_RECOVERY;
|
||||||
|
attribs[n++] = AGL_NONE;
|
||||||
|
|
||||||
return aglSetCurrentContext ((oc != 0) ? oc->renderContext : 0);
|
AGLPixelFormat p = aglChoosePixelFormat (0, 0, attribs);
|
||||||
|
|
||||||
|
while (p != 0)
|
||||||
|
{
|
||||||
|
OpenGLPixelFormat* const pf = new OpenGLPixelFormat();
|
||||||
|
pf->redBits = getAGLAttribute (p, AGL_RED_SIZE);
|
||||||
|
pf->greenBits = getAGLAttribute (p, AGL_GREEN_SIZE);
|
||||||
|
pf->blueBits = getAGLAttribute (p, AGL_BLUE_SIZE);
|
||||||
|
pf->alphaBits = getAGLAttribute (p, AGL_ALPHA_SIZE);
|
||||||
|
pf->depthBufferBits = getAGLAttribute (p, AGL_DEPTH_SIZE);
|
||||||
|
pf->stencilBufferBits = getAGLAttribute (p, AGL_STENCIL_SIZE);
|
||||||
|
pf->accumulationBufferRedBits = getAGLAttribute (p, AGL_ACCUM_RED_SIZE);
|
||||||
|
pf->accumulationBufferGreenBits = getAGLAttribute (p, AGL_ACCUM_GREEN_SIZE);
|
||||||
|
pf->accumulationBufferBlueBits = getAGLAttribute (p, AGL_ACCUM_BLUE_SIZE);
|
||||||
|
pf->accumulationBufferAlphaBits = getAGLAttribute (p, AGL_ACCUM_ALPHA_SIZE);
|
||||||
|
|
||||||
|
results.add (pf);
|
||||||
|
|
||||||
|
p = aglNextPixelFormat (p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool juce_isActiveOpenGLContext (void* context) throw()
|
|
||||||
{
|
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
|
||||||
|
|
||||||
jassert (oc != 0);
|
|
||||||
return aglGetCurrentContext() == oc->renderContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
void juce_swapOpenGLBuffers (void* context)
|
|
||||||
{
|
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
|
||||||
|
|
||||||
if (oc != 0)
|
|
||||||
aglSwapBuffers (oc->renderContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
void juce_repaintOpenGLWindow (void* context)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2640,6 +2640,7 @@ void MouseCursor::showInAllWindows() const throw()
|
||||||
showInWindow (0);
|
showInWindow (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
class JuceDropSource : public IDropSource
|
class JuceDropSource : public IDropSource
|
||||||
{
|
{
|
||||||
|
|
@ -2970,13 +2971,13 @@ static HDROP createHDrop (const StringArray& fileNames) throw()
|
||||||
return hDrop;
|
return hDrop;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool performDragDrop (FORMATETC* format, STGMEDIUM* medium, const DWORD whatToDo) throw()
|
static bool performDragDrop (FORMATETC* const format, STGMEDIUM* const medium, const DWORD whatToDo) throw()
|
||||||
{
|
{
|
||||||
JuceDropSource* const source = new JuceDropSource();
|
JuceDropSource* const source = new JuceDropSource();
|
||||||
JuceDataObject* const data = new JuceDataObject (source, format, medium, 1);
|
JuceDataObject* const data = new JuceDataObject (source, format, medium, 1);
|
||||||
|
|
||||||
DWORD effect;
|
DWORD effect;
|
||||||
HRESULT res = DoDragDrop (data, source, whatToDo, &effect);
|
const HRESULT res = DoDragDrop (data, source, whatToDo, &effect);
|
||||||
|
|
||||||
data->Release();
|
data->Release();
|
||||||
source->Release();
|
source->Release();
|
||||||
|
|
@ -3026,152 +3027,456 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
#if JUCE_OPENGL
|
#if JUCE_OPENGL
|
||||||
|
|
||||||
struct OpenGLContextInfo
|
#define WGL_EXT_FUNCTION_INIT(extType, extFunc) \
|
||||||
|
((extFunc = (extType) wglGetProcAddress (#extFunc)) != 0)
|
||||||
|
|
||||||
|
typedef const char* (WINAPI* PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
|
||||||
|
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
|
||||||
|
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
|
||||||
|
|
||||||
|
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
|
||||||
|
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
|
||||||
|
#define WGL_ACCELERATION_ARB 0x2003
|
||||||
|
#define WGL_SWAP_METHOD_ARB 0x2007
|
||||||
|
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
||||||
|
#define WGL_PIXEL_TYPE_ARB 0x2013
|
||||||
|
#define WGL_DOUBLE_BUFFER_ARB 0x2011
|
||||||
|
#define WGL_COLOR_BITS_ARB 0x2014
|
||||||
|
#define WGL_RED_BITS_ARB 0x2015
|
||||||
|
#define WGL_GREEN_BITS_ARB 0x2017
|
||||||
|
#define WGL_BLUE_BITS_ARB 0x2019
|
||||||
|
#define WGL_ALPHA_BITS_ARB 0x201B
|
||||||
|
#define WGL_DEPTH_BITS_ARB 0x2022
|
||||||
|
#define WGL_STENCIL_BITS_ARB 0x2023
|
||||||
|
#define WGL_FULL_ACCELERATION_ARB 0x2027
|
||||||
|
#define WGL_ACCUM_RED_BITS_ARB 0x201E
|
||||||
|
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
|
||||||
|
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
|
||||||
|
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
|
||||||
|
#define WGL_STEREO_ARB 0x2012
|
||||||
|
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
|
||||||
|
#define WGL_SAMPLES_ARB 0x2042
|
||||||
|
#define WGL_TYPE_RGBA_ARB 0x202B
|
||||||
|
|
||||||
|
static void getWglExtensions (HDC dc, StringArray& result) throw()
|
||||||
{
|
{
|
||||||
Win32ComponentPeer* nativeWindow;
|
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
|
||||||
|
|
||||||
HDC dc;
|
if (WGL_EXT_FUNCTION_INIT (PFNWGLGETEXTENSIONSSTRINGARBPROC, wglGetExtensionsStringARB))
|
||||||
HGLRC renderContext;
|
result.addTokens (String (wglGetExtensionsStringARB (dc)), false);
|
||||||
};
|
else
|
||||||
|
jassertfalse // If this fails, it may be because you didn't activate the openGL context
|
||||||
|
}
|
||||||
|
|
||||||
void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext)
|
|
||||||
|
//==============================================================================
|
||||||
|
class WindowedGLContext : public OpenGLContext
|
||||||
{
|
{
|
||||||
jassert (component != 0);
|
public:
|
||||||
|
WindowedGLContext (Component* const component, HGLRC contextToShareWith)
|
||||||
Win32ComponentPeer* const peer = dynamic_cast <Win32ComponentPeer*> (component->getTopLevelComponent()->getPeer());
|
: renderContext (0),
|
||||||
|
nativeWindow (0)
|
||||||
if (peer == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
OpenGLContextInfo* const oc = new OpenGLContextInfo();
|
|
||||||
|
|
||||||
oc->nativeWindow = new Win32ComponentPeer (component, 0);
|
|
||||||
oc->nativeWindow->dontRepaint = true;
|
|
||||||
oc->nativeWindow->setVisible (true);
|
|
||||||
HWND hwnd = (HWND) oc->nativeWindow->getNativeHandle();
|
|
||||||
|
|
||||||
SetParent (hwnd, (HWND) peer->getNativeHandle());
|
|
||||||
juce_setWindowStyleBit (hwnd, GWL_STYLE, WS_CHILD, true);
|
|
||||||
juce_setWindowStyleBit (hwnd, GWL_STYLE, WS_POPUP, false);
|
|
||||||
|
|
||||||
oc->dc = GetDC (hwnd);
|
|
||||||
|
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
|
||||||
zerostruct (pfd);
|
|
||||||
pfd.nSize = sizeof (pfd);
|
|
||||||
pfd.nVersion = 1;
|
|
||||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
|
||||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
|
||||||
pfd.cColorBits = 32;
|
|
||||||
pfd.cDepthBits = 32;
|
|
||||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
|
||||||
|
|
||||||
int format = ChoosePixelFormat (oc->dc, &pfd);
|
|
||||||
|
|
||||||
if (format == 0 || ! SetPixelFormat (oc->dc, format, &pfd))
|
|
||||||
{
|
{
|
||||||
// try some less ambitious formats if it fails..
|
jassert (component != 0);
|
||||||
pfd.cColorBits = 24;
|
Win32ComponentPeer* const peer = dynamic_cast <Win32ComponentPeer*> (component->getTopLevelComponent()->getPeer());
|
||||||
format = ChoosePixelFormat (oc->dc, &pfd);
|
|
||||||
|
|
||||||
if (format == 0 || ! SetPixelFormat (oc->dc, format, &pfd))
|
nativeWindow = new Win32ComponentPeer (component, 0);
|
||||||
|
nativeWindow->dontRepaint = true;
|
||||||
|
nativeWindow->setVisible (true);
|
||||||
|
|
||||||
|
HWND hwnd = (HWND) nativeWindow->getNativeHandle();
|
||||||
|
|
||||||
|
if (peer != 0)
|
||||||
{
|
{
|
||||||
pfd.cDepthBits = 16;
|
SetParent (hwnd, (HWND) peer->getNativeHandle());
|
||||||
format = ChoosePixelFormat (oc->dc, &pfd);
|
juce_setWindowStyleBit (hwnd, GWL_STYLE, WS_CHILD, true);
|
||||||
|
juce_setWindowStyleBit (hwnd, GWL_STYLE, WS_POPUP, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (format == 0 || ! SetPixelFormat (oc->dc, format, &pfd))
|
dc = GetDC (hwnd);
|
||||||
|
|
||||||
|
// Use a default pixel format that should be supported everywhere
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
zerostruct (pfd);
|
||||||
|
pfd.nSize = sizeof (pfd);
|
||||||
|
pfd.nVersion = 1;
|
||||||
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||||
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||||
|
pfd.cColorBits = 16;
|
||||||
|
pfd.cDepthBits = 16;
|
||||||
|
|
||||||
|
const int format = ChoosePixelFormat (dc, &pfd);
|
||||||
|
|
||||||
|
if (format != 0)
|
||||||
|
SetPixelFormat (dc, format, &pfd);
|
||||||
|
|
||||||
|
renderContext = wglCreateContext (dc);
|
||||||
|
|
||||||
|
if (contextToShareWith != 0 && renderContext != 0)
|
||||||
|
wglShareLists (renderContext, contextToShareWith);
|
||||||
|
}
|
||||||
|
|
||||||
|
~WindowedGLContext()
|
||||||
|
{
|
||||||
|
makeInactive();
|
||||||
|
|
||||||
|
wglDeleteContext (renderContext);
|
||||||
|
ReleaseDC ((HWND) nativeWindow->getNativeHandle(), dc);
|
||||||
|
|
||||||
|
delete nativeWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool makeActive() throw()
|
||||||
|
{
|
||||||
|
jassert (renderContext != 0);
|
||||||
|
return wglMakeCurrent (dc, renderContext) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool makeInactive() throw()
|
||||||
|
{
|
||||||
|
return (! isActive()) || (wglMakeCurrent (0, 0) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isActive() const throw()
|
||||||
|
{
|
||||||
|
return wglGetCurrentContext() == renderContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpenGLPixelFormat getPixelFormat() const
|
||||||
|
{
|
||||||
|
OpenGLPixelFormat pf;
|
||||||
|
|
||||||
|
StringArray availableExtensions;
|
||||||
|
getWglExtensions (dc, availableExtensions);
|
||||||
|
|
||||||
|
fillInPixelFormatDetails (GetPixelFormat (dc), pf, availableExtensions);
|
||||||
|
return pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* getRawContext() const throw()
|
||||||
|
{
|
||||||
|
return renderContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setPixelFormat (const OpenGLPixelFormat& pixelFormat)
|
||||||
|
{
|
||||||
|
jassert (renderContext != 0);
|
||||||
|
|
||||||
|
makeActive();
|
||||||
|
|
||||||
|
StringArray availableExtensions;
|
||||||
|
getWglExtensions (dc, availableExtensions);
|
||||||
|
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
zerostruct (pfd);
|
||||||
|
pfd.nSize = sizeof (pfd);
|
||||||
|
pfd.nVersion = 1;
|
||||||
|
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
|
||||||
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||||
|
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||||
|
pfd.cColorBits = pixelFormat.redBits + pixelFormat.greenBits + pixelFormat.blueBits;
|
||||||
|
pfd.cRedBits = pixelFormat.redBits;
|
||||||
|
pfd.cGreenBits = pixelFormat.greenBits;
|
||||||
|
pfd.cBlueBits = pixelFormat.blueBits;
|
||||||
|
pfd.cAlphaBits = pixelFormat.alphaBits;
|
||||||
|
pfd.cDepthBits = pixelFormat.depthBufferBits;
|
||||||
|
pfd.cStencilBits = pixelFormat.stencilBufferBits;
|
||||||
|
pfd.cAccumBits = pixelFormat.accumulationBufferRedBits + pixelFormat.accumulationBufferGreenBits
|
||||||
|
+ pixelFormat.accumulationBufferBlueBits + pixelFormat.accumulationBufferAlphaBits;
|
||||||
|
pfd.cAccumRedBits = pixelFormat.accumulationBufferRedBits;
|
||||||
|
pfd.cAccumGreenBits = pixelFormat.accumulationBufferGreenBits;
|
||||||
|
pfd.cAccumBlueBits = pixelFormat.accumulationBufferBlueBits;
|
||||||
|
pfd.cAccumAlphaBits = pixelFormat.accumulationBufferAlphaBits;
|
||||||
|
|
||||||
|
int format = 0;
|
||||||
|
|
||||||
|
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = 0;
|
||||||
|
|
||||||
|
if (availableExtensions.contains ("WGL_ARB_pixel_format")
|
||||||
|
&& WGL_EXT_FUNCTION_INIT (PFNWGLCHOOSEPIXELFORMATARBPROC, wglChoosePixelFormatARB))
|
||||||
|
{
|
||||||
|
int attributes[64];
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
attributes[n++] = WGL_DRAW_TO_WINDOW_ARB;
|
||||||
|
attributes[n++] = GL_TRUE;
|
||||||
|
attributes[n++] = WGL_SUPPORT_OPENGL_ARB;
|
||||||
|
attributes[n++] = GL_TRUE;
|
||||||
|
attributes[n++] = WGL_ACCELERATION_ARB;
|
||||||
|
attributes[n++] = WGL_FULL_ACCELERATION_ARB;
|
||||||
|
attributes[n++] = WGL_DOUBLE_BUFFER_ARB;
|
||||||
|
attributes[n++] = GL_TRUE;
|
||||||
|
attributes[n++] = WGL_PIXEL_TYPE_ARB;
|
||||||
|
attributes[n++] = WGL_TYPE_RGBA_ARB;
|
||||||
|
|
||||||
|
attributes[n++] = WGL_COLOR_BITS_ARB;
|
||||||
|
attributes[n++] = pfd.cColorBits;
|
||||||
|
attributes[n++] = WGL_RED_BITS_ARB;
|
||||||
|
attributes[n++] = pixelFormat.redBits;
|
||||||
|
attributes[n++] = WGL_GREEN_BITS_ARB;
|
||||||
|
attributes[n++] = pixelFormat.greenBits;
|
||||||
|
attributes[n++] = WGL_BLUE_BITS_ARB;
|
||||||
|
attributes[n++] = pixelFormat.blueBits;
|
||||||
|
attributes[n++] = WGL_ALPHA_BITS_ARB;
|
||||||
|
attributes[n++] = pixelFormat.alphaBits;
|
||||||
|
attributes[n++] = WGL_DEPTH_BITS_ARB;
|
||||||
|
attributes[n++] = pixelFormat.depthBufferBits;
|
||||||
|
|
||||||
|
if (pixelFormat.stencilBufferBits > 0)
|
||||||
{
|
{
|
||||||
pfd.cColorBits = 32;
|
attributes[n++] = WGL_STENCIL_BITS_ARB;
|
||||||
format = ChoosePixelFormat (oc->dc, &pfd);
|
attributes[n++] = pixelFormat.stencilBufferBits;
|
||||||
|
}
|
||||||
|
|
||||||
if (format == 0 || ! SetPixelFormat (oc->dc, format, &pfd))
|
attributes[n++] = WGL_ACCUM_RED_BITS_ARB;
|
||||||
{
|
attributes[n++] = pixelFormat.accumulationBufferRedBits;
|
||||||
jassertfalse // can't find a suitable pixel format that works for opengl
|
attributes[n++] = WGL_ACCUM_GREEN_BITS_ARB;
|
||||||
}
|
attributes[n++] = pixelFormat.accumulationBufferGreenBits;
|
||||||
|
attributes[n++] = WGL_ACCUM_BLUE_BITS_ARB;
|
||||||
|
attributes[n++] = pixelFormat.accumulationBufferBlueBits;
|
||||||
|
attributes[n++] = WGL_ACCUM_ALPHA_BITS_ARB;
|
||||||
|
attributes[n++] = pixelFormat.accumulationBufferAlphaBits;
|
||||||
|
|
||||||
|
if (availableExtensions.contains ("WGL_ARB_multisample")
|
||||||
|
&& pixelFormat.fullSceneAntiAliasingNumSamples > 0)
|
||||||
|
{
|
||||||
|
attributes[n++] = WGL_SAMPLE_BUFFERS_ARB;
|
||||||
|
attributes[n++] = 1;
|
||||||
|
attributes[n++] = WGL_SAMPLES_ARB;
|
||||||
|
attributes[n++] = pixelFormat.fullSceneAntiAliasingNumSamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes[n++] = 0;
|
||||||
|
|
||||||
|
UINT formatsCount;
|
||||||
|
const BOOL ok = wglChoosePixelFormatARB (dc, attributes, 0, 1, &format, &formatsCount);
|
||||||
|
(void) ok;
|
||||||
|
jassert (ok);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
format = ChoosePixelFormat (dc, &pfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format != 0)
|
||||||
|
{
|
||||||
|
makeInactive();
|
||||||
|
|
||||||
|
// Create the real context..
|
||||||
|
if (SetPixelFormat (dc, format, &pfd))
|
||||||
|
{
|
||||||
|
wglDeleteContext (renderContext);
|
||||||
|
renderContext = wglCreateContext (dc);
|
||||||
|
|
||||||
|
jassert (renderContext != 0);
|
||||||
|
return renderContext != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateWindowPosition (int x, int y, int w, int h, int)
|
||||||
|
{
|
||||||
|
SetWindowPos ((HWND) nativeWindow->getNativeHandle(), 0,
|
||||||
|
x, y, w, h,
|
||||||
|
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void repaint()
|
||||||
|
{
|
||||||
|
int x, y, w, h;
|
||||||
|
nativeWindow->getBounds (x, y, w, h);
|
||||||
|
nativeWindow->repaint (0, 0, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swapBuffers()
|
||||||
|
{
|
||||||
|
SwapBuffers (dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void findAlternativeOpenGLPixelFormats (OwnedArray <OpenGLPixelFormat>& results)
|
||||||
|
{
|
||||||
|
jassert (isActive());
|
||||||
|
|
||||||
|
StringArray availableExtensions;
|
||||||
|
getWglExtensions (dc, availableExtensions);
|
||||||
|
|
||||||
|
PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = 0;
|
||||||
|
int numTypes = 0;
|
||||||
|
|
||||||
|
if (availableExtensions.contains("WGL_ARB_pixel_format")
|
||||||
|
&& WGL_EXT_FUNCTION_INIT (PFNWGLGETPIXELFORMATATTRIBIVARBPROC, wglGetPixelFormatAttribivARB))
|
||||||
|
{
|
||||||
|
int attributes = WGL_NUMBER_PIXEL_FORMATS_ARB;
|
||||||
|
|
||||||
|
if (! wglGetPixelFormatAttribivARB (dc, 1, 0, 1, &attributes, &numTypes))
|
||||||
|
jassertfalse
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numTypes = DescribePixelFormat (dc, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLPixelFormat pf;
|
||||||
|
|
||||||
|
for (int i = 0; i < numTypes; ++i)
|
||||||
|
{
|
||||||
|
if (fillInPixelFormatDetails (i + 1, pf, availableExtensions))
|
||||||
|
{
|
||||||
|
bool alreadyListed = false;
|
||||||
|
for (int j = results.size(); --j >= 0;)
|
||||||
|
if (pf == *results.getUnchecked(j))
|
||||||
|
alreadyListed = true;
|
||||||
|
|
||||||
|
if (! alreadyListed)
|
||||||
|
results.add (new OpenGLPixelFormat (pf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oc->renderContext = wglCreateContext (oc->dc);
|
//==============================================================================
|
||||||
|
juce_UseDebuggingNewOperator
|
||||||
|
|
||||||
if (sharedContext != 0)
|
HGLRC renderContext;
|
||||||
wglShareLists (((OpenGLContextInfo*) sharedContext)->renderContext, oc->renderContext);
|
|
||||||
|
|
||||||
return oc;
|
private:
|
||||||
}
|
Win32ComponentPeer* nativeWindow;
|
||||||
|
HDC dc;
|
||||||
|
|
||||||
void juce_updateOpenGLWindowPos (void* context, Component* owner, Component* topComp)
|
//==============================================================================
|
||||||
{
|
bool fillInPixelFormatDetails (const int pixelFormatIndex,
|
||||||
jassert (context != 0);
|
OpenGLPixelFormat& result,
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
const StringArray& availableExtensions) const throw()
|
||||||
|
|
||||||
SetWindowPos ((HWND) oc->nativeWindow->getNativeHandle(), 0,
|
|
||||||
owner->getScreenX() - topComp->getScreenX(),
|
|
||||||
owner->getScreenY() - topComp->getScreenY(),
|
|
||||||
owner->getWidth(),
|
|
||||||
owner->getHeight(),
|
|
||||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING);
|
|
||||||
}
|
|
||||||
|
|
||||||
void juce_deleteOpenGLContext (void* context)
|
|
||||||
{
|
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
|
||||||
|
|
||||||
if (oc != 0)
|
|
||||||
{
|
{
|
||||||
wglDeleteContext (oc->renderContext);
|
PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = 0;
|
||||||
ReleaseDC ((HWND) oc->nativeWindow->getNativeHandle(), oc->dc);
|
|
||||||
|
|
||||||
deleteAndZero (oc->nativeWindow);
|
if (availableExtensions.contains ("WGL_ARB_pixel_format")
|
||||||
|
&& WGL_EXT_FUNCTION_INIT (PFNWGLGETPIXELFORMATATTRIBIVARBPROC, wglGetPixelFormatAttribivARB))
|
||||||
|
{
|
||||||
|
int attributes[32];
|
||||||
|
int numAttributes = 0;
|
||||||
|
|
||||||
delete oc;
|
attributes[numAttributes++] = WGL_DRAW_TO_WINDOW_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_SUPPORT_OPENGL_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_ACCELERATION_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_DOUBLE_BUFFER_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_PIXEL_TYPE_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_RED_BITS_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_GREEN_BITS_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_BLUE_BITS_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_ALPHA_BITS_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_DEPTH_BITS_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_STENCIL_BITS_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_ACCUM_RED_BITS_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_ACCUM_GREEN_BITS_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_ACCUM_BLUE_BITS_ARB;
|
||||||
|
attributes[numAttributes++] = WGL_ACCUM_ALPHA_BITS_ARB;
|
||||||
|
|
||||||
|
if (availableExtensions.contains ("WGL_ARB_multisample"))
|
||||||
|
attributes[numAttributes++] = WGL_SAMPLES_ARB;
|
||||||
|
|
||||||
|
int values[32];
|
||||||
|
zeromem (values, sizeof (values));
|
||||||
|
|
||||||
|
if (wglGetPixelFormatAttribivARB (dc, pixelFormatIndex, 0, numAttributes, attributes, values))
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
bool isValidFormat = (values[n++] == GL_TRUE); // WGL_DRAW_TO_WINDOW_ARB
|
||||||
|
isValidFormat = (values[n++] == GL_TRUE) && isValidFormat; // WGL_SUPPORT_OPENGL_ARB
|
||||||
|
isValidFormat = (values[n++] == WGL_FULL_ACCELERATION_ARB) && isValidFormat; // WGL_ACCELERATION_ARB
|
||||||
|
isValidFormat = (values[n++] == GL_TRUE) && isValidFormat; // WGL_DOUBLE_BUFFER_ARB:
|
||||||
|
isValidFormat = (values[n++] == WGL_TYPE_RGBA_ARB) && isValidFormat; // WGL_PIXEL_TYPE_ARB
|
||||||
|
result.redBits = values[n++]; // WGL_RED_BITS_ARB
|
||||||
|
result.greenBits = values[n++]; // WGL_GREEN_BITS_ARB
|
||||||
|
result.blueBits = values[n++]; // WGL_BLUE_BITS_ARB
|
||||||
|
result.alphaBits = values[n++]; // WGL_ALPHA_BITS_ARB
|
||||||
|
result.depthBufferBits = values[n++]; // WGL_DEPTH_BITS_ARB
|
||||||
|
result.stencilBufferBits = values[n++]; // WGL_STENCIL_BITS_ARB
|
||||||
|
result.accumulationBufferRedBits = values[n++]; // WGL_ACCUM_RED_BITS_ARB
|
||||||
|
result.accumulationBufferGreenBits = values[n++]; // WGL_ACCUM_GREEN_BITS_ARB
|
||||||
|
result.accumulationBufferBlueBits = values[n++]; // WGL_ACCUM_BLUE_BITS_ARB
|
||||||
|
result.accumulationBufferAlphaBits = values[n++]; // WGL_ACCUM_ALPHA_BITS_ARB
|
||||||
|
result.fullSceneAntiAliasingNumSamples = values[n++]; // WGL_SAMPLES_ARB
|
||||||
|
|
||||||
|
return isValidFormat;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jassertfalse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
|
||||||
|
if (DescribePixelFormat (dc, pixelFormatIndex, sizeof (pfd), &pfd))
|
||||||
|
{
|
||||||
|
result.redBits = pfd.cRedBits;
|
||||||
|
result.greenBits = pfd.cGreenBits;
|
||||||
|
result.blueBits = pfd.cBlueBits;
|
||||||
|
result.alphaBits = pfd.cAlphaBits;
|
||||||
|
result.depthBufferBits = pfd.cDepthBits;
|
||||||
|
result.stencilBufferBits = pfd.cStencilBits;
|
||||||
|
result.accumulationBufferRedBits = pfd.cAccumRedBits;
|
||||||
|
result.accumulationBufferGreenBits = pfd.cAccumGreenBits;
|
||||||
|
result.accumulationBufferBlueBits = pfd.cAccumBlueBits;
|
||||||
|
result.accumulationBufferAlphaBits = pfd.cAccumAlphaBits;
|
||||||
|
result.fullSceneAntiAliasingNumSamples = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jassertfalse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowedGLContext (const WindowedGLContext&);
|
||||||
|
const WindowedGLContext& operator= (const WindowedGLContext&);
|
||||||
|
};
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
OpenGLContext* OpenGLContext::createContextForWindow (Component* const component,
|
||||||
|
const OpenGLPixelFormat& pixelFormat,
|
||||||
|
const OpenGLContext* const contextToShareWith)
|
||||||
|
{
|
||||||
|
WindowedGLContext* c = new WindowedGLContext (component,
|
||||||
|
contextToShareWith != 0 ? (HGLRC) contextToShareWith->getRawContext() : 0);
|
||||||
|
|
||||||
|
if (c->renderContext == 0 || ! c->setPixelFormat (pixelFormat))
|
||||||
|
deleteAndZero (c);
|
||||||
|
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool juce_makeOpenGLContextCurrent (void* context)
|
void juce_glViewport (const int w, const int h)
|
||||||
{
|
{
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
glViewport (0, 0, w, h);
|
||||||
|
|
||||||
if (oc != 0)
|
|
||||||
return wglMakeCurrent (oc->dc, oc->renderContext) != 0;
|
|
||||||
else
|
|
||||||
return wglMakeCurrent (0, 0) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool juce_isActiveOpenGLContext (void* context) throw()
|
void OpenGLPixelFormat::getAvailablePixelFormats (OwnedArray <OpenGLPixelFormat>& results)
|
||||||
{
|
{
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
Component tempComp;
|
||||||
|
|
||||||
jassert (oc != 0);
|
|
||||||
return wglGetCurrentContext() == oc->renderContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
void juce_swapOpenGLBuffers (void* context)
|
|
||||||
{
|
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
|
||||||
|
|
||||||
if (oc != 0)
|
|
||||||
SwapBuffers (oc->dc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void juce_repaintOpenGLWindow (void* context)
|
|
||||||
{
|
|
||||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
|
||||||
|
|
||||||
if (oc != 0)
|
|
||||||
{
|
{
|
||||||
int x, y, w, h;
|
WindowedGLContext wc (&tempComp, 0);
|
||||||
oc->nativeWindow->getBounds (x, y, w, h);
|
wc.makeActive();
|
||||||
oc->nativeWindow->repaint (0, 0, w, h);
|
wc.findAlternativeOpenGLPixelFormats (results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
class JuceIStorage : public IStorage
|
class JuceIStorage : public IStorage
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ Changelist for version 1.45
|
||||||
- new class: FileSearchPathListComponent, for letting the user edit a FileSearchPath.
|
- new class: FileSearchPathListComponent, for letting the user edit a FileSearchPath.
|
||||||
- added a critical section option to ReferenceCountedArray
|
- added a critical section option to ReferenceCountedArray
|
||||||
- refactored and added features to the Socket class, replacing it with StreamableSocket (basically the same as the original class), and DatagramSocket.
|
- refactored and added features to the Socket class, replacing it with StreamableSocket (basically the same as the original class), and DatagramSocket.
|
||||||
|
- refactored the OpenGLComponent, adding new classes OpenGLPixelFormat and OpenGLContext
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Changelist for version 1.44
|
Changelist for version 1.44
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ ifeq ($(CONFIG),Debug)
|
||||||
CPPFLAGS := -MMD -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include"
|
CPPFLAGS := -MMD -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include"
|
||||||
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -D_DEBUG -ggdb
|
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -D_DEBUG -ggdb
|
||||||
CXXFLAGS := $(CFLAGS)
|
CXXFLAGS := $(CFLAGS)
|
||||||
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound -ljuce_debug
|
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound -lXss -ljuce_debug
|
||||||
LDDEPS :=
|
LDDEPS :=
|
||||||
RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include"
|
RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include"
|
||||||
TARGET := jucedemo
|
TARGET := jucedemo
|
||||||
|
|
@ -28,7 +28,7 @@ ifeq ($(CONFIG),Release)
|
||||||
CPPFLAGS := -MMD -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include"
|
CPPFLAGS := -MMD -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include"
|
||||||
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O2
|
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O2
|
||||||
CXXFLAGS := $(CFLAGS)
|
CXXFLAGS := $(CFLAGS)
|
||||||
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -s -L"/usr/X11R6/lib/" -L"../../../../bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound -ljuce
|
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -s -L"/usr/X11R6/lib/" -L"../../../../bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound -lXss -ljuce
|
||||||
LDDEPS :=
|
LDDEPS :=
|
||||||
RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include"
|
RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include"
|
||||||
TARGET := jucedemo
|
TARGET := jucedemo
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,11 @@ package.libpaths = {
|
||||||
}
|
}
|
||||||
|
|
||||||
package.config["Debug"].links = {
|
package.config["Debug"].links = {
|
||||||
"freetype", "pthread", "rt", "X11", "GL", "GLU", "Xinerama", "asound", "juce_debug"
|
"freetype", "pthread", "rt", "X11", "GL", "GLU", "Xinerama", "asound", "Xss", "juce_debug"
|
||||||
}
|
}
|
||||||
|
|
||||||
package.config["Release"].links = {
|
package.config["Release"].links = {
|
||||||
"freetype", "pthread", "rt", "X11", "GL", "GLU", "Xinerama", "asound", "juce"
|
"freetype", "pthread", "rt", "X11", "GL", "GLU", "Xinerama", "asound", "Xss", "juce"
|
||||||
}
|
}
|
||||||
|
|
||||||
package.linkflags = { "static-runtime" }
|
package.linkflags = { "static-runtime" }
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,32 @@ public:
|
||||||
delete im;
|
delete im;
|
||||||
|
|
||||||
startTimer (20);
|
startTimer (20);
|
||||||
|
|
||||||
|
// Just for demo purposes, let's dump a list of all the available pixel formats..
|
||||||
|
OwnedArray <OpenGLPixelFormat> availablePixelFormats;
|
||||||
|
OpenGLPixelFormat::getAvailablePixelFormats (availablePixelFormats);
|
||||||
|
|
||||||
|
for (int i = 0; i < availablePixelFormats.size(); ++i)
|
||||||
|
{
|
||||||
|
const OpenGLPixelFormat* const pixFormat = availablePixelFormats[i];
|
||||||
|
|
||||||
|
String formatDescription;
|
||||||
|
formatDescription
|
||||||
|
<< i << ": RGBA=(" << pixFormat->redBits
|
||||||
|
<< ", " << pixFormat->greenBits
|
||||||
|
<< ", " << pixFormat->blueBits
|
||||||
|
<< ", " << pixFormat->alphaBits
|
||||||
|
<< "), depth=" << pixFormat->depthBufferBits
|
||||||
|
<< ", stencil=" << pixFormat->stencilBufferBits
|
||||||
|
<< ", accum RGBA=(" << pixFormat->accumulationBufferRedBits
|
||||||
|
<< ", " << pixFormat->accumulationBufferGreenBits
|
||||||
|
<< ", " << pixFormat->accumulationBufferBlueBits
|
||||||
|
<< ", " << pixFormat->accumulationBufferAlphaBits
|
||||||
|
<< "), full-scene AA="
|
||||||
|
<< pixFormat->fullSceneAntiAliasingNumSamples;
|
||||||
|
|
||||||
|
Logger::outputDebugString (formatDescription);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~DemoOpenGLCanvas()
|
~DemoOpenGLCanvas()
|
||||||
|
|
|
||||||
|
|
@ -29,229 +29,216 @@
|
||||||
==============================================================================
|
==============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#include "../../../../juce_core/basics/juce_StandardHeader.h"
|
||||||
#pragma warning (disable: 4514)
|
|
||||||
#pragma warning (push)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../../../../../juce_Config.h"
|
|
||||||
|
|
||||||
#if JUCE_OPENGL
|
#if JUCE_OPENGL
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#include <gl/gl.h>
|
|
||||||
#else
|
|
||||||
#ifdef LINUX
|
|
||||||
#include <GL/glx.h>
|
|
||||||
#else
|
|
||||||
#include <agl/agl.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../../../../juce_core/basics/juce_StandardHeader.h"
|
|
||||||
|
|
||||||
BEGIN_JUCE_NAMESPACE
|
BEGIN_JUCE_NAMESPACE
|
||||||
|
|
||||||
#undef KeyPress
|
|
||||||
#include "juce_OpenGLComponent.h"
|
#include "juce_OpenGLComponent.h"
|
||||||
#include "../../graphics/geometry/juce_RectangleList.h"
|
|
||||||
#include "../../../events/juce_Timer.h"
|
|
||||||
#include "../layout/juce_ComponentMovementWatcher.h"
|
#include "../layout/juce_ComponentMovementWatcher.h"
|
||||||
|
#include "../../../../juce_core/threads/juce_ScopedLock.h"
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning (pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
extern void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext);
|
|
||||||
extern void juce_deleteOpenGLContext (void* context);
|
|
||||||
extern bool juce_makeOpenGLContextCurrent (void* context);
|
|
||||||
extern void juce_swapOpenGLBuffers (void* context);
|
|
||||||
extern void juce_updateOpenGLWindowPos (void* context, Component* owner, Component* topComp);
|
|
||||||
extern void juce_repaintOpenGLWindow (void* context);
|
|
||||||
extern bool juce_isActiveOpenGLContext (void* context) throw();
|
|
||||||
|
|
||||||
static VoidArray activeGLWindows (2);
|
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
class InternalGLContextHolder : public ComponentMovementWatcher
|
extern void juce_glViewport (const int w, const int h);
|
||||||
|
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
OpenGLPixelFormat::OpenGLPixelFormat (const int bitsPerRGBComponent,
|
||||||
|
const int alphaBits_,
|
||||||
|
const int depthBufferBits_,
|
||||||
|
const int stencilBufferBits_) throw()
|
||||||
|
: redBits (bitsPerRGBComponent),
|
||||||
|
greenBits (bitsPerRGBComponent),
|
||||||
|
blueBits (bitsPerRGBComponent),
|
||||||
|
alphaBits (alphaBits_),
|
||||||
|
depthBufferBits (depthBufferBits_),
|
||||||
|
stencilBufferBits (stencilBufferBits_),
|
||||||
|
accumulationBufferRedBits (0),
|
||||||
|
accumulationBufferGreenBits (0),
|
||||||
|
accumulationBufferBlueBits (0),
|
||||||
|
accumulationBufferAlphaBits (0),
|
||||||
|
fullSceneAntiAliasingNumSamples (0)
|
||||||
{
|
{
|
||||||
private:
|
}
|
||||||
OpenGLComponent* owner;
|
|
||||||
void* context;
|
|
||||||
InternalGLContextHolder* sharedContext;
|
|
||||||
bool wasShowing;
|
|
||||||
|
|
||||||
|
bool OpenGLPixelFormat::operator== (const OpenGLPixelFormat& other) const throw()
|
||||||
|
{
|
||||||
|
return memcmp (this, &other, sizeof (other)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
class OpenGLComponentWatcher : public ComponentMovementWatcher
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
bool needToUpdateViewport;
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
InternalGLContextHolder (OpenGLComponent* const owner_,
|
OpenGLComponentWatcher (OpenGLComponent* const owner_)
|
||||||
InternalGLContextHolder* const sharedContext_)
|
|
||||||
: ComponentMovementWatcher (owner_),
|
: ComponentMovementWatcher (owner_),
|
||||||
owner (owner_),
|
owner (owner_),
|
||||||
context (0),
|
wasShowing (false)
|
||||||
sharedContext (sharedContext_),
|
|
||||||
wasShowing (false),
|
|
||||||
needToUpdateViewport (true)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~InternalGLContextHolder()
|
~OpenGLComponentWatcher() {}
|
||||||
{
|
|
||||||
release();
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
void release()
|
|
||||||
{
|
|
||||||
if (context != 0)
|
|
||||||
{
|
|
||||||
juce_deleteOpenGLContext (context);
|
|
||||||
context = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void initialise()
|
|
||||||
{
|
|
||||||
jassert (context == 0);
|
|
||||||
|
|
||||||
if (context == 0)
|
|
||||||
{
|
|
||||||
context = juce_createOpenGLContext (owner,
|
|
||||||
sharedContext != 0 ? sharedContext->context
|
|
||||||
: 0);
|
|
||||||
|
|
||||||
if (context != 0)
|
|
||||||
{
|
|
||||||
componentMovedOrResized (true, true);
|
|
||||||
|
|
||||||
if (makeCurrent())
|
|
||||||
owner->newOpenGLContextCreated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
bool makeCurrent() const
|
|
||||||
{
|
|
||||||
return context != 0 && juce_makeOpenGLContextCurrent (context);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isActive() const throw()
|
|
||||||
{
|
|
||||||
return context != 0 && juce_isActiveOpenGLContext (context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void swapBuffers() const
|
|
||||||
{
|
|
||||||
if (context != 0)
|
|
||||||
juce_swapOpenGLBuffers (context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void repaint() const
|
|
||||||
{
|
|
||||||
if (context != 0)
|
|
||||||
juce_repaintOpenGLWindow (context);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
|
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
|
||||||
{
|
{
|
||||||
if (owner->getWidth() > 0 && owner->getHeight() > 0)
|
owner->updateContextPosition();
|
||||||
{
|
|
||||||
Component* const topComp = owner->getTopLevelComponent();
|
|
||||||
|
|
||||||
if (topComp->getPeer() != 0)
|
|
||||||
{
|
|
||||||
needToUpdateViewport = true;
|
|
||||||
|
|
||||||
if (context == 0)
|
|
||||||
{
|
|
||||||
if (owner->isShowing())
|
|
||||||
initialise();
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context != 0)
|
|
||||||
juce_updateOpenGLWindowPos (context, owner, topComp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void componentPeerChanged()
|
void componentPeerChanged()
|
||||||
{
|
{
|
||||||
release();
|
const ScopedLock sl (owner->getContextLock());
|
||||||
|
owner->deleteContext();
|
||||||
if (owner->isShowing() && owner->getTopLevelComponent()->getPeer() != 0)
|
owner->createContext();
|
||||||
initialise();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void componentVisibilityChanged (Component&)
|
void componentVisibilityChanged (Component&)
|
||||||
{
|
{
|
||||||
if (wasShowing != owner->isShowing())
|
const bool isShowingNow = owner->isShowing();
|
||||||
|
|
||||||
|
if (wasShowing != isShowingNow)
|
||||||
{
|
{
|
||||||
wasShowing = owner->isShowing();
|
wasShowing = isShowingNow;
|
||||||
componentMovedOrResized (true, true);
|
owner->updateContextPosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
juce_UseDebuggingNewOperator
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpenGLComponent* const owner;
|
||||||
|
bool wasShowing;
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
OpenGLComponent::OpenGLComponent (OpenGLComponent* share)
|
OpenGLComponent::OpenGLComponent()
|
||||||
|
: context (0),
|
||||||
|
componentToShareListsWith (0),
|
||||||
|
needToUpdateViewport (true)
|
||||||
{
|
{
|
||||||
setOpaque (true);
|
setOpaque (true);
|
||||||
internalData = new InternalGLContextHolder (this, (InternalGLContextHolder*) (share != 0 ? share->internalData : 0));
|
componentWatcher = new OpenGLComponentWatcher (this);
|
||||||
|
|
||||||
activeGLWindows.add (this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLComponent::~OpenGLComponent()
|
OpenGLComponent::~OpenGLComponent()
|
||||||
{
|
{
|
||||||
activeGLWindows.removeValue ((void*) this);
|
deleteContext();
|
||||||
|
delete componentWatcher;
|
||||||
|
}
|
||||||
|
|
||||||
InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
void OpenGLComponent::createContext()
|
||||||
delete context;
|
{
|
||||||
|
const ScopedLock sl (contextLock);
|
||||||
|
|
||||||
|
jassert (context == 0);
|
||||||
|
|
||||||
|
if (context == 0 && isShowing() && getTopLevelComponent()->getPeer() != 0)
|
||||||
|
{
|
||||||
|
context = OpenGLContext::createContextForWindow (this,
|
||||||
|
preferredPixelFormat,
|
||||||
|
componentToShareListsWith != 0
|
||||||
|
? componentToShareListsWith->context
|
||||||
|
: 0);
|
||||||
|
|
||||||
|
if (context != 0)
|
||||||
|
{
|
||||||
|
updateContextPosition();
|
||||||
|
|
||||||
|
if (makeCurrentContextActive())
|
||||||
|
newOpenGLContextCreated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLComponent::deleteContext()
|
||||||
|
{
|
||||||
|
const ScopedLock sl (contextLock);
|
||||||
|
deleteAndZero (context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLComponent::updateContextPosition()
|
||||||
|
{
|
||||||
|
needToUpdateViewport = true;
|
||||||
|
|
||||||
|
if (getWidth() > 0 && getHeight() > 0)
|
||||||
|
{
|
||||||
|
Component* const topComp = getTopLevelComponent();
|
||||||
|
|
||||||
|
if (topComp->getPeer() != 0)
|
||||||
|
{
|
||||||
|
const ScopedLock sl (contextLock);
|
||||||
|
|
||||||
|
if (context == 0)
|
||||||
|
createContext();
|
||||||
|
|
||||||
|
if (context != 0)
|
||||||
|
context->updateWindowPosition (getScreenX() - topComp->getScreenX(),
|
||||||
|
getScreenY() - topComp->getScreenY(),
|
||||||
|
getWidth(),
|
||||||
|
getHeight(),
|
||||||
|
topComp->getHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpenGLPixelFormat OpenGLComponent::getPixelFormat() const
|
||||||
|
{
|
||||||
|
OpenGLPixelFormat pf;
|
||||||
|
|
||||||
|
const ScopedLock sl (contextLock);
|
||||||
|
if (context != 0)
|
||||||
|
pf = context->getPixelFormat();
|
||||||
|
|
||||||
|
return pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenGLComponent::setPixelFormat (const OpenGLPixelFormat& formatToUse)
|
||||||
|
{
|
||||||
|
if (preferredPixelFormat == formatToUse)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const ScopedLock sl (contextLock);
|
||||||
|
deleteContext();
|
||||||
|
preferredPixelFormat = formatToUse;
|
||||||
|
createContext();
|
||||||
|
|
||||||
|
return context != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLComponent::shareWith (OpenGLComponent* const comp)
|
||||||
|
{
|
||||||
|
if (componentToShareListsWith != comp)
|
||||||
|
{
|
||||||
|
const ScopedLock sl (contextLock);
|
||||||
|
deleteContext();
|
||||||
|
componentToShareListsWith = comp;
|
||||||
|
createContext();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLComponent::makeCurrentContextActive()
|
bool OpenGLComponent::makeCurrentContextActive()
|
||||||
{
|
{
|
||||||
InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
return context != 0 && context->makeActive();
|
||||||
return context->makeCurrent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLComponent::makeCurrentContextInactive()
|
void OpenGLComponent::makeCurrentContextInactive()
|
||||||
{
|
{
|
||||||
juce_makeOpenGLContextCurrent (0);
|
if (context != 0)
|
||||||
|
context->makeInactive();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLComponent::isActiveContext() const throw()
|
bool OpenGLComponent::isActiveContext() const throw()
|
||||||
{
|
{
|
||||||
const InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
|
||||||
|
|
||||||
return context != 0 && context->isActive();
|
return context != 0 && context->isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLComponent* OpenGLComponent::getCurrentlyActiveContextComponent() throw()
|
|
||||||
{
|
|
||||||
for (int i = activeGLWindows.size(); --i >= 0;)
|
|
||||||
{
|
|
||||||
OpenGLComponent* const component = (OpenGLComponent*) activeGLWindows.getUnchecked(i);
|
|
||||||
|
|
||||||
if (component->isActiveContext())
|
|
||||||
return component;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLComponent::swapBuffers()
|
void OpenGLComponent::swapBuffers()
|
||||||
{
|
{
|
||||||
InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
|
||||||
|
|
||||||
if (context != 0)
|
if (context != 0)
|
||||||
context->swapBuffers();
|
context->swapBuffers();
|
||||||
}
|
}
|
||||||
|
|
@ -273,20 +260,19 @@ void OpenGLComponent::paint (Graphics&)
|
||||||
|
|
||||||
bool OpenGLComponent::renderAndSwapBuffers()
|
bool OpenGLComponent::renderAndSwapBuffers()
|
||||||
{
|
{
|
||||||
|
const ScopedLock sl (contextLock);
|
||||||
|
|
||||||
if (! makeCurrentContextActive())
|
if (! makeCurrentContextActive())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
if (needToUpdateViewport)
|
||||||
|
|
||||||
if (context->needToUpdateViewport)
|
|
||||||
{
|
{
|
||||||
context->needToUpdateViewport = false;
|
needToUpdateViewport = false;
|
||||||
glViewport (0, 0, getWidth(), getHeight());
|
juce_glViewport (getWidth(), getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
renderOpenGL();
|
renderOpenGL();
|
||||||
|
swapBuffers();
|
||||||
context->swapBuffers();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -295,8 +281,8 @@ void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
Component::internalRepaint (x, y, w, h);
|
Component::internalRepaint (x, y, w, h);
|
||||||
|
|
||||||
InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
if (context != 0)
|
||||||
context->repaint();
|
context->repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,119 @@
|
||||||
// this is used to disable OpenGL, and is defined in juce_Config.h
|
// this is used to disable OpenGL, and is defined in juce_Config.h
|
||||||
#if JUCE_OPENGL || DOXYGEN
|
#if JUCE_OPENGL || DOXYGEN
|
||||||
|
|
||||||
|
class OpenGLComponentWatcher;
|
||||||
|
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/**
|
||||||
|
Represents the various properties of an OpenGL bitmap format.
|
||||||
|
|
||||||
|
@see OpenGLComponent::setPixelFormat
|
||||||
|
*/
|
||||||
|
struct OpenGLPixelFormat
|
||||||
|
{
|
||||||
|
//==============================================================================
|
||||||
|
/** Creates an OpenGLPixelFormat.
|
||||||
|
|
||||||
|
The default constructor just initialises the object as a simple 8-bit
|
||||||
|
RGBA format.
|
||||||
|
*/
|
||||||
|
OpenGLPixelFormat (const int bitsPerRGBComponent = 8,
|
||||||
|
const int alphaBits = 8,
|
||||||
|
const int depthBufferBits = 16,
|
||||||
|
const int stencilBufferBits = 0) throw();
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
int redBits; /**< The number of bits per pixel to use for the red channel. */
|
||||||
|
int greenBits; /**< The number of bits per pixel to use for the green channel. */
|
||||||
|
int blueBits; /**< The number of bits per pixel to use for the blue channel. */
|
||||||
|
int alphaBits; /**< The number of bits per pixel to use for the alpha channel. */
|
||||||
|
|
||||||
|
int depthBufferBits; /**< The number of bits per pixel to use for a depth buffer. */
|
||||||
|
int stencilBufferBits; /**< The number of bits per pixel to use for a stencil buffer. */
|
||||||
|
|
||||||
|
int accumulationBufferRedBits; /**< The number of bits per pixel to use for an accumulation buffer's red channel. */
|
||||||
|
int accumulationBufferGreenBits; /**< The number of bits per pixel to use for an accumulation buffer's green channel. */
|
||||||
|
int accumulationBufferBlueBits; /**< The number of bits per pixel to use for an accumulation buffer's blue channel. */
|
||||||
|
int accumulationBufferAlphaBits; /**< The number of bits per pixel to use for an accumulation buffer's alpha channel. */
|
||||||
|
|
||||||
|
uint8 fullSceneAntiAliasingNumSamples; /**< The number of samples to use in full-scene anti-aliasing (if available). */
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/** Returns a list of all the pixel formats that can be used in this system.
|
||||||
|
*/
|
||||||
|
static void getAvailablePixelFormats (OwnedArray <OpenGLPixelFormat>& results);
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
bool operator== (const OpenGLPixelFormat&) const throw();
|
||||||
|
|
||||||
|
juce_UseDebuggingNewOperator
|
||||||
|
};
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/**
|
||||||
|
A base class for types of OpenGL context.
|
||||||
|
|
||||||
|
An OpenGLComponent will supply its own context for drawing in its window.
|
||||||
|
*/
|
||||||
|
class OpenGLContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//==============================================================================
|
||||||
|
/** Destructor. */
|
||||||
|
virtual ~OpenGLContext() {}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/** Makes this context the currently active one. */
|
||||||
|
virtual bool makeActive() throw() = 0;
|
||||||
|
/** If this context is currently active, it is disactivated. */
|
||||||
|
virtual bool makeInactive() throw() = 0;
|
||||||
|
/** Returns true if this context is currently active. */
|
||||||
|
virtual bool isActive() const throw() = 0;
|
||||||
|
|
||||||
|
/** Swaps the buffers (if the context can do this). */
|
||||||
|
virtual void swapBuffers() = 0;
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/** Returns the pixel format being used by this context. */
|
||||||
|
virtual const OpenGLPixelFormat getPixelFormat() const = 0;
|
||||||
|
|
||||||
|
/** For windowed contexts, this moves the context within the bounds of
|
||||||
|
its parent window.
|
||||||
|
*/
|
||||||
|
virtual void updateWindowPosition (int x, int y, int w, int h, int outerWindowHeight) = 0;
|
||||||
|
|
||||||
|
/** For windowed contexts, this triggers a repaint of the window.
|
||||||
|
|
||||||
|
(Not relevent on all platforms).
|
||||||
|
*/
|
||||||
|
virtual void repaint() = 0;
|
||||||
|
|
||||||
|
/** Returns an OS-dependent handle to the raw GL context.
|
||||||
|
|
||||||
|
On win32, this will be a HGLRC; on the Mac, an AGLContext; on Linux,
|
||||||
|
a GLXContext.
|
||||||
|
*/
|
||||||
|
virtual void* getRawContext() const throw() = 0;
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/** This tries to create a context that can be used for drawing into the
|
||||||
|
area occupied by the specified component.
|
||||||
|
|
||||||
|
Note that you probably shouldn't use this method directly unless you know what
|
||||||
|
you're doing - the OpenGLComponent calls this and manages the context for you.
|
||||||
|
*/
|
||||||
|
static OpenGLContext* createContextForWindow (Component* componentToDrawTo,
|
||||||
|
const OpenGLPixelFormat& pixelFormat,
|
||||||
|
const OpenGLContext* const contextToShareWith);
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
juce_UseDebuggingNewOperator
|
||||||
|
|
||||||
|
protected:
|
||||||
|
OpenGLContext() throw() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/**
|
/**
|
||||||
|
|
@ -51,42 +164,28 @@ class JUCE_API OpenGLComponent : public Component
|
||||||
public:
|
public:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Creates an OpenGLComponent.
|
/** Creates an OpenGLComponent.
|
||||||
|
|
||||||
@param componentToShareContextWith if this is another OpenGLComponent, then
|
|
||||||
the two contexts will have their OpenGL contexts
|
|
||||||
shared
|
|
||||||
*/
|
*/
|
||||||
OpenGLComponent (OpenGLComponent* componentToShareContextWith = 0);
|
OpenGLComponent();
|
||||||
|
|
||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
~OpenGLComponent();
|
~OpenGLComponent();
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Makes this component the current openGL context.
|
/** Changes the pixel format used by this component.
|
||||||
|
|
||||||
You might want to use this in things like your resize() method, before calling
|
@see OpenGLPixelFormat::getAvailablePixelFormats()
|
||||||
GL commands.
|
|
||||||
|
|
||||||
If this returns false, then the context isn't active, so you should avoid
|
|
||||||
making any calls.
|
|
||||||
*/
|
*/
|
||||||
bool makeCurrentContextActive();
|
bool setPixelFormat (const OpenGLPixelFormat& formatToUse);
|
||||||
|
|
||||||
/** Stops the current component being the active OpenGL context.
|
/** Returns the pixel format that this component is currently using. */
|
||||||
|
const OpenGLPixelFormat getPixelFormat() const;
|
||||||
|
|
||||||
This is the opposite of makeCurrentContextActive()
|
/** Specifies another component whose OpenGL context should be shared with
|
||||||
|
this one.
|
||||||
|
|
||||||
|
This is an OpenGL feature that lets two contexts share their texture data.
|
||||||
*/
|
*/
|
||||||
void makeCurrentContextInactive();
|
void shareWith (OpenGLComponent* const componentToShareListsWith);
|
||||||
|
|
||||||
/** Returns true if this component is the active openGL context for the
|
|
||||||
current thread.
|
|
||||||
*/
|
|
||||||
bool isActiveContext() const throw();
|
|
||||||
|
|
||||||
/** Returns the OpenGLComponent that is currently the active context for
|
|
||||||
the current thread.
|
|
||||||
*/
|
|
||||||
static OpenGLComponent* getCurrentlyActiveContextComponent() throw();
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Flips the openGL buffers over. */
|
/** Flips the openGL buffers over. */
|
||||||
|
|
@ -115,16 +214,63 @@ public:
|
||||||
virtual void newOpenGLContextCreated() = 0;
|
virtual void newOpenGLContextCreated() = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/** Returns the context that will draw into this component.
|
||||||
|
|
||||||
|
This may return 0 if it failed to initialise properly, or if the component
|
||||||
|
is currently invisible. The context object may be deleted and a new one created
|
||||||
|
during the life of this component - see newOpenGLContextCreated().
|
||||||
|
*/
|
||||||
|
OpenGLContext* getCurrentContext() const throw();
|
||||||
|
|
||||||
|
/** Makes this component the current openGL context.
|
||||||
|
|
||||||
|
You might want to use this in things like your resize() method, before calling
|
||||||
|
GL commands.
|
||||||
|
|
||||||
|
If this returns false, then the context isn't active, so you should avoid
|
||||||
|
making any calls.
|
||||||
|
|
||||||
|
@see OpenGLContext::makeActive
|
||||||
|
*/
|
||||||
|
bool makeCurrentContextActive();
|
||||||
|
|
||||||
|
/** Stops the current component being the active OpenGL context.
|
||||||
|
|
||||||
|
This is the opposite of makeCurrentContextActive()
|
||||||
|
|
||||||
|
@see OpenGLContext::makeInactive
|
||||||
|
*/
|
||||||
|
void makeCurrentContextInactive();
|
||||||
|
|
||||||
|
/** Returns true if this component is the active openGL context for the
|
||||||
|
current thread.
|
||||||
|
|
||||||
|
@see OpenGLContext::isActive
|
||||||
|
*/
|
||||||
|
bool isActiveContext() const throw();
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Calls the rendering callback, and swaps the buffers afterwards.
|
/** Calls the rendering callback, and swaps the buffers afterwards.
|
||||||
|
|
||||||
Called by paint(), this can be overridden if you need to decouple the rendering
|
This is called automatically by paint() when the component needs to be rendered.
|
||||||
from the paint callback and render with a different thread.
|
|
||||||
|
It can be overridden if you need to decouple the rendering from the paint callback
|
||||||
|
and render with a custom thread.
|
||||||
|
|
||||||
Returns true if the operation succeeded.
|
Returns true if the operation succeeded.
|
||||||
*/
|
*/
|
||||||
virtual bool renderAndSwapBuffers();
|
virtual bool renderAndSwapBuffers();
|
||||||
|
|
||||||
|
/** This returns a critical section that can be used to lock the current context.
|
||||||
|
|
||||||
|
Because the context that is used by this component can change, e.g. when the
|
||||||
|
component is shown or hidden, then if you're rendering to it on a background
|
||||||
|
thread, this allows you to lock the context for the duration of your rendering
|
||||||
|
routine.
|
||||||
|
*/
|
||||||
|
CriticalSection& getContextLock() throw() { return contextLock; }
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** @internal */
|
/** @internal */
|
||||||
|
|
@ -133,13 +279,23 @@ public:
|
||||||
juce_UseDebuggingNewOperator
|
juce_UseDebuggingNewOperator
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class InternalGLContextHolder;
|
friend class OpenGLComponentWatcher;
|
||||||
void* internalData;
|
OpenGLComponentWatcher* componentWatcher;
|
||||||
|
|
||||||
|
OpenGLContext* context;
|
||||||
|
OpenGLComponent* componentToShareListsWith;
|
||||||
|
|
||||||
|
CriticalSection contextLock;
|
||||||
|
OpenGLPixelFormat preferredPixelFormat;
|
||||||
|
bool needToUpdateViewport;
|
||||||
|
|
||||||
|
void createContext();
|
||||||
|
void deleteContext();
|
||||||
|
void updateContextPosition();
|
||||||
|
void internalRepaint (int x, int y, int w, int h);
|
||||||
|
|
||||||
OpenGLComponent (const OpenGLComponent&);
|
OpenGLComponent (const OpenGLComponent&);
|
||||||
const OpenGLComponent& operator= (const OpenGLComponent&);
|
const OpenGLComponent& operator= (const OpenGLComponent&);
|
||||||
|
|
||||||
void internalRepaint (int x, int y, int w, int h);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue