Opengles的基本认识

什么是Opengles?

OpenGL ES(OpenGL for Embedded Systems)是 OpenGL 三维图形API的子集,针对手机、PDA和游戏主机等嵌入式设备而设计,各显卡制造商和系统制造商来实现这组 API。

Opengles与EGL的联系

EGL是OpenGL ES渲染API和本地窗口系统之间的一个中间接口层,它主要有系统制造商实现。EGL提供如下机制:

  • 与设备的原生窗口系统通信
  • 查询绘图表面的可用类型和配置
  • 创建绘图表面
  • 在OpenGL ES和其他图形渲染API之前同步渲染
  • 管理纹理贴图等渲染资源
33333.jpg

Opengles的基本使用流程

  1. 设置上下文
-(void)setupGLContext{
    //初始化渲染上下文,管理所有绘制的状态,命令及资源信息
    _eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    //设置为当前上下文
    if(![EAGLContext setCurrentContext:_eaglContext]){
        NSLog(@"opengl setcontext failure");
    }
}
  1. 创建CAEAGLLayer
  • 直接创建CAEAGLLayer
    _eaglLayer = [CAEAGLLayer layer];
    _eaglLayer.frame = CGRectMake(0, 0, 320, 320);//self.view.frame;
    _eaglLayer.opaque = YES;
    [self.view.layer addSublayer:_eaglLayer];
  • 重写View的layerClass方法
+ (Class)layerClass{
    return [CAEAGLLayer class];
}

3、创建framebuffer、renderBuffer及关联
RenderBuffer是一块存储图像数据的内存区域,包括颜色附件,深度附件,模板附件。
FrameBuffer是一个聚合结构,相当于一个结构体,里面有颜色,深度附件,模板附件等,需要关联其他渲染缓冲区(RenderBuffer或纹理)。

-(void)setupRenderAndFrameBuffer{
    glGenRenderbuffers(1, &_colorRenderBuffer);
    //设置为当前renderBuffer
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
    //renderbuffer 分配存储空间
    if(!([_eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer])){
        NSLog(@"renderbufferstorage failure");
    }
    int _backingWidth;
    int _backingHeight;
    
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_backingWidth);

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_backingHeight);
    NSLog(@"GL_RENDERBUFFER_WIDTH:%d GL_RENDERBUFFER_HEIGHT:%d", _backingWidth, _backingHeight);
    //FBO用于管理colorRenderBUffer,离屏渲染
    glGenFramebuffers(1, &_frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer);

}
  1. 创建顶点着色器及片源着色器
    着色器是用GLSL语法编写的。
    顶点着色器
attribute vec4 Position;
void main(void){
    gl_Position = Position;
}

片元着色器

precision mediump float;

void main(void){
    gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}

5、构建program及编译shader

-(void)compileShaders{
    //生成一个定点着色器对象
    GLuint vertexShader = [self compileShader:@"SimpleVextex" withType:GL_VERTEX_SHADER];
    //生产一个片元着色器对象
    GLuint fragmentShader = [self compileShader:@"SimpleFragment" withType:GL_FRAGMENT_SHADER];
    GLuint programHandle = glCreateProgram();
    glAttachShader(programHandle, vertexShader);
    glAttachShader(programHandle, fragmentShader);
    glLinkProgram(programHandle);
    //着色器对象链接到程序对象后,删除找色器对象
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    
    GLint linkSuccess;
    glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
    if(linkSuccess == GL_FALSE){
        GLchar message[256];
        NSString *messageString = [NSString stringWithUTF8String:message];
        NSLog(@"着色器程序:%@", messageString);
        exit(1);
    }
    
    glUseProgram(programHandle);
    self.position = glGetAttribLocation(programHandle, "Position");
}

-(GLuint)compileShader:(NSString*)shaderName withType:(GLenum)shaderType{
    NSString *shaderPath = [[NSBundle mainBundle] pathForResource:shaderName ofType:@"glsl"];
    NSError *error;
    NSString *shaderString = [NSString stringWithContentsOfFile:shaderPath encoding:NSUTF8StringEncoding error:&error];
    
    GLuint shader = glCreateShader(shaderType);
    const char* shaderStringUTF8 = [shaderString UTF8String];
    int shaderStringLength = (int)shaderString.length;
    
    glShaderSource(shader, 1, &shaderStringUTF8, &shaderStringLength);
    glCompileShader(shader);
    
    GLint compileZSuccess;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compileZSuccess);
    if(compileZSuccess == GL_FALSE){
        GLchar message[256];
        NSString *messageString = [NSString stringWithUTF8String:message];
        NSLog(@"生成着色器对象:%@", messageString);
        exit(1);
    }
    return shader;
}

6、设置视窗大小

    glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    int width  = _eaglLayer.frame.size.width;
    int height = _eaglLayer.frame.size.height;
    glViewport(0, 0, width, height);

7、绘制
定义顶点数组,存入顶点缓冲区对象中,然后传入顶点数据,最后绘制。

-(void)renderUsingIndexVBO{
    const GLfloat vertices[] ={
        0.5f, 0.5f, 0.0f,
        0.5f, -0.5f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        -0.5f, 0.5f, 0.0f
    };
    
    const GLubyte indices[] = {
        0,1,3,
        1,2,3
    };
    
    //创建定点缓冲区
    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    
    //创建索引
    GLuint indexBuffer;
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
    //传递定点数据
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);
//    glDrawArrays(GL_TRIANGLES, 0, 3);
    //根据索引绘制
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
}

8、显示

    if(![_eaglContext presentRenderbuffer:GL_RENDERBUFFER]){
        NSLog(@"presentRenderbuffer failure");
    }

基本流程介绍完毕,再调试中碰到错误,可以调用glError来调试具体的错误。
demo地址 提取码: is5u

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容