在IOS上要實作一個OPENGL ES,需要一個使用到一個UIView的Class。因為 OpenGL ES是Core Animation的客戶,要使用OpenGL ES需要創建一個UIView,這個UIView由一個特殊的core animation layer支持,這個特殊的layer是一個CAEAGLLayer對象。 CAEAGLLayer是OpenGLES和core animation聯繫的橋樑。當應用程序渲染完一幀後,CAEAGLLayer的內容被呈現並且和其他view的數據組合。
core animation是ios圖形子系統的基礎,UIView對象由core animation layer支持。各種各樣的layer更新他們的內容,由core animation動畫和合成,並向顯示設備呈現。
因此framework需要QuartzCore 及 OpenGLES。
OpenGL ES命令被提交到rendering context。這些命令可以讀取context的狀態,改變context的狀態,創建修改和銷毀OpenGL ES Object,以及提交被渲染的幾何體,幾何體通過流水線處理最終光柵化到framebuffer。
EAGLContext是OpenGL ES RenderingContext的iOS實現。每個程序有自己的EAGLContext,這保證了各個OpenGL ES程序互不干擾。在EAGLContext需要在調用任何OpenGL ES api前創建並初始化。
renderbuffer: 是某種特定格式的2d圖形。格式可以是顏色信息,也可以是深度或模板信息。 renderbuffer一般不單獨使用,而是被收集作為fraembuffer的一部分使用。Framebuffers: 是圖形流水線的最終目的地。一個framebuffer object其實是一個容器,包含了attach上去的紋理和renderbuffer。
drawableProperties可參考的官方資料
http://developer.apple.com/library/ios/#documentation/iPhone/Reference/EAGLDrawable_Ref/EAGLDrawable/EAGLDrawable.html
以下是一個實作的例子,參考http://blog.csdn.net/kesalin/article/details/8221393,並將程式改成UIViewController的模式。
1.首先開啓一個專案
2. 加入一個UIView的Class檔,用來放置OpenGLES的程式碼
3. 加入QuartzCore 及 OpenGLES的framework。
4. 在OpenGLView.h加入程式碼
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
@interface OpenGLView : UIView {
CAEAGLLayer* _eaglLayer;
EAGLContext* _context;
GLuint _colorRenderBuffer;
GLuint _frameBuffer;
}
- (void)setupLayer;
- (void)setupContext;
- (void)setupRenderBuffer;
- (void)destoryRenderAndFrameBuffer;
- (void)render;
@end
5. 在OpenGLView.m加入程式碼
#import "OpenGLView.h"
@implementation OpenGLView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self setupLayer];
[self setupContext];
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
+ (Class)layerClass {
// 只有 [CAEAGLLayer class] 类型的 layer 才支持在其上描绘 OpenGL 内容。
return [CAEAGLLayer class];
}
- (void)setupLayer
{
_eaglLayer = (CAEAGLLayer*) self.layer;
// CALayer 默认是透明的,必须将它设为不透明才能让其可见
_eaglLayer.opaque = YES;
// 设置描绘属性,在这里设置不维持渲染内容以及颜色格式为 RGBA8
_eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
}
- (void)setupContext {
// 指定 OpenGL 渲染 API 的版本,在这里我们使用 OpenGL ES 2.0
EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES2;
_context = [[EAGLContext alloc] initWithAPI:api];
if (!_context) {
NSLog(@"Failed to initialize OpenGLES 2.0 context");
exit(1);
}
// 设置为当前上下文
if (![EAGLContext setCurrentContext:_context]) {
_context = nil;
NSLog(@"Failed to set current OpenGL context");
exit(1);
}
}
- (void)setupRenderBuffer {
glGenRenderbuffers(1, &_colorRenderBuffer);
// 设置为当前 renderbuffer
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
// 为 color renderbuffer 分配存储空间
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];
}
- (void)setupFrameBuffer {
glGenFramebuffers(1, &_frameBuffer);
// 设置为当前 framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
// 将 _colorRenderBuffer 装配到 GL_COLOR_ATTACHMENT0 这个装配点上
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, _colorRenderBuffer);
}
- (void)destoryRenderAndFrameBuffer
{
glDeleteFramebuffers(1, &_frameBuffer);
_frameBuffer = 0;
glDeleteRenderbuffers(1, &_colorRenderBuffer);
_colorRenderBuffer = 0;
}
- (void)render {
glClearColor(0, 1.0, 0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
[_context presentRenderbuffer:GL_RENDERBUFFER];
}
- (void)layoutSubviews {
[EAGLContext setCurrentContext:_context];
[self destoryRenderAndFrameBuffer];
[self setupRenderBuffer];
[self setupFrameBuffer];
[self render];
}
@end
6. 在mainViewController.h加入OpenGL的呼叫變數
#import <UIKit/UIKit.h>
#import "OpenGLView.h"
@interface mainViewController : UIViewController
@property (strong, retain) IBOutlet OpenGLView *glView;
@end
7. 在mainViewController.m加入OpenGL執行程式
#import "mainViewController.h"
@interface mainViewController ()
@end
@implementation mainViewController
@synthesize glView = _glView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//CGRect screenBounds = [[UIScreen mainScreen] bounds];
_glView = [[OpenGLView alloc] initWithFrame:CGRectMake(300, 300, 200, 200)];
[self.view addSubview:self.glView];
self.view.backgroundColor = [UIColor whiteColor];
// [self.view makeKeyAndVisible];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
8. 執行結果,劃出一個200x200的區域



