2017-07-12 2 views
0

Je suis en difficulté avec Android, GL et Textures, j'ai un petit exemple et je veux charger deux textures différentes et les peindre à l'écran, mon problème est que dessine toujours la dernière texture chargé.Android GL Comment dessiner différentes textures

Je suis NOOB avec GL dans android et ai copié le code de quelques tutoriels.

Voici le code:

GLRenderer:

public class GLRenderer implements Renderer { 

    // Our matrices 
    private final float[] mtrxProjection = new float[16]; 
    private final float[] mtrxView = new float[16]; 
    private final float[] mtrxProjectionAndView = new float[16]; 

    // Our screenresolution 
    float mScreenWidth = 1280; 
    float mScreenHeight = 768; 

    // Misc 
    Context mContext; 
    long mLastTime; 
    int mProgram; 

    CardView card1; 
    CardView card2; 

    public GLRenderer(Context c) 
    { 
     mContext = c; 
     mLastTime = System.currentTimeMillis() + 100; 
    } 

    public void onPause() 
    { 
     /* Do stuff to pause the renderer */ 
    } 

    public void onResume() 
    { 
     /* Do stuff to resume the renderer */ 
     mLastTime = System.currentTimeMillis(); 
    } 

    @Override 
    public void onDrawFrame(GL10 unused) { 

     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 

     // Get the current time 
     long now = System.currentTimeMillis(); 

     // We should make sure we are valid and sane 
     if (mLastTime > now) return; 

     // Get the amount of time the last frame took. 
     long elapsed = now - mLastTime; 

     // Update our example 

     // Render our example 
     card1.Draw(mtrxProjectionAndView); 
     card2.Draw(mtrxProjectionAndView); 

     // Save the current time to see how long it took :). 
     mLastTime = now; 

    } 


    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 

     // We need to know the current width and height. 
     mScreenWidth = width; 
     mScreenHeight = height; 

     // Redo the Viewport, making it fullscreen. 
     GLES20.glViewport(0, 0, (int)mScreenWidth, (int)mScreenHeight); 

     // Clear our matrices 
     for(int i=0;i<16;i++) 
     { 
      mtrxProjection[i] = 0.0f; 
      mtrxView[i] = 0.0f; 
      mtrxProjectionAndView[i] = 0.0f; 
     } 

     // Setup our screen width and height for normal sprite translation. 
     Matrix.orthoM(mtrxProjection, 0, 0f, mScreenWidth, 0.0f, mScreenHeight, 0, 50); 

     // Set the camera position (View matrix) 
     Matrix.setLookAtM(mtrxView, 0, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 

     // Calculate the projection and view transformation 
     Matrix.multiplyMM(mtrxProjectionAndView, 0, mtrxProjection, 0, mtrxView, 0); 

    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 

     card1 = new CardView(mContext, 1); 
     card2 = new CardView(mContext, 2); 
    } 
} 


public class CardView { 

    // Misc 
    private Context mContext; 

    // Geometric variables 
    // number of coordinates per vertex in this array 
    private static final int COORDS_PER_VERTEX = 3; 
    private static float vertices[] = { 
      10.0f, 300f, 0.0f, 
      10.0f, 100f, 0.0f, 
      450f, 100f, 0.0f, 
      450f, 300f, 0.0f, 
    }; 
    private static float vertices2[] = { 
      450.0f, 600f, 0.0f, 
      450.0f, 300f, 0.0f, 
      900f, 300f, 0.0f, 
      900f, 600f, 0.0f, 
    }; 

