I created a custom (cube) mesh, how do I set a different texture on each face?

Hey guys,
I’m working on a project which involves spawning cubes. When I have cubes that have same texture on each face, it’s simple. However I need certain cubes to have different textures on each face. I’m a long time Blender user, so I exported custom mesh with UV mapping and it works fine.
BUT, I also kinda need to make this via code, so I can edit the material inside the code immediately.
I have followed the the tutorial in the docu - https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:custom_meshes and I managed to create a simple box. Now I don’t know how to set a different texture on each face of the cube :/. My code:

    mesh1 = new Mesh();

            Vector3f[] vertices = new Vector3f[8];
            vertices[0] = new Vector3f(0, 0, 0);
            vertices[1] = new Vector3f(1, 0, 0);
            vertices[2] = new Vector3f(0, 1, 0);
            vertices[3] = new Vector3f(1, 1, 0);
            vertices[4] = new Vector3f(0, 0, 1);
            vertices[5] = new Vector3f(1, 0, 1);
            vertices[6] = new Vector3f(0, 1, 1);
            vertices[7] = new Vector3f(1, 1, 1);

            Vector3f[] texCoord = new Vector3f[8];
            texCoord[0] = new Vector3f(0, 0, 0);
            texCoord[1] = new Vector3f(1, 0, 0);
            texCoord[2] = new Vector3f(0, 1, 0);
            texCoord[3] = new Vector3f(1, 1, 0);
            texCoord[4] = new Vector3f(0, 0, 1);
            texCoord[5] = new Vector3f(1, 0, 1);
            texCoord[6] = new Vector3f(0, 1, 1);
            texCoord[7] = new Vector3f(1, 1, 1);

            int[] indexes =
                    {
                            3,1,0,
                            0,2,3,

                            7,5,1,
                            1,3,7,

                            6,4,5,
                            5,7,6,

                            2,0,4,
                            4,6,2,

                            7,3,2,
                            2,6,7,

                            1,5,4,
                            4,0,1
                    };

            mesh1.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
            mesh1.setBuffer(VertexBuffer.Type.TexCoord, 3, BufferUtils.createFloatBuffer(texCoord));
            mesh1.setBuffer(VertexBuffer.Type.Index,    3, BufferUtils.createIntBuffer(indexes));
            mesh1.updateBound();

            cube = new Geometry("MyGeometry", mesh1);
            mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
            cube.setMaterial(mat);

I’m not sure if the texCoords are correct, and if they are/are not, how to reproduce them for a cube and then how to set the textures?
Thank you very much :slight_smile:

Your texture coordinates are just the same as your vertex positions, they should be a 2D mapping to your texture

Oh I see, so I need to make 2D mapping for each vertex?

yes that’s right. Check the “Box” mesh class in JME, it should help you to get started. First get all faces to look to the same using the same tex coords, then you can look at how to get them to have different ones using a texture atlas.

I think I’m on the right path

Nearly there, just an error somewhere in the coords :). Thanks a lot.

Vector2f[] texCoord = new Vector2f[8];
texCoord[0] = new Vector2f(0,0);
texCoord[1] = new Vector2f(1,0);
texCoord[2] = new Vector2f(0,1);
texCoord[3] = new Vector2f(1,1);

texCoord[4] = new Vector2f(1,0);
texCoord[5] = new Vector2f(0,0);
texCoord[6] = new Vector2f(1,1);
texCoord[7] = new Vector2f(0,1);

No matter what I do, I can’t change the behaviour of top/bottom faces. I observed I can manipulate front/back, left/right faces, does it mean I need to have an array of 12 texCoords to change to top/bottom?

Nevermind. It must be an array of 8.

i think you should use 4 vectors for each side, so you will have each side of cube absolutely independent, so you can control what to display on any side

@Ascaria said: i think you should use 4 vectors for each side, so you will have each side of cube absolutely independent, so you can control what to display on any side

This is what I want to achieve but I can quite get there.

This is the closes I’ve gotten:

       texCoord[0] = new Vector2f(0,0);
            texCoord[1] = new Vector2f(1,0);
            texCoord[2] = new Vector2f(0,1);
            texCoord[3] = new Vector2f(1,1);

            texCoord[4] = new Vector2f(1,1);
            texCoord[5] = new Vector2f(0,1);
            texCoord[6] = new Vector2f(1,0);
            texCoord[7] = new Vector2f(0,0);

And I can’t figure out what’s wrong. I’ve drawn it and it should be correct.

You have to have 4 vertexes per face to do what you want to do. JME has an existing Box mesh you can look at.

The issue above is that the texture coordinates are all messed up for the top face because they are shared with the other four adjoining faces. That can’t really work.

1 Like
@pspeed said: You have to have 4 vertexes per face to do what you want to do. JME has an existing Box mesh you can look at.

The issue above is that the texture coordinates are all messed up for the top face because they are shared with the other four adjoining faces. That can’t really work.

That’s what I though originally. Since I have 6 faces and I want to map each of them with different texture, I will be storing 24 vertices in the Vector2f array for texCoords, is this correct? I need to make faces just like on this picture, same order as I crated the cube (according to docu)

Ok, so in case you had trouble finding it or didn’t look…

…this way I avoid repeating myself again. :wink:

1 Like
@pspeed said: Ok, so in case you had trouble finding it or didn't look... https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/java/com/jme3/scene/shape/Box.java ...this way I avoid repeating myself again. ;)

Thank you very much, I’ve done it by the Box class, used 24 vertices to begin with and it’s working.

Now I need to figure out how to place different img on each texCoord :smiley:

Cool. Easiest way is having a texture atlas:

So to use the bottom left image, your tex coords would be:
0, 0,
0.25, 0,
0.25, 0.25,
0, 0.25

(order may vary)

Is it possible to not need to have the images in the same texture?

No!

https://jmonkeyengine.github.io/wiki/jme3/beginner/hello_material.html#toolbar

Options:
-one mesh per material, one material per texture (ie: one mesh per side, basically)
-one mesh per material, texture with multiple images
-one mesh per material, custom shader that supports multiple textures

Notice the common part, though.

OK, and so how do I have a transparent overlay texture on a texture atlased one-mesh cube?

Do I have to write my own shader? And if so, how do I attach to only one object?

#1: Yes.

#2: object.setMaterial(yourmaterialbasedonyourshader).

And note: if you keep asking “how do I move my left foot forward 24 inches?” style questions then you are going to keep getting “shift the muscles in this leg” type of answers.

Versus, “I’m trying to get to Australia… what’s the best way?” In which case the answers might be veeeery different.