首页 > 系统 > iOS > 正文

iOS之OpenGL ES【1】:基本认识和理解

2019-11-06 09:59:09
字体:
来源:转载
供稿:网友

一、什么是 OpenGL ES?

iOS上绘制图形的方式很多,UIKit,CoreGraphics,SPRiteKit,OpenGL ES,Metal等。OpenGL ES是一套非常底层但使用非常广泛的C语言API,专为移动设备定制,可在不同的手机系统或浏览器上使用,渲染效果很好。

二、iOS的OpenGL ES的使用:

新建一个工程之后,在系统库中需要添加导入OpenGLES.framework和QuartzCore.framework两个库;新建一个单独实现OpenGL ES的类,命名为OpenGLView,并引入#import "OpenGLView.h"#import <QuartzCore/QuartzCore.h>#import <OpenGLES/ES2/gl.h>#import <OpenGLES/ES2/glext.h>在OpenGLView的.m的延展中声明如下实例变量:@interface OpenGLView () { CAEAGLLayer *eaglLayer; //OpenGL context,管理使用openGLES进行绘制的状态,命令及资源 EAGLContext *eaglContext; GLuint colorRenderBuffer;//渲染缓冲区 GLuint frameBuffer;//帧缓冲区}继续在.m中实现layerClass方法: + (Class)layerClass { //为了让 UIView 显示 openGL 内容,必须将默认的layer类型修改为CAEAGLLayer类型 return [CAEAGLLayer class];}CAEAGLLayer的配置:默认的 CALayer 是透明的,需要将它设置为 opaque == YES 才能看到在它上面描绘的东西。为此,使用匿名 category 技巧,在 OpenGLView.m的开头(在@interface OpenGLView 的上面)添加匿名 category,并声明私有函数 setupLayer并在implementation中实现: + (void)setupLayer { eaglLayer = (CAEAGLLayer *)self.layer; eaglLayer.opaque = YES; // 描绘属性:这里不维持渲染内容 // kEAGLDrawablePropertyRetainedBacking:若为YES,则使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)计算得到的最终结果颜色的透明度会考虑目标颜色的透明度值。 // 若为NO,则不考虑目标颜色的透明度值,将其当做1来处理。 // 使用场景:目标颜色为非透明,源颜色有透明度,若设为YES,则使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)得到的结果颜色会有一定的透明度(与实际不符)。若未NO则不会(符合实际)。 eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],kEAGLDrawablePropertyRetainedBacking,kEAGLColorFormatRGBA8,kEAGLDrawablePropertyColorFormat, nil];}EAGLContext渲染上下文: - (void)setupContext { eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; if (!eaglContext) { exit(1); } if (![EAGLContext setCurrentContext:eaglContext]) { exit(1); }}创建RenderBuffer:用于存储渲染的内容(OpenGL ES 总共有三大不同用途的color buffer,depth buffer 和 stencil buffer,这里创建私有方法setupRenderBuffer来生成 color buffer; - (void)setupRenderBuffer { if (colorRenderBuffer) { glDeleteBuffers(1, &colorRenderBuffer); frameBuffer = 0; } // 生成一个renderBuffer,id是colorRenderBuffer glGenBuffers(1, &colorRenderBuffer); // 设置为当前renderBuffer,则后面引用GL_RENDERBUFFER,即指的是colorRenderBuffer glBindRenderbuffer(GL_RENDERBUFFER, colorRenderBuffer); // 为colorRenderBuffer分配存储空间 [eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer];}FrameBuffer:renderBuffer对象本身不能直接使用,不能挂载到GPU上直接输出内容,要使用frameBuffer(OpenGlES的FrameBuffer包含:renderBuffer,depthBuffer,stencilBuffer和accumulationBuffer);- (void)setupFrameBuffer { if (frameBuffer) { glGenBuffers(1, &frameBuffer); frameBuffer = 0; } // FBO用于管理colorRenderBuffer,离屏渲染 glGenFramebuffers(1, &frameBuffer); // 设置为当前frameBuffer glBindRenderbuffer(GL_FRAMEBUFFER, frameBuffer); // 将colorRenderBuffer装配到GL_COLOR_ATTACHMENT0这个装配点上 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderBuffer);}当 UIView 在进行布局变化之后,由于 layer 的宽高变化,导致原来创建的 renderbuffer不再相符,需要销毁既有的 renderbuffer 和 framebuffer; - (void)destoryRenderAndFrameBuffer { glDeleteFramebuffers(1, &frameBuffer); frameBuffer = 0; glDeleteRenderbuffers(1, &colorRenderBuffer); colorRenderBuffer = 0;}声明一个render方法进行真实描绘: - (void)render { // 设置清屏颜色 glClearColor(0, 1.0, 0, 1.0); // 用来指定要用清屏颜色来清除由mask指定的buffer,此处是color buffer glClear(GL_COLOR_BUFFER_BIT); [eaglContext presentRenderbuffer:GL_RENDERBUFFER];}最后在实现layoutSubviews方法:- (void)layoutSubviews { [self setupLayer]; [self setupContext]; [self destoryRenderAndFrameBuffer]; [self setupRenderBuffer]; [self setupFrameBuffer]; [self render];}完成了OpenGLView的基本构造之后,利用OpenGLView在界面上进行渲染:在ViewController中导入#import “OpenGLView.h”,并声明一个OpenGLView的实例属性,在viewDidLoad中调用即可: self.glView = [[OpenGLView alloc] init]; self.glView.frame = self.view.frame; [self.view addSubview:self.glView]; self.view.backgroundColor = [UIColor redColor];
上一篇:iOS真机与模拟器

下一篇:iOS 数组排序

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表