OpenGL ES Texture Mapping Overflow

2019-08-01 19:49发布

I want to animate a 2d Sprite sheet. I hava a sprite sheet with a lot of character animation with different frame size. For a single animation, I scale a vertex to fit one frame and then change Texture position for animation. Works pretty well for one animation, but when switching to another animation with different frame size and scale vertex and fitting texture again, I get side effect where texture is stretcht and not fitting, it is just on one animation frame, but make the change between two animations look very bad.

I think, that is because of the vertex-size change. So my idea ist, to have a fixed vertex size and fit the texture without strechting it to the full vertex (height for every animation is fixed).

Maybe a image will help, so I created one: img http://oi44.tinypic.com/14l09hk.jpg

Here is my code, hope it is enough:

public boolean nextFrame() {

    float textureWidth = textureMap()[currentAnimation][0];
    float frameCount = textureMap()[currentAnimation][1];
    float frameWidth = textureWidth / frameCount;

    if (loop) {
        if (currentFrame == frameCount)
            currentFrame = 0;
    } else {
        if (currentFrame == frameCount) {
            setAnimation(AnimationConstants.IDLE);
            loop = true;
            return false;
        }
    }

    float x_left = (float) currentFrame * frameWidth / textureWidth;
    float x_right = (float) (currentFrame * frameWidth + frameWidth)
            / textureWidth;

    texture[0] = x_left; // top left x
    texture[1] = 1.0f; // top left y

    texture[2] = x_left; // bottom left x
    texture[3] = 0.0f; // bottom left y

    texture[4] = x_right; // top right x
    texture[5] = 1.0f; // top right y

    texture[6] = x_right; // bottom right x
    texture[7] = 0.0f; // bottom right y

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuffer.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);

    currentFrame++;

    return true;
}

private void newVertex() {
    float textureWidth = textureMap()[currentAnimation][0];
    float frameCount = textureMap()[currentAnimation][1];
    float frameWidth = textureWidth / frameCount;

    float width = (float) frameWidth / (float) frameHeight;

    vertices[0] = pos_x; // bottom left x
    vertices[1] = pos_y; // bottom left y

    vertices[3] = pos_x; // top left x
    vertices[4] = pos_y + (1.0f * scale); // top left y

    vertices[6] = pos_x + (width * scale); // bottom right x
    vertices[7] = pos_y; // bottom right y

    vertices[9] = pos_x + (width * scale); // top right x
    vertices[10] = pos_y + (1.0f * scale); // top right y

    // z values
    vertices[2] = -0.2f; // bottom left z
    vertices[5] = -0.2f; // top left z
    vertices[8] = -0.2f; // bottom right z
    vertices[11] = -0.2f; // top right z

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());

    vertexBuffer = byteBuffer.asFloatBuffer();

    vertexBuffer.put(vertices);

    vertexBuffer.position(0);
}

so for every new animation, I call newVertex().

1条回答
时光不老,我们不散
2楼-- · 2019-08-01 20:34

Check this out. I suppose you should use the same general idea. If needed I can describe in detail how to place texture correctly in your case.

查看更多
登录 后发表回答