[OpenGL ES] - GLKit绘制与动画
2018-05-05 本文已影响0人
coder_xiaoyu
1.配置OpenGL ES 上下文
// OpenGL ES版本
var context = EAGLContext.init(api: .openGLES3)
if context == nil {
context = EAGLContext.init(api: .openGLES2)
}
guard let ctx = context else {
return
}
EAGLContext.setCurrent(ctx) // 设置当前上下文
2.配置GLKView
let view = self.view as! GLKView
view.context = ctx
// 32位RGB颜色 (R+G+B+A)
view.drawableColorFormat = .RGBA8888
// 深度格式
view.drawableDepthFormat = .format24
3.准备数据(顶点,着色器,纹理)
// 1. 顶点数据
let vertices: [Vertex] = [
Vertex(Position: (-0.5, 0.5, 0.0), Color: (0.0, 0.0, 0.5, 1.0), TexCoord: (0.0, 1.0)), // 左上0
Vertex(Position: (0.5, 0.5, 0.0), Color: (0.0, 0.5, 0.0, 1.0), TexCoord: (1.0, 1.0)), // 右上1
Vertex(Position: (-0.5, -0.5, 0.0), Color: (0.5, 0.0, 1.0, 1.0), TexCoord: (0.0, 0.0)), // 左下2
Vertex(Position: (0.5, -0.5, 0.0), Color: (0.0, 0.0, 0.5, 1.0), TexCoord: (1.0, 0.0)), // 右下3
Vertex(Position: (0.0, 0.0, 1.0), Color: (1.0, 1.0, 1.0, 1.0), TexCoord: (0.5, 0.5)), // 顶点4
]
// 2. 索引
let indices:[GLubyte] = [
0, 3, 2,
0, 1, 3,
0, 2, 4,
0, 4, 1,
2, 3, 4,
1, 4, 3,
]
// 3.顶点个数
self.vCount = GLsizei(indices.count)
// glGenVertexArraysOES(1, &VAO)
// glBindVertexArrayOES(VAO)
// 4.将顶点数组放到缓冲区
glGenBuffers(GLsizei(1), &buffer)
glBindBuffer(GLenum(GL_ARRAY_BUFFER), buffer)
glBufferData(GLenum(GL_ARRAY_BUFFER), vertices.size(), vertices, GLenum(GL_STATIC_DRAW))
// 5.将索引放入缓冲区
glGenBuffers(GLsizei(1), &index)
glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), index)
glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), indices.size(), indices, GLenum(GL_STATIC_DRAW))
// 6.使用顶点数据
let positionSlotFirstComponent = UnsafePointer<Int>(bitPattern: 0)
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.position.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.position.rawValue), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<Vertex>.size), positionSlotFirstComponent)
// 7.颜色数据
let colorSlotFirstComponent = UnsafePointer<Int>(bitPattern: MemoryLayout<GLfloat>.size * 3)
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.color.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.color.rawValue), 4, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<Vertex>.size), colorSlotFirstComponent)
// 8.纹理数据
let texSlotFirstComponent = UnsafePointer<Int>(bitPattern: MemoryLayout<GLfloat>.size * 7)
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.texCoord0.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<Vertex>.size), texSlotFirstComponent)
// glBindVertexArrayOES(0)
// 9.获取纹理数据
guard let textureInfo = self.loadTexture("cTest.jpg") else { return }
// 10. 效果
self.effect.texture2d0.enabled = GLboolean(GL_TRUE)
self.effect.texture2d0.name = textureInfo.name
// 11.透视投影
let size = self.view.bounds.size
let aspect = fabs(size.width/size.height)
/*
参数1:视角
参数2:屏幕宽高比
参数3:距离近平面的距离
参数3:距离近平面的距离
*/
var projectionMatrix = GLKMatrix4MakePerspective(GLKMathRadiansToDegrees(90), Float(aspect), 0.1, 10.0)
projectionMatrix = GLKMatrix4Scale(projectionMatrix, 1, 1, 1)
self.effect.transform.projectionMatrix = projectionMatrix
let modelViewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0.0, 0.0, -2.0)
// modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, 0.4)
// modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, 0.6)
// modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, 0.9)
self.effect.transform.modelviewMatrix = modelViewMatrix
4.在代理中绘制
override func glkView(_ view: GLKView, drawIn rect: CGRect) {
// 清除缓冲
glClearColor(0.0, 0.0, 1.0, 1.0)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT))
glEnable(GLenum(GL_DEPTH_TEST))
// 准备绘制
self.effect.prepareToDraw()
// glBindVertexArrayOES(VAO)
// 索引绘制 参数1:图元类型。参数2:顶点个数。参数3:索引值类型。参数4:指向索引数组的指针.
glDrawElements(GLenum(GL_TRIANGLES), self.vCount, GLenum(GL_UNSIGNED_BYTE), nil)
// glBindVertexArrayOES(0)
}
5.GLKViewControllerDelegate代理中更新
func glkViewControllerUpdate(_ controller: GLKViewController) {
var modelViewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0.0, 0.0, -2.0)
modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, xDegree)
modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, yDegree)
modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, zDegree)
self.effect.transform.modelviewMatrix = modelViewMatrix
}
update_display_loop