OpenGL ES 是在OpenGL的简化版,是苹果提供了一个既易于学习又更易于在移动图形硬件中实现的库。
OpenGL ES中没有定义窗口,在iOS中使用GLKView来呈现OpenGL ES的内容,使用GLKViewController来管理视图。
以下一个简单的例子显示一张图片(Swift语言编写)。
首先引进GLKit框架
import GLKit
把storyboard中的viewController的view改为GLKView。然后让ViewController继承GLKViewController。
在ViewController中创建一个EAGLContext
lazy var context:EAGLContext? = {
guard let cont = EAGLContext(api: .openGLES3) else{return nil}
return cont
}()
一、设置GLKView
把创建出来的上下文(context)赋值给GLKView,设置颜色缓冲区和深度缓冲区的方式,
guard let context = self.context else {
return
}
myView.context = context
myView.drawableColorFormat = .RGBA8888//设置颜色缓冲区
myView.drawableDepthFormat = .format24//设置深度缓冲区
EAGLContext.setCurrent(context)
glEnable(GLenum(GL_DEPTH_TEST))//开启深度测试
glClearColor(0.1, 0.2, 0.3, 0.1)//初始化背景颜色
二、设置定点数据
var vertexData:[GLfloat] = [0.5,-0.5,0.0,1.0,0.0,
0.5,0.5,-0.0,1.0,1.0,
-0.5,0.5,0.0,0.0,1.0,
0.5,-0.5,0.0,1.0,0.0,
-0.5,0.5,0.0,0.0,1.0,
-0.5,-0.5,0.0,0.0,0.0]
在OpenGL ES世界坐标系的范围是[-1,1] ,第一行数据定点左边代表x,y,z 和2个纹理坐标。纹理坐标取值是[0,1]。
初始化一个缓冲区标识符
var buffer:GLuint = 0
glGenBuffers(1, &buffer)
然后绑定标识符,在把数据冲cpu中拷贝到gpu中
glBindBuffer(GLenum(GL_ARRAY_BUFFER), buffer)
glBufferData(GLenum(GL_ARRAY_BUFFER), MemoryLayout.size*vertexData.count, &vertexData, GLenum(GL_STATIC_DRAW))
让定点着色器允许读取GPU上的数据,然后设置定点数据。
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.position.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.position.rawValue), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout.stride*5), nil)
设置纹理数据
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.texCoord0.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout.stride*5), UnsafeMutableRawPointer(bitPattern: 3*MemoryLayout.stride))
其中glVertexAttribPointer函数。
参数一:定点数据类型(GLKVertexAttrib是一个枚举)
参数二:定点数据每个数据的组成个数(例如position是由3个(x,y,z)组成,而颜色是4个(r,g,b,a))
参数三:数据的组成类型
参数四:数据是否归一化
参数五:数据的步长
参数六:数据的偏移量(UnsafeRawPointer)传nil 代表从头开始。
三、加载纹理数据
初始化固定管线
var mEffect:GLKBaseEffect = GLKBaseEffect()
加载图片
guard let path = Bundle.main.path(forResource: "yejing", ofType: "jpg"),
let textureInfo = try? GLKTextureLoader.texture(withContentsOfFile: path, options: [GLKTextureLoaderOriginBottomLeft:NSNumber.init(integerLiteral: 1)] ) else {
return
}
mEffect.texture2d0.enabled = GLboolean(GL_TRUE)
mEffect.texture2d0.name = textureInfo.name
在func glkView(_ view: GLKView, drawIn rect: CGRect)方法中画图像
glClearColor(0.3, 0.6, 1.0, 1.0)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT))
mEffect.prepareToDraw()
glDrawArrays(GLenum(GL_TRIANGLES), 0, 6)
官方文档
demo