您的位置:首页 > 电脑网络 > 电脑配件 > Apple's OpenGL--纹理基础

Apple's OpenGL--纹理基础

luyued 发布于 2011-02-06 03:06   浏览 N 次  

这是 CocoaChina 版主“zenny_chen” 撰写的 OpenGL 系列教程的最新一篇,主要介绍如何在 OpenGL Shading Language 中使用纹理贴图。

在 shader 中,与固定功能的纹理初始化有所不同的是,这里增加了 glActiveTexture 这一接口,用于指定使用哪个纹理单元。而去除了对 glTexEnv 这个函数接口的调用。下面,我们首先看在主机端如何初始化纹理:

initCheckImage();

GLuint texName;
glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_FLOAT, checkImage);

initCheckImage函数用于初始化纹理图像。然后我们指定GL_TEXTURE0即纹理单元0作为后续纹理操作对象。当前一般的GPU至少有8个纹理单元,比如iPod Touch3代上的PowerVR SGX GPU上就有8个。在OpenGL规范中指定,纹理单元至少要有2个。

我们看到这边的初始化与固定功能的差不多。下面我们来看一下增加的uniform和attribute变量:

// uniform index
enum{
UNIFORM_TRANSLATE,
UNIFORM_PROJECTION,
UNIFORM_DEGREE,
UNIFORM_SAMPLER,

NUM_UNIFORMS
};
GLint uniforms[NUM_UNIFORMS];

// attribute index
enum{
ATTRIB_VERTEX,
ATTRIB_COLOR,
ATTRIB_TEXCOORD,

NUM_ATTRIBUTES
};

这里我们增加了一个UNIFORM_SAMPLER的uniform变量,作为纹理采样器。还有一个ATTRIB_TEXCOORD这一varying变量为纹理坐标。
采样器被shader使用,通过当前的纹理坐标来获取纹理颜色值。下面是为uniform变量初始化,以及初始化attribute变量:

glUniformMatrix4fv(uniforms[UNIFORM_TRANSLATE], 1, GL_FALSE, translation);
glUniformMatrix4fv(uniforms[UNIFORM_PROJECTION], 1, GL_FALSE, projection);
glUniform1i(uniforms[UNIFORM_SAMPLER], 0); // Set the sampler value

// Update attribute values
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, 1, 0, squareColors);
glEnableVertexAttribArray(ATTRIB_COLOR);
glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, 0, 0, texCoords);
glEnableVertexAttribArray(ATTRIB_TEXCOORD);

这里要说明的是:glUniform1i(uniforms[UNIFORM_SAMPLER], 0);这个采样器的值是与前面所指定的纹理单元号对应的。由于我们前面使用GL_TEXTURE0,因此这里用0。如果这里写为0以外的其它值,那么图像将无法被显示出来。当然,如果我们用了纹理单元1,即GL_TEXTURE1,那么我们这里要使用glUniform1i(uniforms[UNIFORM_SAMPLER], 1)。

下面给出顶点着色器的代码:

attribute vec4 position;
attribute vec4 color;
attribute vec4 texCoords;
varying vec4 colorVarying;
uniform mat4 translate;
uniform mat4 projection;
uniform float degree;

void main()
{
float radian = radians(degree);

gl_Position = position;

colorVarying = color;

gl_TexCoord[0] = texCoords;
}

这里,gl_TexCoord是个GLSL内建的varying变量。这个变量起始是个数组,可用于多重纹理。我们这里只使用一个纹理,因此就用索引0。下面看一下片断着色器的代码:

varying vec4 colorVarying;

图文资讯
广告赞助商