2012-05-29 51 views
2

我有一個iPhone應用程序,它模擬了Planet Earth!我想使它現實:有一個球體對象,Nightside和Dayside紋理和着色器,但它不起作用!OpneGL ES 2.0中的地球日/夜側着色器

我的球對象的繪製方法:

-(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); //常數是淡藍色,爲使其更輕有點

陰面fragmentshader:

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;      
} 

晝Fragmentshader:

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;      
} 

如果我使用着色器只有一個,它看起來很好,但它不會一起工作!

回答

1

要使glUniform...調用生效,必須有一個有效的程序綁定/使用,並且即使此時它也只會更改該特定程序統一的統一值(由統一位置標識)。所以你必須打電話給你glUniform...功能,每個程序各自glUseProgram

這就是爲什麼它只與一個着色器程序一起工作,因爲你永遠不會綁定任何其他程序。但是它在概念上仍然是錯誤的,因爲在這種情況下,您依賴於已經綁定的特定程序,這總是錯誤的來源(如添加第二個程序時),因爲OpenGL是一個狀態機

另一方面,即使其相應的程序未被綁定,統一變量也會保留其值(glUseProgram(0_or_any_other_program))。