From e5684ea03b4b9fa41d81968236aa070eefd30374 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 13 Sep 2009 17:22:13 +0000 Subject: [PATCH 1/1] OpenGL for iPhone git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61908 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/osx/iphone/glcanvas.mm | 399 +++++++++++++++++++++++++++++++++++++ 1 file changed, 399 insertions(+) create mode 100644 src/osx/iphone/glcanvas.mm diff --git a/src/osx/iphone/glcanvas.mm b/src/osx/iphone/glcanvas.mm new file mode 100644 index 0000000000..5231dde912 --- /dev/null +++ b/src/osx/iphone/glcanvas.mm @@ -0,0 +1,399 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/osx/iphone/glcanvas.mm +// Purpose: wxGLCanvas, for using OpenGL with wxWidgets under iPhone +// Author: Stefan Csomor +// Modified by: +// Created: 1998-01-01 +// RCS-ID: $Id: glcanvas.cpp 54129 2008-06-11 19:30:52Z SC $ +// Copyright: (c) Stefan Csomor +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/wxprec.h" + +#if defined(__BORLANDC__) + #pragma hdrstop +#endif + +#if wxUSE_GLCANVAS + +#include "wx/glcanvas.h" + +#ifndef WX_PRECOMP + #include "wx/frame.h" + #include "wx/log.h" + #include "wx/settings.h" +#endif + +#include "wx/osx/private.h" + +#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 +{ + 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; + +@end + +@implementation wxUICustomOpenGLView + ++ (Class)layerClass { + return [CAEAGLLayer class]; +} + ++ (void)initialize +{ + static BOOL initialized = NO; + if (!initialized) + { + initialized = YES; + wxOSXIPhoneClassAddWXMethods( self ); + } +} + +- (BOOL)isOpaque +{ + return YES; +} + +- (BOOL)createFramebuffer { + + glGenFramebuffersOES(1, &viewFramebuffer); + glGenRenderbuffersOES(1, &viewRenderbuffer); + + 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]; + [self destroyFramebuffer]; + [self createFramebuffer]; + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); +} + +- (void) swapBuffers { + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +} + +@end + + +WXGLContext WXGLCreateContext( WXGLPixelFormat pixelFormat, WXGLContext shareContext ) +{ + WXGLContext context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + + // [[EAGLContext alloc] initWithFormat:pixelFormat shareContext: shareContext]; + if ( !context ) + wxFAIL_MSG("NSOpenGLContext creation failed"); + return context ; +} + +void WXGLDestroyContext( WXGLContext context ) +{ + if ( context ) + { + [context release]; + } +} + +WXGLContext WXGLGetCurrentContext() +{ + return [EAGLContext currentContext]; +} + +bool WXGLSetCurrentContext(WXGLContext context) +{ + [EAGLContext setCurrentContext:context]; + return true; +} + +void WXGLDestroyPixelFormat( WXGLPixelFormat pixelFormat ) +{ +/* + if ( pixelFormat ) + { + [pixelFormat release]; + } +*/ +} + + +WXGLPixelFormat WXGLChoosePixelFormat(const int *attribList) +{ +#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 NULL; +} + +bool wxGLContext::SetCurrent(const wxGLCanvas& win) const +{ + if ( !m_glContext ) + return false; + + wxUICustomOpenGLView* v = (wxUICustomOpenGLView*) win.GetPeer()->GetWXWidget(); + [v setContext:m_glContext]; + return true; +} + +#define USE_SEPARATE_VIEW 1 + +bool wxGLCanvas::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name, + const int *attribList, + const wxPalette& WXUNUSED(palette)) +{ +/* + m_glFormat = WXGLChoosePixelFormat(attribList); + if ( !m_glFormat ) + return false; +*/ +#if USE_SEPARATE_VIEW + m_macIsUserPane = false ; +#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]; + + m_peer = new wxWidgetIPhoneImpl( this, v ); + + MacPostControlCreate(pos, size) ; +#endif + return true; +} + +wxGLCanvas::~wxGLCanvas() +{ + if ( m_glFormat ) + WXGLDestroyPixelFormat(m_glFormat); +} + +bool wxGLCanvas::SwapBuffers() +{ + WXGLContext context = WXGLGetCurrentContext(); + wxCHECK_MSG(context, false, wxT("should have current context")); + + wxUICustomOpenGLView* v = (wxUICustomOpenGLView*) m_peer->GetWXWidget(); + [v swapBuffers]; + return true; +} + + +#endif // wxUSE_GLCANVAS -- 2.45.2