1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

First check-in of the "jucequake": a major re-organisation of the library to break it up into modules. For more details about this, see the website forum..

This commit is contained in:
Julian Storer 2011-08-12 10:04:52 +01:00
parent 1a21c89755
commit b70e0a28d2
1527 changed files with 90380 additions and 396643 deletions

View file

@ -0,0 +1,17 @@
{
"id": "juce_opengl",
"name": "JUCE OpenGL classes",
"version": "2.0.0",
"description": "Classes for rendering OpenGL in a JUCE window.",
"website": "http://www.juce.com/juce",
"license": "GPL/Commercial",
"dependencies": [ { "id": "juce_gui_basics", "version": "matching" } ],
"include": "juce_opengl.h",
"compile": [ { "file": "juce_opengl.cpp" } ],
"browse": [ "opengl/*",
"native/*" ]
}

View file

@ -0,0 +1,152 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifdef __JUCE_OPENGL_JUCEHEADER__
/* When you add this cpp file to your project, you mustn't include it in a file where you've
already included any other headers - just put it inside a file on its own, possibly with your config
flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix
header files that the compiler may be using.
*/
#error "Incorrect use of JUCE cpp file"
#endif
#define JUCE_DONT_DEFINE_MACROS 1
#include "../juce_core/native/juce_BasicNativeHeaders.h"
#include "juce_opengl.h"
//==============================================================================
#if JUCE_IOS
#import <QuartzCore/QuartzCore.h>
#include <OpenGLES/ES1/gl.h>
#include <OpenGLES/ES1/glext.h>
//==============================================================================
#elif JUCE_WINDOWS
#include <windowsx.h>
#include <vfw.h>
#include <commdlg.h>
#if JUCE_WEB_BROWSER
#include <Exdisp.h>
#include <exdispid.h>
#endif
#if JUCE_MSVC && ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
#pragma comment(lib, "vfw32.lib")
#pragma comment(lib, "imm32.lib")
#endif
#include <gl/gl.h>
#if JUCE_MSVC && ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
#pragma comment(lib, "OpenGL32.Lib")
#pragma comment(lib, "GlU32.Lib")
#endif
#if JUCE_QUICKTIME && JUCE_MSVC && ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
#pragma comment (lib, "QTMLClient.lib")
#endif
#if JUCE_DIRECT2D && JUCE_MSVC && ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
#pragma comment (lib, "Dwrite.lib")
#pragma comment (lib, "D2d1.lib")
#endif
//==============================================================================
#elif JUCE_LINUX
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#include <X11/keysym.h>
#include <X11/cursorfont.h>
#if JUCE_USE_XINERAMA
/* If you're trying to use Xinerama, you'll need to install the "libxinerama-dev" package.. */
#include <X11/extensions/Xinerama.h>
#endif
#if JUCE_USE_XSHM
#include <X11/extensions/XShm.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#endif
#if JUCE_USE_XRENDER
// If you're missing these headers, try installing the libxrender-dev and libxcomposite-dev
#include <X11/extensions/Xrender.h>
#include <X11/extensions/Xcomposite.h>
#endif
#if JUCE_USE_XCURSOR
// If you're missing this header, try installing the libxcursor-dev package
#include <X11/Xcursor/Xcursor.h>
#endif
/* Got an include error here?
If you want to install OpenGL support, the packages to get are "mesa-common-dev"
and "freeglut3-dev".
*/
#include <GL/glx.h>
#undef SIZEOF
#undef KeyPress
#endif
//==============================================================================
// START_AUTOINCLUDE opengl/*.cpp
#include "opengl/juce_OpenGLComponent.cpp"
// END_AUTOINCLUDE
using namespace JUCE_NAMESPACE;
//==============================================================================
BEGIN_JUCE_NAMESPACE
#if JUCE_MAC || JUCE_IOS
#include "../juce_core/native/juce_osx_ObjCHelpers.h"
#include "../juce_core/native/juce_mac_ObjCSuffix.h"
#include "../juce_graphics/native/juce_mac_CoreGraphicsHelpers.h"
#if JUCE_MAC
#include "native/juce_mac_OpenGLComponent.mm"
#else
#include "native/juce_ios_OpenGLComponent.mm"
#endif
#elif JUCE_WINDOWS
#include "native/juce_win32_OpenGLComponent.cpp"
#elif JUCE_LINUX
#include "native/juce_linux_OpenGLComponent.cpp"
#elif JUCE_ANDROID
#include "native/juce_android_OpenGLComponent.cpp"
#endif
END_JUCE_NAMESPACE

View file

@ -0,0 +1,53 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_OPENGL_JUCEHEADER__
#define __JUCE_OPENGL_JUCEHEADER__
#include "../juce_gui_extra/juce_gui_extra.h"
#undef JUCE_OPENGL
#if ! JUCE_ANDROID
#define JUCE_OPENGL 1
#endif
//=============================================================================
BEGIN_JUCE_NAMESPACE
// START_AUTOINCLUDE opengl
#ifndef __JUCE_OPENGLCOMPONENT_JUCEHEADER__
#include "opengl/juce_OpenGLComponent.h"
#endif
#ifndef __JUCE_OPENGLCONTEXT_JUCEHEADER__
#include "opengl/juce_OpenGLContext.h"
#endif
#ifndef __JUCE_OPENGLPIXELFORMAT_JUCEHEADER__
#include "opengl/juce_OpenGLPixelFormat.h"
#endif
// END_AUTOINCLUDE
END_JUCE_NAMESPACE
#endif // __JUCE_OPENGL_JUCEHEADER__

View file

@ -0,0 +1,46 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
// TODO
OpenGLContext* OpenGLComponent::createContext()
{
return nullptr;
}
void* OpenGLComponent::getNativeWindowHandle() const
{
return nullptr;
}
void juce_glViewport (const int w, const int h)
{
// glViewport (0, 0, w, h);
}
void OpenGLPixelFormat::getAvailablePixelFormats (Component* component,
OwnedArray <OpenGLPixelFormat>& results)
{
}

View file

