2016-02-13 5 views
0

Я хочу нарисовать изображение на экране, но то, что я получаю, это черный квадрат, но без текстуры на нем. Путь изображения правильный и загруженный, потому что прямоугольник имеет правильный размер. У меня есть отдельный класс для загрузки текстуры с именем 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); 

EDIT: Вот шейдеры:

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

А вот полный класс Texture:

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]); 
    } 
} 
+0

Можете добавить, пожалуйста, шейдеры. –

+0

is mTexture.useTexture() привязывает правильный обработчик GL_TEXTURE_2D? Я не вижу реализации класса Texture. – DanP

+0

Я отредактировал сообщение и добавил полный класс текстуры и шейдеры – Mihai

ответ

0

Я нашел проблему: до следующего линии были опубликованы в MyGLRenderer перед построением класса Texture, но теперь я добавляю их между glBindTexture() и texImage2D в классе Texture:

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

    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); 
Смежные вопросы