我有一个模拟地球模型的 iPhone 应用程序!我想让它更逼真:有一个球体对象,以及夜边和日边纹理和着色器,但它不起作用!
我的 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;
}
如果我只使用其中一个着色器,它看起来不错,但不能协同工作!
最佳答案
要使 glUniform...
调用生效,必须绑定(bind)/使用有效的程序,即便如此,它也只会更改该特定程序的制服(由统一定位)。因此,您必须在相应的 glUseProgram
之后为每个程序调用 glUniform...
函数。
这就是它只适用于一个着色器程序的原因,因为您永远不会绑定(bind)任何其他程序。但这在概念上仍然是错误的,因为在这种情况下你依赖于一个已经绑定(bind)的特定程序,这总是错误的来源(比如添加第二个程序时),因为 OpenGL 是一个状态机.
另一方面,统一变量即使在其相应程序未绑定(bind)时仍保持其值(glUseProgram(0_or_any_other_program)
)。
关于iphone - OpenGL ES 2.0 中的地球日/夜侧着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10799661/