在Android上的openGL ES 2中无法正确渲染纹理

时间:2015-02-26 13:22:28

标签: android textures opengl-es-2.0

我在Android上的openGL ES 2中渲染纹理时出现问题。正在绘制图像,但纹理没有正确地包裹它。

我已经尝试了所有常见的事情来解决问题,但没有任何效果。

以下是其中一张图片的外观:

enter image description here

但是这是他们在屏幕上的样子:

enter image description here

忽略纹理部分的黑色边框。

这是我的Texture类:

public class HFTexture {

private int width;
private int height;

private int textureId;

private HFGame game;
private String textureFile;

public HFTexture(HFGame game, String textureFile) {
    this.game = game;
    this.textureFile = textureFile;
    //load();
}

public void load() {
    int[] texIds = new int[1];
    GLES20.glGenTextures(1, texIds, 0);
    textureId = texIds[0];

    InputStream in;
    try {
        in = game.getFileManager().getAsset(textureFile);
        Bitmap bitmap = BitmapFactory.decodeStream(in);
        width = bitmap.getWidth();
        height = bitmap.getHeight();
        bind();
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
        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_LINEAR);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
        bitmap.recycle();
    } catch(IOException ex) {

    }
}

public void bind() {
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
}

public void activate(HFShader shader, int texture) {
    GLES20.glActiveTexture(texture);
    bind();
    GLES20.glUniform1i(shader.getHandle("sampler0"), 0);
}

public void delete() {
    bind();
    int[] textureIds = {textureId};
    GLES20.glDeleteTextures(1, textureIds, 0);
}

}

这是我的Vertices类:

public class Vertices {

private FloatBuffer vertexBuffer;
private FloatBuffer normalBuffer;
private FloatBuffer texCoordBuffer;
private ShortBuffer indexBuffer;

private final int VERTEX_COUNT;
private final int VERTEX_STRIDE;
private final int VERTEX_SIZE = 3;

private final int NORMAL_STRIDE;
private final int NORMAL_SIZE = 3;

private final int TEXTURE_COORD_STRIDE;
private final int TEXTURE_COORD_SIZE = 2;

private final int INDEX_COUNT;

public Vertices(float[] vertices, float[] normals, float[] texCoords, short[] indices) {
    VERTEX_STRIDE = VERTEX_SIZE * 4;
    NORMAL_STRIDE = NORMAL_SIZE * 4;
    TEXTURE_COORD_STRIDE = TEXTURE_COORD_SIZE * 4;
    VERTEX_COUNT = vertices.length;
    INDEX_COUNT = indices.length;

    ByteBuffer bb = ByteBuffer.allocateDirect(VERTEX_COUNT * VERTEX_STRIDE);
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

    bb = ByteBuffer.allocateDirect(normals.length * NORMAL_STRIDE);
    bb.order(ByteOrder.nativeOrder());
    normalBuffer = bb.asFloatBuffer();
    normalBuffer.put(normals);
    normalBuffer.position(0);

    bb = ByteBuffer.allocateDirect(texCoords.length * TEXTURE_COORD_STRIDE);
    bb.order(ByteOrder.nativeOrder());
    texCoordBuffer = bb.asFloatBuffer();
    texCoordBuffer.put(texCoords);
    texCoordBuffer.position(0);

    bb = ByteBuffer.allocateDirect(indices.length * 2);
    bb.order(ByteOrder.nativeOrder());
    indexBuffer = bb.asShortBuffer();
    indexBuffer.put(indices);
    indexBuffer.position(0);
}

public void bind(HFShader shader) {
    int positionHandle = shader.getHandle("position");
    int normalHandle = shader.getHandle("normal");
    int texCoordHandle = shader.getHandle("texCoord");
    GLES20.glEnableVertexAttribArray(positionHandle);
    GLES20.glVertexAttribPointer(
            positionHandle, VERTEX_SIZE,
            GLES20.GL_FLOAT, false,
            VERTEX_STRIDE, vertexBuffer);
    GLES20.glEnableVertexAttribArray(normalHandle);
    GLES20.glVertexAttribPointer(
            normalHandle, NORMAL_SIZE,
            GLES20.GL_FLOAT, false,
            NORMAL_STRIDE, normalBuffer);
    GLES20.glEnableVertexAttribArray(texCoordHandle);
    GLES20.glVertexAttribPointer(
            texCoordHandle, TEXTURE_COORD_SIZE,
            GLES20.GL_FLOAT, false,
            TEXTURE_COORD_STRIDE, vertexBuffer);
}

public void unbind(HFShader shader) {
    int positionHandle = shader.getHandle("position");
    int normalHandle = shader.getHandle("normal");
    int texCoordHandle = shader.getHandle("texCoord");
    GLES20.glDisableVertexAttribArray(positionHandle);
    GLES20.glDisableVertexAttribArray(normalHandle);
    GLES20.glDisableVertexAttribArray(texCoordHandle);
}

public void draw() {
    if(indexBuffer != null) {
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, INDEX_COUNT, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
    } else {
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, VERTEX_COUNT);
    }
}

}

这是我的Vertex数据:

float[] verts = {
            -(width / 2f), (height / 2f), 0f,  // index 0
            -(width / 2f), -(height / 2f), 0f, // index 1
            (width / 2f), -(height / 2f), 0f,  // index 2
            (width / 2f), (height / 2f), 0f    // index 3
    };
    float[] norms = {
            0.0f, 0.0f, -1.0f,
            0.0f, 0.0f, -1.0f,
            0.0f, 0.0f, -1.0f,
            0.0f, 0.0f, -1.0f
    };
    float[] texCoords = {
            0f, 1f,
            0f, 0f,
            1f, 0f,
            1f, 1f
    };

    short[] indices = {
            0,1,2,2,3,0
    };

我已经尝试将夹具添加到边缘纹理参数,但这似乎没有帮助。我是否只是将顶点和纹理坐标放错了顺序,或者是否有一些我完全缺失的东西?

1 个答案:

答案 0 :(得分:0)

您正在为纹理坐标设置顶点缓冲区而不是纹理坐标缓冲区:

GLES20.glEnableVertexAttribArray(texCoordHandle);
GLES20.glVertexAttribPointer(
        texCoordHandle, TEXTURE_COORD_SIZE,
        GLES20.GL_FLOAT, false,
        TEXTURE_COORD_STRIDE, vertexBuffer); // <-- here

应该是:

GLES20.glEnableVertexAttribArray(texCoordHandle);
GLES20.glVertexAttribPointer(
        texCoordHandle, TEXTURE_COORD_SIZE,
        GLES20.GL_FLOAT, false,
        TEXTURE_COORD_STRIDE, texCoordBuffer);
相关问题