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()函數最后一個參數變成偏移量;
 
紋理的概念
 
坐標系:紋理坐標系、世界坐標系、屏幕坐標系
 
着色器:頂點着色器和片元着色器
 
光照
 
視圖變換
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM