Learn OpenGL 6-1. 进入 3D 世界, 画一个正方体

## 坐标系统

• 局部空间(Local Space，或者称为物体空间(Object Space))
• 世界空间(World Space)
• 观察空间(View Space，或者称为视觉空间(Eye Space))
• 裁剪空间(Clip Space)
• 屏幕空间(Screen Space)

## 定义顶点数组和索引数组

private let scale = GLfloat(UIScreen.main.bounds.width / UIScreen.main.bounds.height) // 屏幕缩放比例

// 顶点数组
private let vertices: [L6Vertex] = [

// Front
L6Vertex(position: (1, -scale, 1), color: (1, 0, 0, 1), texCoord: (1, 0)), // 0
L6Vertex(position: (1, scale, 1), color: (0, 1, 0, 1), texCoord: (1, 1)), // 0
L6Vertex(position: (-1, scale, 1), color: (0, 0, 1, 1), texCoord: (0, 1)), // 0
L6Vertex(position: (-1, -scale, 1), color: (0, 0, 0, 1), texCoord: (0, 0)), // 0

// Back
L6Vertex(position: (-1, -scale, -1), color: (1, 0, 0, 1), texCoord: (1, 0)), // 0
L6Vertex(position: (-1, scale, -1), color: (0, 1, 0, 1), texCoord: (1, 1)), // 1
L6Vertex(position: (1, scale, -1), color: (0, 0, 1, 1), texCoord: (0, 1)), // 2
L6Vertex(position: (1, -scale, -1), color: (0, 0, 0, 1), texCoord: (0, 0)), // 3

// Left
L6Vertex(position: (-1, -scale, 1), color: (1, 0, 0, 1), texCoord: (1, 0)), // 4
L6Vertex(position: (-1, scale, 1), color: (0, 1, 0, 1), texCoord: (1, 1)), // 5
L6Vertex(position: (-1, scale, -1), color: (0, 0, 1, 1), texCoord: (0, 1)), // 6
L6Vertex(position: (-1, -scale, -1), color: (0, 0, 0, 1), texCoord: (0, 0)), // 7

// Right
L6Vertex(position: (1, -scale, -1), color: (1, 0, 0, 1), texCoord: (1, 0)), // 8
L6Vertex(position: (1, scale, -1), color: (0, 1, 0, 1), texCoord: (1, 1)), // 9
L6Vertex(position: (1, scale, 1), color: (0, 0, 1, 1), texCoord: (0, 1)), // 10
L6Vertex(position: (1, -scale, 1), color: (0, 0, 0, 1), texCoord: (0, 0)), // 11

// Top
L6Vertex(position: (1, scale, 1), color: (1, 0, 0, 1), texCoord: (1, 0)), // 12
L6Vertex(position: (1, scale, -1), color: (0, 1, 0, 1), texCoord: (1, 1)), // 13
L6Vertex(position: (-1, scale, -1), color: (0, 0, 1, 1), texCoord: (0, 1)), // 14
L6Vertex(position: (-1, scale, 1), color: (0, 0, 0, 1), texCoord: (0, 0)), // 15

// Bottom
L6Vertex(position: (1, -scale, -1), color: (1, 0, 0, 1), texCoord: (1, 0)), // 16
L6Vertex(position: (1, -scale, 1), color: (0, 1, 0, 1), texCoord: (1, 1)), // 17
L6Vertex(position: (-1, -scale, 1), color: (0, 0, 1, 1), texCoord: (0, 1)), // 18
L6Vertex(position: (-1, -scale, -1), color: (0, 0, 0, 1), texCoord: (0, 0)), // 19
]

// 索引数组
private let indices: [GLubyte] = [
// Front
0, 1, 2,
2, 3, 0,

// Back
4, 5, 6,
6, 7, 4,

// Left
8, 9, 10,
10, 11, 8,

// Right
12, 13, 14,
14, 15, 12,

// Top
16, 17, 18,
18, 19, 16,

// Bottom
20, 21, 22,
22, 23, 20
]

### 传入变换矩阵

override func glkView(_ view: GLKView, drawIn rect: CGRect) {

...

effect.prepareToDraw()

var modelMatrix = GLKMatrix4Rotate(GLKMatrix4Identity, radians, 0, 1, 0) // 沿 Y 轴旋转
modelMatrix = GLKMatrix4Scale(modelMatrix, 0.2, 0.2, 0.2)
effect.modelMatrix = modelMatrix // 缩小 0.2 倍

...

glDrawElements(
GLenum(GL_TRIANGLES),
GLsizei(indices.count),
GLenum(GL_UNSIGNED_BYTE),
nil
)
}

<p align="center">
<source id="mp4" src="https://images.xiaozhuanlan.com/photo/2019/d84ee8b16abe23282dfcf5de8ffb4afd.mov"></video>

override func glkView(_ view: GLKView, drawIn rect: CGRect) {

glEnable(GLenum(GL_CULL_FACE))
glEnable(GLenum(GL_DEPTH_TEST))
glClearColor(1, 1, 1, 1)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT) | GLbitfield
(GL_DEPTH_BUFFER_BIT))

...
}

## 小结

• 了解到不同的坐标系统，以及温故知新，画了一个正方体。