@ -0,0 +1,239 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
END_JUCE_NAMESPACE
@interface JuceGLView : UIView
{
}
+ (Class) layerClass;
@end
@implementation JuceGLView
+ (Class) layerClass
{
return [CAEAGLLayer class];
}
@end
BEGIN_JUCE_NAMESPACE
//==============================================================================
class GLESContext : public OpenGLContext
{
public:
GLESContext (UIView* parentView,
Component* const component_,
const OpenGLPixelFormat& pixelFormat_,
const GLESContext* const sharedContext,
NSUInteger apiType)
: component (component_), pixelFormat (pixelFormat_), glLayer (nil), context (nil),
useDepthBuffer (pixelFormat_.depthBufferBits > 0), frameBufferHandle (0), colorBufferHandle (0),
depthBufferHandle (0), lastWidth (0), lastHeight (0)
{
view = [[JuceGLView alloc] initWithFrame: CGRectMake (0, 0, 64, 64)];
view.opaque = YES;
view.hidden = NO;
view.backgroundColor = [UIColor blackColor];
view.userInteractionEnabled = NO;
glLayer = (CAEAGLLayer*) [view layer];
[parentView addSubview: view];
if (sharedContext != nullptr)
context = [[EAGLContext alloc] initWithAPI: apiType
sharegroup: [sharedContext->context sharegroup]];
else
context = [[EAGLContext alloc] initWithAPI: apiType];
createGLBuffers();
}
~GLESContext()
{
deleteContext();
[view removeFromSuperview];
[view release];
freeGLBuffers();
}
void deleteContext()
{
makeInactive();
[context release];
context = nil;
}
bool makeActive() const noexcept
{
jassert (context != nil);
[EAGLContext setCurrentContext: context];
glBindFramebufferOES (GL_FRAMEBUFFER_OES, frameBufferHandle);
return true;
}
void swapBuffers()
{
glBindRenderbufferOES (GL_RENDERBUFFER_OES, colorBufferHandle);
[context presentRenderbuffer: GL_RENDERBUFFER_OES];
}
bool makeInactive() const noexcept
{
return [EAGLContext setCurrentContext: nil];
}
bool isActive() const noexcept
{
return [EAGLContext currentContext] == context;
}
const OpenGLPixelFormat getPixelFormat() const { return pixelFormat; }
void* getRawContext() const noexcept { return glLayer; }
void updateWindowPosition (const Rectangle<int>& bounds)
{
view.frame = CGRectMake ((CGFloat) bounds.getX(), (CGFloat) bounds.getY(),
(CGFloat) bounds.getWidth(), (CGFloat) bounds.getHeight());
if (lastWidth != bounds.getWidth() || lastHeight != bounds.getHeight())
{
lastWidth = bounds.getWidth();
lastHeight = bounds.getHeight();
freeGLBuffers();
createGLBuffers();
}
}
bool setSwapInterval (const int numFramesPerSwap)
{
numFrames = numFramesPerSwap;
return true;
}
int getSwapInterval() const
{
return numFrames;
}
void repaint()
{
}
//==============================================================================
void createGLBuffers()
{
makeActive();
glGenFramebuffersOES (1, &frameBufferHandle);
glGenRenderbuffersOES (1, &colorBufferHandle);
glGenRenderbuffersOES (1, &depthBufferHandle);
glBindRenderbufferOES (GL_RENDERBUFFER_OES, colorBufferHandle);
[context renderbufferStorage: GL_RENDERBUFFER_OES fromDrawable: glLayer];
GLint width, height;
glGetRenderbufferParameterivOES (GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &width);
glGetRenderbufferParameterivOES (GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &height);
if (useDepthBuffer)
{
glBindRenderbufferOES (GL_RENDERBUFFER_OES, depthBufferHandle);
glRenderbufferStorageOES (GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height);
}
glBindRenderbufferOES (GL_RENDERBUFFER_OES, colorBufferHandle);
glBindFramebufferOES (GL_FRAMEBUFFER_OES, frameBufferHandle);
glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorBufferHandle);
if (useDepthBuffer)
glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthBufferHandle);
jassert (glCheckFramebufferStatusOES (GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES);
}
void freeGLBuffers()
{
if (frameBufferHandle != 0)
{
glDeleteFramebuffersOES (1, &frameBufferHandle);
frameBufferHandle = 0;
}
if (colorBufferHandle != 0)
{
glDeleteRenderbuffersOES (1, &colorBufferHandle);
colorBufferHandle = 0;
}
if (depthBufferHandle != 0)
{
glDeleteRenderbuffersOES (1, &depthBufferHandle);
depthBufferHandle = 0;
}
}
//==============================================================================
private:
WeakReference<Component> component;
OpenGLPixelFormat pixelFormat;
JuceGLView* view;
CAEAGLLayer* glLayer;
EAGLContext* context;
bool useDepthBuffer;
GLuint frameBufferHandle, colorBufferHandle, depthBufferHandle;
int numFrames;
int lastWidth, lastHeight;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GLESContext);
};
OpenGLContext* OpenGLComponent::createContext()
{
JUCE_AUTORELEASEPOOL
ComponentPeer* peer = getPeer();
if (peer != nullptr)
return new GLESContext ((UIView*) peer->getNativeHandle(), this, preferredPixelFormat,
dynamic_cast <const GLESContext*> (contextToShareListsWith),
type == openGLES2 ? kEAGLRenderingAPIOpenGLES2 : kEAGLRenderingAPIOpenGLES1);
return nullptr;
}
void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
OwnedArray <OpenGLPixelFormat>& /*results*/)
{
}
void juce_glViewport (const int w, const int h)
{
glViewport (0, 0, w, h);
}

View file

