2012-09-18 58 views
0

我的iOS 4應用程序使用OpenGL ES 2.0並呈現具有單一紋理的元素。我想繪製使用多種不同紋理的元素,並且遇到問題需要解決。如何使用OpenGL ES 2.0顯示多個單獨的紋理(不是多紋理)?

我加入到我的頂點着色器的變量,以指示要應用的質地:

... 
attribute float TextureIn; 
varying float TextureOut; 

void main(void) 
{ 
    ... 
    TextureOut = TextureIn; 
} 

我使用該值在片段着色器來選擇質地:

... 
varying lowp float TextureOut; 

uniform sampler2D Texture0; 
uniform sampler2D Texture1; 

void main(void) 
{ 
    if (TextureOut == 1.0) 
    { 
     gl_FragColor = texture2D(Texture1, TexCoordOut); 
    } 
    else // 0 
    { 
     gl_FragColor = texture2D(Texture0, TexCoordOut); 
    } 
} 

編譯着色器:

... 
_texture = glGetAttribLocation(programHandle, "TextureIn"); 
glEnableVertexAttribArray(_texture); 
_textureUniform0 = glGetUniformLocation(programHandle, "Texture0"); 
_textureUniform1 = glGetUniformLocation(programHandle, "Texture1"); 

初始設定:

... 
GLuint _texture; 
GLuint _textureUniform0; 
GLuint _textureUniform1; 

... 
glActiveTexture(GL_TEXTURE0); 
glEnable(GL_TEXTURE_2D); // ? 
glBindTexture(GL_TEXTURE_2D, _textureUniform0); 
glUniform1i(_textureUniform0, 0); 

glActiveTexture(GL_TEXTURE1); 
glEnable(GL_TEXTURE_2D); // ? 
glBindTexture(GL_TEXTURE_2D, _textureUniform1); 
glUniform1i(_textureUniform1, 1); 

glActiveTexture(GL_TEXTURE0); 

渲染:

... 
glVertexAttribPointer(_texture, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 13));  

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, _textureUniform0); 
glUniform1i(_textureUniform0, 0); 

glActiveTexture(GL_TEXTURE1); 
glBindTexture(GL_TEXTURE_2D, _textureUniform1); 
glUniform1i(_textureUniform1, 1); 

glActiveTexture(GL_TEXTURE0); 

glDrawElements(GL_TRIANGLES, indicesCountA, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * 0)); 
glDrawElements(GL_TRIANGLES, indicesCountB, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * indicesCountA)); 
glDrawElements(GL_TRIANGLES, indicesCountC, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * (indicesCountA + indicesCountB))); 

我希望是動態應用與頂點相關聯的紋理,但它似乎只認GL_TEXTURE0。

我已經能夠改變紋理的是與每一個紋理GL_TEXTURE0,然後得出的唯一途徑:

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, _textureUniformX); 
glUniform1i(_textureUniformX, 0); 
glDrawElements(GL_TRIANGLES, indicesCountA, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * 0)); 
... 

爲了使所有的紋理,我需要一個單獨的glDrawElements()調用每個紋理,我已經讀過,glDrawElements()調用對性能影響很大,調用次數應該最小化。這就是爲什麼我試圖動態指定每個頂點使用哪個紋理。

這完全有可能是因爲我的理解錯誤或者我錯過了一些重要的東西。我還是OpenGL的新手,我越學越多,我覺得我有更多的學習。

必須可以使用除GL_TEXTURE0以外的紋理,但我還沒有弄清楚如何。

任何指導或方向將不勝感激。

回答

2

難道你只是遇到浮點舍入問題?不應該有任何(除非一個單獨的特權共享具有不同紋理的頂點),但只是爲了確保將這個TextureOut == 1.0替換爲TextureOut > 0.5或類似物。

作爲一般性建議,您應該儘可能減少繪製調用次數,但您的方法很奇怪。您正在使用片段着色器分支來購買繪圖調用。由於您始終需要使用單獨紋理單元中的所有紋理,因此您的方法也不能與整體紋理數量一致。

減少紋理切換的常用方法是將所有紋理放入單個大紋理中,即所謂的紋理圖集,然後使用紋理座標在此紋理中選擇適當的子區域。這也有一些陷阱(這是一個完全不同的問題),但沒有任何東西是免費的。

編輯:哦,等一下,我看到你實際上是做錯了什麼

glBindTexture(GL_TEXTURE_2D, _textureUniform0); 

要綁定一個紋理到當前紋理單元,但不是紋理對象,你給這個函數統一的位置,這是完全垃圾(但可能在奇怪的情況下工作,因爲統一的位置和紋理對象本身就是整數)。當然,你必須綁定實際的紋理。

+0

更改爲正確綁定紋理並檢查浮動範圍,但仍然存在問題。 只有7個紋理,我想把它作爲第一步。 最後,我想要選擇這7個紋理的各個區域,以擁有數十個或數百個不同的紋理。穿過紋理圖集的想法,並將其作爲我的下一步。 因爲無論如何我都希望看到紋理地圖集,也許我現在就走那條路。 感謝您的輸入。 – GRW

+0

發現如果我在片段着色器中指定一個值來選擇紋理,那麼該紋理會得到渲染: lowp float temp = 1.0; // TextureOut;如果((temp> 0.5)&&(temp <1.5))// 1 ...看起來是一個動態傳遞的TextureOut值的問題,所以我正在研究這個問題。 – GRW

+0

成功! 我發現了我忘記放在一行的代碼: vertex.Texture = [(NSNumber *)[vertexBucketAll objectAtIndex:(i + 13)] floatValue]; 如果我實際上沒有在我的頂點數組中設置紋理數據,我們不會取得太大進展。 解決方法,連同你的指針,讓我在駝峯。現在到下一個頭髮拉扯的困境,我想是紋理地圖集。 謝謝 – GRW