2

地球をモデル化する iPhone アプリケーションがあります。現実的にしたいのですが、球体オブジェクトと、Nightside と Dayside のテクスチャとシェーダーがありますが、機能しません!

My Sphere オブジェクトの draw メソッド:

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

シェーダーの 1 つだけを使用すると、うまくいくように見えますが、一緒には機能しません。

4

1 に答える 1

1

呼び出しを有効にするには、有効なプログラムがバインド/使用されている必要があり、そのglUniform...場合でも、その特定のプログラムのユニフォーム (ユニフォームの場所によって識別される) のユニフォーム値のみを変更します。したがって、それぞれの のglUniform...に各プログラムの関数を呼び出す必要があります。glUseProgram

これが、他のプログラムをバインドしないため、1 つのシェーダー プログラムでのみ機能する理由です。ただし、 OpenGL はステート マシンであるため、この場合は既にバインドされている特定のプログラムに依存しているため、(2 番目のプログラムを追加する場合など) 常にエラーの原因となるため、概念的には間違っています。

一方、一様変数は、対応するプログラムがアンバインドされても値を保持します ( glUseProgram(0_or_any_other_program))。

于 2012-05-29T13:20:13.820 に答える