OpenGLES(三)- GLKit: 多边形纹理、旋转

2020-08-04  本文已影响0人  Henry________

OpenGLES(三)- GLKit: 多边形纹理、旋转

本文中会省略关于GLKit最基本的API的注释,如果需要详细注释可以看另一篇OpenGLES(二)- 纹理贴图

展示效果

1. 上下文创建

不同于上文中的GLKView的创建方式。使用这种initWithFrame方式可以不用依赖GLKViewController。

    content = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
    if(!content){return;}
    [EAGLContext setCurrentContext:content];
    
//GLKView创建
    glkView = [[GLKView alloc] initWithFrame:CGRectMake(0, 100, UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height) context:content];
//必须注册代理
    glkView.delegate = self;
    self.view = glkView;
    
    glkView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
    glkView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
    glClearColor(0.3, 0.1, 0.7, 1.0f);
    
//这里相当于翻转 z 轴,使正方形朝屏幕外
    glDepthRangef(1, 0);
/*
    //默认(0, 1)正方形朝屏幕内
    glDepthRangef(0, 1);
 */
2.顶点创建

正方形6个面,每个面由2个三角形组成,所以一共需要36个顶点。

// 具体36个点的信息就不放出来了
    vertexs = malloc(sizeof(HRVertex) * 36);
// 创建帧缓存区
    GLuint bufferId;
    glGenBuffers(1, &bufferId);
    glBindBuffer(GL_ARRAY_BUFFER, bufferId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(HRVertex) * 36, vertexs, GL_STATIC_DRAW);

//将顶点、纹理坐标、法线传入顶点着色器
  glEnableVertexAttribArray(GLKVertexAttribPosition);
  glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(HRVertex), NULL + offsetof(HRVertex, positionCoord));
    
  glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
  glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(HRVertex), NULL + offsetof(HRVertex, textureCoord));
    
  glEnableVertexAttribArray(GLKVertexAttribNormal);
  glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(HRVertex), NULL + offsetof(HRVertex, normal));
3. 效果器创建、纹理图片加载
    NSString *file = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"jpg"];
    UIImage *image = [UIImage imageWithContentsOfFile:file];
    NSDictionary *option = @{GLKTextureLoaderOriginBottomLeft: @(YES)};
    
    GLKTextureInfo *info = [GLKTextureLoader textureWithCGImage:[image CGImage] options:option error:nil];
    
    effect = [[GLKBaseEffect alloc] init];
    effect.texture2d0.enabled = YES;
    effect.texture2d0.name = info.name;
    effect.texture2d0.target = info.target;
    //创建光线
    effect.light0.enabled = YES;
    //反射光线颜色
    effect.light0.diffuseColor = GLKVector4Make(1, 1, 1, 1);
    //光源位置
    effect.light0.position = GLKVector4Make(-0.5, 0.5, 5, 1);
4. CADisplayLink创建
disLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];

[disLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

-(void)update{
    //1.计算旋转度数
    angle = (angle + 1) % 360;
    //2.修改baseEffect.transform.modelviewMatrix,完成旋转的视图变换
    effect.transform.modelviewMatrix = GLKMatrix4MakeRotation(GLKMathDegreesToRadians(angle), 0.3, 0.5, 0.7);
    //3.重新渲染
    [glkView display];
}
5. 代理
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    [effect prepareToDraw];
    
    glDrawArrays(GL_TRIANGLES, 0, 36);
}
6. dealloc(销毁)
- (void)dealloc
{
    //displayLink 失效
    [disLink invalidate];
    disLink = nil;
    
    //重置content
    if ([EAGLContext currentContext] == [(GLKView *)self.view context] ) {
        [EAGLContext setCurrentContext:nil];
    }
    
    //顶点数组重置
    if(vertexs){
        free(vertexs);
        vertexs = nil;
    }
}
demo地址: GLKit-002GLKit物体旋转
上一篇下一篇

猜你喜欢

热点阅读