Ver*_*sen 4 shader opengl-es ios opengl-es-2.0
我有一个带有多个 OpenGL-ES 视图的 iPad 应用程序,这些视图使用 OpenGL ES 2.0 和一个自定义片段着色器。目前,着色器会针对每个单独的 OpenGL 视图进行编译和链接。我想编译和链接一次着色器,并为每个视图重新使用它们。从理论上讲,这应该只是调用的问题
gluseProgram(gProgramHandle);
在我的 render() 方法中,在渲染之前,并加载 gProgramHandle 一次,对吗?但这不起作用。当我切换到使用单个 gProgramHandle(在初始化时设置为 -1)时,只有一个 OpenGL 视图有效,其他视图显示为深绿色矩形。我究竟做错了什么?
- (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");
}
Run Code Online (Sandbox Code Playgroud)
以下是来自EAGLSharegroup Class Reference关于共享的引用:
目前,共享组管理纹理、缓冲区、帧缓冲区和渲染缓冲区。
如您所见,未提及着色器/程序/管道。
然而,这里引用了Apple 开发论坛的内容:
共享着色器/程序/管道是合法的,但实际上同时使用相同的程序是需要避免的。
问题是 Uniform 值是程序本身的属性,因此如果您从多个线程使用同一个程序,这将违反禁止从一个线程修改对象而从另一个线程使用它的规则。
如果用法不重叠(例如,一个上下文生成程序,另一个呈现),那应该可以正常工作。
为了测试着色器和管道的共享,我为 iPad 开发了一个简单的项目:https : //github.com/Gubarev/shared-shaders-test。我可以确认共享有效!
您无法跨上下文共享程序。GL 上下文是状态信息的集合,程序是该状态的一部分。我会质疑是否每个视图都需要自己的上下文,这很可能不需要。如果您在主线程上完成所有渲染,则在视图之间共享上下文,并在每个视图的每次绘制调用中设置所需的状态。如果您在多个线程上进行渲染,请查看[[EAGLContext alloc] initWithAPI:... sharegroup:...]
使用主上下文创建上下文并传入共享组。
归档时间: |
|
查看次数: |
2877 次 |
最近记录: |