【问题标题】:Libgdx get texture from Texture Atlas with findRegionLibgdx 使用 findRegion 从 Texture Atlas 获取纹理
【发布时间】:2025-12-07 00:10:02
【问题描述】:

我有这个代码

textureAtlas = TextureAtlas("atlas.atlas")

val box = textureAtlas.findRegion("box")

我想用“盒子”创建一个纹理。可能吗? box.texture 返回原始纹理,而不是区域。哦,我不想使用 Sprite 和 SpriteBatch。我需要这个 3D,而不是 2D。

谢谢

【问题讨论】:

  • 如果您在 3D 中使用它,则没有理由使用 TextureAtlas。您无法从 TextureRegion 中提取纹理,因此您要么需要直接使用 Pixmap 并从源图像文件的区域创建新的 Pixmap,要么对您的网格进行一些花哨的 UV 操作以得到它使用该特定区域。

标签: libgdx


【解决方案1】:

TextureAtlas 实际上并没有分离碎片。当您从地图集获取区域时,它只是说这是您要使用的区域 (u,v,u2,v2),这是对整个纹理的原始引用。

这就是为什么 batch.draw(Texture) 和 batch.draw(TextureRegion) 在使用上不一样的原因。

但是可以将图片的一部分作为纹理。

  • 你可以使用像素图来做到这一点。

    首先从图集纹理生成像素图。然后以您想要的“框”区域大小创建新的空像素图。然后分配像素数组并从您的新像素图生成纹理。

由于您的 Textureatlas 大小,它可能非常昂贵。

  • 您可以使用帧缓冲区。 创建 FBbuilder 并构建新的帧缓冲区。将纹理区域绘制到此缓冲区并从中获取纹理。

这里的问题是纹理的大小将与视口/屏幕大小相同。我想您可以创建新相机将其更改为您想要的大小。

GLFrameBuffer.FrameBufferBuilder frameBufferBuilder = new GLFrameBuffer.FrameBufferBuilder(widthofBox, heightofBox);
    frameBufferBuilder.addColorTextureAttachment(GL30.GL_RGBA8, GL30.GL_RGBA, GL30.GL_UNSIGNED_BYTE);
    frameBuffer = frameBufferBuilder.build();
    OrthographicCamera c = new OrthographicCamera(widthofBox, heightofBox);
    c.up.set(0, 1, 0);
    c.direction.set(0, 0, -1);
    c.position.set(widthofBox / 2, heightofBox / 2, 0f);
    c.update();
    batch.setProjectionMatrix(c.combined);
    frameBuffer.begin();
    batch.begin();
    batch.draw(boxregion...)
    batch.end();
    frameBuffer.end();
    Texture texturefbo = frameBuffer.getColorBufferTexture();

Texturefbo 将被翻转。您可以通过将 scaleY 设置为 -1 来使用纹理绘制方法解决此问题,或者您可以在帧缓冲区上绘制时将 scaleY 缩放为 -1,或者可以像这样更改相机

up.set(0, -1, 0);
direction.set(0, 0, 1);

翻转到y轴上的相机。

我想到的最后一件事是对这个纹理进行 mipmap。它也没有那么难。

    texturefbo.bind();
    Gdx.gl.glGenerateMipmap(GL20.GL_TEXTURE_2D);
    texturefbo.setFilter(Texture.TextureFilter.MipMapLinearLinear, 
    Texture.TextureFilter.MipMapLinearLinear);

【讨论】:

    【解决方案2】:

    你可以这样做:

    Texture boxTexture = new TextureRegion(textureAtlas.findRegion("box")).getTexture();
    

    【讨论】:

    • 这是整个纹理,而不是区域纹理,我想我必须为此创建一个自定义着色器