首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Open GL ES,多个着色器

Open GL ES,多个着色器
EN

Stack Overflow用户
提问于 2013-03-07 08:04:13
回答 2查看 313关注 0票数 0

我很好奇在Open GL ES 2.0程序中是否可以有多个着色器。

这是我的着色器代码。但是,attributes和uniforms仅从rigid.vert和rigid.frag着色器检索变量:

代码语言:javascript
复制
- (BOOL)loadShaders
{
GLuint rigidVertShader, rigidFragShader, skinningVertShader, skinningFragShader;
NSString *rigidVertShaderPathname, *rigidFragShaderPathname, *skinningVertShaderPathname, *skinningFragShaderPathname;

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

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

// Create and compile rigid fragment shader.
rigidFragShaderPathname = [[NSBundle mainBundle] pathForResource:@"rigid" ofType:@"frag"];
if (![self compileShader:&rigidFragShader type:GL_FRAGMENT_SHADER file:rigidFragShaderPathname]) {
    NSLog(@"Failed to compile rigid fragment shader");
    return NO;
}

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

// Create and compile skinning fragment shader.
skinningFragShaderPathname = [[NSBundle mainBundle] pathForResource:@"skinning" ofType:@"frag"];
if (![self compileShader:&skinningFragShader type:GL_FRAGMENT_SHADER file:skinningFragShaderPathname]) {
    NSLog(@"Failed to compile skinning fragment shader");
    return NO;
}

// Attach rigid vertex shader to program.
glAttachShader(_program, rigidVertShader);

// Attach rigid fragment shader to program.
glAttachShader(_program, rigidFragShader);

// Attach skinning vertex shader to program.
glAttachShader(_program, skinningVertShader);

// Attach skinning fragment shader to program.
glAttachShader(_program, skinningFragShader);

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

    if (rigidVertShader) {
        glDeleteShader(rigidVertShader);
        rigidVertShader = 0;
    }
    if (rigidFragShader) {
        glDeleteShader(rigidFragShader);
        rigidFragShader = 0;
    }
    if (skinningVertShader) {
        glDeleteShader(skinningVertShader);
        skinningVertShader = 0;
    }
    if (skinningFragShader) {
        glDeleteShader(skinningFragShader);
        skinningFragShader = 0;
    }
    if (_program) {
        glDeleteProgram(_program);
        _program = 0;
    }

    return NO;
}

// GET UNIFORM LOCATIONS
// Dictionary to store each active uniform
NSMutableDictionary *m_uniforms = [[NSMutableDictionary alloc] init];
int m_nUniforms = -1;
glGetProgramiv( _program, GL_ACTIVE_UNIFORMS, &m_nUniforms );

for(GLuint i = 0; i < m_nUniforms; i++)  {
    int name_len=-1, num=-1;
    GLenum type = GL_ZERO;
    char uniformName[100];

    glGetActiveUniform( _program, i, sizeof(uniformName)-1, &name_len, &num, &type, uniformName );

    uniformName[name_len] = 0;

    GLuint uniform = glGetUniformLocation( _program, uniformName );

    [m_uniforms setObject:[NSNumber numberWithUnsignedInt:uniform]
                   forKey:[NSString stringWithUTF8String:uniformName]];    
}

// GET ATTRIBUTE LOCATIONS
// Dictionary to store each active attribute
NSMutableDictionary *m_attributes = [[NSMutableDictionary alloc] init];
int m_nAttributes = -1;
glGetProgramiv( _program, GL_ACTIVE_ATTRIBUTES, &m_nAttributes );

for(GLuint i = 0; i < m_nAttributes; i++)  {
    int name_len=-1, num=-1;
    GLenum type = GL_ZERO;
    char attributesName[100];

    glGetActiveAttrib( _program, i, sizeof(attributesName)-1, &name_len, &num, &type, attributesName );

    attributesName[name_len] = 0;

    GLuint attributes = glGetAttribLocation( _program, attributesName );

    [m_attributes setObject:[NSNumber numberWithUnsignedInt:attributes]
                     forKey:[NSString stringWithUTF8String:attributesName]];
}


// Release vertex and fragment shaders.
if (rigidVertShader) {
    glDetachShader(_program, rigidVertShader);
    glDeleteShader(rigidVertShader);
}
if (rigidFragShader) {
    glDetachShader(_program, rigidFragShader);
    glDeleteShader(rigidFragShader);
}
if (skinningVertShader) {
    glDetachShader(_program, skinningVertShader);
    glDeleteShader(skinningVertShader);
}
if (skinningFragShader) {
    glDetachShader(_program, skinningFragShader);
    glDeleteShader(skinningFragShader);
}

return YES;
}
EN

回答 2

Stack Overflow用户

发布于 2013-03-07 08:17:06

OpenGL ES不允许在程序unlike "desktop" OpenGL中使用同一类型的多个着色器(但它只允许声明公共函数/变量,因此它与连接着色器源代码大致相同)。从glAttachShader() spec

同一类型的多个着色器对象不能附加到单个程序对象。

..。

错误

...如果着色器已附加到程序,或者与着色器类型相同的另一个着色器对象已附加到程序,则会生成GL_INVALID_OPERATION

我强烈怀疑对glAttachShader()的第三次和第四次调用设置了GL_INVALID_OPERATION

检查你的错误!我在循环中调用glGetError(),直到它返回GL_NO_ERROR

票数 2
EN

Stack Overflow用户

发布于 2013-03-07 08:13:36

在OpenGL ES中,每个着色器程序只能使用一个片段和一个顶点着色器。否则它就不会起作用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15260656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档