@ -0,0 +1,204 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
class WindowedGLContext : public OpenGLContext
{
public:
WindowedGLContext (Component* const component,
const OpenGLPixelFormat& pixelFormat_,
GLXContext sharedContext)
: renderContext (0),
embeddedWindow (0),
pixelFormat (pixelFormat_),
swapInterval (0)
{
jassert (component != nullptr);
LinuxComponentPeer* const peer = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer());
if (peer == nullptr)
return;
ScopedXLock xlock;
XSync (display, False);
GLint attribs[] =
{
GLX_RGBA, GLX_DOUBLEBUFFER,
GLX_RED_SIZE, pixelFormat.redBits,
GLX_GREEN_SIZE, pixelFormat.greenBits,
GLX_BLUE_SIZE, pixelFormat.blueBits,
GLX_ALPHA_SIZE, pixelFormat.alphaBits,
GLX_DEPTH_SIZE, pixelFormat.depthBufferBits,
GLX_STENCIL_SIZE, pixelFormat.stencilBufferBits,
GLX_ACCUM_RED_SIZE, pixelFormat.accumulationBufferRedBits,
GLX_ACCUM_GREEN_SIZE, pixelFormat.accumulationBufferGreenBits,
GLX_ACCUM_BLUE_SIZE, pixelFormat.accumulationBufferBlueBits,
GLX_ACCUM_ALPHA_SIZE, pixelFormat.accumulationBufferAlphaBits,
None
};
XVisualInfo* const bestVisual = glXChooseVisual (display, DefaultScreen (display), attribs);
if (bestVisual == 0)
return;
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,
bestVisual->visual,
CWBorderPixel | CWColormap | CWEventMask,
&swa);
XSaveContext (display, (XID) embeddedWindow, windowHandleXContext, (XPointer) peer);
XMapWindow (display, embeddedWindow);
XFreeColormap (display, colourMap);
XFree (bestVisual);
XSync (display, False);
}
~WindowedGLContext()
{
ScopedXLock xlock;
deleteContext();
XUnmapWindow (display, embeddedWindow);
XDestroyWindow (display, embeddedWindow);
}
void deleteContext()
{
makeInactive();
if (renderContext != 0)
{
ScopedXLock xlock;
glXDestroyContext (display, renderContext);
renderContext = nullptr;
}
}
bool makeActive() const noexcept
{
jassert (renderContext != 0);
ScopedXLock xlock;
return glXMakeCurrent (display, embeddedWindow, renderContext)
&& XSync (display, False);
}
bool makeInactive() const noexcept
{
ScopedXLock xlock;
return (! isActive()) || glXMakeCurrent (display, None, 0);
}
bool isActive() const noexcept
{
ScopedXLock xlock;
return glXGetCurrentContext() == renderContext;
}
const OpenGLPixelFormat getPixelFormat() const
{
return pixelFormat;
}
void* getRawContext() const noexcept
{
return renderContext;
}
void updateWindowPosition (const Rectangle<int>& bounds)
{
ScopedXLock xlock;
XMoveResizeWindow (display, embeddedWindow,
bounds.getX(), bounds.getY(), jmax (1, bounds.getWidth()), jmax (1, bounds.getHeight()));
}
void swapBuffers()
{
ScopedXLock xlock;
glXSwapBuffers (display, embeddedWindow);
}
bool setSwapInterval (const int numFramesPerSwap)
{
static PFNGLXSWAPINTERVALSGIPROC GLXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddress ((const GLubyte*) "glXSwapIntervalSGI");
if (GLXSwapIntervalSGI != 0)
{
swapInterval = numFramesPerSwap;
GLXSwapIntervalSGI (numFramesPerSwap);
return true;
}
return false;
}
int getSwapInterval() const { return swapInterval; }
void repaint() {}
//==============================================================================
GLXContext renderContext;
private:
Window embeddedWindow;
OpenGLPixelFormat pixelFormat;
int swapInterval;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowedGLContext);
};
//==============================================================================
OpenGLContext* OpenGLComponent::createContext()
{
ScopedPointer<WindowedGLContext> c (new WindowedGLContext (this, preferredPixelFormat,
contextToShareListsWith != 0 ? (GLXContext) contextToShareListsWith->getRawContext() : 0));
return (c->renderContext != 0) ? c.release() : nullptr;
}
void juce_glViewport (const int w, const int h)
{
glViewport (0, 0, w, h);
}
void OpenGLPixelFormat::getAvailablePixelFormats (Component* component, OwnedArray <OpenGLPixelFormat>& results)
{
results.add (new OpenGLPixelFormat()); // xxx
}

View file

