[SOLVED] Multi-texture models

Sorry if this have been answered elsewhere, but I haven’t been able to find any examples of using multiple textures on a model, is this at all possible?

I wanted to use one of the Mixamo-models (Erika-archer) for my game, but are having a lot of problems. One of them is that her body apparently uses another texture than her clothes.

Would be awesome if someone had the model game-ready for download, but I’d also be happy if someone could just point me in the right direction.

Yes it is possible. Models can have multiple materials and meshes, and each mesh can use a different material.
You can make a car with four wheels that use a rubber tyre material, and not need four wheel meshes, as well.
The windscreen and other windows can be made of another material, this is fine, within a single model.

Do you know of any examples of this?
just a basic one would be great since I have a hard time learning something without seeing it in action.

You can set a material per geometry by calling animatedModel->SetMaterial(geometryId , material);
The number of geometries can be checked by calling model->GetNumGeometries();

1 Like

If you create a ModelName.txt file in the same directory as the model you can call ApplyMaterialList() on the model component. This file would simply contain a list of the names of the materials.

Materials/Mat0.xml
Materials/Mat1.xml
Materials/Mat2.xml
2 Likes

How about for this model for Jack?

I’ve been trying to get the Jack.mdl model here to use the face and body textures.

It has an associated material, but it’s been edited to use no texture.

However, there are two textures, here and here that seem like the right ones.

How would the Material/Jack file need to be edited to include those two textures for this one model?

Thanks for all the tips, I think I have an idea of how to do this now.

It would still be nice if there was an example in the samples, perhaps just a change in one of the existing samples?

Create two materials JackBody.xml and JackHead.xml set technique , and diffuse texture unit to your corresponding texture files. And finally create a Jack.txt file and set to point to your materials.(as Modanung suggested)

@Dave82

  1. Created the two files, JackBody/JackHead.xml in materials folder.
  2. Copied the existing Jack.xml contents to each, and modified the texture of each
  3. Created the Jack.txt file where Jack.mdl exists and added paths to the jack materials.
  4. Made code change to ApplyMaterialList and removed to previous call to setmaterial to jack.xml.

Tested … couldn’t find Materials/JackHead.xml

ERROR: Could not find resource Materials/JackHead.xml

Tried putting in path in Jack.txt as …/Materials/JackHead.xml … same error.
Created a new folder Materials inside the models folder and put materials there … same error.
Put materials in models folder as same level as Jack.mdl and edited paths in Jack.txt to just file names … same error.

If I load the JackHead.xml material just by itself or JackBody.xml, both load fine.

If I set the material directly using either the head or body, nothing paints but default material, but no error messages.

modelObject.Material = Application.ResourceCache.GetMaterial("Materials/JackBody.xml");

But this will give Jack a colored body:

modelObject.Material = Material.FromColor(Randoms.NextColor());

Seems simple enough, what am I missing?

Here is the JackHead.xml file after edit:

<material>
  <technique name="Techniques/NoTexture.xml" />
  <parameter name="MatSpecColor" value="0.5 0.5 0.5 16" />
  <texture unit="diffuse" name="Materials/Jack_face.jpg" />
</material>

And the Jack.txt file contents:

JackHead.xml
JackBody.xml

As @sandsound pointed out, a working sample really is useful. When I try this simple case, the error messages aren’t helpful enough to figure out the problem.

The NoTexture technique does not support textures.

And … is there a technique which does? Could you give a clue?

Any technique with the word Diff, depending on your final goal.

I’d really just like to see a working example where more than one material is added to one model.

That is my goal.

I’m not 100% sure for Urho#, but there shall be someting like Materials, or some other plural property or function to setup materials for model. Or use text file, but all resource names still have to be “absolute” (relative to base resource folders)

I got it working, but it’s not working …

modelObject.ApplyMaterialList();
modelObject.Material = Application.ResourceCache.GetMaterial("Materials/JackBody.xml");

ApplyMaterialList() throws this error::

ERROR: Could not find resource Materials/JackBody.xml

But does paint Jack’s head.
The next line paints Jack’s body. No problems finding the material I guess.

JackHead.xml contents

<material>
  <technique name="Techniques/Diff.xml" />
  <parameter name="MatSpecColor" value="0.5 0.5 0.5 16" />
  <texture unit="diffuse" name="Jack_face.jpg" />
</material>

JackBody.xml contents

<material>
  <technique name="Techniques/Diff.xml" />
  <parameter name="MatSpecColor" value="0.5 0.5 0.5 16" />
  <texture unit="diffuse" name="Jack_body_color.jpg" />
</material>

Jack.txt contents

Materials/JackBody.xml
Materials/JackHead.xml

If the two lines are swapped in Jack.txt, then Jack’s head gets the body material.
modelObject.Material = always sets the body’s material, never the head.

Also, changing the path on texture of either file, for instance to:

  <texture unit="diffuse" name="Textures/Jack_body_color.jpg" />

makes no difference. There is a single Jack_body_color.jpg and setting material directly finds it regardless of the path set differently, and has no effect on the errors thrown by ApplyMaterialList().

The issue is whichever resource is listed first in Jack.txt is never found. If it’s the second line, it works fine.

Created the file in visual studio by adding a new file. Edited the contents also in visual studio. Probably something to do with encoding or line endings.

But there is a workaround, and this is then to set the material using whatever was on the first line of the .txt file. That setting overrides the first line of the .txt, which isn’t set due to some issue reading the file.

Tried adding a space and a blank line to that first line. If a blank first line, both of the resources are found, but the body will be default material. In fact, no matter what I did with the Jack.txt file, never could get the body to paint through using ApplyMaterialsList(). This very well could be due to something in the SharpReality binding, or a bug in the reading of the .txt file contents in Urho.dll.

Finally, also tried @Dave82 's suggestion for .SetMaterial, though in my exerience, the sharpreality binding tends to throw a lot of exceptions with .SetMaterial, so I don’t like to use it.

But, this works with no exceptions or errors noted in my case:

modelObject.SetMaterial(0, Application.ResourceCache.GetMaterial("Materials/JackBody.xml"));
modelObject.SetMaterial(1, Application.ResourceCache.GetMaterial("Materials/JackHead.xml"));

And if creating a lot of models, for instance for the skeletal animation model, there the errors add quite a bit of delay lessening the user experience.

Also, @Egorbo could have made a Materials field rather than a Material field. That’s a purely SharpReality issue though, unrelated.

namespace Urho
{
	partial class StaticModel
	{
		public Material Material
		{
			get { return GetMaterial(0); }
			set { SetMaterial(0, value); }
		}
	}

	partial class AnimatedModel
	{
		public Model Model
		{
			get { return base.Model; }
			set { this.SetModel(value, true); }
		}
	}
}

I remember having similar problems with Borlands Delphi back in the day, that’s why I use a simple text-editor today.

Regarding an example, I threw something together, but haven’t found a place to host it yet, besides… I’m almost certain that one of the actual devs can make something better :slight_smile:

Ugh line endings!

I’m fairly new to Linux - porting my old Windows code to Linux is painful enough without having to deal with line endings.
I feel for you.

Surely we can find a common encoding that just works? Sigh.

We did, Microsoft is just keeping up a tradition of ignoring standards.

Best ignore that for the sake of sanity. :wink:

3 Likes