How To Export Blender Models to OpenGL ES: Part 2/3

In this second part of our Blender to OpenGL ES tutorial series, learn how to export and render your model’s materials! By Ricardo Rendon Cepeda.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 6 of this article. Click here to view the first page.

The MTL File Format

The Material Template Library (.mtl) definition describes a list of materials referenced by the geometry of an OBJ file, specifically its faces. While OBJ and MTL files go hand-in-hand, be aware that there are other popular ways to reference materials, such as mapping.

Nonetheless, now that you know all about OBJ files, you’ll have an easy time analyzing and parsing an MTL file. Plus, working with MTL is a great way to better understand the back-end of computer graphics and, later on, implement a neat shader.

An OBJ file linked to an MTL file will reference materials by name. The MTL file lists the properties of these materials with many possible attributes, but you’ll only be implementing diffuse and specular colors. You know something about these already, so let’s get to exporting!

Exporting an MTL File From Blender

MTL files are exported along with OBJ files, so many of the steps below are repeated from Part 1, but they’re worth a second walkthrough.

In Blender, with cube.blend open, go to File\Export\Wavefront (.obj). An export screen with many options will appear. Check the following boxes:

  • Include Normals
  • Include UVs
  • Write Materials
  • Triangulate Faces

Uncheck all other boxes and leave the remaining fields in their default state. Name your file cube.obj and click Export OBJ. Your materials will be exported as cube.mtl automatically. You may export or copy your newly-minted OBJ and MTL files to your /Resources/ folder if you wish.

b_Export

Your material-laden cube is ready! That’s all you need from Blender for now, so you may close the application.

Analyzing Your MTL File

Using a text editor like TextEdit, open cube.obj. Its contents should look like this, possibly with some irrelevant differences due to floating point imprecision or a different order to the lines.

All the geometry components (v, vt, vn, f) will be the same as in Part 1. There is a new line towards the top of the file that looks like this:

mtllib cube.mtl

This is the reference to your MTL file, cube.mtl. That’s simple enough. If you scroll down to the end of the file, you’ll see a more interesting set of lines:

usemtl MaterialPhongC
f 1/5/6 2/8/6 3/9/6
f 1/5/6 3/9/6 4/3/6

This is a reference to the material MaterialPhongC in your linked MTL file. The material is attached to all the faces listed below the usemtl declaration—in this case, two faces.

Let’s follow this reference. Open cube.mtl in the same text editor. Its contents should look like this.

As mentioned earlier, in this tutorial you’ll only be implementing diffuse and specular colors. Using MaterialPhongC as an example again, let’s examine the relevant lines in cube.mtl:

newmtl MaterialPhongC
Kd 0.000000 0.500000 0.500000
Ks 1.000000 1.000000 1.000000

In cube.blend, MaterialPhongC is a cyan surface with a white highlight. In your MTL file, the following lines represent this material:

  • Name (newmtl): The name of the material (referenced in your OBJ file).
  • Diffuse color (Kd): The diffuse color of your material, in RGB color mode, with each channel ranging from 0.0 to 1.0. In this case, it’s the dark cyan: color r=0.0, g=0.5, b=0.5.
  • Specular color (Ks): The specular color of your material, defined as above. In this case, it’s a pure white color: r=1.0, g=1.0, b=1.0.

That’s all you need to know about MTL files for this tutorial! You’re ready to extend your command line tool, so feel free to take a break before you start coding.

Building Your MTL to OpenGL ES Tool

Before you begin, locate your command line tool project directory using Finder (/Code/blender2opengles/) and copy your exported model files, cube.obj and cube.mtl, into the folder named source.

Using Xcode, open the blender2opengles project included in the starter kit for this part of the tutorial. As mentioned before, this is exactly the same project from Part 1, with no modifications.

Build and run your project. As expected, cube.h and cube.c are written to your directory (/Code/blender2opengles/product).

You’ll be writing to console many times before you write to a file, so for now comment out the following lines in main()—you’ll use these later:

// Save for later...
    
/*
// Write H file
writeH(filepathH, nameOBJ, model);
    
// Write C file
writeCvertices(filepathC, nameOBJ, model);
writeCpositions(filepathC, nameOBJ, model, faces, positions);
writeCtexels(filepathC, nameOBJ, model, faces, texels);
writeCnormals(filepathC, nameOBJ, model, faces, normals);
*/

Add the following line to the beginning of main(), amongst the other file path definitions:

string filepathMTL = "source/" + nameOBJ + ".mtl";

This will be a handy reference to your MTL file.

In Part 1 you created a useful data structure, Model, to represent your model’s geometry. You’re now enhancing your model with materials, so it would be very useful to have a field for the number of materials. At the top of main.cpp, add the following line as the last member within the typedef for the struct Model:

int materials;

That’s a pretty easy setup for your materials, so let’s move on.

The Material Info

It’s time to write a function to read your MTL file. Add the following function definition to main.cpp, above main():

// 1
int getMTLinfo(string fp)
{
    // 2
    int m = 0;
    
    // 3
    // Open MTL file
    ifstream inMTL;
    inMTL.open(fp);
    if(!inMTL.good())
    {
        cout << "ERROR OPENING MTL FILE" << endl;
        exit(1);
    }
    
    // 4
    // Read MTL file
    while(!inMTL.eof())
    {
        // 5
        string line;
        getline(inMTL, line);
        string type = line.substr(0,2);
        
        if(type.compare("ne") == 0)
            m++;
    }
    
    // 6
    // Close MTL file
    inMTL.close();
    
    // 7
    return m;
}

This method should be very familiar since it’s almost an exact copy of getOBJInfo() from Part 1. Here’s a quick refresher of what’s happening:

  1. fp is the path of your MTL file.
  2. m is a counter for your materials.
  3. ifstream opens your MTL file for reading (input).
  4. You read your MTL file from start to finish.
  5. Each material declaration begins with the identifier newmtl, which is the only identifier in the MTL file that begins with “ne”. Therefore, the parser examines each line for this two-character token and increases the material counter m whenever it finds a match.
  6. You close your MTL file.
  7. You return your material counter, m.

You’ll now verify the number of materials returned. Add the following lines to main(), right after you initialize your model by calling getOBJinfo():

model.materials = getMTLinfo(filepathMTL);
cout << "Materials: " << model.materials << endl;

Build and run! You already know that you have six materials and now your program knows, too. :]

s_MaterialInfo

Ricardo Rendon Cepeda

Contributors

Ricardo Rendon Cepeda

Author

Over 300 content creators. Join our team.