    private final short indices[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices 
    private static float uvs[] = { 
      0.0f, 0.0f, 
      0.0f, 1.0f, 
      1.0f, 1.0f, 
      1.0f, 0.0f 
    }; 
    private FloatBuffer vertexBuffer; 
    private ShortBuffer drawListBuffer; 
    private FloatBuffer uvBuffer; 


    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex 

    public CardView(Context c, int index) 
    { 
     // Save context reference 
     mContext = c; 
     // Create the triangles 
     SetupCard(index); 
     // Create the image information 
     SetupImage(index); 

     // Set the clear color to black 
     GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1); 

     // Create the shaders, solid color 
     int vertexShader = riGraphicTools.loadShader(GLES20.GL_VERTEX_SHADER, riGraphicTools.vs_SolidColor); 
     int fragmentShader = riGraphicTools.loadShader(GLES20.GL_FRAGMENT_SHADER, riGraphicTools.fs_SolidColor); 

     riGraphicTools.sp_SolidColor = GLES20.glCreateProgram();    // create empty OpenGL ES Program 
     GLES20.glAttachShader(riGraphicTools.sp_SolidColor, vertexShader); // add the vertex shader to program 
     GLES20.glAttachShader(riGraphicTools.sp_SolidColor, fragmentShader); // add the fragment shader to program 
     GLES20.glLinkProgram(riGraphicTools.sp_SolidColor);     // creates OpenGL ES program executables 

     // Create the shaders, images 
     vertexShader = riGraphicTools.loadShader(GLES20.GL_VERTEX_SHADER, riGraphicTools.vs_Image); 
     fragmentShader = riGraphicTools.loadShader(GLES20.GL_FRAGMENT_SHADER, riGraphicTools.fs_Image); 

     riGraphicTools.sp_Image = GLES20.glCreateProgram();    // create empty OpenGL ES Program 
     GLES20.glAttachShader(riGraphicTools.sp_Image, vertexShader); // add the vertex shader to program 
     GLES20.glAttachShader(riGraphicTools.sp_Image, fragmentShader); // add the fragment shader to program 
     GLES20.glLinkProgram(riGraphicTools.sp_Image);     // creates OpenGL ES program executables 


     // Set our shader programm 
     GLES20.glUseProgram(riGraphicTools.sp_Image); 
    } 



    public void SetupImage(int index) 
    { 
     // The texture buffer 
     ByteBuffer bb = ByteBuffer.allocateDirect(uvs.length * 4); 
     bb.order(ByteOrder.nativeOrder()); 
     uvBuffer = bb.asFloatBuffer(); 
     uvBuffer.put(uvs); 
     uvBuffer.position(0); 

     // Generate Textures, if more needed, alter these numbers. 
     int[] texturenames = new int[1]; 
     GLES20.glGenTextures(1, texturenames, 0); 

     // Retrieve our image from resources. 
     //int id = mContext.getResources().getIdentifier("drawable/test_backbground1", null, mContext.getPackageName()); 
     if(index == 1) { 
      int id = riGraphicTools.loadTexture(mContext, R.drawable.test_backbground1, index); 
     }else{ 
      int id = riGraphicTools.loadTexture(mContext, R.drawable.test_backbground2, index); 
     } 

    } 


    public void SetupCard(int index) 
    { 

     if(index == 1) { 
      // The vertex buffer. 
      ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4); 
      bb.order(ByteOrder.nativeOrder()); 
      vertexBuffer = bb.asFloatBuffer(); 
      vertexBuffer.put(vertices); 
      vertexBuffer.position(0); 
     }else{ 
      // The vertex buffer. 
      ByteBuffer bb = ByteBuffer.allocateDirect(vertices2.length * 4); 
      bb.order(ByteOrder.nativeOrder()); 
      vertexBuffer = bb.asFloatBuffer(); 
      vertexBuffer.put(vertices2); 
      vertexBuffer.position(0); 
     } 

