OpenGL ES 纹理映射溢出
我想要制作 2d Sprite 表的动画。我有一个精灵表,其中有很多不同帧大小的角色动画。对于单个动画,我缩放顶点以适合一帧,然后更改动画的纹理位置。对于一个动画效果很好,但是当切换到另一个具有不同帧大小和比例顶点并再次拟合纹理的动画时,我会得到纹理拉伸且不拟合的副作用,它仅在一个动画帧上,但在之间进行更改两个动画看起来很糟糕。
我认为,这是因为顶点大小的变化。所以我的想法是,有一个固定的顶点大小并适合纹理而不将其拉伸到完整的顶点(每个动画的高度是固定的)。
这是我的代码,希望它足够:
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:
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
检查这个。
我想你应该使用相同的总体想法。如果需要,我可以详细描述如何在您的案例中正确放置纹理。
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.