0
votes

SOLVED: Turns out, I was passing the OpenGL named texture to the shader instead of the active texture number, fixed it with:

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

UPDATE: glGetError() returns 0, after calling glTexImage2D(). So there are no OpenGL flagged errors...

I've been working on a game using OpenGL 2.0 for the rendering.

I've been testing it on my Samsung Galaxy Nexus, and haven't had any texturing errors. All of my textures are powers of 2, in a .png format, and stored in the No -DPI folder. All textures load, and render perfectly using or not using alpha.

I tried the game on the Samsung Galaxy S4 and a Droid Bionic, both of which resulted in black textures (with and without alpha blending).

I have scoured the internet for people with the same problem, but all of their fixes were already reflected in my code.

I'm thinking it must be something with the way I create the texture, or my OpenGL setup because why else would it only work on the Galaxy Nexus?

OpenGL Setup:

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

Texture Loading Code:

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

Other Texture Attempt (In replace of GLUtils.texImage2D and the bitmap):

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

Before rendering I call these:

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

Vertex Shader:

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;
}

And for the sake of solving the bug, I disabled blending because I know the alpha can often cause a headache aswell.

Both types of texturing (Using an image or using pixel data) works on my Galaxy Nexus, but not on the S4. I don't know if it's my texturing code that's broken, or some other OpenGL setting, but I'll try to post all relevant code.

1

1 Answers

0
votes

Turns out, I was passing the OpenGL named texture to the shader instead of the active texture number, fixed it with:

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

instead of:

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