ios - 在多个 OpenGL-ES 上下文之间共享一个 glProgram?

标签 ios opengl-es opengl-es-2.0 shader

我有一个带有多个 OpenGL-ES View 的 iPad 应用程序,这些 View 使用 OpenGL ES 2.0 和一个自定义片段着色器。目前,着色器会针对每个单独的 OpenGL View 进行编译和链接。我想编译和链接一次着色器,并为每个 View 重新使用它们。从理论上讲,这应该只是调用的问题
gluseProgram(gProgramHandle);
在我的 render() 方法中,在渲染之前,并加载一次 gProgramHandle,对吗?但这不起作用。当我切换到使用单个 gProgramHandle(在初始化时设置为 -1)时,只有一个 OpenGL View 有效,其他 View 显示为深绿色矩形。我究竟做错了什么?

- (void)loadShaders
{
   if (gProgramHandle == -1)
{
    NSLog(@"Compiling shaders...");

    GLuint vertexShader = [self compileShader:@"AIMGsiVertexShader" withType:GL_VERTEX_SHADER];
    GLuint fragmentShader = [self compileShader:@"AIMGsiFragmentShader" withType:GL_FRAGMENT_SHADER];

    gProgramHandle = glCreateProgram();
    glAttachShader(gProgramHandle, vertexShader);
    glAttachShader(gProgramHandle, fragmentShader);
    glLinkProgram(gProgramHandle);

    GLint linkSuccess;
    glGetProgramiv(gProgramHandle, GL_LINK_STATUS, &linkSuccess);
    if (linkSuccess == GL_FALSE)
    {
            // If there was an error when compiling the gsls shaders, report the compile error and quit.
        GLchar messages[256];
        glGetProgramInfoLog(gProgramHandle, sizeof(messages), 0, &messages[0]);
        NSString *messageString = [NSString stringWithUTF8String:messages];
        NSLog(@"%@", messageString);
        exit(1);
    }

    NSLog(@"Done compiling and linking shaders.");
}

    // We can efficiently switch between shaders by calling glUseProgram() to use the program with the shaders we want to use.
glUseProgram(gProgramHandle);

    // Gradient map values are sent in this vector: numValuesInCache, factor, offset
_gradientValsUniform = glGetUniformLocation(gProgramHandle, "GradientVals");
_numColorsInGradient = glGetUniformLocation(gProgramHandle, "NumColorsInCache");
_gradientColorsArray = glGetUniformLocation(gProgramHandle, "ColorsArray");


_positionSlot = glGetAttribLocation(gProgramHandle, "Position");

glEnableVertexAttribArray(_positionSlot);

_projectionUniform = glGetUniformLocation(gProgramHandle, "Projection");
_modelViewUniform = glGetUniformLocation(gProgramHandle, "Modelview");

_texCoordSlot = glGetAttribLocation(gProgramHandle, "TexCoordIn");
glEnableVertexAttribArray(_texCoordSlot);
_textureUniform = glGetUniformLocation(gProgramHandle, "Texture");

}

最佳答案

这里引用自 EAGLSharegroup Class Reference关于分享:

Currently, the sharegroup manages textures, buffers, framebuffers, and renderbuffers.


如您所见,未提及着色器/程序/管道。
然而这里引用自 Apple dev forum :

It is legal to share Shaders/Programs/Pipelines, but actually using the same Program at the same time is something to be avoided.

The problem is that Uniform values are properties of the Program itself, and so if you're using the same program from multiple threads that will violate the rules against modifying an object from one thread while using it from another.

If the usage does not overlap (one context produces programs, another renders, for example), that should work out fine.


为了测试着色器和管道的共享,我为 iPad 开发了一个简单的项目:https://github.com/Gubarev/shared-shaders-test .我可以确认共享有效!

关于ios - 在多个 OpenGL-ES 上下文之间共享一个 glProgram?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13574140/

相关文章:

opengl-es - 如何在左轴和右轴之间转换opengl投影矩阵?

ios - 来自不透明的地址簿(_ :) in Swift 3

c++ - 为设备编译 Boost 1.54 XCode5 - fatal error : error in backend: symbol '___umodsi3' can not be undefined in a subtraction expression

ios 8 opengl es 1.1 停产了吗?

swift - 用于更改顶点数据的缓冲区对象和属性指针是什么样的

opengl-es - OpenGL ES 2.0 状态的 UML 图?

ios - cordova 3.0 插件 plist 配置

ios - 如何获取 objective-c 中文本字段的文本颜色?

opengl-es - eclipse中未定义的引用glBindVertexArrayOES、glGenVertexArraysOES、glDeleteVertexArraysOES

opengl - openGL中glFrustum的分解