zoukankan      html  css  js  c++  java
  • iOS开发-OpenGL ES入门教程1

    http://www.jianshu.com/p/750fde1d8b6a

    这里是一篇新手教程,环境是Xcode7+OpenGL ES 2.0,目标写一个OpenGL ES的hello world
    OpenGL ES系列教程在这里
    OpenGL ES系列教程的代码地址

    你的star和fork是我的源动力,你的意见能让我走得更远

    核心思路

    通过GLKit,尽量简单地实现把一张图片绘制到屏幕。

    效果展示


     

    具体细节

    1、新建OpenGL ES上下文

    - (void)setupConfig {
        //新建OpenGLES 上下文
        self.mContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; //2.0,还有1.0和3.0
        GLKView* view = (GLKView *)self.view; //storyboard记得添加
        view.context = self.mContext;
        view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;  //颜色缓冲区格式
        [EAGLContext setCurrentContext:self.mContext];
    }

    GLKView* view = (GLKView *)self.view;这里需要在storyboard里面把view的类设置成GLKView,其他代码是OpenGL ES上下文的创建。

    2、顶点数组和索引数组

    //顶点数据,前三个是顶点坐标,后面两个是纹理坐标
        GLfloat squareVertexData[] =
        {
            0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下
            0.5, 0.5, -0.0f,    1.0f, 1.0f, //右上
            -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
    
            0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下
            -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
            -0.5, -0.5, 0.0f,   0.0f, 0.0f, //左下
        };

    顶点数组里包括顶点坐标,OpenGLES的世界坐标系是[-1, 1],故而点(0, 0)是在屏幕的正中间
    纹理坐标系的取值范围是[0, 1],原点是在左下角。故而点(0, 0)在左下角,点(1, 1)在右上角。
    索引数组是顶点数组的索引,把squareVertexData数组看成4个顶点,每个顶点会有5个GLfloat数据,索引从0开始。

    3、顶点数据缓存

        //顶点数据缓存
        GLuint buffer;
        glGenBuffers(1, &buffer);
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW);
    
        glEnableVertexAttribArray(GLKVertexAttribPosition); //顶点数据缓存
        glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 0);
        glEnableVertexAttribArray(GLKVertexAttribTexCoord0); //纹理
        glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);

    这是本章节的核心内容

    • glGenBuffers申请一个标识符
    • glBindBuffer把标识符绑定到GL_ARRAY_BUFFER
    • glBufferData把顶点数据从cpu内存复制到gpu内存
    • glEnableVertexAttribArray 是开启对应的顶点属性
    • glVertexAttribPointer设置合适的格式从buffer里面读取数据

    4、纹理贴图

    - (void)uploadTexture {
        //纹理贴图
        NSString* filePath = [[NSBundle mainBundle] pathForResource:@"for_test" ofType:@"jpg"];
        NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@(1), GLKTextureLoaderOriginBottomLeft, nil];//GLKTextureLoaderOriginBottomLeft 纹理坐标系是相反的
        GLKTextureInfo* textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
        //着色器
        self.mEffect = [[GLKBaseEffect alloc] init];
        self.mEffect.texture2d0.enabled = GL_TRUE;
        self.mEffect.texture2d0.name = textureInfo.name;
    }
    • GLKTextureLoader读取图片,创建纹理GLKTextureInfo
    • 创建着色器GLKBaseEffect,把纹理赋值给着色器

    基础

    代码带了很多注释,百度下相应的概念,会有更多解释。
    如果对OpengGL ES感兴趣,但是却毫无图形学基础的,可以看看LearnOpenGL教程

    思考题

    • 1、代码中有6个顶点坐标,能否使用更少的顶点显示一个图像?
    • 2、顶点缓存数组可以不用glBufferData,要如何实现?
    • 3、如果把这个图变成左右两只对称的熊猫,该如何改?

    这里可以下载demo代码。

    思考题答案

    思考题1:
    可以使用四个顶点,绘制2个三角形 的6个顶点中有2个是重复的,使用索引可以减少重复。

    思考题2:
    顶点缓存数组可以不用glBufferData,要如何实现?顶点数组可以通过glBufferData放入缓存,也可以直接通过glVertexAttribPointer最后一个参数,直接把顶点数组从CPU传送到GPU。区别:glBufferData里面的顶点缓存可以复用,glVertexAttribPointer是每次都会把顶点数组从CPU发送到GPU,影响性能。

    思考题3
    如果把这个图变成左右两只对称的熊猫,该如何改?把屏幕切分成4个三角形,左边两个三角形同上,右边两个三角形的纹理坐标的x值调整即可。



    作者:落影loyinglin
    链接:http://www.jianshu.com/p/750fde1d8b6a
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    FileZilla Server下载及安装
    FileZilla Server设置虚拟目录
    FileZilla Server超详细配置
    Freaktab将于12月底关闭
    Thinkpad笔记本指点杆(小红点)自动漂移的问题
    STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解)
    STC12C5A56S2和DS12C887做的电子闹铃
    联盛德 HLKW806 (九): 软件SPI和硬件SPI驱动ST7789V液晶LCD
    联盛德 HLKW806 (六): I2C驱动SSD1306 128x64 OLED液晶屏
    联盛德 HLKW806 (五): W801开发板上手报告
  • 原文地址:https://www.cnblogs.com/jukan/p/7880827.html
Copyright © 2011-2022 走看看