     // initialize byte buffer for the draw list 
     ByteBuffer dlb = ByteBuffer.allocateDirect(indices.length * 2); 
     dlb.order(ByteOrder.nativeOrder()); 
     drawListBuffer = dlb.asShortBuffer(); 
     drawListBuffer.put(indices); 
     drawListBuffer.position(0); 


    } 

    /** 
    * Encapsulates the OpenGL ES instructions for drawing this shape. 
    * 
    * @param mvpMatrix - The Model View Project matrix in which to draw 
    * this shape. 
    */ 

    public void Draw(float[] mvpMatrix){ 

     // clear Screen and Depth Buffer, we have set the clear color as black. 
     //GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 

     // get handle to vertex shader's vPosition member 
     int mPositionHandle = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "vPosition"); 

     // Enable generic vertex attribute array 
     GLES20.glEnableVertexAttribArray(mPositionHandle); 

     // Prepare the triangle coordinate data 
     GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, 
       GLES20.GL_FLOAT, false, 
       vertexStride, vertexBuffer); 

     // Get handle to texture coordinates location 
     int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "a_texCoord"); 

     // Enable generic vertex attribute array 
     GLES20.glEnableVertexAttribArray (mTexCoordLoc); 

     // Prepare the texturecoordinates 
     GLES20.glVertexAttribPointer (mTexCoordLoc, 2, GLES20.GL_FLOAT, 
       false, 
       0, uvBuffer); 

     // Get handle to shape's transformation matrix 
     int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "uMVPMatrix"); 

     // Apply the projection and view transformation 
     GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, mvpMatrix, 0); 

     // Get handle to textures locations 
     int mSamplerLoc = GLES20.glGetUniformLocation (riGraphicTools.sp_Image, "s_texture"); 

     // Set the sampler texture unit to 0, where we have saved the texture. 
     GLES20.glUniform1i (mSamplerLoc, 0); 

     // Draw the triangle 
     GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, 
       GLES20.GL_UNSIGNED_SHORT, drawListBuffer); 

     // Disable vertex array 
     GLES20.glDisableVertexAttribArray(mPositionHandle); 
     GLES20.glDisableVertexAttribArray(mTexCoordLoc); 

    } 
} 


public class riGraphicTools { 

    private static final String TAG = "GraphicTools"; 

    // Program variables 
    public static int sp_SolidColor; 
    public static int sp_Image; 


    /* SHADER Solid 
    * 
    * This shader is for rendering a colored primitive. 
    * 
    */ 
    public static final String vs_SolidColor = 
      "uniform mat4  uMVPMatrix;" + 
        "attribute vec4  vPosition;" + 
        "void main() {" + 
        " gl_Position = uMVPMatrix * vPosition;" + 
        "}"; 

    public static final String fs_SolidColor = 
      "precision mediump float;" + 
        "void main() {" + 
        " gl_FragColor = vec4(0.5,0,0,1);" + 
        "}"; 

    /* SHADER Image 
    * 
    * This shader is for rendering 2D images straight from a texture 
    * No additional effects. 
    * 
    */ 
    public static final String vs_Image = 
      "uniform mat4 uMVPMatrix;" + 
        "attribute vec4 vPosition;" + 
        "attribute vec2 a_texCoord;" + 
        "varying vec2 v_texCoord;" + 
        "void main() {" + 
        " gl_Position = uMVPMatrix * vPosition;" + 
        " v_texCoord = a_texCoord;" + 
        "}"; 

    public static final String fs_Image = 
      "precision mediump float;" + 
        "varying vec2 v_texCoord;" + 
        "uniform sampler2D s_texture;" + 
        "void main() {" + 
        " gl_FragColor = texture2D(s_texture, v_texCoord);" + 
        "}"; 




    /** 
    * Utility method for compiling a OpenGL shader. 
    * 
    * <p><strong>Note:</strong> When developing shaders, use the checkGlError() 
    * method to debug shader coding errors.</p> 
    * 
    * @param type - Vertex or fragment shader type. 
    * @param shaderCode - String containing the shader code. 
    * @return - Returns an id for the shader. 
    */ 
    public static int loadShader(int type, String shaderCode){ 

     // create a vertex shader type (GLES20.GL_VERTEX_SHADER) 
     // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) 
     int shader = GLES20.glCreateShader(type); 

     // add the source code to the shader and compile it 
     GLES20.glShaderSource(shader, shaderCode); 
     GLES20.glCompileShader(shader); 

     // return the shader 
     return shader; 
    } 



    /** 
    * Utility method for debugging OpenGL calls. Provide the name of the call 
    * just after making it: 
    * 
    * <pre> 
    * mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); 
    * FandeckRenderer.checkGlError("glGetUniformLocation");</pre> 
    * 
    * If the operation is not successful, the check throws an error. 
    * 
    * @param glOperation - Name of the OpenGL call to check. 
    */ 
    public static void checkGlError(String glOperation) { 
     int error; 
     while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { 
      Log.e(TAG, glOperation + ": glError " + error); 
      throw new RuntimeException(glOperation + ": glError " + error); 
     } 
    } 

    public static int loadTexture(final Context context, final int resourceId, int[] textureHandler, int index) 
    { 

     //GLES20.glGenTextures(1, textureHandler, index); 

     if (textureHandler[index] != 0) 
     { 
      final BitmapFactory.Options options = new BitmapFactory.Options(); 
      options.inScaled = false; // No pre-scaling 

      // Read in the resource 
      final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options); 

      // Bind to the texture in OpenGL 
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandler[index]); 

