Reputation: 115
In my libgdx project I'm trying to add additional materials to model. Actually, I need to obtain texture combination - texture of the following material must be placed on the texture of the previous one. In some cases with transparency.
Something like that
Model knight = assets.get("data/g3d/knight.g3db", Model.class);
knightInstance = new ModelInstance(knight);
Material additionalMaterial = new Material();
knightInstance.materials.add(additionalMaterial);
knightInstance.materials.get(0).clear();
knightInstance.materials.get(0).set(TextureAttribute.createDiffuse(assets.get("data/g3d/checkboard.png", Texture.class)));
BlendingAttribute blendingAttribute1 = new BlendingAttribute(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, 0.4f);
knightInstance.materials.get(0).set(blendingAttribute1);
knightInstance.materials.get(1).clear();
knightInstance.materials.get(1).set(TextureAttribute.createDiffuse(assets.get("data/g3d/tiles.png", Texture.class)));
BlendingAttribute blendingAttribute2 = new BlendingAttribute(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, 0.6f);
knightInstance.materials.get(1).set(blendingAttribute2);
Offcorse, It doesn't work. Only first material is visible. Is that possible to do in LibGDX?
Upvotes: 2
Views: 4762
Reputation: 8123
You can only have one material per NodePart (which is the actual mesh/material combination being rendered).
If you simply want to render your model twice, but with a different texture the second time. You can also create two ModelInstances and set the texture on each like you did above.
If you don't want to create two ModelInstances, you can also duplicate the NodePart within the model (or modelinstance). Assuming your model has one node with one part, this can be done like this:
Model knight = assets.get(...);
NodePart part1 = knight.nodes.get(0).parts.get(0);
NodePart part2 = new NodePart(part1.meshPart, new Material());
knight.nodes.get(0).parts.add(part2);
part1.material.set(TextureAttribute.createDiffuse(texture1));
part2.material.set(TextureAttribute.createDiffuse(texture2));
Note that this will remove any skinning/bones information from the second NodePart. If your model is animated/skinned, you'll need to copy the bones array and bind poses as well.
Depending on depth testing, this method (rendering the NodePart twice) will probably not work as you might expect it. And if it works, I would not recommend it. Instead you should use a shader to combine the two textures.
Each material attribute basically represents an uniform of the shader. If you want to combine two textures, you will have to create a shader that implements the actual rendering. Next you can add two TextureAttributes (of different types) to your material to be used by your shader. Have a look at: http://blog.xoppa.com/using-materials-with-libgdx/ where this is explained in detail including an example.
Upvotes: 3