Ios 编译GLSL着色器会打断其他着色器

Ios 编译GLSL着色器会打断其他着色器,ios,ipad,opengl-es-2.0,glsles,Ios,Ipad,Opengl Es 2.0,Glsles,在我在iPad模拟器上运行的iOS项目中,我有3个着色器程序,每个程序使用相似但不完全相同的属性和制服集。前两个着色器完美地编译和工作在一起,在编译或绘制过程中的任何时候都没有gl错误。我现在需要添加第三个着色器,这导致了一个问题:现在,其他两个着色器都不绘制任何内容,当我尝试使用glUniform传递一致性时,glGetError返回1282(GL_INVALID_操作)。glGetError在调用glUniform之前返回0行 我相信在我尝试调用glUniform之前,我已经将程序设置为正确

在我在iPad模拟器上运行的iOS项目中,我有3个着色器程序,每个程序使用相似但不完全相同的属性和制服集。前两个着色器完美地编译和工作在一起,在编译或绘制过程中的任何时候都没有gl错误。我现在需要添加第三个着色器,这导致了一个问题:现在,其他两个着色器都不绘制任何内容,当我尝试使用glUniform传递一致性时,glGetError返回1282(GL_INVALID_操作)。glGetError在调用glUniform之前返回0行

我相信在我尝试调用glUniform之前,我已经将程序设置为正确的,因为当我在通过制服之前使用GL_CURRENT_程序调用glGetIntegerv时,它与我尝试使用的程序的GL名称匹配(我调用glUseProgram时使用的程序是我想在问题GluseForm调用的方法开始时使用的程序).glGetError在编译问题着色器之前和之后返回0。编译代码是从Apple的一个示例项目中稍微修改的,我看不到任何内容会影响其他着色器的状态

- (BOOL)loadGLProgramWithVertexShader: (NSString*) vertexShaderName fragmentShader:    (NSString*) fragementShaderName
{
GLuint vertShader, normFragShader;
NSString *vertShaderPathname, *normFragShaderPathName;

// Create shader program.
shaderProgram = glCreateProgram();

// Create and compile vertex shader.
vertShaderPathname = [[NSBundle mainBundle] pathForResource: vertexShaderName ofType:@"vsh"];
if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
    NSLog(@"Failed to compile vertex shader");
    return NO;
}


// Create and compile normal mapping fragment shader.
normFragShaderPathName = [[NSBundle mainBundle] pathForResource: fragementShaderName ofType:@"fsh"];
if (![self compileShader:&normFragShader type:GL_FRAGMENT_SHADER file:normFragShaderPathName]) {
    NSLog(@"Failed to compile fragment shader");
    return NO;
}

// Attach vertex shader to program.
glAttachShader(shaderProgram, vertShader);

// Attach fragment shader to program.
glAttachShader(shaderProgram, normFragShader);

// Bind attribute locations.
// This needs to be done prior to linking.
glBindAttribLocation(shaderProgram, ATTRIB_VERTEX, "position");
glBindAttribLocation(shaderProgram, ATTRIB_TEXTURECOORD, "texCoord");

// Link program.
if (![self linkProgram:shaderProgram]) {
    NSLog(@"Failed to link program: %d", shaderProgram);

    if (vertShader) {
        glDeleteShader(vertShader);
        vertShader = 0;
    }

    if (normFragShader) {
        glDeleteShader(normFragShader);
        normFragShader = 0;
    }
    if (shaderProgram) {
        glDeleteProgram(shaderProgram);
        shaderProgram = 0;
    }

    return NO;
}

// Get uniform locations.
uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(shaderProgram, "modelViewProjectionMatrix");
uniforms[UNIFORM_TEXTURE] = glGetUniformLocation(shaderProgram, "texture");


// Release vertex and fragment shaders.
if (vertShader) {
    glDetachShader(shaderProgram, vertShader);
    glDeleteShader(vertShader);
}

if (normFragShader) {
    glDetachShader(shaderProgram, normFragShader);
    glDeleteShader(normFragShader);
}

return YES;
}

我找到了答案。在我的第三个着色器中,我有一个名为“texture”的sampler2D。在着色器中更改此名称并调用glGetUniformLocation修复了此问题。我不明白为什么,因为“texture”在GLSL中不是保留字,在任何其他统一中也没有其他用途(有一个“texcoord”)属性,但我怀疑这是否导致了问题),但它起了作用


编辑:我实际上在不久前找到了具体的原因——我一直在使用Apple的GLKit示例项目,该项目将着色器属性绑定到一个枚举,该枚举位于我使用的示例中,放置在视图控制器的@implementation之外,这意味着它的作用域在类的特定实例之外这个问题实际上有两个着色器,当第二个着色器被编译时,它删除了以前的绑定。真正的谜团是为什么我给出的第一个解决方案在第一个地方起作用…

我找到了答案。在我的第三个着色器中,我有一个取样器2D,名为“纹理”在着色器中更改此名称并调用glGetUniformLocation修复了问题。我不明白为什么,因为“texture”在GLSL中不是保留字,并且在任何其他统一中都没有该字的其他用途(有一个“texcoord”属性,但我怀疑这是否导致了问题),但它起到了作用

编辑:我实际上在不久前找到了具体的原因——我一直在使用Apple的GLKit示例项目,该项目将着色器属性绑定到一个枚举,该枚举位于我使用的示例中,放置在视图控制器的@implementation之外,这意味着它的作用域在类的特定实例之外如果这个问题实际上有两个着色器,当第二个着色器被编译时,它会删除以前的绑定。那么真正的谜团是为什么我给出的第一个解决方案在第一个地方起作用