@ -0,0 +1,319 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
END_JUCE_NAMESPACE
#define ThreadSafeNSOpenGLView MakeObjCClassName(ThreadSafeNSOpenGLView)
//==============================================================================
@interface ThreadSafeNSOpenGLView : NSOpenGLView
{
CriticalSection* contextLock;
bool needsUpdate;
}
- (id) initWithFrame: (NSRect) frameRect pixelFormat: (NSOpenGLPixelFormat*) format;
- (bool) makeActive;
- (void) makeInactive;
- (void) reshape;
- (void) rightMouseDown: (NSEvent*) ev;
- (void) rightMouseUp: (NSEvent*) ev;
@end
@implementation ThreadSafeNSOpenGLView
- (id) initWithFrame: (NSRect) frameRect
pixelFormat: (NSOpenGLPixelFormat*) format
{
contextLock = new CriticalSection();
self = [super initWithFrame: frameRect pixelFormat: format];
if (self != nil)
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector (_surfaceNeedsUpdate:)
name: NSViewGlobalFrameDidChangeNotification
object: self];
return self;
}
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver: self];
delete contextLock;
[super dealloc];
}
- (bool) makeActive
{
const ScopedLock sl (*contextLock);
if ([self openGLContext] == 0)
return false;
[[self openGLContext] makeCurrentContext];
if (needsUpdate)
{
[super update];
needsUpdate = false;
}
return true;
}
- (void) makeInactive
{
const ScopedLock sl (*contextLock);
[NSOpenGLContext clearCurrentContext];
}
- (void) _surfaceNeedsUpdate: (NSNotification*) notification
{
(void) notification;
const ScopedLock sl (*contextLock);
needsUpdate = true;
}
- (void) update
{
const ScopedLock sl (*contextLock);
needsUpdate = true;
}
- (void) reshape
{
const ScopedLock sl (*contextLock);
needsUpdate = true;
}
- (void) rightMouseDown: (NSEvent*) ev
{
[[self superview] rightMouseDown: ev];
}
- (void) rightMouseUp: (NSEvent*) ev
{
[[self superview] rightMouseUp: ev];
}
@end
BEGIN_JUCE_NAMESPACE
//==============================================================================
class WindowedGLContext : public OpenGLContext
{
public:
WindowedGLContext (OpenGLComponent& component,
const OpenGLPixelFormat& pixelFormat_,
NSOpenGLContext* sharedContext)
: renderContext (nil),
pixelFormat (pixelFormat_)
{
NSOpenGLPixelFormatAttribute attribs[] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFAMPSafe,
NSOpenGLPFAClosestPolicy,
NSOpenGLPFANoRecovery,
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) (pixelFormat.redBits
+ pixelFormat.greenBits
+ pixelFormat.blueBits),
NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute) pixelFormat.alphaBits,
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute) pixelFormat.depthBufferBits,
NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute) pixelFormat.stencilBufferBits,
NSOpenGLPFAAccumSize, (NSOpenGLPixelFormatAttribute) (pixelFormat.accumulationBufferRedBits
+ pixelFormat.accumulationBufferGreenBits
+ pixelFormat.accumulationBufferBlueBits
+ pixelFormat.accumulationBufferAlphaBits),
NSOpenGLPFASampleBuffers, (NSOpenGLPixelFormatAttribute) 1,
(NSOpenGLPixelFormatAttribute) 0
};
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs];
view = [[ThreadSafeNSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
pixelFormat: format];
renderContext = [[[NSOpenGLContext alloc] initWithFormat: format
shareContext: sharedContext] autorelease];
const GLint swapInterval = 1;
[renderContext setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
[view setOpenGLContext: renderContext];
[format release];
component.setView (view);
}
~WindowedGLContext()
{
deleteContext();
}
void deleteContext()
{
makeInactive();
[renderContext clearDrawable];
[renderContext setView: nil];
[view setOpenGLContext: nil];
renderContext = nil;
}
bool makeActive() const noexcept
{
jassert (renderContext != nil);
if ([renderContext view] != view)
[renderContext setView: view];
[view makeActive];
return isActive();
}
bool makeInactive() const noexcept
{
[view makeInactive];
return true;
}
bool isActive() const noexcept
{
return [NSOpenGLContext currentContext] == renderContext;
}
const OpenGLPixelFormat getPixelFormat() const { return pixelFormat; }
void* getRawContext() const noexcept { return renderContext; }
void updateWindowPosition (const Rectangle<int>&) {}
void swapBuffers()
{
[renderContext flushBuffer];
}
bool setSwapInterval (const int numFramesPerSwap)
{
[renderContext setValues: (const GLint*) &numFramesPerSwap
forParameter: NSOpenGLCPSwapInterval];
return true;
}
int getSwapInterval() const
{
GLint numFrames = 0;
[renderContext getValues: &numFrames
forParameter: NSOpenGLCPSwapInterval];
return numFrames;
}
void repaint()
{
// we need to invalidate the juce view that holds this gl view, to make it
// cause a repaint callback
NSRect r = [view frame];
// bit of a bodge here.. if we only invalidate the area of the gl component,
// it's completely covered by the NSOpenGLView, so the OS throws away the
// repaint message, thus never causing our paint() callback, and never repainting
// the comp. So invalidating just a little bit around the edge helps..
[[view superview] setNeedsDisplayInRect: NSInsetRect (r, -2.0f, -2.0f)];
}
void* getNativeWindowHandle() const { return view; }
//==============================================================================
NSOpenGLContext* renderContext;
ThreadSafeNSOpenGLView* view;
private:
OpenGLPixelFormat pixelFormat;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowedGLContext);
};
//==============================================================================
OpenGLContext* OpenGLComponent::createContext()
{
ScopedPointer<WindowedGLContext> c (new WindowedGLContext (*this, preferredPixelFormat,
contextToShareListsWith != nullptr ? (NSOpenGLContext*) contextToShareListsWith->getRawContext() : nil));
return (c->renderContext != nil) ? c.release() : nullptr;
}
void* OpenGLComponent::getNativeWindowHandle() const
{
return context != nullptr ? static_cast<WindowedGLContext*> (static_cast<OpenGLContext*> (context))->getNativeWindowHandle()
: nullptr;
}
void juce_glViewport (const int w, const int h)
{
glViewport (0, 0, w, h);
}
static int getPixelFormatAttribute (NSOpenGLPixelFormat* p, NSOpenGLPixelFormatAttribute att)
{
GLint val = 0;
[p getValues: &val forAttribute: att forVirtualScreen: 0];
return (int) val;
}
void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
OwnedArray <OpenGLPixelFormat>& results)
{
NSOpenGLPixelFormatAttribute attributes[] =
{
NSOpenGLPFAWindow,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery,
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute) 16,
NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute) 8,
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) 24,
NSOpenGLPFAAccumSize, (NSOpenGLPixelFormatAttribute) 32,
(NSOpenGLPixelFormatAttribute) 0
};
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes: attributes];
if (format != nil)
{
OpenGLPixelFormat* const pf = new OpenGLPixelFormat();
pf->redBits = pf->greenBits = pf->blueBits = getPixelFormatAttribute (format, NSOpenGLPFAColorSize) / 3;
pf->alphaBits = getPixelFormatAttribute (format, NSOpenGLPFAAlphaSize);
pf->depthBufferBits = getPixelFormatAttribute (format, NSOpenGLPFADepthSize);
pf->stencilBufferBits = getPixelFormatAttribute (format, NSOpenGLPFAStencilSize);
pf->accumulationBufferRedBits = pf->accumulationBufferGreenBits
= pf->accumulationBufferBlueBits = pf->accumulationBufferAlphaBits
= getPixelFormatAttribute (format, NSOpenGLPFAAccumSize) / 4;
[format release];
results.add (pf);
}
}

View file

