2013-12-20 108 views
0

解決:事實證明,我是路過命名紋理着色器,而不是活動紋理數OpenGL的,固定它:的Android的OpenGL ES 2.0 - 黑色紋理在某些設備上

GLES20.glUniform1i(sTextureHandle, 0); // 0 means GLES20.GL_TEXTURE0 

UPDATE : glGetError()在調用glTexImage2D()後返回0。所以沒有OpenGL標記的錯誤...

我一直在使用OpenGL 2.0進行渲染的遊戲。

我一直在我的三星Galaxy Nexus上測試它,並沒有任何紋理錯誤。我所有的紋理都是2的冪,格式爲.png,並存儲在No-DPI文件夾中。所有紋理加載,並完美使用或不使用alpha。

我嘗試過三星Galaxy S4和Droid仿生遊戲,兩者都導致黑色紋理(有和沒有alpha混合)。

我已經爲有相同問題的人搜索了互聯網,但他們的所有修復都已經反映在我的代碼中。

我在想它一定是用我創建紋理的方式,或者我的OpenGL設置,因爲爲什麼它只能在Galaxy Nexus上工作?

的OpenGL設置:

GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f); //Black Background 
GLES20.glClearDepthf(1.0f);      //Depth Buffer Setup 
GLES20.glEnable(GLES20.GL_DEPTH_TEST);   //Enables Depth Testing 
GLES20.glDepthFunc(GLES20.GL_LEQUAL);   //The Type Of Depth Testing To Do 
GLES20.glDisable(GLES20.GL_BLEND); 
Matrix.orthoM(sProjectionMatrix, 0, 0.0f, width, height, 0.0f, 0.0f, MAX_DEPTH); 
Matrix.setLookAtM(sViewMatrix, 0, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); 

// Get the texturing handles 
GLES20.glBindAttribLocation(sShaderProgram, 2, "a_tex_coords"); 
sTexCoordsHandle = GLES20.glGetAttribLocation(sShaderProgram, "a_tex_coords"); 
sTextureHandle = GLES20.glGetUniformLocation(sShaderProgram, "u_texture"); 
GLES20.glUseProgram(sShaderProgram); 

GLES20.glEnableVertexAttribArray(sPositionHandle); 
GLES20.glEnableVertexAttribArray(sColorHandle); 
GLES20.glEnableVertexAttribArray(sTexCoordsHandle); 

紋理加載代碼:

Bitmap bitmap = BitmapFactory.decodeStream(sGame.CONTEXT.getResources().openRawResource(R.drawable.circle)); 

LAST_TEXTURE_INDEX++; 
GLES20.glGenTextures(1, Texture.IDS, LAST_TEXTURE_INDEX); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, IDS[LAST_TEXTURE_INDEX]); 
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); 
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 
bitmap.recycle(); 

其它質地嘗試(在更換GLUtils.texImage2D和位圖):

int width = 128; 
int height = 128; 
ByteBuffer pixelBuffer = ByteBuffer.allocateDirect(width * height * 3).order(ByteOrder.nativeOrder()); 

for (int y = 0; y < height; y++) 
{ 
    for (int x = 0; x < width; x++) 
    { 
     pixelBuffer.put((byte) 0x00); 
     pixelBuffer.put((byte) 0xFF); 
     pixelBuffer.put((byte) 0xFF); 
    } 
} 

pixelBuffer.position(0); 
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, width, height, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, pixelBuffer); 

渲染我之前請撥打以下電話:

GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, sTextureIndex); 
GLES20.glUniform1i(sTextureHandle, sTextureIndex); 

頂點着色器:

attribute vec4 a_position; 
attribute vec4 a_color; 
attribute vec2 a_tex_coords; 
uniform mat4 u_model_view_projection; 
varying vec4 v_color; 
varying vec2 v_tex_coords; 

void main() { 
    v_color = a_color; 
    v_tex_coords = a_tex_coords; 
    gl_Position = u_model_view_projection * a_position; 
} 

片段着色器:

varying vec2 v_tex_coords; 
uniform sampler2D u_texture; 
void main() { 
    vec4 color = texture2D(u_texture, v_tex_coords); 
    gl_FragColor = color; 
} 

以及解決的bug的緣故,我禁用混合,因爲我知道阿爾法常可引起頭痛以及。

這兩種紋理類型(使用圖像或使用像素數據)都適用於我的Galaxy Nexus,但不適用於S4。我不知道這是我的紋理代碼是壞了還是其他的OpenGL設置,但我會盡量發佈所有相關的代碼。

回答

0

事實證明,我經過命名質感的OpenGL着色器,而不是活動紋理數量,固定它:

GLES20.glUniform1i(sTextureHandle, 0); // 0 means GLES20.GL_TEXTURE0 

代替:

GLES20.glUniform1i(sTextureHandle, sTextureIndex); // sTextureIndex = generated texture ID