#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>和
#import <OpenGLES/EAGLDrawable.h>
#import <QuartzCore/QuartzCore.h>
然后必须重载以下函数:
+ (Class)layerClass;
- (void)layoutSubviews;
下面是函数内容:
// You must implement this另外还使用到了两重要函数:
+ (Class)layerClass {
return [CAEAGLLayer class];
}
- (void)layoutSubviews {
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
[self drawView];
}
- (BOOL) createFramebuffer;// 创建桢缓冲区
- (void) destroyFramebuffer;// 销毁桢缓冲区
- (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;
}
}
另外,我们还忘了初始化是怎么弄的,EAGLView文件内容是存在了nib文件里面,所以我们用:initWithCode初始化如下:
//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder {
if ((self = [super initWithCoder:coder])) { // 重载
// Get the layer
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
eaglLayer.opaque = YES; // 显示设置不透明
// 属性:(缓存颜色格式:kEAGLColorFormatRGBA8)
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
// 调用initWithAPI初始化 EAGLContext *context;
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
// 设为当前画布
if (!context || ![EAGLContext setCurrentContext:context]) {
[self release];
return nil;
}
// 时间间隔
animationInterval = 1.0 / 60.0;
}
return self;
}
最终,我们要描绘一个彩色的方块:
使用到函数 : - (void)drawView;
- (void)drawView {
// Replace the implementation of this method to do your own custom drawing
const GLfloat squareVertices[] = { //顶点数据
-0.5f, -0.5f,
0.5f, -0.5f,
-0.5f, 0.5f,
0.5f, 0.5f,
};
const GLubyte squareColors[] = { // 颜色数据
255, 255, 0, 255,
0, 255, 255, 255,
0, 0, 0, 0,
255, 0, 255, 255,
};
// 设为当前画布
[EAGLContext setCurrentContext:context];
// 绑定桢缓冲区
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
// 设置视图窗口大小
glViewport(0, 0, backingWidth, backingHeight);
// 投影变换
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // 设置为单位矩阵
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f); //正投影,创建一个正交平行的可视空间
glMatrixMode(GL_MODELVIEW); // 模型变换
glRotatef(3.0f, 0.0f, 0.0f, 1.0f); // 围绕x轴旋转
glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // 清屏颜色
glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲区
glVertexPointer(2, GL_FLOAT, 0, squareVertices); // 指定顶点数据指针
glEnableClientState(GL_VERTEX_ARRAY); // 开启顶点数组
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors); // 指定颜色数据数组指针
glEnableClientState(GL_COLOR_ARRAY); // 开启颜色数组
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 解引用一个数组元素序列,描绘
// 绑定到渲染缓冲区
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES]; // 渲染到设备
}
到此从建立接口到显示就这样完成了,另外在动态渲染的时候用到了一个定时器NSTimer,以下是它的方法:(这里不详细介绍)
- (void)startAnimation {
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
}
- (void)stopAnimation {
self.animationTimer = nil;
}
- (void)setAnimationTimer:(NSTimer *)newTimer {
[animationTimer invalidate];
animationTimer = newTimer;
}
- (void)setAnimationInterval:(NSTimeInterval)interval {
animationInterval = interval;
if (animationTimer) {
[self stopAnimation];
[self startAnimation];
}
}
在以后文章里面会建立一个EAGLView类,它的功能只是建立UIView到EAGL的接口,所以以后需要3D视图的类都可以通过继承它来完成,就像一个接口一样使用,这次就写到这.有的地方还不够详细,以后碰到了再介绍...(待续)