From 4455b6e784d76cd442d0cd1f3240e4bea46f0f7e Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Mon, 15 Mar 2021 10:17:20 +0100 Subject: [PATCH] using specialized native view for OpenGL as in osx --- src/osx/iphone/glcanvas.mm | 298 ++++--------------------------------- 1 file changed, 25 insertions(+), 273 deletions(-) diff --git a/src/osx/iphone/glcanvas.mm b/src/osx/iphone/glcanvas.mm index 158edf42ce..6f292b86cf 100644 --- a/src/osx/iphone/glcanvas.mm +++ b/src/osx/iphone/glcanvas.mm @@ -31,43 +31,21 @@ #include "wx/osx/private.h" +#import #import #import #import -// a lot of the code is from the OpenGL ES Template - -// can be turned on for ES 2.0 only -#define USE_DEPTH_BUFFER 0 - -@interface wxUICustomOpenGLView : UIView +@interface wxUICustomOpenGLView : GLKView { - 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; -- (void) destroyFramebuffer; -- (id) initWithFrame:(CGRect) rect; +@property (retain) GLKViewController *viewController; @end @implementation wxUICustomOpenGLView -+ (Class)layerClass { - return [CAEAGLLayer class]; -} - + (void)initialize { 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 { - glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); - [context presentRenderbuffer:GL_RENDERBUFFER_OES]; -} - -- (void)layoutSubviews { - [EAGLContext setCurrentContext:context]; - [self destroyFramebuffer]; - [self createFramebuffer]; + [self.context presentRenderbuffer:GL_RENDERBUFFER_OES]; } @end @@ -166,7 +67,6 @@ WXGLContext WXGLCreateContext( WXGLPixelFormat pixelFormat, WXGLContext shareCon { WXGLContext context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; - // [[EAGLContext alloc] initWithFormat:pixelFormat shareContext: shareContext]; if ( !context ) wxFAIL_MSG("NSOpenGLContext creation failed"); return context ; @@ -193,12 +93,6 @@ bool WXGLSetCurrentContext(WXGLContext context) void WXGLDestroyPixelFormat( WXGLPixelFormat pixelFormat ) { -/* - if ( pixelFormat ) - { - [pixelFormat release]; - } -*/ } @@ -207,148 +101,6 @@ WXGLPixelFormat WXGLChoosePixelFormat(const int *GLAttrs, const int *ctxAttrs, 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"; } @@ -358,12 +110,15 @@ bool wxGLContext::SetCurrent(const wxGLCanvas& win) const return false; wxUICustomOpenGLView* v = (wxUICustomOpenGLView*) win.GetPeer()->GetWXWidget(); - [v setContext:m_glContext]; + if ( v.context != m_glContext ) { + [v setContext:m_glContext]; + [v bindDrawable]; + } + WXGLSetCurrentContext(m_glContext); + return true; } -#define USE_SEPARATE_VIEW 1 - bool wxGLCanvas::DoCreate(wxWindow *parent, wxWindowID id, const wxPoint& pos, @@ -371,31 +126,27 @@ bool wxGLCanvas::DoCreate(wxWindow *parent, long style, const wxString& name) { -/* - m_glFormat = WXGLChoosePixelFormat(attribList); - if ( !m_glFormat ) - return false; -*/ -#if USE_SEPARATE_VIEW DontCreatePeer(); -#endif if ( !wxWindow::Create(parent, id, pos, size, style, name) ) return false; -#if USE_SEPARATE_VIEW 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) ; -#endif + return true; } @@ -411,7 +162,8 @@ bool wxGLCanvas::SwapBuffers() wxCHECK_MSG(context, false, wxT("should have current context")); wxUICustomOpenGLView* v = (wxUICustomOpenGLView*) GetPeer()->GetWXWidget(); - [v swapBuffers]; + if ( v != nil ) + [v swapBuffers]; return true; }