2013-02-24 3 views
4

J'essaie de convertir une texture en Pixmap dans LibGDX afin que je puisse obtenir toutes les données de pixels dans un ByteBuffer pour certaines expériences, et de ce que je peux dire, je devrais être capable de le faire en procédez comme suit:LibGDX Texture à ByteBuffer

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

Cela ne semble renvoyer une taille appropriée Pixmap et le ByteBuffer ne semble être créé très bien, mais il est entièrement rempli avec des zéros, qui donne une image vierge, transparente. Ceci, et quelques autres tests, me portent à croire que le Pixmap lui-même est simplement créé comme une image totalement transparente comme ça, mais je ne peux pas trouver ce qui peut être à l'origine de cela. Existe-t-il une sorte de limitation empêchant cela de fonctionner, ou est-ce que je manque simplement quelque chose d'évident?

Répondre

7

Je crois que l'API (consumePixmap()) est destiné à la classe Texture pour extraire des données d'un Pixmap en poussant le Pixmap jusqu'au GPU.
Un objet Libgdx Texture représente des données de texture sur le GPU, donc l'obtention des données sous-jacentes à la CPU n'est généralement pas triviale (c'est la «mauvaise» direction pour une API de rendu). Voir http://code.google.com/p/libgdx/wiki/GraphicsPixmap

En outre, la documentation sur consumePixmap() indique requires a prepare() call avant qu'il ne fonctionne.

Pour extraire des informations de pixel d'une texture, vous devez construire un objet FrameBuffer, lui appliquer la texture, puis extraire les pixels (voir ScreenUtils). Ce n'est pas clair ce que vous essayez d'accomplir, mais aller dans l'autre sens (tableau d'octets ->Pixmap ->Texture) puis modifier le tableau d'octets et refaire la transformation pourrait fonctionner.

+0

La texture est créée par l'utilisateur au sein de l'application dans une simple interface de type peinture, donc je n'ai aucune des données auparavant. Si je pouvais extraire les informations du FrameBuffer que j'utilise pour créer la texture qui serait parfaite, j'étais sous l'impression que vous ne pouviez faire cela qu'à partir du FrameBuffer par défaut qui dessine à l'écran. Dans mon cas, il est possible que la texture dépasse la résolution de l'écran, de sorte qu'elle couperait ou déformerait l'image en suivant cette route. Malheureusement, utiliser Pixmaps eux-mêmes pour le dessin n'est pas une option non plus. – Shamrock

7

J'ai rencontré un problème similaire lorsque j'ai voulu créer un PNG d'un niveau fait dans mon éditeur de niveau. Le niveau est fait de tuiles placées par le créateur, le niveau entier est alors enregistré en tant que .png pour être utilisé dans le jeu.

Résolu le chemin P.T. explique. J'espère que c'est utile pour d'autres qui rencontrent le même problème.

Et dans la configuration de votre application: cfg.useGL20 = true; GL20 doit être en mesure de construire le 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(); 

Note: Je suis nouveau à LibGDX si cela peut ne pas être la plus élégante façon de le faire.

+0

C'est exactement ce que je cherchais. Merci Toast. – LukTar

Questions connexes