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

239 lines
7.6 KiB
Text

/*
==============================================================================
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;
}
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);
}