如何修改默认的iOS OpenGL ES 2.0模板以显示纹理?

时间:2011-10-24 02:02:28

标签: ios opengl-es textures opengl-es-2.0

我正在尝试学习一些用于iPhone开发的基本OpenGL ES,我有一项任务我无法开始工作。

我似乎无法更改默认的OpenGL ES模板,以在弹跳方块上显示纹理,而不是默认的彩虹效果。我正在尝试为这个方块使用纹理,但到目前为止,方块只显示黑色。在这个简单的情况下,我可能做错了什么,如何修改基本模板代码以显示我的纹理?

1 个答案:

答案 0 :(得分:2)

作为旁注,默认的OpenGL ES模板似乎已经针对iOS 5.0 SDK进行了更改,现在使用GLKit绘制旋转立方体,因此我无法创建基于原始彩虹方块的简单测试项目一直在使用。

相反,您可能希望查看我为此课程准备的sample application。它是一个相当精简的应用程序,在旋转立方体的面上显示纹理。我在video for that class on iTunes U中详细描述了它的工作原理。

此示例应用程序使用Apple的PVRTexture类(来自其他一个示例应用程序)加载PVRTC压缩的纹理文件(比普通图像更高的内存效率)。设置纹理的核心代码是:

glGenTextures(1, &_name);
glBindTexture(GL_TEXTURE_2D, _name);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glCompressedTexImage2D(GL_TEXTURE_2D, i, _internalFormat, width, height, 0, [data length], [data bytes]);

其中_name是您稍后用于绑定该纹理的标识符。如果使用正常的未压缩纹理,则使用glTexImage2D()而不是最后一个函数。

然后,您可以启用纹理:

glEnable(GL_TEXTURE_2D);

并使用您在创建纹理时获得的标识符绑定要显示的纹理:

glBindTexture(GL_TEXTURE_2D, pvrTexture.name);

默认情况下,此纹理绑定到纹理单元0,但您可以使用glActiveTexture(GL_TEXTURE1)等切换到另一个单元。

然后,您需要将此纹理作为制服传递到着色器程序,第二个参数是纹理绑定到的纹理单元:

glUniform1i(uniforms[UNIFORM_TEXTURE], 0);

您还需要顶点的相应纹理位置,以便纹理以正确的方式映射到曲面上:

const GLfloat cubeTexCoords[] = {
    1.0, 0.0,
    0.0, 0.0,
    1.0, 1.0,
    0.0, 1.0,
    0.0, 0.0,
    1.0, 0.0,
    0.0, 1.0,
    1.0, 1.0,
    1.0, 1.0,
    0.0, 1.0,
    0.0, 0.0,
    1.0, 0.0,
    0.0, 1.0,
    1.0, 1.0,
};

这些坐标将作为属性输入到着色器程序中:

glVertexAttribPointer(ATTRIB_TEXTUREPOSITION, 2, GL_FLOAT, 0, 0, cubeTexCoords);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITION);

你的着色器程序需要能够接受纹理均匀及其坐标,所以在顶点着色器中你会看到这样的东西:

attribute vec4 position;
attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

uniform mat4 modelViewProjMatrix;

void main()
{
    gl_Position = modelViewProjMatrix * position;
    textureCoordinate = inputTextureCoordinate.xy;
}

这是匹配的片段着色器:

varying highp vec2 textureCoordinate;

uniform sampler2D texture;

void main()
{
    gl_FragColor = texture2D(texture, textureCoordinate);
}

您可以看到着色器程序如何获取纹理坐标并将它们传递到片段着色器,在该着色器中对纹理进行采样并用于在该片段处生成最终颜色。

编译此着色器时,您需要匹配属性和制服,但OpenGL ES 2.0模板应显示如何执行此操作。

虽然我没有提供在OpenGL ES 2.0模板上启用纹理显示的确切代码,但您应该能够使用上述内容作为基础来执行此操作。