Added .mtl loader to ObjLoader #71

merged 4 commits into from Oct 19, 2012

5 participants


adds support to load .mtl material files (diffuse+specular colors +texture)

@Danny02 Danny02 and 1 other commented on an outdated diff Oct 16, 2012
@@ -38,6 +45,8 @@
* @author mzechner, espitz */
public class ObjLoader implements StillModelLoader {
+ public static String TEXTURE_PATH = "data/textures/";
Danny02 Oct 16, 2012

all these global state ^^

isn't it possible to give the default texture path as a parameter?
or just delete it completly, the texture paths in the mdl file would just have to point to the full path

badlogic Oct 16, 2012 libgdx member

Agreed, the global state has to be removed. Passing in an additional parameter specifying the texture root directory voa a FileHandle shouldn't be an issue. Texture file names could be derrived from texturedir.child("texturefile.png").


Oops I updated that file and your comments disappeared.

I removed TEXTURE_PATH and did it differently now. If user doesnt give textureDir parameter, then it loads textures at the same directory where .obj file is.

model = ModelLoaderRegistry.loadStillModel(Gdx.files.internal(fileName)); // loads where fileName is

ObjLoader obj=new ObjLoader();
model = obj.loadObj(Gdx.files.internal(fileName), Gdx.files.internal("data/textures"), false);
// loads textures from data/textures

bosoni fix fb61bac
libgdx member

I used to use a similar (but quick and dirty) solution: And I think it's usefull to add.

However I found that it causes alot of unneccessary texture switching, because it didn't reuse textures which are shared among models and materials. So I think ideally it would use AssetManager (I'm currently experimenting with that).


Checked that, but not sure what you mean. What I should do next?
You mean textures shouldnt loaded this way (of course if these load them everytime and dont make a copy), havent read Texture loader code yet to check it, I just thought it doesnt load textures multiple times.

libgdx member

I meant that I think it's a usefull functionality to add. I can't see why it shouldn't be added at this moment. Textures not being reused should IMHO not necessarily prevent that. Just thought it might help to share my experience.


Im sorry, I still dont get what you mean (sometimes Im just blind when reading others code)?
Paste specific point, then hopefully see what you mean.

libgdx member

I totally see what you mean now, sorry for being unclear. With "it" in above comments I meant a mtl loader in general or your pull request in particular. Forget about the link I mentioned. So to rephrase.

I think a mtl loader is usefull to add and I don't see a reason why your pull request shouldn't be included. It could be optimized by reusing textures, however that can be added later.


I totally misunderstood you, sorry about that :D (it happens time to time ;) )

I just checked how libgdx loads textures. It doesnt check if texture is already loaded. I can add that check to this mtl loader but I think it should be in the Texture -class.
ie in Texture -class

private static HashMap< Texture, String > //(where string is that texture's filename), and
mytex = new Texture("something.jpg"); // returns already loaded Texture object or new one.

(or using FileHandle instead of String but something like that)

[blah blah text removed]


yes I agree totaly it is not the concern of a model loader to cache textures

libgdx member

AssetManager does reuse textures and handles reference counting if I'm not mistaken.

libgdx member

The implementation I am currently testing uses some abstraction:

package com.badlogic.gdx.assets;

public interface AssetProvider {
    <T> T provide(String fileName, Class<T> type);

public interface TypedAssetProvider<T> extends AssetProvider {
    T provide(String fileName);
// this might as well be an abstact class with a default provide(string, class<t>) implementation.

A slightly changed ModelLoaderHints:

public class ModelLoaderHints {
    public final boolean flipV;
    public final AssetProvider provider;
// etc

And then in the MtlLoader you can do something like this:

Texture texture;
if (hints.provider != null)
  texture = hints.provider.provide(texturename, Texture.class);
if (texture == null) // fall back to default behaviour:
  texture = new Texture(....);

Now you can either use your own implementation:

new AssetProvider() {
<T> T provide(String fileName, Class<T> type) {
  if (type == Texture.class)
    return SomeTextureCacheImplementation.get(fileName);
  return null;

Or AssetManager can implement the AssetProvider interface (which was my goal in the first place). However, that requires AssetManager to be modified with a synchronous JIT loader if necessary. (Hence the TypedAssetProvider which AssetLoader could implement for easy maintenance).

However I guess thats way beyond the scope of this commit, thats why I mentioned I could be added later.

BTW, in my experiments I go a bit futher and also allow hints.provider to provide a TextureRegion (for packed textured) and I then remap the UV's of the mesh accordingly.


Ok, I will check AssetManager, hopefully tomorrow.


texture loading is now via AssetManager.

libgdx member

Hm, i guess i'll have to come up with a proper texture/material managment mechanism for the 3D API/loaders once i tackle that problem. I'll merge this in for now, though it's not 100% ideal (e.g. new Texture(1, 1, Format.RGB888), or calls to assetManager.finishLoading()).

Thanks a bunch!

@badlogic badlogic merged commit 61b5d6d into libgdx:master Oct 19, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment