/* 初始化上下文并设置当前上下文
* EAGLContext 是苹果iOS平台下实现OpenGLES 渲染层
* kEAGLRenderingAPIOpenGLES1 = 1, 固定管线
* kEAGLRenderingAPIOpenGLES2 = 2,
* kEAGLRenderingAPIOpenGLES3 = 3,
*/
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
// 判断是否创建成功
if (!context) {
NSLog(@"Creat failed");
}
// 设置上下文
[EAGLContext setCurrentContext:context];
// 设置上下文
[EAGLContext setCurrentContext:context];
// 获取GLKView 设置context
GLKView *view = (GLKView *)self.view;
view.context = context;
// 配置视图创建的渲染缓存区
view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
/* 设置顶点数组(顶点坐标,纹理坐标)
* 纹理坐标系取值范围[0,1];原点是左下角(0,0);
* 故(0,0)是纹理图像的左下角, 点(1,1)是右上角
* 一个正方体有六个面,因此需要六个面,每个面两个三角形,每一行前三个为顶点的坐标,后两个值为纹理坐标
*/
GLfloat vertexData[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
/* 顶点数组:可以选择设定函数指针,在调用绘制方法的时候,直接由内存传入顶点数据
* 也就是说这部分数据之前是存储在内存当中的,被称为顶点数组
*
* 顶点缓存区: 性能更高的做法是,提前分配一块显存,将顶点数据预先传入到显存当中
* 这部分的显存,就被称为顶点缓冲区
*/
// 开辟顶点缓存区
GLuint bufferID;
// 创建顶点缓存区标识符ID
glGenBuffers(1, &bufferID);
// 绑定顶点缓存区
glBindBuffer(GL_ARRAY_BUFFER, bufferID);
// 将顶点数组的数据copy到顶点缓存区中(GPU显存中)
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
/* glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
* 功能:上传顶点数据到显存的方法(设置合适的方式从buffer里面读取数据)
* index:指定要修改的顶点属性的索引值
* size:每次读取数量(如position是由3个(x,y,z)组成,而颜色是4个(r,g,b,a),纹理则是2个)
* type:指定数组中每个组件的数据类型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值为GL_FLOAT。
* normalized:指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)
* stride:指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0
* ptr:指定一个指针,指向数组中第一个顶点属性的第一个组件。初始值为0
*/
// 顶点坐标数据
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);
// 获取纹理图片路径
NSString *name = [[NSBundle mainBundle] pathForResource:@"祎祎美女" ofType:@"jpg"];
// 设置纹理参数:纹理坐标原点是左下角,但是图片显示原点应该是左上角
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:name options:options error:nil];
// 使用苹果GLKit 提供GLKBaseEffect 完成着色器工作(顶点/片元)
effect = [[GLKBaseEffect alloc] init];
effect.texture2d0.enabled = GL_TRUE;
effect.texture2d0.name = textureInfo.name;
// 透视投影矩阵
CGFloat aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0), aspect, 0.1, 100.0);
effect.transform.projectionMatrix = projectionMatrix;
// 向后(屏幕里面)平移4.0
GLKMatrix4 modelviewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0, 0, -4.0);
effect.transform.modelviewMatrix = modelviewMatrix;
/* 绘制视图的内容
* GLKView对象使其OpenGL ES上下文成为当前上下文,并将其framebuffer绑定为OpenGL ES呈现命令的目标,然后委托方法应该绘制视图的内容
*/
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_angle = (_angle + 2) % 360;
GLKMatrix4 modelviewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0, 0, -4.0);
modelviewMatrix = GLKMatrix4Rotate(modelviewMatrix, GLKMathDegreesToRadians(_angle), 0.3, 0.5, 0.7);
effect.transform.modelviewMatrix = modelviewMatrix;
[effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 48);
}
OpenGL ES之渲染旋转的立方体并展示图片
OpenGL ES之CubeImage