OpenGL ES 2.0多个着色器程序 - 纹理渲染不再起作用

时间:2011-04-21 12:19:17

标签: ios ipad opengl-es shader opengl-es-2.0

我的应用程序绘制了点精灵和标准四边形纹理的混合。直到最近,我才使用单个着色器程序 - 然而片段着色器中的一个分支(决定是否使用点精灵坐标/颜色)严重限制了渲染的性能。我的片段着色器最初看起来像这样:

precision highp float;

uniform sampler2D u_textureSprite;
uniform bool u_isSprite;

varying vec4 v_color;
varying vec2 v_textureCoord;

void main()
{    
    vec4 textureColor = texture2D(u_textureSprite, u_isSprite ? gl_PointCoord : v_textureCoord);  
    if (u_isSprite) {
        gl_FragColor = v_color * textureColor;
    }
    else {
        gl_FragColor = textureColor;
    }
}

在OpenGL ES编程指南中阅读Apple的建议使得使用多个着色器程序听起来很容易......只需正常创建另一个并在相关绘图代码之前调用glUseProgram()。但是,由于这样做,我无法使纹理渲染工作。两个新的片段着色器是:

pointSprite.fsh:

precision highp float;

uniform sampler2D s_textureSprite;

varying vec4 v_color;

void main()
{    
    vec4 textureColor = texture2D(s_textureSprite, gl_PointCoord);
    gl_FragColor = v_color * textureColor;
}

texture.fsh:

precision highp float;

uniform sampler2D s_texture;


varying vec2 v_textureCoord;

void main()

{    
    gl_FragColor = texture2D(s_texture, v_textureCoord);
}

我觉得很琐碎。如果我忽略所有绘制纹理的调用,我可以看到点精灵被渲染得很好。然而,纹理四边形只是呈现为纯灰色 - 顺便说一下,这种灰色颜色与任何glClearColor()颜色都不匹配,我相信它是从它试图渲染的纹理的某个点开始的颜色。

纹理渲染的一些示例代码如下:

- (void)drawTexture:(GLuint)texture {
    glUseProgram(programs[PROGRAM_TEXTURE]);


    glBindTexture(GL_TEXTURE_2D, texture);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjects[VBO_TEXTURE_VERTICES]);

    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(ISTextureData), (void*)offsetof(ISTextureData, vertex));
    glEnableVertexAttribArray(ATTRIB_VERTEX);
    glVertexAttribPointer(ATTRIB_TEXTURE_COORD, 2, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ISTextureData), (void*)offsetof(ISTextureData, textureCoord));
    glEnableVertexAttribArray(ATTRIB_TEXTURE_COORD);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexBufferObjects[VBO_TEXTURE_INDICIES]);
    glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
}

此代码在不处理多个着色器时有效。或者我是不小心,纹理片段着色器代码是错误的?

谢谢

修改

这是一段漫长而痛苦的时间,真正令人恼火的是,它不是代码问题,而是与项目目录的名称有关。

我的Xcode项目目录的名称如下:“ProjectName(current)”。这是我遇到麻烦的项目。我后来发现将此文件夹名称更改为任何不同的应用程序使应用程序工作,并正确呈现背景纹理。只是为了澄清 - 除了在OpenGL中渲染背景纹理之外,应用程序以前正常工作,并且在重命名项目文件夹之后一切正常。

为什么会出现这种情况?

2 个答案:

答案 0 :(得分:2)

在哪里为着色器设置纹理均匀度?您需要使用以下代码分配用于纹理均匀的相应纹理单元的编号:

glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, sphereDepthMappingTexture);
glUniform1i(sphereDepthPrecalculatedDepthTextureUniform, 2);

glUniform1i()中的第二个参数是从中提取纹理的纹理单元的数量。

默认情况下,此均匀值为0,对应于GL_TEXTURE0,这就是为什么它可能在第一个位置工作,但如果您将活动纹理单元切换到其他位置,则不再能够读取纹理你的着色器。

答案 1 :(得分:0)

奇怪的是,这与项目目录的名称有某种关系。我的Xcode项目目录是这样命名的:“ProjectName(current)”。这是我遇到麻烦的项目。将此文件夹名称更改为任何不同的应用程序使应用程序工作,并正确呈现背景纹理。很奇怪。