2013-02-24 82 views
4

我想將紋理轉換爲LibGDX中的Pixmap,以便我可以將所有像素數據轉換爲ByteBuffer進行一些實驗,並且從我所知道的情況來看,我應該可以通過執行以下操作:LibGDX Texture to ByteBuffer

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

這似乎並返回一個適當大小的像素圖,和字節緩衝區似乎要創建得很好,但它是用零完全充滿,造成一片空白,透明圖像。這一點以及其他一些測試讓我相信Pixmap本身只是被創建爲一個完全透明的圖像,但我無法找到可能導致這種情況發生的原因。是否有某種限制阻止這種工作,或者我只是錯過了明顯的東西?

回答

7

我相信API(consumePixmap())是爲Texture類提取數據時從Pixmap提取數據時將Pixmap推到GPU。
Libgdx Texture對象表示GPU上的紋理數據,因此將底層數據提供給CPU通常不是微不足道的(它是渲染API的「錯誤」方向)。請參閱http://code.google.com/p/libgdx/wiki/GraphicsPixmap

此外,consumePixmap()上的文檔在它可以工作之前表示它requires a prepare() call

要從紋理中提取像素信息,您需要構建一個FrameBuffer對象,爲其渲染紋理,然後提取像素(請參閱ScreenUtils)。

它不清楚你想完成什麼,但走向另一個方向(字節數組 - >Pixmap - >Texture),然後修改字節數組並重新進行轉換可能會奏效。

+0

紋理是由用戶在應用程序中創建的一個簡單的類似油漆的界面,所以我手邊沒有任何數據。如果我可以從FrameBuffer中提取信息來創建完美的紋理,但我的印象是,您只能從繪製到屏幕的默認FrameBuffer中執行此操作。在我的情況下,紋理可能會超出屏幕的分辨率,所以它會切斷或扭曲此路線上的圖像。不幸的是,使用Pixmaps自己繪圖也不是一種選擇。 – Shamrock 2013-02-25 02:33:50

7

當我想要在我的關卡編輯器中創建一個關卡的PNG時,遇到了類似的問題。 級別由創建者放置的圖塊製作而成,然後將整個級別保存爲.png以用於遊戲。

解決了P.T.解釋。我希望它對遇到同樣問題的其他人有用。

而在你的應用程序配置中:cfg.useGL20 = true; GL20需要能夠建立幀緩衝

 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所以這可能不會是這樣做的最巧妙的方法。

+0

這正是我在找的東西。謝謝Toast。 – LukTar 2015-01-01 23:17:25