@ -0,0 +1,516 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#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);
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
enum
{
WGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000,
WGL_DRAW_TO_WINDOW_ARB = 0x2001,
WGL_ACCELERATION_ARB = 0x2003,
WGL_SWAP_METHOD_ARB = 0x2007,
WGL_SUPPORT_OPENGL_ARB = 0x2010,
WGL_PIXEL_TYPE_ARB = 0x2013,
WGL_DOUBLE_BUFFER_ARB = 0x2011,
WGL_COLOR_BITS_ARB = 0x2014,
WGL_RED_BITS_ARB = 0x2015,
WGL_GREEN_BITS_ARB = 0x2017,
WGL_BLUE_BITS_ARB = 0x2019,
WGL_ALPHA_BITS_ARB = 0x201B,
WGL_DEPTH_BITS_ARB = 0x2022,
WGL_STENCIL_BITS_ARB = 0x2023,
WGL_FULL_ACCELERATION_ARB = 0x2027,
WGL_ACCUM_RED_BITS_ARB = 0x201E,
WGL_ACCUM_GREEN_BITS_ARB = 0x201F,
WGL_ACCUM_BLUE_BITS_ARB = 0x2020,
WGL_ACCUM_ALPHA_BITS_ARB = 0x2021,
WGL_STEREO_ARB = 0x2012,
WGL_SAMPLE_BUFFERS_ARB = 0x2041,
WGL_SAMPLES_ARB = 0x2042,
WGL_TYPE_RGBA_ARB = 0x202B
};
static void getWglExtensions (HDC dc, StringArray& result) noexcept
{
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
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
}
extern ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component* component, void* parent);
//==============================================================================
class WindowedGLContext : public OpenGLContext
{
public:
WindowedGLContext (Component* const component_,
HGLRC contextToShareWith,
const OpenGLPixelFormat& pixelFormat)
: renderContext (0),
component (component_),
dc (0)
{
jassert (component != nullptr);
createNativeWindow();
// Use a default pixel format that should be supported everywhere
PIXELFORMATDESCRIPTOR pfd = { 0 };
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 = 24;
pfd.cDepthBits = 16;
const int format = ChoosePixelFormat (dc, &pfd);
if (format != 0)
SetPixelFormat (dc, format, &pfd);
renderContext = wglCreateContext (dc);
makeActive();
setPixelFormat (pixelFormat);
if (contextToShareWith != 0 && renderContext != 0)
wglShareLists (contextToShareWith, renderContext);
}
~WindowedGLContext()
{
deleteContext();
ReleaseDC ((HWND) nativeWindow->getNativeHandle(), dc);
nativeWindow = nullptr;
}
void deleteContext()
{
makeInactive();
if (renderContext != 0)
{
wglDeleteContext (renderContext);
renderContext = 0;
}
}
bool makeActive() const noexcept
{
jassert (renderContext != 0);
return wglMakeCurrent (dc, renderContext) != 0;
}
bool makeInactive() const noexcept
{
return (! isActive()) || (wglMakeCurrent (0, 0) != 0);
}
bool isActive() const noexcept
{
return wglGetCurrentContext() == renderContext;
}
const OpenGLPixelFormat getPixelFormat() const
{
OpenGLPixelFormat pf;
makeActive();
StringArray availableExtensions;
getWglExtensions (dc, availableExtensions);
fillInPixelFormatDetails (GetPixelFormat (dc), pf, availableExtensions);
return pf;
}
void* getRawContext() const noexcept
{
return renderContext;
}
bool setPixelFormat (const OpenGLPixelFormat& pixelFormat)
{
makeActive();
PIXELFORMATDESCRIPTOR pfd = { 0 };
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 = (BYTE) (pixelFormat.redBits + pixelFormat.greenBits + pixelFormat.blueBits);
pfd.cRedBits = (BYTE) pixelFormat.redBits;
pfd.cGreenBits = (BYTE) pixelFormat.greenBits;
pfd.cBlueBits = (BYTE) pixelFormat.blueBits;
pfd.cAlphaBits = (BYTE) pixelFormat.alphaBits;
pfd.cDepthBits = (BYTE) pixelFormat.depthBufferBits;
pfd.cStencilBits = (BYTE) pixelFormat.stencilBufferBits;
pfd.cAccumBits = (BYTE) (pixelFormat.accumulationBufferRedBits + pixelFormat.accumulationBufferGreenBits
+ pixelFormat.accumulationBufferBlueBits + pixelFormat.accumulationBufferAlphaBits);
pfd.cAccumRedBits = (BYTE) pixelFormat.accumulationBufferRedBits;
pfd.cAccumGreenBits = (BYTE) pixelFormat.accumulationBufferGreenBits;
pfd.cAccumBlueBits = (BYTE) pixelFormat.accumulationBufferBlueBits;
pfd.cAccumAlphaBits = (BYTE) pixelFormat.accumulationBufferAlphaBits;
int format = 0;
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = 0;
StringArray availableExtensions;
getWglExtensions (dc, availableExtensions);
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)
{
attributes[n++] = WGL_STENCIL_BITS_ARB;
attributes[n++] = pixelFormat.stencilBufferBits;
}
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();
// win32 can't change the pixel format of a window, so need to delete the
// old one and create a new one..
jassert (nativeWindow != 0);
ReleaseDC ((HWND) nativeWindow->getNativeHandle(), dc);
nativeWindow = nullptr;
createNativeWindow();
if (SetPixelFormat (dc, format, &pfd))
{
wglDeleteContext (renderContext);
renderContext = wglCreateContext (dc);
jassert (renderContext != 0);
return renderContext != 0;
}
}
return false;
}
void updateWindowPosition (const Rectangle<int>& bounds)
{
SetWindowPos ((HWND) nativeWindow->getNativeHandle(), 0,
bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(),
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
}
void repaint()
{
nativeWindow->repaint (nativeWindow->getBounds().withPosition (Point<int>()));
}
void swapBuffers()
{
SwapBuffers (dc);
}
bool setSwapInterval (int numFramesPerSwap)
{
makeActive();
StringArray availableExtensions;
getWglExtensions (dc, availableExtensions);
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = 0;
return availableExtensions.contains ("WGL_EXT_swap_control")
&& WGL_EXT_FUNCTION_INIT (PFNWGLSWAPINTERVALEXTPROC, wglSwapIntervalEXT)
&& wglSwapIntervalEXT (numFramesPerSwap) != FALSE;
}
int getSwapInterval() const
{
makeActive();
StringArray availableExtensions;
getWglExtensions (dc, availableExtensions);
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = 0;
if (availableExtensions.contains ("WGL_EXT_swap_control")
&& WGL_EXT_FUNCTION_INIT (PFNWGLGETSWAPINTERVALEXTPROC, wglGetSwapIntervalEXT))
return wglGetSwapIntervalEXT();
return 0;
}
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));
}
}
}
void* getNativeWindowHandle() const
{
return nativeWindow != nullptr ? nativeWindow->getNativeHandle() : nullptr;
}
//==============================================================================
HGLRC renderContext;
private:
ScopedPointer<ComponentPeer> nativeWindow;
Component* const component;
HDC dc;
//==============================================================================
void createNativeWindow()
{
nativeWindow = createNonRepaintingEmbeddedWindowsPeer (component, component->getTopLevelComponent()->getWindowHandle());
nativeWindow->setVisible (true);
dc = GetDC ((HWND) nativeWindow->getNativeHandle());
}
bool fillInPixelFormatDetails (const int pixelFormatIndex,
OpenGLPixelFormat& result,
const StringArray& availableExtensions) const noexcept
{
PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = 0;
if (availableExtensions.contains ("WGL_ARB_pixel_format")
&& WGL_EXT_FUNCTION_INIT (PFNWGLGETPIXELFORMATATTRIBIVARBPROC, wglGetPixelFormatAttribivARB))
{
int attributes[32];
UINT numAttributes = 0;
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] = { 0 };
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 = (uint8) 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;
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowedGLContext);
};
//==============================================================================
OpenGLContext* OpenGLComponent::createContext()
{
ScopedPointer<WindowedGLContext> c (new WindowedGLContext (this,
contextToShareListsWith != nullptr ? (HGLRC) contextToShareListsWith->getRawContext() : 0,
preferredPixelFormat));
return (c->renderContext != 0) ? c.release() : nullptr;
}
void* OpenGLComponent::getNativeWindowHandle() const
{
return context != nullptr ? static_cast<WindowedGLContext*> (static_cast<OpenGLContext*> (context))->getNativeWindowHandle() : nullptr;
}
void juce_glViewport (const int w, const int h)
{
glViewport (0, 0, w, h);
}
void OpenGLPixelFormat::getAvailablePixelFormats (Component* component,
OwnedArray <OpenGLPixelFormat>& results)
{
Component tempComp;
{
WindowedGLContext wc (component, 0, OpenGLPixelFormat (8, 8, 16, 0));
wc.makeActive();
wc.findAlternativeOpenGLPixelFormats (results);
}
}

