Skip to content Skip to sidebar Skip to footer

Can't Map Textures With Opengl Es On Real Devices

I've tried a simple program that dynamically generates a texture and map it to a quad using NDK. Everything is fine on an emulator but failed on real devices. Here is my code: pri

Solution 1:

White block means texturing is working but the textures haven't loaded properly.

If the actual mapping were a problem, you would see the textures but all the colours warped or messed up.

Check the actual values given by glGenTextures(). I found that when using openGL-es 1.x on later versions of android (2.2+) that glGenTextures() threw out some really random numbers rather than giving id's of 0,1,2,3 etc. It may be you have to manually supply your own ID's and not use glGenTextures()

Alternatively, check the pixel data is being correctly loaded from file. Blank white textures may appear if you have a filename wrong or file missing but have put in some error handling that allows the app to continue. And/or don't forget to refresh res folders or even clean the project when you add new textures

UPDATE:

This is how I did it:

publicclassTexture{

privateint textureId = -1;
// initialise to -1publicintgetTextureId(){
    return textureId;
}

publicvoidloadTexture(GL10 gl, Context context){

    String[] filenamesplit = filename.split("\\.");

    name = filenamesplit[filenamesplit.length-2];

    int[] textures = newint[1];
    //Generate one texture pointer...//GLES20.glGenTextures(1, textures, 0);             
    textures[0] = ((IridianGraphicsEngine)context).texturecount;
    ((IridianGraphicsEngine)context).texturecount++;

    //...and bind it to our array
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);

    //Create Nearest Filtered Texture
    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_LINEAR);

    //Different possible texture parameters, e.g. GLES20.GL_CLAMP_TO_EDGE
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);

    Bitmap bitmap = FileUtil.openBitmap(name, context);

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

    bitmap.recycle();   

    textureId = textures[0];

}
}

Then when drawing:

publicclassMesh{

private Texture texture;

publicvoiddraw(GL10 gl){

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    // Pass the vertex buffer in
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
                             vertices);

    int textureId = texture.getTextureId();

    if(textureID>=0){

        // Enable Textures
        gl.glEnable(GL10.GL_TEXTURE_2D);

        // Get specific texture.
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);

        // Use UV coordinates.
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        // Pass in texture coordinates          
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureCoordinates);

    } 

    // Pass in vertex normals
    gl.glNormalPointer(GL10.GL_FLOAT, 0, normals);

    gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

    gl.glDrawElements(GL10.GL_TRIANGLES, numindices,GL10.GL_UNSIGNED_SHORT, indices);

    gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

    if(textureID>=0){
        // Disable buffers          
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }

    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

}

This however is all in java and uses a weird mix of opengl-es 2.0 for texture loading and opengl-es 1.1 for drawing

Solution 2:

I moved my JNI native methods to a separate wrapper class, similar to gl2-jni example in Android NDK, then the problem solved. I don't know why implementing static native code in a wrapper class makes differences, but anyway, it works.

GLJNILib.java

// Wrapper for native librarypublicclassGLJNILib {

     static {
         System.loadLibrary("gljni");
     }

    /**
     * @param width the current view width
     * @param height the current view height
     */publicstaticnativevoidinit(int width, int height);
     publicstaticnativevoidstep();
}

GLJNIView.java

// some other stuffprivateclassRendererimplementsGLSurfaceView.Renderer {
    privatestaticfinalStringTAG="Renderer";
    publicvoidonDrawFrame(GL10 gl) {
        GLJNILib.step();
    }

    publicvoidonSurfaceChanged(GL10 gl, int width, int height) {
        GLJNILib.init(width, height);
    }

    publicvoidonSurfaceCreated(GL10 gl, EGLConfig config) {
        // Do nothing.
    }
}

// some other stuff

Post a Comment for "Can't Map Textures With Opengl Es On Real Devices"