using specialized native view for OpenGL as in osx
This commit is contained in:
@@ -31,43 +31,21 @@
|
|||||||
|
|
||||||
#include "wx/osx/private.h"
|
#include "wx/osx/private.h"
|
||||||
|
|
||||||
|
#import <GLKit/GLKit.h>
|
||||||
#import <OpenGLES/EAGL.h>
|
#import <OpenGLES/EAGL.h>
|
||||||
#import <OpenGLES/EAGLDrawable.h>
|
#import <OpenGLES/EAGLDrawable.h>
|
||||||
#import <QuartzCore/QuartzCore.h>
|
#import <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
// a lot of the code is from the OpenGL ES Template
|
@interface wxUICustomOpenGLView : GLKView
|
||||||
|
|
||||||
// can be turned on for ES 2.0 only
|
|
||||||
#define USE_DEPTH_BUFFER 0
|
|
||||||
|
|
||||||
@interface wxUICustomOpenGLView : UIView
|
|
||||||
{
|
{
|
||||||
CGRect oldRect;
|
|
||||||
EAGLContext* context;
|
|
||||||
|
|
||||||
/* The pixel dimensions of the backbuffer */
|
|
||||||
GLint backingWidth;
|
|
||||||
GLint backingHeight;
|
|
||||||
|
|
||||||
/* OpenGL names for the renderbuffer and framebuffers used to render to this view */
|
|
||||||
GLuint viewRenderbuffer, viewFramebuffer;
|
|
||||||
|
|
||||||
/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
|
|
||||||
GLuint depthRenderbuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) createFramebuffer;
|
@property (retain) GLKViewController *viewController;
|
||||||
- (void) destroyFramebuffer;
|
|
||||||
- (id) initWithFrame:(CGRect) rect;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation wxUICustomOpenGLView
|
@implementation wxUICustomOpenGLView
|
||||||
|
|
||||||
+ (Class)layerClass {
|
|
||||||
return [CAEAGLLayer class];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)initialize
|
+ (void)initialize
|
||||||
{
|
{
|
||||||
static BOOL initialized = NO;
|
static BOOL initialized = NO;
|
||||||
@@ -78,85 +56,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithFrame:(CGRect)rect
|
|
||||||
{
|
|
||||||
if ( !(self=[super initWithFrame:rect]) )
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
oldRect = rect;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isOpaque
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)createFramebuffer {
|
|
||||||
|
|
||||||
glGenFramebuffersOES(1, &viewFramebuffer);
|
|
||||||
glGenRenderbuffersOES(1, &viewRenderbuffer);
|
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
|
|
||||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
|
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
|
|
||||||
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
|
|
||||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
|
|
||||||
|
|
||||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
|
|
||||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
|
|
||||||
|
|
||||||
if (USE_DEPTH_BUFFER) {
|
|
||||||
glGenRenderbuffersOES(1, &depthRenderbuffer);
|
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
|
|
||||||
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
|
|
||||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
|
|
||||||
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (void)destroyFramebuffer {
|
|
||||||
|
|
||||||
glDeleteFramebuffersOES(1, &viewFramebuffer);
|
|
||||||
viewFramebuffer = 0;
|
|
||||||
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
|
|
||||||
viewRenderbuffer = 0;
|
|
||||||
|
|
||||||
if(depthRenderbuffer) {
|
|
||||||
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
|
|
||||||
depthRenderbuffer = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setContext:(EAGLContext*) ctx {
|
|
||||||
context = ctx;
|
|
||||||
[EAGLContext setCurrentContext:ctx];
|
|
||||||
|
|
||||||
if ( viewFramebuffer == 0 )
|
|
||||||
{
|
|
||||||
[self destroyFramebuffer];
|
|
||||||
[self createFramebuffer];
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) swapBuffers {
|
- (void) swapBuffers {
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
|
[self.context presentRenderbuffer:GL_RENDERBUFFER_OES];
|
||||||
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)layoutSubviews {
|
|
||||||
[EAGLContext setCurrentContext:context];
|
|
||||||
[self destroyFramebuffer];
|
|
||||||
[self createFramebuffer];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -166,7 +67,6 @@ WXGLContext WXGLCreateContext( WXGLPixelFormat pixelFormat, WXGLContext shareCon
|
|||||||
{
|
{
|
||||||
WXGLContext context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
|
WXGLContext context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
|
||||||
|
|
||||||
// [[EAGLContext alloc] initWithFormat:pixelFormat shareContext: shareContext];
|
|
||||||
if ( !context )
|
if ( !context )
|
||||||
wxFAIL_MSG("NSOpenGLContext creation failed");
|
wxFAIL_MSG("NSOpenGLContext creation failed");
|
||||||
return context ;
|
return context ;
|
||||||
@@ -193,12 +93,6 @@ bool WXGLSetCurrentContext(WXGLContext context)
|
|||||||
|
|
||||||
void WXGLDestroyPixelFormat( WXGLPixelFormat pixelFormat )
|
void WXGLDestroyPixelFormat( WXGLPixelFormat pixelFormat )
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
if ( pixelFormat )
|
|
||||||
{
|
|
||||||
[pixelFormat release];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -207,148 +101,6 @@ WXGLPixelFormat WXGLChoosePixelFormat(const int *GLAttrs,
|
|||||||
const int *ctxAttrs,
|
const int *ctxAttrs,
|
||||||
int n2)
|
int n2)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
NSOpenGLPixelFormatAttribute data[512];
|
|
||||||
const NSOpenGLPixelFormatAttribute defaultAttribs[] =
|
|
||||||
{
|
|
||||||
NSOpenGLPFADoubleBuffer,
|
|
||||||
NSOpenGLPFAMinimumPolicy,
|
|
||||||
NSOpenGLPFAColorSize,(NSOpenGLPixelFormatAttribute)8,
|
|
||||||
NSOpenGLPFAAlphaSize,(NSOpenGLPixelFormatAttribute)0,
|
|
||||||
NSOpenGLPFADepthSize,(NSOpenGLPixelFormatAttribute)8,
|
|
||||||
(NSOpenGLPixelFormatAttribute)nil
|
|
||||||
};
|
|
||||||
|
|
||||||
const NSOpenGLPixelFormatAttribute *attribs;
|
|
||||||
if ( !attribList )
|
|
||||||
{
|
|
||||||
attribs = defaultAttribs;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned p = 0;
|
|
||||||
data[p++] = NSOpenGLPFAMinimumPolicy; // make _SIZE tags behave more like GLX
|
|
||||||
|
|
||||||
for ( unsigned arg = 0; attribList[arg] !=0 && p < WXSIZEOF(data); )
|
|
||||||
{
|
|
||||||
switch ( attribList[arg++] )
|
|
||||||
{
|
|
||||||
case WX_GL_RGBA:
|
|
||||||
//data[p++] = AGL_RGBA;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_BUFFER_SIZE:
|
|
||||||
//data[p++] = AGL_BUFFER_SIZE;
|
|
||||||
//data[p++] = attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_LEVEL:
|
|
||||||
//data[p++]=AGL_LEVEL;
|
|
||||||
//data[p++]=attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_DOUBLEBUFFER:
|
|
||||||
data[p++] = NSOpenGLPFADoubleBuffer;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_STEREO:
|
|
||||||
data[p++] = NSOpenGLPFAStereo;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_AUX_BUFFERS:
|
|
||||||
data[p++] = NSOpenGLPFAAuxBuffers;
|
|
||||||
data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_MIN_RED:
|
|
||||||
data[p++] = NSOpenGLPFAColorSize;
|
|
||||||
data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_MIN_GREEN:
|
|
||||||
//data[p++] = AGL_GREEN_SIZE;
|
|
||||||
//data[p++] = attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_MIN_BLUE:
|
|
||||||
//data[p++] = AGL_BLUE_SIZE;
|
|
||||||
//data[p++] = attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_MIN_ALPHA:
|
|
||||||
data[p++] = NSOpenGLPFAAlphaSize;
|
|
||||||
data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_DEPTH_SIZE:
|
|
||||||
data[p++] = NSOpenGLPFADepthSize;
|
|
||||||
data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_STENCIL_SIZE:
|
|
||||||
data[p++] = NSOpenGLPFAStencilSize;
|
|
||||||
data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_MIN_ACCUM_RED:
|
|
||||||
data[p++] = NSOpenGLPFAAccumSize;
|
|
||||||
data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_MIN_ACCUM_GREEN:
|
|
||||||
//data[p++] = AGL_ACCUM_GREEN_SIZE;
|
|
||||||
//data[p++] = attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_MIN_ACCUM_BLUE:
|
|
||||||
//data[p++] = AGL_ACCUM_BLUE_SIZE;
|
|
||||||
//data[p++] = attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_MIN_ACCUM_ALPHA:
|
|
||||||
//data[p++] = AGL_ACCUM_ALPHA_SIZE;
|
|
||||||
//data[p++] = attribList[arg++];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_SAMPLE_BUFFERS:
|
|
||||||
if ( !wxGLCanvas::IsAGLMultiSampleAvailable() )
|
|
||||||
{
|
|
||||||
if ( !attribList[arg++] )
|
|
||||||
break;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
data[p++] = NSOpenGLPFASampleBuffers;
|
|
||||||
if ( (data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++]) == true )
|
|
||||||
{
|
|
||||||
// don't use software fallback
|
|
||||||
data[p++] = NSOpenGLPFANoRecovery;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WX_GL_SAMPLES:
|
|
||||||
if ( !wxGLCanvas::IsAGLMultiSampleAvailable() )
|
|
||||||
{
|
|
||||||
if ( !attribList[arg++] )
|
|
||||||
break;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
data[p++] = NSOpenGLPFASamples;
|
|
||||||
data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data[p] = (NSOpenGLPixelFormatAttribute)nil;
|
|
||||||
|
|
||||||
attribs = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [[NSOpenGLPixelFormat alloc] initWithAttributes:(NSOpenGLPixelFormatAttribute*) attribs];
|
|
||||||
#endif
|
|
||||||
return @"dummy";
|
return @"dummy";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,12 +110,15 @@ bool wxGLContext::SetCurrent(const wxGLCanvas& win) const
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
wxUICustomOpenGLView* v = (wxUICustomOpenGLView*) win.GetPeer()->GetWXWidget();
|
wxUICustomOpenGLView* v = (wxUICustomOpenGLView*) win.GetPeer()->GetWXWidget();
|
||||||
|
if ( v.context != m_glContext ) {
|
||||||
[v setContext:m_glContext];
|
[v setContext:m_glContext];
|
||||||
|
[v bindDrawable];
|
||||||
|
}
|
||||||
|
WXGLSetCurrentContext(m_glContext);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define USE_SEPARATE_VIEW 1
|
|
||||||
|
|
||||||
bool wxGLCanvas::DoCreate(wxWindow *parent,
|
bool wxGLCanvas::DoCreate(wxWindow *parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
const wxPoint& pos,
|
const wxPoint& pos,
|
||||||
@@ -371,31 +126,27 @@ bool wxGLCanvas::DoCreate(wxWindow *parent,
|
|||||||
long style,
|
long style,
|
||||||
const wxString& name)
|
const wxString& name)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
m_glFormat = WXGLChoosePixelFormat(attribList);
|
|
||||||
if ( !m_glFormat )
|
|
||||||
return false;
|
|
||||||
*/
|
|
||||||
#if USE_SEPARATE_VIEW
|
|
||||||
DontCreatePeer();
|
DontCreatePeer();
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( !wxWindow::Create(parent, id, pos, size, style, name) )
|
if ( !wxWindow::Create(parent, id, pos, size, style, name) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#if USE_SEPARATE_VIEW
|
|
||||||
CGRect r = wxOSXGetFrameForControl( this, pos , size ) ;
|
CGRect r = wxOSXGetFrameForControl( this, pos , size ) ;
|
||||||
wxUICustomOpenGLView* v = [[wxUICustomOpenGLView alloc] initWithFrame:r];
|
|
||||||
CAEAGLLayer* eaglLayer = (CAEAGLLayer*) v.layer;
|
|
||||||
eaglLayer.opaque = YES;
|
|
||||||
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
|
|
||||||
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking,
|
|
||||||
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
|
|
||||||
|
|
||||||
SetPeer(new wxWidgetIPhoneImpl( this, v ));
|
// We need a context, otherwise the view will not get an initial
|
||||||
|
// Paint Event, making our own samples fail ...
|
||||||
|
WXGLPixelFormat pf = WXGLChoosePixelFormat(NULL, 0, NULL, 0);
|
||||||
|
WXGLContext context = WXGLCreateContext(pf, NULL);
|
||||||
|
|
||||||
|
wxUICustomOpenGLView* v = [[wxUICustomOpenGLView alloc] initWithFrame:r context: context ];
|
||||||
|
|
||||||
|
WXGLDestroyContext(context);
|
||||||
|
WXGLDestroyPixelFormat(pf);
|
||||||
|
|
||||||
|
wxWidgetIPhoneImpl* c = new wxWidgetIPhoneImpl( this, v, wxWidgetImpl::Widget_UserKeyEvents | wxWidgetImpl::Widget_UserMouseEvents );
|
||||||
|
SetPeer(c);
|
||||||
MacPostControlCreate(pos, size) ;
|
MacPostControlCreate(pos, size) ;
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,6 +162,7 @@ bool wxGLCanvas::SwapBuffers()
|
|||||||
wxCHECK_MSG(context, false, wxT("should have current context"));
|
wxCHECK_MSG(context, false, wxT("should have current context"));
|
||||||
|
|
||||||
wxUICustomOpenGLView* v = (wxUICustomOpenGLView*) GetPeer()->GetWXWidget();
|
wxUICustomOpenGLView* v = (wxUICustomOpenGLView*) GetPeer()->GetWXWidget();
|
||||||
|
if ( v != nil )
|
||||||
[v swapBuffers];
|
[v swapBuffers];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user