View file

@ -0,0 +1,447 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
BEGIN_JUCE_NAMESPACE
//==============================================================================
extern void juce_glViewport (const int w, const int h);
//==============================================================================
OpenGLPixelFormat::OpenGLPixelFormat (const int bitsPerRGBComponent,
const int alphaBits_,
const int depthBufferBits_,
const int stencilBufferBits_)
: redBits (bitsPerRGBComponent),
greenBits (bitsPerRGBComponent),
blueBits (bitsPerRGBComponent),
alphaBits (alphaBits_),
depthBufferBits (depthBufferBits_),
stencilBufferBits (stencilBufferBits_),
accumulationBufferRedBits (0),
accumulationBufferGreenBits (0),
accumulationBufferBlueBits (0),
accumulationBufferAlphaBits (0),
fullSceneAntiAliasingNumSamples (0)
{
}
OpenGLPixelFormat::OpenGLPixelFormat (const OpenGLPixelFormat& other)
: redBits (other.redBits),
greenBits (other.greenBits),
blueBits (other.blueBits),
alphaBits (other.alphaBits),
depthBufferBits (other.depthBufferBits),
stencilBufferBits (other.stencilBufferBits),
accumulationBufferRedBits (other.accumulationBufferRedBits),
accumulationBufferGreenBits (other.accumulationBufferGreenBits),
accumulationBufferBlueBits (other.accumulationBufferBlueBits),
accumulationBufferAlphaBits (other.accumulationBufferAlphaBits),
fullSceneAntiAliasingNumSamples (other.fullSceneAntiAliasingNumSamples)
{
}
OpenGLPixelFormat& OpenGLPixelFormat::operator= (const OpenGLPixelFormat& other)
{
redBits = other.redBits;
greenBits = other.greenBits;
blueBits = other.blueBits;
alphaBits = other.alphaBits;
depthBufferBits = other.depthBufferBits;
stencilBufferBits = other.stencilBufferBits;
accumulationBufferRedBits = other.accumulationBufferRedBits;
accumulationBufferGreenBits = other.accumulationBufferGreenBits;
accumulationBufferBlueBits = other.accumulationBufferBlueBits;
accumulationBufferAlphaBits = other.accumulationBufferAlphaBits;
fullSceneAntiAliasingNumSamples = other.fullSceneAntiAliasingNumSamples;
return *this;
}
bool OpenGLPixelFormat::operator== (const OpenGLPixelFormat& other) const
{
return redBits == other.redBits
&& greenBits == other.greenBits
&& blueBits == other.blueBits
&& alphaBits == other.alphaBits
&& depthBufferBits == other.depthBufferBits
&& stencilBufferBits == other.stencilBufferBits
&& accumulationBufferRedBits == other.accumulationBufferRedBits
&& accumulationBufferGreenBits == other.accumulationBufferGreenBits
&& accumulationBufferBlueBits == other.accumulationBufferBlueBits
&& accumulationBufferAlphaBits == other.accumulationBufferAlphaBits
&& fullSceneAntiAliasingNumSamples == other.fullSceneAntiAliasingNumSamples;
}
//==============================================================================
static Array<OpenGLContext*> knownContexts;
OpenGLContext::OpenGLContext() noexcept
{
knownContexts.add (this);
}
OpenGLContext::~OpenGLContext()
{
knownContexts.removeValue (this);
}
OpenGLContext* OpenGLContext::getCurrentContext()
{
for (int i = knownContexts.size(); --i >= 0;)
{
OpenGLContext* const oglc = knownContexts.getUnchecked(i);
if (oglc->isActive())
return oglc;
}
return nullptr;
}
//==============================================================================
class OpenGLComponent::OpenGLComponentWatcher : public ComponentMovementWatcher
{
public:
//==============================================================================
OpenGLComponentWatcher (OpenGLComponent* const owner_)
: ComponentMovementWatcher (owner_),
owner (owner_)
{
}
//==============================================================================
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
{
owner->updateContextPosition();
}
void componentPeerChanged()
{
owner->recreateContextAsync();
}
void componentVisibilityChanged()
{
if (! owner->isShowing())
owner->stopBackgroundThread();
}
//==============================================================================
private:
OpenGLComponent* const owner;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLComponentWatcher);
};
//==============================================================================
class OpenGLComponent::OpenGLComponentRenderThread : public Thread
{
public:
OpenGLComponentRenderThread (OpenGLComponent& owner_)
: Thread ("OpenGL Render"),
owner (owner_)
{
}
void run()
{
#if JUCE_LINUX
{
MessageManagerLock mml (this);
if (! mml.lockWasGained())
return;
owner.updateContext();
owner.updateContextPosition();
}
#endif
while (! threadShouldExit())
{
const uint32 startOfRendering = Time::getMillisecondCounter();
if (! owner.renderAndSwapBuffers())
break;
const int elapsed = (int) (Time::getMillisecondCounter() - startOfRendering);
Thread::sleep (jmax (1, 20 - elapsed));
}
#if JUCE_LINUX
owner.deleteContext();
#endif
}
private:
OpenGLComponent& owner;
JUCE_DECLARE_NON_COPYABLE (OpenGLComponentRenderThread);
};
void OpenGLComponent::startRenderThread()
{
if (renderThread == nullptr)
renderThread = new OpenGLComponentRenderThread (*this);
renderThread->startThread (6);
}
void OpenGLComponent::stopRenderThread()
{
if (renderThread != nullptr)
{
renderThread->stopThread (5000);
renderThread = nullptr;
}
#if ! JUCE_LINUX
deleteContext();
#endif
}
//==============================================================================
OpenGLComponent::OpenGLComponent (const OpenGLType type_, const bool useBackgroundThread)
: type (type_),
contextToShareListsWith (nullptr),
needToUpdateViewport (true),
needToDeleteContext (false),
threadStarted (false),
useThread (useBackgroundThread)
{
setOpaque (true);
componentWatcher = new OpenGLComponentWatcher (this);
}
OpenGLComponent::~OpenGLComponent()
{
stopBackgroundThread();
componentWatcher = nullptr;
}
const OpenGLPixelFormat OpenGLComponent::getPixelFormat() const
{
OpenGLPixelFormat pf;
const ScopedLock sl (contextLock);
if (context != nullptr)
pf = context->getPixelFormat();
return pf;
}
void OpenGLComponent::setPixelFormat (const OpenGLPixelFormat& formatToUse)
{
if (! (preferredPixelFormat == formatToUse))
{
const ScopedLock sl (contextLock);
preferredPixelFormat = formatToUse;
recreateContextAsync();
}
}
void OpenGLComponent::shareWith (OpenGLContext* c)
{
if (contextToShareListsWith != c)
{
const ScopedLock sl (contextLock);
contextToShareListsWith = c;
recreateContextAsync();
}
}
void OpenGLComponent::recreateContextAsync()
{
const ScopedLock sl (contextLock);
needToDeleteContext = true;
repaint();
}
bool OpenGLComponent::makeCurrentContextActive()
{
return context != nullptr && context->makeActive();
}
void OpenGLComponent::makeCurrentContextInactive()
{
if (context != nullptr)
context->makeInactive();
}
bool OpenGLComponent::isActiveContext() const noexcept
{
return context != nullptr && context->isActive();
}
void OpenGLComponent::swapBuffers()
{
if (context != nullptr)
context->swapBuffers();
}
void OpenGLComponent::updateContext()
{
if (needToDeleteContext)
deleteContext();
if (context == nullptr)
{
const ScopedLock sl (contextLock);
if (context == nullptr)
{
context = createContext();
if (context != nullptr)
{
#if JUCE_LINUX
if (! useThread)
#endif
updateContextPosition();
if (context->makeActive())
{
newOpenGLContextCreated();
context->makeInactive();
}
}
}
}
}
void OpenGLComponent::deleteContext()
{
const ScopedLock sl (contextLock);
if (context != nullptr)
{
if (context->makeActive())
{
releaseOpenGLContext();
context->makeInactive();
}
context = nullptr;
}
needToDeleteContext = false;
}
void OpenGLComponent::updateContextPosition()
{
needToUpdateViewport = true;
if (getWidth() > 0 && getHeight() > 0)
{
Component* const topComp = getTopLevelComponent();
if (topComp->getPeer() != nullptr)
{
const ScopedLock sl (contextLock);
if (context != nullptr)
context->updateWindowPosition (topComp->getLocalArea (this, getLocalBounds()));
}
}
}
void OpenGLComponent::stopBackgroundThread()
{
if (threadStarted)
{
stopRenderThread();
threadStarted = false;
}
}
void OpenGLComponent::paint (Graphics&)
{
ComponentPeer* const peer = getPeer();
if (useThread)
{
if (peer != nullptr && isShowing())
{
#if ! JUCE_LINUX
updateContext();
#endif
if (! threadStarted)
{
threadStarted = true;
startRenderThread();
}
}
}
else
{
updateContext();
if (! renderAndSwapBuffers())
return;
}
if (peer != nullptr)
{
const Point<int> topLeft (getScreenPosition() - peer->getScreenPosition());
peer->addMaskedRegion (topLeft.getX(), topLeft.getY(), getWidth(), getHeight());
}
}
bool OpenGLComponent::renderAndSwapBuffers()
{
const ScopedLock sl (contextLock);
#if JUCE_LINUX
updateContext();
#endif
if (context != nullptr)
{
if (! makeCurrentContextActive())
return false;
if (needToUpdateViewport)
{
needToUpdateViewport = false;
juce_glViewport (getWidth(), getHeight());
}
renderOpenGL();
swapBuffers();
}
return true;
}
void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
{
Component::internalRepaint (x, y, w, h);
if (context != nullptr)
context->repaint();
}
END_JUCE_NAMESPACE

