【问题标题】:LibGDX Texture to ByteBufferLibGDX 纹理到 ByteBuffer
【发布时间】:2013-02-09 18:42:46
【问题描述】:

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

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

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

【问题讨论】:

    标签: textures libgdx bytebuffer pixmap


    【解决方案1】:

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

    此外,consumePixmap() 上的文档说它requires a prepare() call 才能工作。

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

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

    【讨论】:

    • 纹理是由用户在应用程序中在一个简单的类似绘画的界面中创建的,所以我手头没有任何数据。如果我可以从用于创建完美纹理的 FrameBuffer 中提取信息,但是我的印象是您只能从绘制到屏幕的默认 FrameBuffer 中执行此操作。在我的情况下,纹理可能会超出屏幕的分辨率,因此它会切断或扭曲沿着这条路线的图像。不幸的是,使用像素图本身进行绘图也不是一种选择。
    【解决方案2】:

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

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

    在您的应用程序配置中: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 的新手,所以这可能不是最好的方法。

    【讨论】:

    • 这正是我想要的。谢谢吐司。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    相关资源
    最近更新 更多