http://www.helmsmansoft.com/index.php/archives/1436
由于本人也是一面学习一面做此教程以分享学习中的一些东西分享给大家,突然发现手里的一些资料和网上的资料大多数都是OpenGLES 1.1版本的教程,所以本课程教程也以OpenGLES 1.1为基础开始,待1.1教程完成以后在继续探讨2.0版本的技术。如果您也对此感兴趣,可随本站一起来进入OpenGLES的世界,感受技术带来的快乐。
本教程不多说关于OpenGLES的基础内容,直接用图像化的界面来带大家走进OpenGLES的世界,如果您对基础内容还不是很了解,也没有关系,本站教程会对教程中的每句代码加上说明注释,以求傻瓜式的学习方式。
下面就开始OpenGLES 1.1的第一课:
首先新建工程,选择“Single View Application”模板,如下图:
点击“next”,给工程起名为“OpenGLES_Class_One”,点击“next”,把工程保存在桌面。
接下来新建文件,起名为“RenderView”,下图:
导入编写OpenGLES代码需要的框架,OpenGLES.framework和QuartzCore.framework,并在RenderView.h文件中导入头文件
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import <QuartzCore/QuartzCore.h>
到此工程所需的框架和基本文件已经准备完毕,如下图所示,接下来就要开始编码了。
接下来就要在RenderView中进行编码了,具体的编码说明见下:
RenderView.h文件代码如下:
//
// RenderView.h
// OpenGLES_Class_One
//
// Created by Helmsmansoft on 12-6-9.
// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
// http://www.helmsmansoft.com 舵手网络
#import <UIKit/UIKit.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import <QuartzCore/QuartzCore.h>
@interface RenderView : UIView{
EAGLContext * _context;
}
@property (nonatomic, retain) EAGLContext * context;
@end
RenderView.m文件代码如下 :
//
// RenderView.m
// OpenGLES_Class_One
//
// Created by Helmsmansoft on 12-6-9.
// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
// http://www.helmsmansoft.com 舵手网络
#import "RenderView.h"
@implementation RenderView
@synthesize context = _context;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; //
eaglLayer.opaque = YES; //不透明度设置,为真
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:FALSE],
kEAGLDrawablePropertyRetainedBacking,
kEAGLColorFormatRGBA8,
kEAGLDrawablePropertyColorFormat,nil]; //设置drawableProperties属性
EAGLRenderingAPI renderAPI = kEAGLRenderingAPIOpenGLES1; //OpenGLES Version 1.1
_context = [[EAGLContext alloc] initWithAPI:renderAPI]; //初始化上下文环境
if(!_context || ![EAGLContext setCurrentContext:_context]){ //容错处理
[self release];
return nil;
}
}
return self;
}
- (void)dealloc
{
[_context release];
[super dealloc];
}
/*重写UIView的layerClass方法*/
+ (Class)layerClass
{
return [CAEAGLLayer class];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
@end
上面的代码中,重写layerClass方法,默认位[CALayer class],重写后此方法告诉UIView这个视图的主要层是CAEAGLLayer,CAEAGLLayer是最终渲染opengl的地方,如果没有此层就无法渲染opengl,此层非常重要。
在类初始化方法中,首先获得当前层,然后设定其属性的不透明度(opaque)为真,设置层不透明,无特别好的理由,不要在层中使用透明,此方法默认为透明,在此设置其不透明,如果透明会严重影响性能,特别实在opengl中。如果允许CAEAGLLayer透明,显示图层后的内容需要使用大量混色才能显示。混色是一个很费资源的处理过程,可能会带来性能问题。
然后设置drawableProperties属性,此属性建立一个包含许多对象和键的清单,这些对象和键值规定了绘制表面在呈现图像后可保留的内容,同时内部颜色缓冲格式将提供绘制表面使用。
然后EAGLContext初始化语境,设定使用的OpenGLES版本, EAGLContext负责管理状态信息,命令和OpenGLES绘制时使用的资源等。
然后是一个容错处理,如果初始化或者设置失败,self就会被释放,这个很重要,因为self已经被分配并占用了内存。
接下来在RenderView.h文件中添加如下代码:
GLuint defaultFrameBuffer;
GLuint colorRenderBuffer;
GLint backingHeight;
GLint backingWidth;
RenderView.m文件中添加如下代码:
@synthesize defaultFrameBuffer;
@synthesize colorRenderBuffer;
@synthesize backingWidth,backingHeight;
//----------------------------------------
/*设置帧缓冲区*/
- (void)setupFrameBuffer
{
glGenFramebuffersOES(1, &defaultFrameBuffer); //创建帧缓冲区,存储在defaultFrameBuffer中
glBindFramebuffer(GL_FRAMEBUFFER_OES, defaultFrameBuffer); //绑定帧缓冲区
}
/*设置渲染缓冲区*/
- (void)setupRenderBuffer
{
glGenRenderbuffersOES(1, &colorRenderBuffer); //创建渲染缓冲区,存储在colorRenderBuffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderBuffer); //绑定渲染缓冲区
}
/*设置OpenGL*/
- (void)setupOpenGLESLayer
{
[_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer]; //绑定layer的可绘制对象到刚才创建的OpenGLES缓冲区
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, defaultFrameBuffer); //GL_COLOR_ATTACHMENT0_OES命令将渲染缓冲区关联到帧缓冲区,使用glFramebufferRenderbufferOES命令将渲染缓冲区作为一个特殊附件附加到帧缓冲区
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); //从渲染缓冲区获取尺寸,存储在backingWidth中,下同
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES){ //检测帧缓冲区是否编译正确
NSLog(@"Faild to make complete framebuffer object!");
[self release];
}
}
//渲染方法
- (void)render
{
glClearColor(0.1f, 0.8f, 1.0f, 1.0f); //设置清屏颜色
glClear(GL_COLOR_BUFFER_BIT); //清屏
glViewport(0, 0, backingWidth, backingHeight); //设置视口
[_context presentRenderbuffer:GL_RENDERBUFFER_OES]; //将渲染缓冲区的内容呈现到屏幕上
}
然后在初始化方法中依次调用方法即可,
最后一部就是关联本类到程序了,在ViewController.m的viewDidLoad中添加如下代码
RenderView *renderView = [[RenderView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.view = renderView;
[renderView release];
最后呈现出如下图的界面
以上内容所使用的命令与方法均为OpenGLES 1.1版本。
代码下载:OpenGLES_Class_One
以上就是本课程的全部内容,如果不明白之处,可发送邮件到helmsmansoft@163.com。