纹理不绘制

Texture doesn't draw

我想在屏幕上绘制图像,但得到的是黑色方块,上面没有纹理。图像路径正确并已加载,因为矩形的大小正确。我有一个单独的 class 用于加载名为 Texture 的纹理,还有一个 class 用于绘制名为 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 );
}

这是完整的 class 纹理:

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

我发现了问题:在构造纹理 class 之前将下一行发布到 MyGLRenderer 之前,但现在我已经将它们添加到纹理 class 中的 glBindTexture() 和 texImage2D 之间:

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

我在使用相同的 open gl 命令时遇到了类似的问题,即我的纹理未被绘制(黑屏)。

为了在屏幕上渲染纹理,我还添加了一些额外的 open gl 命令以使用顶点着色器绘制纹理。

查看此项目以了解如何使用开放式 gl 顶点着色器 只需使用纹理句柄和适当的宽度和高度调用 renderTexture 方法即可解决您的问题 https://github.com/rsri/Pic2Fro/blob/b4fe69b44343dab2515c3fd6e769f3370bf31312/app/src/main/java/com/pic2fro/pic2fro/util/Util.java