      // Set filtering 
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); 

      // Load the bitmap into the bound texture. 
      GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

      // Recycle the bitmap, since its data has been loaded into OpenGL. 
      bitmap.recycle(); 
     } 

     if (textureHandler[index] == 0) 
     { 
      throw new RuntimeException("Error loading texture."); 
     } 

     return textureHandler[0]; 
    } 
} 

Répondre

0

Ok, le problème a été le textureHandle, je l'ai déplacé à la classe supérieure pour conserver les données, et dans la méthode draw j'ai ajouté:

GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[textureIndex]); 

et cela fonctionne.

le code final est la suivante:

GLRenderer public class implémente Renderer {

// Our matrices 
private final float[] mtrxProjection = new float[16]; 
private final float[] mtrxView = new float[16]; 
private final float[] mtrxProjectionAndView = new float[16]; 

// Our screenresolution 
float mScreenWidth = 1280; 
float mScreenHeight = 768; 

// Misc 
Context mContext; 
long mLastTime; 
int mProgram; 

CardView card1; 
CardView card2; 

public GLRenderer(Context c) 
{ 
    mContext = c; 
    mLastTime = System.currentTimeMillis() + 100; 
} 

public void onPause() 
{ 
    /* Do stuff to pause the renderer */ 
} 

public void onResume() 
{ 
    /* Do stuff to resume the renderer */ 
    mLastTime = System.currentTimeMillis(); 
} 

@Override 
public void onDrawFrame(GL10 unused) { 

    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 

    // Get the current time 
    long now = System.currentTimeMillis(); 

    // We should make sure we are valid and sane 
    if (mLastTime > now) return; 

    // Get the amount of time the last frame took. 
    long elapsed = now - mLastTime; 

    // Update our example 

    // Render our example 
    card1.Draw(mtrxProjectionAndView, 0); 

    card2.Draw(mtrxProjectionAndView , 1); 

    // Save the current time to see how long it took :). 
    mLastTime = now; 

} 


@Override 
public void onSurfaceChanged(GL10 gl, int width, int height) { 

    // We need to know the current width and height. 
    mScreenWidth = width; 
    mScreenHeight = height; 

    // Redo the Viewport, making it fullscreen. 
    GLES20.glViewport(0, 0, (int)mScreenWidth, (int)mScreenHeight); 

    // Clear our matrices 
    for(int i=0;i<16;i++) 
    { 
     mtrxProjection[i] = 0.0f; 
     mtrxView[i] = 0.0f; 
     mtrxProjectionAndView[i] = 0.0f; 
    } 

    // Setup our screen width and height for normal sprite translation. 
    Matrix.orthoM(mtrxProjection, 0, 0f, mScreenWidth, 0.0f, mScreenHeight, 0, 50); 

    // Set the camera position (View matrix) 
    Matrix.setLookAtM(mtrxView, 0, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 

    // Calculate the projection and view transformation 
    Matrix.multiplyMM(mtrxProjectionAndView, 0, mtrxProjection, 0, mtrxView, 0); 

} 

@Override 
public void onSurfaceCreated(GL10 gl, EGLConfig config) { 

    card1 = new CardView(mContext, 0); 
    card2 = new CardView(mContext, 1); 
} 

}

public class Vignettes {

// Misc 
private Context mContext; 

// Geometric variables 
// number of coordinates per vertex in this array 
private static final int COORDS_PER_VERTEX = 3; 
private static float vertices[] = { 
     10.0f, 300f, 0.0f, 
     10.0f, 100f, 0.0f, 
     450f, 100f, 0.0f, 
     450f, 300f, 0.0f, 
}; 
private static float vertices2[] = { 
     450.0f, 600f, 0.0f, 
     450.0f, 300f, 0.0f, 
     900f, 300f, 0.0f, 
     900f, 600f, 0.0f, 
}; 

private final short indices[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices 
private static float uvs[] = { 
     0.0f, 0.0f, 
     0.0f, 1.0f, 
     1.0f, 1.0f, 
     1.0f, 0.0f 
}; 
private FloatBuffer vertexBuffer; 
private ShortBuffer drawListBuffer; 
private FloatBuffer uvBuffer; 


private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex 

final int[] textureHandle; 

public CardView(Context c, int index) 
{ 

    textureHandle = new int[2]; 
    // Save context reference 
    mContext = c; 
    // Create the triangles 
    SetupCard(index); 
    // Create the image information 
    SetupImage(index); 

    // Set the clear color to black 
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1); 

    // Create the shaders, solid color 
    int vertexShader = riGraphicTools.loadShader(GLES20.GL_VERTEX_SHADER, riGraphicTools.vs_SolidColor); 
    int fragmentShader = riGraphicTools.loadShader(GLES20.GL_FRAGMENT_SHADER, riGraphicTools.fs_SolidColor); 

    riGraphicTools.sp_SolidColor = GLES20.glCreateProgram();    // create empty OpenGL ES Program 
    GLES20.glAttachShader(riGraphicTools.sp_SolidColor, vertexShader); // add the vertex shader to program 
    GLES20.glAttachShader(riGraphicTools.sp_SolidColor, fragmentShader); // add the fragment shader to program 
    GLES20.glLinkProgram(riGraphicTools.sp_SolidColor);     // creates OpenGL ES program executables 

    // Create the shaders, images 
    vertexShader = riGraphicTools.loadShader(GLES20.GL_VERTEX_SHADER, riGraphicTools.vs_Image); 
    fragmentShader = riGraphicTools.loadShader(GLES20.GL_FRAGMENT_SHADER, riGraphicTools.fs_Image); 

    riGraphicTools.sp_Image = GLES20.glCreateProgram();    // create empty OpenGL ES Program 
    GLES20.glAttachShader(riGraphicTools.sp_Image, vertexShader); // add the vertex shader to program 
    GLES20.glAttachShader(riGraphicTools.sp_Image, fragmentShader); // add the fragment shader to program 
    GLES20.glLinkProgram(riGraphicTools.sp_Image);     // creates OpenGL ES program executables 


    // Set our shader programm 
    GLES20.glUseProgram(riGraphicTools.sp_Image); 
} 



public void SetupImage(int index) 
{ 

    GLES20.glGenTextures(2, textureHandle, 0); 

    // The texture buffer 
    ByteBuffer bb = ByteBuffer.allocateDirect(uvs.length * 4); 
    bb.order(ByteOrder.nativeOrder()); 
    uvBuffer = bb.asFloatBuffer(); 
    uvBuffer.put(uvs); 
    uvBuffer.position(0); 

    // Generate Textures, if more needed, alter these numbers. 
    int[] texturenames = new int[1]; 
    GLES20.glGenTextures(1, texturenames, 0); 

    // Retrieve our image from resources. 
    //int id = mContext.getResources().getIdentifier("drawable/test_backbground1", null, mContext.getPackageName()); 
    if(index == 1) { 
     int id = riGraphicTools.loadTexture(mContext, R.drawable.test_backbground1, textureHandle, index); 
    }else{ 
     int id = riGraphicTools.loadTexture(mContext, R.drawable.test_backbground2, textureHandle, index); 
    } 

} 


public void SetupCard(int index) 
{ 

    if(index == 1) { 
     // The vertex buffer. 
     ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4); 
     bb.order(ByteOrder.nativeOrder()); 
     vertexBuffer = bb.asFloatBuffer(); 
     vertexBuffer.put(vertices); 
     vertexBuffer.position(0); 
    }else{ 
     // The vertex buffer. 
     ByteBuffer bb = ByteBuffer.allocateDirect(vertices2.length * 4); 
     bb.order(ByteOrder.nativeOrder()); 
     vertexBuffer = bb.asFloatBuffer(); 
     vertexBuffer.put(vertices2); 
     vertexBuffer.position(0); 
    } 

    // initialize byte buffer for the draw list 
    ByteBuffer dlb = ByteBuffer.allocateDirect(indices.length * 2); 
    dlb.order(ByteOrder.nativeOrder()); 
    drawListBuffer = dlb.asShortBuffer(); 
    drawListBuffer.put(indices); 
    drawListBuffer.position(0); 


} 

/** 
* Encapsulates the OpenGL ES instructions for drawing this shape. 
* 
* @param mvpMatrix - The Model View Project matrix in which to draw 
* this shape. 
*/ 

public void Draw(float[] mvpMatrix, int textureIndex){ 

    // clear Screen and Depth Buffer, we have set the clear color as black. 
    //GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 


    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[textureIndex]); 

    // get handle to vertex shader's vPosition member 
    int mPositionHandle = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "vPosition"); 

    // Enable generic vertex attribute array 
    GLES20.glEnableVertexAttribArray(mPositionHandle); 

    // Prepare the triangle coordinate data 
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, 
      GLES20.GL_FLOAT, false, 
      vertexStride, vertexBuffer); 

    // Get handle to texture coordinates location 
    int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "a_texCoord"); 

    // Enable generic vertex attribute array 
    GLES20.glEnableVertexAttribArray (mTexCoordLoc); 

    // Prepare the texturecoordinates 
    GLES20.glVertexAttribPointer (mTexCoordLoc, 2, GLES20.GL_FLOAT, 
      false, 
      0, uvBuffer); 

    // Get handle to shape's transformation matrix 
    int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "uMVPMatrix"); 

    // Apply the projection and view transformation 
    GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, mvpMatrix, 0); 

    // Get handle to textures locations 
    int mSamplerLoc = GLES20.glGetUniformLocation (riGraphicTools.sp_Image, "s_texture"); 

    // Set the sampler texture unit to 0, where we have saved the texture. 
    GLES20.glUniform1i (mSamplerLoc, 0); 

    // Draw the triangle 
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, 
      GLES20.GL_UNSIGNED_SHORT, drawListBuffer); 

    // Disable vertex array 
    GLES20.glDisableVertexAttribArray(mPositionHandle); 
    GLES20.glDisableVertexAttribArray(mTexCoordLoc); 

} 

}

