mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +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
|
||||
|
||||
struct OpenGLContextInfo
|
||||
|
||||
//==============================================================================
|
||||
class WindowedGLContext : public OpenGLContext
|
||||
{
|
||||
Window embeddedWindow;
|
||||
GLXContext renderContext;
|
||||
};
|
||||
|
||||
void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext)
|
||||
{
|
||||
XSync (display, False);
|
||||
jassert (component != 0);
|
||||
|
||||
if (component == 0)
|
||||
return 0;
|
||||
|
||||
LinuxComponentPeer* const peer
|
||||
= dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer());
|
||||
|
||||
if (peer == 0)
|
||||
return 0;
|
||||
|
||||
GLint attribList[] =
|
||||
public:
|
||||
WindowedGLContext (Component* const component,
|
||||
const OpenGLPixelFormat& pixelFormat_,
|
||||
GLXContext sharedContext)
|
||||
: renderContext (0),
|
||||
embeddedWindow (0),
|
||||
pixelFormat (pixelFormat_)
|
||||
{
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_ALPHA_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, 8,
|
||||
None
|
||||
};
|
||||
jassert (component != 0);
|
||||
LinuxComponentPeer* const peer = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer());
|
||||
if (peer == 0)
|
||||
return;
|
||||
|
||||
XVisualInfo* const bestVisual = glXChooseVisual (display, DefaultScreen (display), attribList);
|
||||
XSync (display, False);
|
||||
|
||||
if (bestVisual == 0)
|
||||
return 0;
|
||||
GLint attribs [64];
|
||||
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,
|
||||
(sharedContext != 0) ? ((OpenGLContextInfo*) sharedContext)->renderContext
|
||||
: 0,
|
||||
GL_TRUE);
|
||||
attribs[n++] = None;
|
||||
|
||||
Window windowH = (Window) peer->getNativeHandle();
|
||||
XVisualInfo* const bestVisual = glXChooseVisual (display, DefaultScreen (display), attribs);
|
||||
|
||||
Colormap colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone);
|
||||
XSetWindowAttributes swa;
|
||||
swa.colormap = colourMap;
|
||||
swa.border_pixel = 0;
|
||||
swa.event_mask = ExposureMask | StructureNotifyMask;
|
||||
if (bestVisual == 0)
|
||||
return;
|
||||
|
||||
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,
|
||||
bestVisual->depth,
|
||||
InputOutput,
|
||||
|
|
@ -2855,73 +2866,104 @@ void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext)
|
|||
CWBorderPixel | CWColormap | CWEventMask,
|
||||
&swa);
|
||||
|
||||
XSaveContext (display, (XID) oc->embeddedWindow, improbableNumber, (XPointer) peer);
|
||||
XSaveContext (display, (XID) embeddedWindow, improbableNumber, (XPointer) peer);
|
||||
|
||||
XMapWindow (display, oc->embeddedWindow);
|
||||
XFreeColormap (display, colourMap);
|
||||
XMapWindow (display, embeddedWindow);
|
||||
XFreeColormap (display, colourMap);
|
||||
|
||||
XFree (bestVisual);
|
||||
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;
|
||||
XFree (bestVisual);
|
||||
XSync (display, False);
|
||||
}
|
||||
}
|
||||
|
||||
bool juce_makeOpenGLContextCurrent (void* context)
|
||||
{
|
||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
||||
~WindowedGLContext()
|
||||
{
|
||||
makeInactive();
|
||||
|
||||
if (oc != 0)
|
||||
return glXMakeCurrent (display, oc->embeddedWindow, oc->renderContext)
|
||||
glXDestroyContext (display, renderContext);
|
||||
|
||||
XUnmapWindow (display, embeddedWindow);
|
||||
XDestroyWindow (display, embeddedWindow);
|
||||
}
|
||||
|
||||
bool makeActive() throw()
|
||||
{
|
||||
jassert (renderContext != 0);
|
||||
|
||||
return glXMakeCurrent (display, embeddedWindow, renderContext)
|
||||
&& 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;
|
||||
|
||||
jassert (oc != 0);
|
||||
return glXGetCurrentContext() == oc->renderContext;
|
||||
glViewport (0, 0, w, h);
|
||||
}
|
||||
|
||||
void juce_swapOpenGLBuffers (void* context)
|
||||
{
|
||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
||||
|
||||
if (oc != 0)
|
||||
glXSwapBuffers (display, oc->embeddedWindow);
|
||||
}
|
||||
|
||||
void juce_repaintOpenGLWindow (void* context)
|
||||
void OpenGLPixelFormat::getAvailablePixelFormats (OwnedArray <OpenGLPixelFormat>& results)
|
||||
{
|
||||
results.add (new OpenGLPixelFormat()); // xxx
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3292,92 +3292,190 @@ void AppleRemoteDevice::handleCallbackInternal()
|
|||
//==============================================================================
|
||||
#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;
|
||||
|
||||
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 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;
|
||||
return c;
|
||||
}
|
||||
|
||||
void juce_updateOpenGLWindowPos (void* context, Component* owner, Component* topComp)
|
||||
void juce_glViewport (const int w, const int h)
|
||||
{
|
||||
jassert (context != 0);
|
||||
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);
|
||||
glViewport (0, 0, w, h);
|
||||
}
|
||||
|
||||
void juce_deleteOpenGLContext (void* context)
|
||||
static int getAGLAttribute (AGLPixelFormat p, const GLint attrib)
|
||||
{
|
||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
||||
|
||||
aglDestroyContext (oc->renderContext);
|
||||
|
||||
delete oc;
|
||||
GLint result = 0;
|
||||
aglDescribePixelFormat (p, attrib, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -2640,6 +2640,7 @@ void MouseCursor::showInAllWindows() const throw()
|
|||
showInWindow (0);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
class JuceDropSource : public IDropSource
|
||||
{
|
||||
|
|
@ -2970,13 +2971,13 @@ static HDROP createHDrop (const StringArray& fileNames) throw()
|
|||
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();
|
||||
JuceDataObject* const data = new JuceDataObject (source, format, medium, 1);
|
||||
|
||||
DWORD effect;
|
||||
HRESULT res = DoDragDrop (data, source, whatToDo, &effect);
|
||||
const HRESULT res = DoDragDrop (data, source, whatToDo, &effect);
|
||||
|
||||
data->Release();
|
||||
source->Release();
|
||||
|
|
@ -3026,152 +3027,456 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
|
|||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
#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;
|
||||
HGLRC renderContext;
|
||||
};
|
||||
if (WGL_EXT_FUNCTION_INIT (PFNWGLGETEXTENSIONSSTRINGARBPROC, wglGetExtensionsStringARB))
|
||||
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);
|
||||
|
||||
Win32ComponentPeer* const peer = dynamic_cast <Win32ComponentPeer*> (component->getTopLevelComponent()->getPeer());
|
||||
|
||||
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))
|
||||
public:
|
||||
WindowedGLContext (Component* const component, HGLRC contextToShareWith)
|
||||
: renderContext (0),
|
||||
nativeWindow (0)
|
||||
{
|
||||
// try some less ambitious formats if it fails..
|
||||
pfd.cColorBits = 24;
|
||||
format = ChoosePixelFormat (oc->dc, &pfd);
|
||||
jassert (component != 0);
|
||||
Win32ComponentPeer* const peer = dynamic_cast <Win32ComponentPeer*> (component->getTopLevelComponent()->getPeer());
|
||||
|
||||
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;
|
||||
format = ChoosePixelFormat (oc->dc, &pfd);
|
||||
SetParent (hwnd, (HWND) peer->getNativeHandle());
|
||||
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;
|
||||
format = ChoosePixelFormat (oc->dc, &pfd);
|
||||
attributes[n++] = WGL_STENCIL_BITS_ARB;
|
||||
attributes[n++] = pixelFormat.stencilBufferBits;
|
||||
}
|
||||
|
||||
if (format == 0 || ! SetPixelFormat (oc->dc, format, &pfd))
|
||||
{
|
||||
jassertfalse // can't find a suitable pixel format that works for opengl
|
||||
}
|
||||
attributes[n++] = WGL_ACCUM_RED_BITS_ARB;
|
||||
attributes[n++] = pixelFormat.accumulationBufferRedBits;
|
||||
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)
|
||||
wglShareLists (((OpenGLContextInfo*) sharedContext)->renderContext, oc->renderContext);
|
||||
HGLRC renderContext;
|
||||
|
||||
return oc;
|
||||
}
|
||||
private:
|
||||
Win32ComponentPeer* nativeWindow;
|
||||
HDC dc;
|
||||
|
||||
void juce_updateOpenGLWindowPos (void* context, Component* owner, Component* topComp)
|
||||
{
|
||||
jassert (context != 0);
|
||||
OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
|
||||
|
||||
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)
|
||||
//==============================================================================
|
||||
bool fillInPixelFormatDetails (const int pixelFormatIndex,
|
||||
OpenGLPixelFormat& result,
|
||||
const StringArray& availableExtensions) const throw()
|
||||
{
|
||||
wglDeleteContext (oc->renderContext);
|
||||
ReleaseDC ((HWND) oc->nativeWindow->getNativeHandle(), oc->dc);
|
||||
PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = 0;
|
||||
|
||||
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;
|
||||
|
||||
if (oc != 0)
|
||||
return wglMakeCurrent (oc->dc, oc->renderContext) != 0;
|
||||
else
|
||||
return wglMakeCurrent (0, 0) != 0;
|
||||
glViewport (0, 0, w, h);
|
||||
}
|
||||
|
||||
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;
|
||||
oc->nativeWindow->getBounds (x, y, w, h);
|
||||
oc->nativeWindow->repaint (0, 0, w, h);
|
||||
WindowedGLContext wc (&tempComp, 0);
|
||||
wc.makeActive();
|
||||
wc.findAlternativeOpenGLPixelFormats (results);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
class JuceIStorage : public IStorage
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ Changelist for version 1.45
|
|||
- new class: FileSearchPathListComponent, for letting the user edit a FileSearchPath.
|
||||
- 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 the OpenGLComponent, adding new classes OpenGLPixelFormat and OpenGLContext
|
||||
|
||||
==============================================================================
|
||||
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"
|
||||
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -D_DEBUG -ggdb
|
||||
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 :=
|
||||
RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include"
|
||||
TARGET := jucedemo
|
||||
|
|
@ -28,7 +28,7 @@ ifeq ($(CONFIG),Release)
|
|||
CPPFLAGS := -MMD -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include"
|
||||
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O2
|
||||
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 :=
|
||||
RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include"
|
||||
TARGET := jucedemo
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ package.libpaths = {
|
|||
}
|
||||
|
||||
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 = {
|
||||
"freetype", "pthread", "rt", "X11", "GL", "GLU", "Xinerama", "asound", "juce"
|
||||
"freetype", "pthread", "rt", "X11", "GL", "GLU", "Xinerama", "asound", "Xss", "juce"
|
||||
}
|
||||
|
||||
package.linkflags = { "static-runtime" }
|
||||
|
|
|
|||
|
|
@ -81,6 +81,32 @@ public:
|
|||
delete im;
|
||||
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -29,229 +29,216 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4514)
|
||||
#pragma warning (push)
|
||||
#endif
|
||||
|
||||
#include "../../../../../juce_Config.h"
|
||||
#include "../../../../juce_core/basics/juce_StandardHeader.h"
|
||||
|
||||
#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
|
||||
|
||||
#undef KeyPress
|
||||
#include "juce_OpenGLComponent.h"
|
||||
#include "../../graphics/geometry/juce_RectangleList.h"
|
||||
#include "../../../events/juce_Timer.h"
|
||||
#include "../layout/juce_ComponentMovementWatcher.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);
|
||||
#include "../../../../juce_core/threads/juce_ScopedLock.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
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:
|
||||
bool needToUpdateViewport;
|
||||
|
||||
//==============================================================================
|
||||
InternalGLContextHolder (OpenGLComponent* const owner_,
|
||||
InternalGLContextHolder* const sharedContext_)
|
||||
OpenGLComponentWatcher (OpenGLComponent* const owner_)
|
||||
: ComponentMovementWatcher (owner_),
|
||||
owner (owner_),
|
||||
context (0),
|
||||
sharedContext (sharedContext_),
|
||||
wasShowing (false),
|
||||
needToUpdateViewport (true)
|
||||
wasShowing (false)
|
||||
{
|
||||
}
|
||||
|
||||
~InternalGLContextHolder()
|
||||
{
|
||||
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);
|
||||
}
|
||||
~OpenGLComponentWatcher() {}
|
||||
|
||||
//==============================================================================
|
||||
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
|
||||
{
|
||||
if (owner->getWidth() > 0 && owner->getHeight() > 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
owner->updateContextPosition();
|
||||
}
|
||||
|
||||
void componentPeerChanged()
|
||||
{
|
||||
release();
|
||||
|
||||
if (owner->isShowing() && owner->getTopLevelComponent()->getPeer() != 0)
|
||||
initialise();
|
||||
const ScopedLock sl (owner->getContextLock());
|
||||
owner->deleteContext();
|
||||
owner->createContext();
|
||||
}
|
||||
|
||||
void componentVisibilityChanged (Component&)
|
||||
{
|
||||
if (wasShowing != owner->isShowing())
|
||||
const bool isShowingNow = owner->isShowing();
|
||||
|
||||
if (wasShowing != isShowingNow)
|
||||
{
|
||||
wasShowing = owner->isShowing();
|
||||
componentMovedOrResized (true, true);
|
||||
wasShowing = isShowingNow;
|
||||
owner->updateContextPosition();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
OpenGLComponent* const owner;
|
||||
bool wasShowing;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
OpenGLComponent::OpenGLComponent (OpenGLComponent* share)
|
||||
OpenGLComponent::OpenGLComponent()
|
||||
: context (0),
|
||||
componentToShareListsWith (0),
|
||||
needToUpdateViewport (true)
|
||||
{
|
||||
setOpaque (true);
|
||||
internalData = new InternalGLContextHolder (this, (InternalGLContextHolder*) (share != 0 ? share->internalData : 0));
|
||||
|
||||
activeGLWindows.add (this);
|
||||
componentWatcher = new OpenGLComponentWatcher (this);
|
||||
}
|
||||
|
||||
OpenGLComponent::~OpenGLComponent()
|
||||
{
|
||||
activeGLWindows.removeValue ((void*) this);
|
||||
deleteContext();
|
||||
delete componentWatcher;
|
||||
}
|
||||
|
||||
InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
||||
delete context;
|
||||
void OpenGLComponent::createContext()
|
||||
{
|
||||
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()
|
||||
{
|
||||
InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
||||
return context->makeCurrent();
|
||||
return context != 0 && context->makeActive();
|
||||
}
|
||||
|
||||
void OpenGLComponent::makeCurrentContextInactive()
|
||||
{
|
||||
juce_makeOpenGLContextCurrent (0);
|
||||
if (context != 0)
|
||||
context->makeInactive();
|
||||
}
|
||||
|
||||
bool OpenGLComponent::isActiveContext() const throw()
|
||||
{
|
||||
const InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
||||
|
||||
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()
|
||||
{
|
||||
InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
||||
|
||||
if (context != 0)
|
||||
context->swapBuffers();
|
||||
}
|
||||
|
|
@ -273,20 +260,19 @@ void OpenGLComponent::paint (Graphics&)
|
|||
|
||||
bool OpenGLComponent::renderAndSwapBuffers()
|
||||
{
|
||||
const ScopedLock sl (contextLock);
|
||||
|
||||
if (! makeCurrentContextActive())
|
||||
return false;
|
||||
|
||||
InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
||||
|
||||
if (context->needToUpdateViewport)
|
||||
if (needToUpdateViewport)
|
||||
{
|
||||
context->needToUpdateViewport = false;
|
||||
glViewport (0, 0, getWidth(), getHeight());
|
||||
needToUpdateViewport = false;
|
||||
juce_glViewport (getWidth(), getHeight());
|
||||
}
|
||||
|
||||
renderOpenGL();
|
||||
|
||||
context->swapBuffers();
|
||||
swapBuffers();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -295,8 +281,8 @@ void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
|
|||
{
|
||||
Component::internalRepaint (x, y, w, h);
|
||||
|
||||
InternalGLContextHolder* const context = (InternalGLContextHolder*) internalData;
|
||||
context->repaint();
|
||||
if (context != 0)
|
||||
context->repaint();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,119 @@
|
|||
// this is used to disable OpenGL, and is defined in juce_Config.h
|
||||
#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:
|
||||
//==============================================================================
|
||||
/** 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. */
|
||||
~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
|
||||
GL commands.
|
||||
|
||||
If this returns false, then the context isn't active, so you should avoid
|
||||
making any calls.
|
||||
@see OpenGLPixelFormat::getAvailablePixelFormats()
|
||||
*/
|
||||
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();
|
||||
|
||||
/** 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();
|
||||
void shareWith (OpenGLComponent* const componentToShareListsWith);
|
||||
|
||||
//==============================================================================
|
||||
/** Flips the openGL buffers over. */
|
||||
|
|
@ -115,16 +214,63 @@ public:
|
|||
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.
|
||||
|
||||
Called by paint(), this can be overridden if you need to decouple the rendering
|
||||
from the paint callback and render with a different thread.
|
||||
This is called automatically by paint() when the component needs to be rendered.
|
||||
|
||||
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.
|
||||
*/
|
||||
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 */
|
||||
|
|
@ -133,13 +279,23 @@ public:
|
|||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
friend class InternalGLContextHolder;
|
||||
void* internalData;
|
||||
friend class OpenGLComponentWatcher;
|
||||
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&);
|
||||
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