iOS开发-OpenGLES的新手教程

OpenGLES

这里是一篇新手教程,环境是xcode7+OpenGLES2.0,主要是用一个样例,介绍OpenGLES的基本概念。

代码先行

1,到 这里 下载demo代码。打开tutorial01,核心代码如下:

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic , strong) EAGLContext* mContext;
@property (nonatomic , strong) GLKBaseEffect* mEffect;

@property (nonatomic , assign) int mCount;
@end

@implementation ViewController
{
    dispatch_source_t timer; //临时变量的弱引用会导致定时器失效
}
- (void)viewDidLoad {
    [super viewDidLoad];
   

    //新建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;  //颜色缓冲区格式
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24; // 模板缓冲区格式
    [EAGLContext setCurrentContext:self.mContext];
    glEnable(GL_DEPTH_TEST); //开启深度测试,这里因为是2D图形,没有作用,可以尝试注释进阶里面的这句
    
    
    //顶点数据,前三个是顶点坐标,法线,纹理坐标
    GLfloat squareVertexData[48] =
    {
        0.5, -0.5, 0.0f,    0.0f, 0.0f, 1.0f,   1.0f, 0.0f, //右下
        -0.5, 0.5, 0.0f,    0.0f, 0.0f, 1.0f,   0.0f, 1.0f, //左上
        -0.5, -0.5, 0.0f,    0.0f, 0.0f, 1.0f,   0.0f, 0.0f, //左下
        0.5, 0.5, -0.0f,    0.0f, 0.0f, 1.0f,   1.0f, 1.0f, //右上
    };

    //顶点索引
    GLuint indices[] =
    {
        0, 1, 2,
        1, 3, 0
    };
    self.mCount = sizeof(indices) / sizeof(GLuint);

    
    //顶点数据缓存
    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW);
    
    GLuint index;
    glGenBuffers(1, &index);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
    glEnableVertexAttribArray(GLKVertexAttribPosition); //顶点数据缓存
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 4 * 8, (char *)NULL + 0);

    glEnableVertexAttribArray(GLKVertexAttribNormal); //法线
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 4 * 8, (char *)NULL + 12);

    glEnableVertexAttribArray(GLKVertexAttribTexCoord0); //纹理
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 4 * 8, (char *)NULL + 24);

    
    //纹理贴图
    NSString* filePath = [[NSBundle mainBundle] pathForResource:@"for_test" ofType:@"png"];
    NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@(1), GLKTextureLoaderOriginBottomLeft, nil];//GLKTextureLoaderOriginBottomLeft 纹理坐标系是相反的
    GLKTextureInfo* textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
    //着色器
    self.mEffect = [[GLKBaseEffect alloc] init];
    self.mEffect.light0.enabled = GL_TRUE;
    self.mEffect.light0.diffuseColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);
    self.mEffect.texture2d0.enabled = GL_TRUE;
    self.mEffect.texture2d0.name = textureInfo.name;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/**
 *  场景数据变化
 */
- (void)update {
    
    //投影变换
    CGSize size = self.view.bounds.size;
    float aspect = fabs(size.width / size.height);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(90.0), aspect, 0.1f, 10.f);
    projectionMatrix = GLKMatrix4Scale(projectionMatrix, 1.0f, 1.0f, 1.0f);
    self.mEffect.transform.projectionMatrix = projectionMatrix;
    
    //z轴平移
    GLKMatrix4 modelViewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0.0f, 0.0f, -2.0f);
    self.mEffect.transform.modelviewMatrix = modelViewMatrix;
}


/**
 *  渲染场景代码
 */
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    glClearColor(0.3f, 0.6f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    //启动着色器
    [self.mEffect prepareToDraw];
    glDrawElements(GL_TRIANGLES, self.mCount, GL_UNSIGNED_INT, 0);
}

@end

 

概念介绍

三大缓冲区:颜色缓冲区、模板缓冲区、深度缓冲区
 
OpenGLES的顶点数据缓存
重点理解 glBufferData()和 glVertexAttribPointer()两个函数。
当调用过glBufferData()函数过后,glVertexAttribPointer()函数最后一个参数变成偏移量;
 
纹理的概念
 
坐标系:纹理坐标系、世界坐标系、屏幕坐标系
 
着色器:顶点着色器和片元着色器
 
光照
 
视图变换
 
 

posted on 2016-03-25 15:13  loying  阅读(2373)  评论(0编辑  收藏  举报

导航