OpenglES学习5-纹理

1. 什么是纹理 ?

OpenglES中纹理有两种类型:Textures in OpenGL ES 2.0 come in two forms: 2D textures and cube map textures.

2D纹理:A 2D texture is the most basic and common form of texture in OpenGL ES. A 2D texture is—as you might guess—a two-dimensional array of image data. The individual data elements of a texture are known as texels. A texel is a shortened way of describing a texture pixel.Textures are typically applied to a surface by using texture coordinates that can be thought of as indices into texture array data.When rendering with a 2D texture, a texture coordinate is used as an index into the texture image.
可以看点纹理就是一个二维的图片数据数组。通过纹理坐标获取每块纹理数据。纹理坐标系通过(s,t)或者(u,v)表示,并且纹理的左下角问坐标原点(0,0),右上角是为(1,1).
纹理图片的格式,有如下几种:

2. 如何使用纹理

The first step in the application of textures is to create a texture object. A texture object is a container object that holds the texture data that is needed for rendering such as image data, filtering modes, and wrap modes.

  • 首先要创建纹理对象,纹理对象是一个容器,可以保存图片数据,过滤模式,边界模式glGenTextures
  • 然后绑定刚才创建的纹理对象到一个纹理类型GL_TEXTURE_2D,绑定完成后,后续对这个纹理类型的操作都是对这个纹理对象。glBindTexture
  • 然后就是加载图片数据glTexImage2D

3. 看实例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
self.ctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:self.ctx];
//------ 1. 配置帧,渲染缓存 ---------
// 1.1 帧缓存
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
// 1.2 渲染缓存
glGenRenderbuffers(1, &colorRboId);
glBindRenderbuffer(GL_RENDERBUFFER, colorRboId);
[self.ctx renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
// 1.3 绑定渲染缓存
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRboId);
// 1.4 计算渲染宽高
GLint renderWidth = 0, renderHeight = 0;
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &renderWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &renderHeight);
//----- 2. 准备顶点和下标数据 -----
glGenBuffers(1, &vboId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
const GLvoid *data = NULL;
data = text2DSquare;
glBufferData(GL_ARRAY_BUFFER, sizeof(text2DSquare), text2DSquare, GL_STATIC_DRAW);
const GLvoid *indicts = NULL;
indicts = squareIndicts;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(squareIndicts), indicts, GL_STATIC_DRAW);
//------- 3. 设置shader program -------
GLuint vShaderId = [self addShader:GL_VERTEX_SHADER];
GLuint fShaderId = [self addShader:GL_FRAGMENT_SHADER];
programId = glCreateProgram();
glAttachShader(programId, vShaderId);
glAttachShader(programId, fShaderId);
glBindAttribLocation(programId, 0, "a_position");
glBindAttribLocation(programId, 1, "a_texCoord");
glLinkProgram(programId);
//------ 4.使用shader程序 ------
// 4.1 设置背景
glClearColor(0.3,0.3, 0.3, 1);
// 4.2 清理缓存
glClear(GL_COLOR_BUFFER_BIT);
// 4.3 设置视口
glViewport(0, 0, renderWidth, renderHeight);
// 4.4 使用shader 程序
glUseProgram(programId);
// 4.5 坐标转换 计算变换矩阵
GLuint modelViewLoc = glGetUniformLocation(programId, "u_modelViewMat4");
GLuint projectionLoc = glGetUniformLocation(programId, "u_projectionMat4");
VYTransforms *trans = self.currentTransforms;
trans.modelTransform = VYSTTransformSetPosition(trans.modelTransform, trans.PositionVec3Make(0,-0.5,-3));
trans.modelTransformMat4 = VYSTTransformMat4Make(trans.modelTransform);
trans.viewTransformMat4 = VYSTTransformMat4Make(trans.viewTransform);
trans.lookAtMat4 = VYLookAtMat4Make(trans.lookAt);
trans.perspectiveProjMat4 = VYPerspectivePerspectiveMat4Make(trans.perspectiveProj);
trans.baseCamera = VYCameraMake(trans.lookAtMat4, trans.perspectiveProjMat4);
trans.baseCameraMat4 = VYCameraMat4Make(trans.baseCamera);
trans.mvpTransfrom = VYMVPTransformMake(trans.modelTransformMat4, trans.viewTransformMat4, trans.baseCameraMat4);
// 4.6 给shader中uniform变量赋值
VYMVPTransform mvp = trans.mvpTransfrom;
glUniformMatrix4fv(modelViewLoc, 1, GL_FALSE, VYMVPTransformModelViewMat4Make(mvp).m);
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, mvp.cameraProjMat4.m);
// 4.7 给attribute变量赋值
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ZYVextex), (const GLvoid*)offsetof(ZYVextex, postion));
// GLfloat *d = text2DSquare;
// glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ZYVextex),d);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(ZYVextex), (const GLvoid *)offsetof(ZYVextex, texCoord));
// d = d + 3;
// glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(ZYVextex),d);
//------ 5. 创建texture -----
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
// 5.1给sample变量赋值
GLuint textureSourceLoc = glGetUniformLocation(programId, "us2d_texture");
glUniform1i(textureSourceLoc, 0);
// 5.2 加载纹理数据
[self p_loadTextureImg:@"512_512" completion:^(NSMutableData *data, size_t newWidth, size_t newHeight) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, newWidth, newHeight, GL_FALSE, GL_RGBA, GL_UNSIGNED_BYTE, data.bytes);
}];
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//----- 6.绘制------
glBindRenderbuffer(GL_RENDERBUFFER, colorRboId);
glDrawElements(GL_TRIANGLES, sizeof(indicts)/sizeof(indicts[0]), GL_UNSIGNED_BYTE, indicts);
// glDrawArrays(GL_TRIANGLES, 0, 4);
[self.ctx presentRenderbuffer:GL_RENDERBUFFER];

fragment shader 代码

1
2
3
4
5
6
uniform sampler2D us2d_texture;
varying highp vec2 v_texCoord;
void main(void){
gl_FragColor = texture2D(us2d_texture,v_texCoord);
}

GLuint textureSourceLoc = glGetUniformLocation(programId, "us2d_texture"); 是获取shader 采样参数的下标。
glUniform1i(textureSourceLoc, 0); 把采样参数绑定的0这个纹理单元。
glActiveTexture(GL_TEXTURE0); 表示激活0纹理单元。

OpenGL ES 2.0 (iOS)06-1:基础纹理 - 简书

文章目录
  1. 1. 1. 什么是纹理 ?
  2. 2. 2. 如何使用纹理
  3. 3. 3. 看实例代码
|