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

2021-08-09 11:17:57 浏览数 (1)

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

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

展示效果

  • 在本案例中增加了固定光源,让物体更加逼真。
1. 上下文创建

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

代码语言:javascript复制
    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个顶点。

代码语言:javascript复制
// 具体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));
  • 法线: 垂直于一个平面的向量,可以用于反射光线的计算。法线是通过计算两个向量的叉乘来得到。
  • 向量A X 向量B = (AyBz-AzBy,AxBz-AzBx,AxBy-AyBx)
3. 效果器创建、纹理图片加载
代码语言:javascript复制
    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);
  • baseEffect中可以支持3个默认光源。
4. CADisplayLink创建
代码语言:javascript复制
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. 代理
代码语言:javascript复制
- (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(销毁)
代码语言:javascript复制
- (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物体旋转

0 人点赞