riGraphicTools public class {

// Program variables 
public static int sp_SolidColor; 
public static int sp_Image; 


/* SHADER Solid 
* 
* This shader is for rendering a colored primitive. 
* 
*/ 
public static final String vs_SolidColor = 
    "uniform mat4  uMVPMatrix;" + 
    "attribute vec4  vPosition;" + 
    "void main() {" + 
    " gl_Position = uMVPMatrix * vPosition;" + 
    "}"; 

public static final String fs_SolidColor = 
    "precision mediump float;" + 
    "void main() {" + 
    " gl_FragColor = vec4(0.5,0,0,1);" + 
    "}"; 

/* SHADER Image 
* 
* This shader is for rendering 2D images straight from a texture 
* No additional effects. 
* 
*/ 
public static final String vs_Image = 
    "uniform mat4 uMVPMatrix;" + 
    "attribute vec4 vPosition;" + 
    "attribute vec2 a_texCoord;" + 
    "varying vec2 v_texCoord;" + 
    "void main() {" + 
    " gl_Position = uMVPMatrix * vPosition;" + 
    " v_texCoord = a_texCoord;" + 
    "}"; 

public static final String fs_Image = 
    "precision mediump float;" + 
    "varying vec2 v_texCoord;" + 
    "uniform sampler2D s_texture;" + 
    "void main() {" + 
    " gl_FragColor = texture2D(s_texture, v_texCoord);" + 
    "}"; 



public static int loadShader(int type, String shaderCode){ 

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER) 
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) 
    int shader = GLES20.glCreateShader(type); 

    // add the source code to the shader and compile it 
    GLES20.glShaderSource(shader, shaderCode); 
    GLES20.glCompileShader(shader); 

    // return the shader 
    return shader; 
} 

public static int loadTexture(final Context context, final int resourceId, int[] textureHandle , int index) 
{ 

    if (textureHandle[index] != 0) 
    { 
     final BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inScaled = false; // No pre-scaling 

     // Read in the resource 
     final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options); 

     // Bind to the texture in OpenGL 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[index]); 

     // Set filtering 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); 

     // Load the bitmap into the bound texture. 
     GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

     // Recycle the bitmap, since its data has been loaded into OpenGL. 
     bitmap.recycle(); 
    } 

    if (textureHandle[index] == 0) 
    { 
     throw new RuntimeException("Error loading texture."); 
    } 

    return textureHandle[index]; 
} 

}

J'espère que cela aidera quelqu'un.