Set texture

I’ve created an image in the form of a bytebuffer in code, and want to set my model to use this texture. This is as far as I have got:

[java]
Material mat = new Material(new MaterialDef(asset,“name”));
Image img = new Image(Image.Format.RGBA32F,4,4,buffer);
Texture2D tex = new Texture2D(img);
[/java]

I guessed in which I should use, Texture2D or Texture3D, and just put “name” as I wasn’t sure what else.
When I do

mat.setTexture(“name”, tex);

I get

Material parameter is not defined: name

How do I use my new image?

Of course putting “name” as Material parameter and Material definition will not work.
Read How to use Materials and the Hello Material Tutorial

Hi, thanks for the reply. I should have specified I had tried various other combinations, but from your link I did get it working with "“Common/MatDefs/Misc/Unshaded.j3md” and “ColorMap”.

However… I then got

java.lang.IllegalArgumentException: Number of remaining buffer elements is 64, must be at least 256. Because at most 256 elements can be returned, a buffer with at least 256 elements is required, regardless of actual returned element count

So I changed my image size to 8 by 8, thinking my buffer size would be 884(rgba) to get 256, and then it says

java.lang.IllegalArgumentException: Number of remaining buffer elements is 256, must be at least 1024. Because at most 1024 elements can be returned, a buffer with at least 1024 elements is required, regardless of actual returned element count

My overall goal is to use a BufferedImage as my texture

Funny, I did something similar recently and had the exact same problem.
I did however not try to change the BufferedImage, but the ByteBuffer.
I’m not experienced enough (neither in Java, nor with JME) to fully explain it to you, but it basically came down to that:
The BufferedImage:
[java]
image = new BufferedImage(width, height,
BufferedImage.TYPE_4BYTE_ABGR);
[/java]
Whatever the width / height is, I create the ByteBuffer this way:
[java]
byteBuffer = BufferUtils.createByteBuffer(width * height * 4);
[/java]

I hope it helps.

Still can’t avoid the error :frowning:

Well, you have an error in how you created your buffer but we can’t see that. So it’s hard for us to help. It would be like if my answer was actually:

“how you created your buffer but we can’t see that. So”

…not as helpful without all of the information. In general, too much information is better than too little. Err on the side of more.

Well, I don’t know then…
Maybe if you would post all the relevant code + the exception…?

Very true, ok. Here is the method for BufferedImage -> Bytebuffer. I should note, this is from java-gaming, I did not write this.

[java]
private ByteBuffer convertImageData(BufferedImage image)
{
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
//width, height, bytes
ByteBuffer buffer = BufferUtils.createByteBuffer(4 * 4* 4); //4 for RGBA, 3 for RGB

    for(int y = 0; y < image.getHeight(); y++)
    {
        for(int x = 0; x < image.getWidth(); x++)
        {
            int pixel = pixels[y * image.getWidth() + x];
            buffer.put((byte) ((pixel >> 16) & 0xFF));     // Red component
            buffer.put((byte) ((pixel >> "EIGHT") & 0xFF));      // Green component
            buffer.put((byte) (pixel & 0xFF));               // Blue component
            buffer.put((byte) ((pixel >> 24) & 0xFF));    // Alpha component. Only for RGBA
        }
    }

    buffer.flip();
    return buffer;
}

[/java]
“EIGHT”: put there in the post as using the number 8 caused some image thing to come up, so yes there is an 8 in the actual code

Then,

[java]
Material mat = new Material(asset, “Common/MatDefs/Misc/Unshaded.j3md”);

    Image img = new Image(Image.Format.RGBA32F,4,4,convertImageData2(image));
    Texture2D tex = new Texture2D(img);
    mat.setTexture("ColorMap", tex);

[/java]

That image format couldnt be a problem?

I suppose I should include this too

error:

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.IllegalArgumentException: Number of remaining buffer elements is 64, must be at least 256. Because at most 256 elements can be returned, a buffer with at least 256 elements is required, regardless of actual returned element count
at org.lwjgl.BufferChecks.throwBufferSizeException(BufferChecks.java:162)
at org.lwjgl.BufferChecks.checkBufferSize(BufferChecks.java:189)
at org.lwjgl.BufferChecks.checkBuffer(BufferChecks.java:230)
at org.lwjgl.opengl.GL11.glTexImage2D(GL11.java:2845)
at com.jme3.renderer.lwjgl.TextureUtil.uploadTexture(TextureUtil.java:352)

I do this using the above convertImageData method

[java]
Material mat = new Material(asset, “Common/MatDefs/Misc/Unshaded.j3md”);

Image img = new Image(Image.Format.RGBA32F,4,4,convertImageData(image)); //convertImageData returns the bytebuffer when given the bufferedimage

Texture2D tex = new Texture2D(img);

mat.setTexture(“ColorMap”, tex);

model.setMaterial(mat); //this is when the error occurs, model is a Spatial, a model I load (assetManager.loadmodel…);

[/java]

I will put these here as hints:
http://docs.oracle.com/javase/6/docs/api/java/awt/image/BufferedImage.html#TYPE_4BYTE_ABGR
http://hub.jmonkeyengine.org/javadoc/com/jme3/texture/Image.Format.html#RGB32F

Read those descriptions carefully and you should see what your issue is.

But frankly, if all you are trying to do is convert a BufferedImage to a JME image, there is already code that will do that:
http://hub.jmonkeyengine.org/javadoc/com/jme3/texture/plugins/AWTLoader.html#load(java.awt.image.BufferedImage,%20boolean)

Image img = new AWTLoader().load(bufferedImage, false);

1 Like

edit: Thanks, I just noticed that from a post I found by norman, going to follow your links and try it, as just changing that format results in it running, but with a completely black model (I have a pointlight and ambient light)

edit2: Thats absolutely perfect, thank you, working now.