Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
241 views
in Technique[技术] by (71.8m points)

java - LibGDX - Mapping Individual Textures to each face of a box using Modelbuilder.createBox

I have the following code snippet that generates a 3D cube:

ModelBuilder modelBuilder = new ModelBuilder();

box = modelBuilder.createBox(2f, 2f, 2f,
                new Material(TextureAttribute.createDiffuse(AssetLoader.tr[0])),
                VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal | VertexAttributes.Usage.TextureCoordinates
        );

So far so good. The problem is that all faces of the cube uses the same texture, whereas what I want is Assetloader.tr[], which is an array with 6 individual textures to appear on each face respectively.

I have tried

box.nodes.get(0).parts.get(0).material.set(new Material(TextureAttribute.createDiffuse(AssetLoader.tr[0])));
box.nodes.get(0).parts.get(1).material.set(new Material(TextureAttribute.createDiffuse(AssetLoader.tr[1])));
...

but somehow the documentation doesn't give me any hints for how to do it properly. I'm a bit stuck here atm.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are several considerations to keep in mind. First of all make sure to carefully read: https://github.com/libgdx/libgdx/wiki/ModelBuilder%2C-MeshBuilder-and-MeshPartBuilder.

Secondly, try to avoid the ModelBuilder#createXXX methods. They are just a shortcut for debugging and testing purposes. If you look at the code behind it, you'll see that's very straightforward:

modelBuilder.begin();
modelBuilder.part("box", GL20.GL_TRIANGLES, 
        VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal | VertexAttributes.Usage.TextureCoordinates,
        new Material(TextureAttribute.createDiffuse(AssetLoader.tr[0])))
    .box(2f, 2f, 2f);
box = modelBuilder.end();

As you can see this creates a single part for the entire box, so trying to access a second part (as you do in your example) will not work. But because you want to use a different material for each face, you'll need to create a part for each face.

int attr = VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal | VertexAttributes.Usage.TextureCoordinates;
modelBuilder.begin();
modelBuilder.part("front", GL20.GL_TRIANGLES, attr, new Material(TextureAttribute.createDiffuse(AssetLoader.tr[0])))
    .rect(-2f,-2f,-2f, -2f,2f,-2f,  2f,2f,-2, 2f,-2f,-2f, 0,0,-1);
modelBuilder.part("back", GL20.GL_TRIANGLES, attr, new Material(TextureAttribute.createDiffuse(AssetLoader.tr[1])))
    .rect(-2f,2f,2f, -2f,-2f,2f,  2f,-2f,2f, 2f,2f,2f, 0,0,1);
modelBuilder.part("bottom", GL20.GL_TRIANGLES, attr, new Material(TextureAttribute.createDiffuse(AssetLoader.tr[2])))
    .rect(-2f,-2f,2f, -2f,-2f,-2f,  2f,-2f,-2f, 2f,-2f,2f, 0,-1,0);
modelBuilder.part("top", GL20.GL_TRIANGLES, attr, new Material(TextureAttribute.createDiffuse(AssetLoader.tr[3])))
    .rect(-2f,2f,-2f, -2f,2f,2f,  2f,2f,2f, 2f,2f,-2f, 0,1,0);
modelBuilder.part("left", GL20.GL_TRIANGLES, attr, new Material(TextureAttribute.createDiffuse(AssetLoader.tr[4])))
    .rect(-2f,-2f,2f, -2f,2f,2f,  -2f,2f,-2f, -2f,-2f,-2f, -1,0,0);
modelBuilder.part("right", GL20.GL_TRIANGLES, attr, new Material(TextureAttribute.createDiffuse(AssetLoader.tr[5])))
    .rect(2f,-2f,-2f, 2f,2f,-2f,  2f,2f,2f, 2f,-2f,2f, 1,0,0);
box = modelBuilder.end();

However, having a part for each face does imply a render call for each face. It is more performant to make sure that all TextureRegions share the same texture and use that instead:

int attr = VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal | VertexAttributes.Usage.TextureCoordinates;
modelBuilder.begin();
MeshPartBuilder mpb = modelBuilder.part("box", GL20.GL_TRIANGLES, attr, new Material(TextureAttribute.createDiffuse(AssetLoader.tr[0].getTexture())));
mpb.setUVRange(AssetLoader.tr[0]);
mpb.rect(-2f,-2f,-2f, -2f,2f,-2f,  2f,2f,-2, 2f,-2f,-2f, 0,0,-1);
mpb.setUVRange(AssetLoader.tr[1]);
mpb.rect(-2f,2f,2f, -2f,-2f,2f,  2f,-2f,2f, 2f,2f,2f, 0,0,1);
mpb.setUVRange(AssetLoader.tr[2]);
mpb.rect(-2f,-2f,2f, -2f,-2f,-2f,  2f,-2f,-2f, 2f,-2f,2f, 0,-1,0);
mpb.setUVRange(AssetLoader.tr[3]);
mpb.rect(-2f,2f,-2f, -2f,2f,2f,  2f,2f,2f, 2f,2f,-2f, 0,1,0);
mpb.setUVRange(AssetLoader.tr[4]);
mpb.rect(-2f,-2f,2f, -2f,2f,2f,  -2f,2f,-2f, -2f,-2f,-2f, -1,0,0);
mpb.setUVRange(AssetLoader.tr[5]);
mpb.rect(2f,-2f,-2f, 2f,2f,-2f,  2f,2f,2f, 2f,-2f,2f, 1,0,0);
box = modelBuilder.end();

While this might help you do you want, you should really reconsider your approach. As you can see, creating a model by code can get messy really fast. And, moreover, creating a single model for a box is in most cases far from optimal unless your goal is to only render a single box and nothing more than a box. Instead use a modeling application to create your models. Have a look at my blog at http://blog.xoppa.com/ for more info. If you really want to modify parts yourself, then make sure to read at least up to and including the "behind the scenes" tutorials.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...