2012-11-26 34 views
0

我有一個使用OpenGL ES 2.0和自定義片段着色器的多個OpenGL-ES視圖的iPad應用程序。目前,着色器會針對每個單獨的OpenGL視圖進行編譯和鏈接。我想編譯和鏈接着色器一次,並重新使用它們的每個視圖。在理論上,這應該僅僅是調用在多個OpenGL-ES上下文中共享glProgram?

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"); 

} 

回答

3

您不能跨上下文共享程序。 GL上下文是狀態信息的集合,程序是該狀態的一部分。我會質疑每個觀點是否需要自己的背景,這可能不是必要的。如果在主線程上完成所有渲染,則在視圖之間共享上下文,並在每個視圖的每次繪製調用中設置所需的狀態。如果您在多個線程上渲染,請查看使用[[EAGLContext alloc] initWithAPI:... sharegroup:...]創建上下文,並從您的主要上下文中傳入共享組。

+0

太棒了,非常感謝你! –

+0

在OpenGL ES 2.0中共享着色器/程序/管道是合法的。 – Vlad

+0

你的意思是「分享」?在這種情況下,在上下文之間共享着色器/程序時,我發現很難看到這將是非法的,除非你有許可的着色器禁止它,這看起來很奇怪。 – combinatorial

1

下面是引自EAGLSharegroup Class Reference共享一下:

目前,sharegroup管理紋理緩衝器,幀緩存,和renderbuffers。

正如您所看到的着色器/程序/管道未提及。

但是這裏是引自Apple dev forum

是合法的分享着色器/程序/管道,但實際上使用相同的計劃,同時要避免的東西。

問題是統一值是程序本身的屬性,所以如果您從多個線程使用相同的程序,將違反從一個線程修改對象時使用另一個線程的規則。

如果用法不重疊(例如一個上下文產生程序,另一個上下文呈現),那麼應該可以正常工作。

爲了測試着色器和流水線的共享我爲iPad開發了簡單的項目:https://github.com/Gubarev/shared-shaders-test。我可以確認分享的作品!

相關問題