View file

@ -0,0 +1,272 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_OPENGLCOMPONENT_JUCEHEADER__
#define __JUCE_OPENGLCOMPONENT_JUCEHEADER__
#include "juce_OpenGLContext.h"
#if JUCE_MAC && ! defined (DOXYGEN)
typedef NSViewComponent OpenGLBaseType;
#else
typedef Component OpenGLBaseType;
#endif
//==============================================================================
/**
A component that contains an OpenGL canvas.
Override this, add it to whatever component you want to, and use the renderOpenGL()
method to draw its contents.
*/
class JUCE_API OpenGLComponent : public OpenGLBaseType
{
public:
//==============================================================================
/** Used to select the type of openGL API to use, if more than one choice is available
on a particular platform.
*/
enum OpenGLType
{
openGLDefault = 0,
#if JUCE_IOS
openGLES1, /**< On the iPhone, this selects openGL ES 1.0 */
openGLES2 /**< On the iPhone, this selects openGL ES 2.0 */
#endif
};
/** Creates an OpenGLComponent.
If useBackgroundThread is true, the component will launch a background thread
to do the rendering. If false, then renderOpenGL() will be called as part of the
normal paint() method.
*/
OpenGLComponent (OpenGLType type = openGLDefault,
bool useBackgroundThread = false);
/** Destructor. */
~OpenGLComponent();
//==============================================================================
/** Changes the pixel format used by this component.
@see OpenGLPixelFormat::getAvailablePixelFormats()
*/
void setPixelFormat (const OpenGLPixelFormat& formatToUse);
/** Returns the pixel format that this component is currently using. */
const OpenGLPixelFormat getPixelFormat() const;
/** Specifies an OpenGL context which should be shared with the one that this
component is using.
This is an OpenGL feature that lets two contexts share their texture data.
Note that this pointer is stored by the component, and when the component
needs to recreate its internal context for some reason, the same context
will be used again to share lists. So if you pass a context in here,
don't delete the context while this component is still using it! You can
call shareWith (nullptr) to stop this component from sharing with it.
*/
void shareWith (OpenGLContext* contextToShareListsWith);
/** Returns the context that this component is sharing with.
@see shareWith
*/
OpenGLContext* getShareContext() const noexcept { return contextToShareListsWith; }
//==============================================================================
/** Flips the openGL buffers over. */
void swapBuffers();
/** Returns true if the component is performing the rendering on a background thread.
This property is specified in the constructor.
*/
bool isUsingDedicatedThread() const noexcept { return useThread; }
/** This replaces the normal paint() callback - use it to draw your openGL stuff.
When this is called, makeCurrentContextActive() will already have been called
for you, so you just need to draw.
*/
virtual void renderOpenGL() = 0;
/** This method is called when the component creates a new OpenGL context.
A new context may be created when the component is first used, or when it
is moved to a different window, or when the window is hidden and re-shown,
etc.
You can use this callback as an opportunity to set up things like textures
that your context needs.
New contexts are created on-demand by the makeCurrentContextActive() method - so
if the context is deleted, e.g. by changing the pixel format or window, no context
will be created until the next call to makeCurrentContextActive(), which will
synchronously create one and call this method. This means that if you're using
a non-GUI thread for rendering, you can make sure this method is be called by
your renderer thread.
When this callback happens, the context will already have been made current
using the makeCurrentContextActive() method, so there's no need to call it
again in your code.
*/
virtual void newOpenGLContextCreated() = 0;
/** This method is called when the component shuts down its OpenGL context.
You can use this callback to delete textures and any other OpenGL objects you
created in the component's context. Be aware: if you are using a render
thread, this may be called on the thread.
When this callback happens, the context will have been made current
using the makeCurrentContextActive() method, so there's no need to call it
again in your code.
*/
virtual void releaseOpenGLContext() {}
//==============================================================================
/** Returns the context that will draw into this component.
This may return 0 if the component is currently invisible or hasn't currently
got a context. The context object can be deleted and a new one created during
the lifetime of this component, and there may be times when it doesn't have one.
@see newOpenGLContextCreated()
*/
OpenGLContext* getCurrentContext() const noexcept { return context; }
/** 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.
This call may actually create a context if one isn't currently initialised. If
it does this, it will also synchronously call the newOpenGLContextCreated()
method to let you initialise it as necessary.
@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's context is the active openGL context for the
current thread.
@see OpenGLContext::isActive
*/
bool isActiveContext() const noexcept;
//==============================================================================
/** Calls the rendering callback, and swaps the buffers afterwards.
This is called automatically by paint() when the component needs to be rendered.
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() noexcept { return contextLock; }
/** Delete the context.
You should only need to call this if you've written a custom thread - if so, make
sure that your thread calls this before it terminates.
*/
void deleteContext();
//==============================================================================
/** Returns the native handle of an embedded heavyweight window, if there is one.
E.g. On windows, this will return the HWND of the sub-window containing
the opengl context, on the mac it'll be the NSOpenGLView.
*/
void* getNativeWindowHandle() const;
protected:
/** Kicks off a thread to start rendering.
The default implementation creates and manages an internal thread that tries
to render at around 50fps, but this can be overloaded to create a custom thread.
*/
virtual void startRenderThread();
/** Cleans up the rendering thread.
Used to shut down the thread that was started by startRenderThread(). If you've
created a custom thread, then you should overload this to clean it up and delete it.
*/
virtual void stopRenderThread();
//==============================================================================
/** @internal */
void paint (Graphics& g);
private:
const OpenGLType type;
class OpenGLComponentRenderThread;
friend class OpenGLComponentRenderThread;
friend class ScopedPointer <OpenGLComponentRenderThread>;
ScopedPointer <OpenGLComponentRenderThread> renderThread;
class OpenGLComponentWatcher;
friend class OpenGLComponentWatcher;
friend class ScopedPointer <OpenGLComponentWatcher>;
ScopedPointer <OpenGLComponentWatcher> componentWatcher;
ScopedPointer <OpenGLContext> context;
OpenGLContext* contextToShareListsWith;
CriticalSection contextLock;
OpenGLPixelFormat preferredPixelFormat;
bool needToUpdateViewport, needToDeleteContext, threadStarted;
const bool useThread;
OpenGLContext* createContext();
void updateContext();
void updateContextPosition();
void stopBackgroundThread();
void recreateContextAsync();
void internalRepaint (int x, int y, int w, int h);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLComponent);
};
#endif // __JUCE_OPENGLCOMPONENT_JUCEHEADER__

