如何使用libGDX为纹理着色?

时间:2018-01-29 22:40:40

标签: opengl libgdx textures

我正在为我的库工作libGDX,它绘制ASCII图块以创建文本GUI。我当前的Swing + BufferedImage实现如下所示:

enter image description here

这可以通过复制灰度纹理的一部分来生成CP437字符并通过为每个像素添加颜色来转换它们。

我的问题是我的libGDX实现由于某种原因不起作用:

enter image description here

我试过的是:

    val backend: TextureRegion = region.getBackend()

    val texture = backend.texture
    if (!texture.textureData.isPrepared) {
        texture.textureData.prepare()
    }
    val pixmap = texture.textureData.consumePixmap()
    (0 until backend.regionWidth).forEach { x ->
        (0 until backend.regionHeight).forEach { y ->
            val color = Color(pixmap.getPixel(backend.regionX + x, backend.regionY + y))

            val ax = color.a
            var rx = color.r
            var gx = color.g
            var bx = color.b
            rx *= r
            gx *= g
            bx *= b
            if (ax < 50) {
                pixmap.drawPixel(backend.regionX + x, backend.regionY + y, textCharacter.getBackgroundColor().toAWTColor().rgb)
            } else {
                pixmap.drawPixel(backend.regionX + x, backend.regionY + yy, Color(rx, gx, bx, ax).toIntBits())
            }
        }
    }

    return region

我知道我错过了一些东西,但我无法弄清楚这里的问题是什么。我尝试过各种选项,例如复制TextureRegion,但我无法让它发挥作用。

我的其他实现使用BufferedImage,它只是起作用:

    val r = textCharacter.getForegroundColor().getRed().toFloat() / 255
    val g = textCharacter.getForegroundColor().getGreen().toFloat() / 255
    val b = textCharacter.getForegroundColor().getBlue().toFloat() / 255

    val backend: BufferedImage = region.getBackend()
    (0 until backend.width).forEach { x ->
        (0 until backend.height).forEach { y ->
            val ax = backend.colorModel.getAlpha(backend.raster.getDataElements(x, y, null))
            var rx = backend.colorModel.getRed(backend.raster.getDataElements(x, y, null))
            var gx = backend.colorModel.getGreen(backend.raster.getDataElements(x, y, null))
            var bx = backend.colorModel.getBlue(backend.raster.getDataElements(x, y, null))
            rx = (rx * r).toInt()
            gx = (gx * g).toInt()
            bx = (bx * b).toInt()
            if (ax < 50) {
                backend.setRGB(x, y, textCharacter.getBackgroundColor().toAWTColor().rgb)
            } else {
                backend.setRGB(x, y, (ax shl 24) or (rx shl 16) or (gx shl 8) or (bx shl 0))
            }
        }
    }
    return region

我做错了什么?

1 个答案:

答案 0 :(得分:0)

加载纹理时,它会将Pixmap数据复制到GPU,因此开始更改Pixmap数据为时已晚。您正在更改源数据,但不是更改加载到GPU的图像。执行此操作的典型方法是首先直接加载Pixmap,修改它,然后将其传递给Texture构造函数。

另外,在编辑Pixmap之前,请确保将其混合设置为None而不是SourceOver。否则,调用drawPixel会将您的像素与Pixmap中已有的像素进行alpha混合。

完全不同的方法是使用自定义着色器在渲染过程中实时修改它。对于这样一个简单的场景,这会产生微不足道的性能影响。如果你想要想象你的效果,它将允许你做颜色的实时动画。我现在正在打电话,所以不能输出这样做的说明。如果有兴趣发表评论,我会看看明天是否可以更新答案。