BufferedImage into a Spatial of some sort?

Is it possible to turn a java.awt.image.BufferedImage, into a Geometry/Spatial for displaying



Some methods ive been been looking at are ImageToAwt.convert, and the Picture class



any examples/ideas?

Look into the “Picture” class

I have. I’m not referring to loading a image from a directly i.e “assets/…”, I’m referring to turning a BufferedImage object e.g:



public static BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_4BYTE_ABGR);



and turning that into a Picture

You should be able to do it via the ImageToAwt class

I figured i just need an example.

Like the one in TestRenderToMemory?

I would like to do the same thing that the original poster here asked about doing, however, I just looked through TestRenderToMemory, and it seems to do the opposite of what is required. It transfers a jME view into an image so that it can be displayed in a swing window.



What is required is to take a picture and apply it as an asset, but the picture is one acquired at runtime instead of one predefined in the assets directory. In my specific case, I am generating images at runtime by creating a BufferedImage and painting to it using its graphics object, and the contents of the generated image I would like to apply to a Picture object and display in the guiNode.



Does jME provide its own mechanisms for generating images in this fashion, or is the way we are going about it as good as any other?



If jME has built in a better way to handle image generation internally, what would that be? If it does not, how can a dynamically generated image be applied as the texture for a Geometry?

So basically you need to do the inverse of what TestRenderToMemory is doing. You need to create a jME3 Image from an AWT BufferedImage, I think the code you’re looking for is in the “Screenshots” class. If you create your AWT BufferedImage with the format TYPE_4BYTE_ABGR, you can essentially do a “blit” like copy directly into a jME3 Image, byte by byte. However, simply updating the ByteBuffer is not enough, you also have to call Image.setUpdateNeeded() to indicate that you changed the data.

something im trying to do too atm.



I cant test right now, because i first have to complete a vital class, but is there any reason why the AWTLoader-methods have not been declared static? I dont know if something like…



[java]BufferedImage img /* = … */;

boolean flip = true;

com.jme3.texture.Image i = ((AWTLoader) null).load(img, flip);[/java]



… is allowed, but the code would be there.

I can’t speak to why those are or aren’t static methods… but here’s the non-static way to call them:

[java]

BufferedImage img /* = … */;

boolean flip = true;

com.jme3.texture.Image i = new AWTLoader().load(img, flip);

[/java]

I looked up jME’s version of Image that you mentioned and saw that it had a constructor that takes the raw byte data and was starting to make something that would get the data and make the Image out of it; thanks for mentioning that AWTLoader().load() as that will save some time.



So, now we have a very simple way to get an Image that jME likes; great. Now there’s still the problem of using it as an asset. It looks like we have plenty of methods available for retrieving named assets, but once we have created something to use, how do we register it with the AssetManager or make it available to an AssetLocator? There does not seem to be any documentation or explanation available that I can see that discusses this.



So now we are at a similar question to the original one. How can we apply a jME Image to a Geometry?

loduwijk said:
So, now we have a very simple way to get an Image that jME likes; great. Now there's still the problem of using it as an asset. It looks like we have plenty of methods available for retrieving named assets, but once we have created something to use, how do we register it with the AssetManager or make it available to an AssetLocator? There does not seem to be any documentation or explanation available that I can see that discusses this.

You might need to make your own AssetLocator

loduwijk said:
So now we are at a similar question to the original one. How can we apply a jME Image to a Geometry?

You can put an Image inside a Texture. For a more detailed explanation, see the tutorials in the wiki.

I may have missed why asset loader has to be involved. If you have the geometry then why can’t you just set its material?

@pspeed: Because the Material constructor wants a named asset. I was not sure how to use the Image object as an asset if it did not have something to use for the defName parameter.



However, I’ve still been looking into this, and it appears that Material has a setTexture(), and Texture has a setImage()! So it looks like the problem is solved, and pretty simply.



So I think the overall answer to this thread is as follows:



Use AWTLoader.load() to get a jME Image from the AWT BufferedImage.

Make a new Texture and use setImage(image)

Make a new Material and use setTexture(texture)

Use the Material.



Result: texture on the Geometry specified by the BufferedImage.



:slight_smile:



(edit)

It would probably make sense to just have a Material constructor that takes a Texture, and a Texture constructor that takes an Image. No big deal, obviously, as otherwise it just means 1 more line, but still, it would make sense.

(/edit)

Nope, never mind, it doesn’t work that way. According to setTexture()



Parameters:

name - the name of the texture defined in the material definition (j3md) (for example Texture for Lighting.j3md)

value - the Texture object previously loaded by the asset manager



So we DO still have to go the extra mile, I guess. I’ll look into AssetLocator and see how feasible it is to make one for loading dynamically created images.



It seems odd that there is no easier way to do this. Does nobody here ever create images at runtime? Or, if they do, do they always reinvent the wheel every time? Or am I still overlooking something? If anyone knows of something I’m missing, a pointer would be greatly appreciated; until then, I’ll be going over AssetLocator.



(edit)

@Momoko_Fan: Oh, and by the way, the tutorial doesn’t cover any of this; I did take another look just to be sure I hadn’t forgotten something that was said there. The tutorials you guys have for beginners are great and they are a good way to quickly figure out how to use the system, but none of them go any further past the most basic of needs like what we’re doing here.

(/edit)



(edit2)

Never mind, I just realized I’m wasting too much time on this. Most of the stuff in the JavaDoc has no descriptions, so it’s almost impossible to figure out the relationship between the asset loading classes from that, and I don’t see where they are explained anywhere else.



For now I’m going to just start dropping or changing features in the project I’m working on that relied on dynamic images. Maybe I can come back to this topic later in the year after this project when I have time to delve into the jMonkeyEngine source code and see an example of how asset management is handled.



If someone can provide real, deep insight that would be great and I’ll continue and make whatever is necessary and post my results. Otherwise, I’m going to drop this topic for now.

(/edit2)

“the Texture object previously loaded by the asset manager” That’s just a helpful note as to where you (the general you) probably got it. You shouldn’t have to load a texture from the asset manager. It’s just an object, after all.

@pspeed: I was hoping initially that such was the case, and I did try to just make a new texture and use it, but when I tried to setTexture("", myTexture), I got an exception. That was a couple hours ago now, but if I recall correctly, I think it was a NullPointerException. It did not seem to like me telling it to use a texture without giving it a real defName.

Yeah… you have to set a texture that the shader you are using will understand. You have to give it a name. AssetLoader will not help you with that.



Steps are basically:

-create a material using one of the existing material types like Lighting.j3md

-create the image

-create a texture with the image

-set the texture on the material. Which for Lighting.j3md is “DiffuseMap”.

-set material to geometry.