View file

@ -0,0 +1,119 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_OPENGLCONTEXT_JUCEHEADER__
#define __JUCE_OPENGLCONTEXT_JUCEHEADER__
#include "juce_OpenGLPixelFormat.h"
//==============================================================================
/**
A base class for types of OpenGL context.
An OpenGLComponent will supply its own context for drawing in its window.
*/
class JUCE_API OpenGLContext
{
public:
//==============================================================================
/** Destructor. */
virtual ~OpenGLContext();
//==============================================================================
/** Makes this context the currently active one. */
virtual bool makeActive() const noexcept = 0;
/** If this context is currently active, it is disactivated. */
virtual bool makeInactive() const noexcept = 0;
/** Returns true if this context is currently active. */
virtual bool isActive() const noexcept = 0;
/** Swaps the buffers (if the context can do this). */
virtual void swapBuffers() = 0;
/** Sets whether the context checks the vertical sync before swapping.
The value is the number of frames to allow between buffer-swapping. This is
fairly system-dependent, but 0 turns off syncing, 1 makes it swap on frame-boundaries,
and greater numbers indicate that it should swap less often.
Returns true if it sets the value successfully.
*/
virtual bool setSwapInterval (int numFramesPerSwap) = 0;
/** Returns the current swap-sync interval.
See setSwapInterval() for info about the value returned.
*/
virtual int getSwapInterval() const = 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 (const Rectangle<int>& bounds) = 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 noexcept = 0;
/** Deletes the context.
This must only be called on the message thread, or will deadlock.
On background threads, call getCurrentContext()->deleteContext(), but be careful not
to call any other OpenGL function afterwards.
This doesn't touch other resources, such as window handles, etc.
You'll probably never have to call this method directly.
*/
virtual void deleteContext() = 0;
//==============================================================================
/** Returns the context that's currently in active use by the calling thread.
Returns 0 if there isn't an active context.
*/
static OpenGLContext* getCurrentContext();
protected:
//==============================================================================
OpenGLContext() noexcept;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLContext);
};
#endif // __JUCE_OPENGLCONTEXT_JUCEHEADER__

View file

@ -0,0 +1,85 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_OPENGLPIXELFORMAT_JUCEHEADER__
#define __JUCE_OPENGLPIXELFORMAT_JUCEHEADER__
//==============================================================================
/**
Represents the various properties of an OpenGL bitmap format.
@see OpenGLComponent::setPixelFormat
*/
class JUCE_API OpenGLPixelFormat
{
public:
//==============================================================================
/** Creates an OpenGLPixelFormat.
The default constructor just initialises the object as a simple 8-bit
RGBA format.
*/
OpenGLPixelFormat (int bitsPerRGBComponent = 8,
int alphaBits = 8,
int depthBufferBits = 16,
int stencilBufferBits = 0);
OpenGLPixelFormat (const OpenGLPixelFormat&);
OpenGLPixelFormat& operator= (const OpenGLPixelFormat&);
bool operator== (const OpenGLPixelFormat&) const;
//==============================================================================
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.
A reference component is needed in case there are multiple screens with different
capabilities - in which case, the one that the component is on will be used.
*/
static void getAvailablePixelFormats (Component* component,
OwnedArray <OpenGLPixelFormat>& results);
private:
//==============================================================================
JUCE_LEAK_DETECTOR (OpenGLPixelFormat);
};
#endif // __JUCE_OPENGLPIXELFORMAT_JUCEHEADER__