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:
parent
1a21c89755
commit
b70e0a28d2
1527 changed files with 90380 additions and 396643 deletions
17
modules/juce_opengl/juce_module_info
Normal file
17
modules/juce_opengl/juce_module_info
Normal 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/*" ]
|
||||
}
|
||||
152
modules/juce_opengl/juce_opengl.cpp
Normal file
152
modules/juce_opengl/juce_opengl.cpp
Normal 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
|
||||
53
modules/juce_opengl/juce_opengl.h
Normal file
53
modules/juce_opengl/juce_opengl.h
Normal 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__
|
||||
46
modules/juce_opengl/native/juce_android_OpenGLComponent.cpp
Normal file
46
modules/juce_opengl/native/juce_android_OpenGLComponent.cpp
Normal 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)
|
||||
{
|
||||
|
||||
}
|
||||
239
modules/juce_opengl/native/juce_ios_OpenGLComponent.mm
Normal file
239
modules/juce_opengl/native/juce_ios_OpenGLComponent.mm
Normal 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);
|
||||
}
|
||||
204
modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp
Normal file
204
modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp
Normal 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
|
||||
}
|
||||
319
modules/juce_opengl/native/juce_mac_OpenGLComponent.mm
Normal file
319
modules/juce_opengl/native/juce_mac_OpenGLComponent.mm
Normal 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);
|
||||
}
|
||||
}
|
||||
516
modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp
Normal file
516
modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
447
modules/juce_opengl/opengl/juce_OpenGLComponent.cpp
Normal file
447
modules/juce_opengl/opengl/juce_OpenGLComponent.cpp
Normal 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
|
||||
272
modules/juce_opengl/opengl/juce_OpenGLComponent.h
Normal file
272
modules/juce_opengl/opengl/juce_OpenGLComponent.h
Normal 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__
|
||||
119
modules/juce_opengl/opengl/juce_OpenGLContext.h
Normal file
119
modules/juce_opengl/opengl/juce_OpenGLContext.h
Normal 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__
|
||||
85
modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h
Normal file
85
modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h
Normal 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__
|
||||
Loading…
Add table
Add a link
Reference in a new issue