OpenGL ES 纹理映射溢出

发布于 2025-01-08 05:25:53 字数 2791 浏览 4 评论 0原文

我想要制作 2d Sprite 表的动画。我有一个精灵表,其中有很多不同帧大小的角色动画。对于单个动画,我缩放顶点以适合一帧,然后更改动画的纹理位置。对于一个动画效果很好,但是当切换到另一个具有不同帧大小和比例顶点并再次拟合纹理的动画时,我会得到纹理拉伸且不拟合的副作用,它仅在一个动画帧上,但在之间进行更改两个动画看起来很糟糕。

我认为,这是因为顶点大小的变化。所以我的想法是,有一个固定的顶点大小并适合纹理而不将其拉伸到完整的顶点(每个动画的高度是固定的)。

也许图像会有所帮助,所以我创建了一个: img

这是我的代码,希望它足够:

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

所以对于每个新动画,我调用 newVertex()。

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

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().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一指流沙 2025-01-15 05:25:53

检查这个
我想你应该使用相同的总体想法。如果需要,我可以详细描述如何在您的案例中正确放置纹理。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文