OpenGL for iPhone
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61908 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
b90817de2b
commit
e5684ea03b
399
src/osx/iphone/glcanvas.mm
Normal file
399
src/osx/iphone/glcanvas.mm
Normal file
@ -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 <OpenGLES/EAGL.h>
|
||||
#import <OpenGLES/EAGLDrawable.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
// 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
|
Loading…
Reference in New Issue
Block a user