Текстура не рисует

Я хочу нарисовать изображение на экране, но получаю черный квадрат, но без текстуры на нем. Путь к изображению правильный и загружен, потому что прямоугольник имеет правильный размер. У меня есть отдельный класс для загрузки текстуры с именем Texture и класс для рисования текстуры под названием Sprite. Вот код:

// Class Texture
public void loadFromResources(final Context context, int id) {
    GLES20.glGenTextures(1, mTextureID, 0);

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inScaled = false;   // No pre-scaling

    // Temporary create a bitmap
    Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), id, options);

    // Bind texture to texturename
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID[0]);

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

    mSize = new Size(bmp.getWidth(), bmp.getHeight());

    // We are done using the bitmap so we should recycle it.
    bmp.recycle();
}

// Sprite class
public void setTexture(Texture texture) {
    mTexture = texture;

    Log.d("Sprite", mTexture.getSize().getWidth() + " " + mTexture.getSize().getHeight());

    vertices = new float[] {
            0.0f,                         0.0f,
            texture.getSize().getWidth(), 0.0f,
            texture.getSize().getWidth(), texture.getSize().getHeight(),
            0.0f,                         texture.getSize().getHeight() };


    // The vertex buffer.
    ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

    // Create our UV coordinates.
    uvs = new float[] {
            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 1.0f,
            1.0f, 0.0f
    };

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

public void draw(float[] projectionMatrix) {
    float[] scratch = new float[16];

    float[] move = new float[16];
    Matrix.setIdentityM(move, 0);
    Matrix.translateM(move, 0, 10, 10, 0);

    Matrix.multiplyMM(scratch, 0, projectionMatrix, 0, move, 0);

    GLES20.glUseProgram(mProgram);

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

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

    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, 2,
            GLES20.GL_FLOAT, false,
            2 * 4, vertexBuffer);

    // Get handle to texture coordinates location
    int mTexCoordLoc = GLES20.glGetAttribLocation(mProgram, "a_texCoord");
    MyGLRenderer.checkGlError("glGetAttribLocation");

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

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

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

    // Apply the projection and view transformation
    GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, scratch, 0);
    MyGLRenderer.checkGlError("glUniformMatrix4fv");

    mTexture.useTexture();

    // Get handle to textures locations
    int mSamplerLoc = GLES20.glGetUniformLocation(mProgram, "s_texture" );
    MyGLRenderer.checkGlError("glGetUniformLocation");

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

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

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

// MyGLRenderer class
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

    mTexture = new Texture();
    mTexture.loadFromResources(context, R.drawable.hex);

    mSprite = new Sprite(context);
    mSprite.setTexture(mTexture);

РЕДАКТИРОВАТЬ: Вот шейдеры:

// vert
uniform mat4 uMVPMatrix;
attribute vec4 vPosition;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;

void main() {
    gl_Position = uMVPMatrix * vPosition;
    v_texCoord = a_texCoord;
}

// frag
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D s_texture;

void main() {
    gl_FragColor = texture2D( s_texture, v_texCoord );
}

А вот и полный класс текстур:

public class Texture {
    private final int[] mTextureID = new int[1];
    private Size mSize = new Size(0,0);

    public Texture() {

    }

    public Size getSize() { return mSize; }

    public void loadFromResources(final Context context, int id) {
        GLES20.glGenTextures(1, mTextureID, 0);

        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;   // No pre-scaling

        // Temporary create a bitmap
        Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), id, options);

        // Bind texture to texturename
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID[0]);

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

        mSize = new Size(bmp.getWidth(), bmp.getHeight());

        // We are done using the bitmap so we should recycle it.
        bmp.recycle();
    }

    public void useTexture() {
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID[0]);
    }
}

Ответы на вопрос(2)

Ваш ответ на вопрос