4

我正在尝试将纹理转换为 LibGDX 中的像素图,以便我可以将所有像素数据放入 ByteBuffer 进行一些实验,据我所知,我应该能够通过执行以下操作来做到这一点:

Pixmap pixmap = textureName.getTexture().getTextureData().consumePixmap();
ByteBuffer data = pixmap.getPixels();

这似乎返回了一个适当大小的像素图,并且 ByteBuffer 似乎创建得很好,但它完全用零填充,从而产生一个空白的透明图像。这个以及其他一些测试让我相信 Pixmap 本身只是被创建为像这样的完全透明的图像,但我找不到可能导致这种情况发生的原因。是否有某种限制阻止它工作,或者我只是错过了一些明显的东西?

4

2 回答 2

7

我相信 API ( consumePixmap()) 是为了让类在将 Pixmap 推送到 GPU 时Texture从中提取数据。 Libgdx对象表示 GPU 上的纹理数据,因此将底层数据传输到 CPU 通常并非易事(它是渲染 API 的“错误”方向)。请参阅http://code.google.com/p/libgdx/wiki/GraphicsPixmapPixmap
Texture

此外,关于它的文档consumePixmap()说它需要一个prepare()电话才能工作。

要从纹理中提取像素信息,您需要构建一个FrameBuffer对象,向其渲染纹理,然后提取像素(请参阅 参考资料ScreenUtils)。

目前尚不清楚您要完成什么,但是朝另一个方向(字节数组 -> Pixmap-> Texture)然后修改字节数组并重新进行转换可能会起作用。

于 2013-02-25T01:14:01.747 回答
7

当我想创建在我的关卡编辑器中制作的关卡的 PNG 时,我遇到了类似的问题。该级别由创建者放置的图块组成,然后将整个级别保存为 .png 以在游戏中使用。

以PT解释的方式解决了它。我希望它对遇到同样问题的其他人有用。

在您的应用程序配置中:cfg.useGL20 = true; 需要 GL20 才能构建 FrameBuffer

        public boolean exportLevel(){   

            //width and height in pixels
            int width = (int)lba.getPrefWidth();
            int height = (int)lba.getPrefHeight();

            //Create a SpriteBatch to handle the drawing.
            SpriteBatch sb = new SpriteBatch();

            //Set the projection matrix for the SpriteBatch.
            Matrix4 projectionMatrix = new Matrix4();

            //because Pixmap has its origin on the topleft and everything else in LibGDX has the origin left bottom
            //we flip the projection matrix on y and move it -height. So it will end up side up in the .png
            projectionMatrix.setToOrtho2D(0, -height, width, height).scale(1,-1,1); 

            //Set the projection matrix on the SpriteBatch
            sb.setProjectionMatrix(projectionMatrix);

            //Create a frame buffer.
            FrameBuffer fb = new FrameBuffer(Pixmap.Format.RGBA8888, width, height, false);

            //Call begin(). So all next drawing will go to the new FrameBuffer.
            fb.begin();

            //Set up the SpriteBatch for drawing.
            sb.begin();

            //Draw all the tiles.
            BuildTileActor[][] btada = lba.getTiles();
            for(BuildTileActor[] btaa: btada){
                for(BuildTileActor bta: btaa){
                    bta.drawTileOnly(sb);
                }
            }

            //End drawing on the SpriteBatch. This will flush() any sprites remaining to be drawn as well.
            sb.end();

            //Then retrieve the Pixmap from the buffer.
            Pixmap pm = ScreenUtils.getFrameBufferPixmap(0, 0, width, height);

            //Close the FrameBuffer. Rendering will resume to the normal buffer.
            fb.end();

            //Save the pixmap as png to the disk.
            FileHandle levelTexture = Gdx.files.local("levelTexture.png");
            PixmapIO.writePNG(levelTexture, pm);

            //Dispose of the resources.
            fb.dispose();
            sb.dispose();

注意:我是 LibGDX 的新手,所以这可能不是最好的方法。

于 2014-02-19T20:11:40.447 回答