2

我有一个模拟地球的 iPhone 应用程序!我想让它变得逼真:有一个球体对象,以及 Nightside 和 Dayside 纹理和着色器,但它不起作用!

我的 Sphere 对象的绘制方法:

    -(bool)execute:(GLuint)texture;
 {    
    glBindTexture(GL_TEXTURE_2D, texture);
    glBindVertexArrayOES(m_VertexArrayName);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, m_NumVertices);
    glBindTexture(GL_TEXTURE_2D, 0);
    return true;
 }

我的 ViewController 调用方法:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

    glUseProgram(m_NightsideProgram);
    [m_Sphere setBlendMode:0];
    [m_Sphere execute:m_EarthNightTexture.name];

    glUseProgram(m_DaysideProgram);
    [m_Sphere setBlendMode:1];
    [m_Sphere execute:m_EarthDayTexture.name];

    glCullFace(GL_FRONT);
    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CW);

}

混合模式:0:glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR); 1: glBlendFunc(GL_ONE, GL_CONSTANT_COLOR); //常量是中间蓝色,为了让它更亮一点

夜间碎片着色器:

precision mediump float;

varying lowp vec4 colorVarying;
varying vec2 v_texCoord;

uniform sampler2D s_texture;


void main() {
    vec4 newColor;

    newColor=1.0-colorVarying;

    gl_FragColor = texture2D(s_texture, v_texCoord)*newColor;                    
}

DaySide 片段着色器:

precision mediump float;

varying lowp vec4 colorVarying;
varying lowp vec4 specularColorVarying;
varying vec2 v_texCoord;

uniform sampler2D s_texture;


void main() {
    vec4 finalSpecular=vec4(0,0,0,1);
    vec4 surfaceColor;
    float halfBlue;

    surfaceColor=texture2D(s_texture,v_texCoord);

    halfBlue=0.5*surfaceColor[2];

    if(halfBlue>1.0)
        halfBlue=1.0;

    if((surfaceColor[0]<halfBlue) && (surfaceColor[1]<halfBlue))
        finalSpecular=specularColorVarying;

    gl_FragColor = surfaceColor*colorVarying+colorVarying*finalSpecular;                    
}

如果我使用唯一的一个着色器,它看起来很好,但它不会一起工作!

4

1 回答 1

1

要使glUniform...调用生效,必须有一个有效的程序绑定/使用,即使那样它也只会更改该特定程序的统一的统一值(由统一位置标识)。所以你必须glUniform...各自的.glUseProgram

这就是为什么它只适用于一个着色器程序的原因,因为您永远不会绑定任何其他程序。但它在概念上仍然是错误的,因为在这种情况下,您依赖于已经绑定的特定程序,这始终是错误的来源(例如添加第二个程序时),因为OpenGL 是一个状态机

另一方面,统一变量即使在其对应的程序未绑定(glUseProgram(0_or_any_other_program))时也保持其值。

于 2012-05-29T13:20:13.820 回答