已解决:原来,我将OpenGL命名纹理传递给着色器而不是活动纹理编号,修复它:
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 Bionic上的游戏,两者都产生了黑色纹理(有和没有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;
}
Fragment Shader:
varying vec2 v_tex_coords;
uniform sampler2D u_texture;
void main() {
vec4 color = texture2D(u_texture, v_tex_coords);
gl_FragColor = color;
}
为了解决这个问题,我禁用了混合,因为我知道alpha也经常引起头痛。
两种类型的纹理(使用图像或使用像素数据)都适用于我的Galaxy Nexus,但不适用于S4。我不知道这是我的纹理代码是否破碎,或者其他一些OpenGL设置,但我会尝试发布所有相关代码。
答案 0 :(得分:0)
原来,我将OpenGL命名纹理传递给着色器而不是活动纹理编号,修复它:
GLES20.glUniform1i(sTextureHandle, 0); // 0 means GLES20.GL_TEXTURE0
而不是:
GLES20.glUniform1i(sTextureHandle, sTextureIndex); // sTextureIndex = generated texture ID