Material XML Plugin
From C4 Engine Wiki
Contents |
Introduction
The MaterialXML Plug-In allows you to import XML into MAT files or MaterialObjects, as well as export MaterialObjects or MAT files as XML
Installation
Download the current version and unzip it in the root C4 folder. The download contains a configuration file, several examples, the source code, and VC++ 2008 project.
A few small changes to the engine code are necessary. First, in ToolCode/C4MaterialContainer.h, change the declaration of
MaterialResource(const char *name, ResourceCatalog *catalog);
to
C4EDITORAPI MaterialResource(const char *name, ResourceCatalog *catalog);
Also, in EngineCode/C4PrefixWindows.h, add the following line after the other includes:
#include "../ToolCode/MaterialXMLtinyxml.h"
Compile the new project, and then run C4. Type ixmat in the console, and you should get a message with the usage.
Command Line Usage
ixmat path/to/xmt/file path/to/mat/file
This will create a material in the Data folder that corresponds to the name and path of the imported file. The file to be imported must have the extension xmt. Keep in mind the import path is relative to the Import folder in the root C4 directory.
exmat path/to/mat/file path/to/xmt/file
This will create an XML material file (extension .xmt) in the path you specify under the Export directory in the root C4 diretory.
Examples
The source code ships with two example MAT files, and two example XMT files. The example MAT files are in Data/MatXML/Examples. To verify we can export "simple" (non-shader graph materials), enter the following command
exmat Examples/export_simple MatXML/Examples/export_simple
You should now be able to browse to the Export/MatXML/Examples folder in your file manager and open up export_simple.xmt in a text editor and see the XML.
Now we can try import a material. In the console, type
ixmat MatXML/Examples/import_simple MatXML/Examples/import_simple
In the Material Manager, you should now be able to Import your new material. Click on the Import button, and browse to Data/MatXML/Examples and select import_simple.mat.
Syntax
Shader Materials
Introduction
The basic shader material XML looks like this:
<material name="impostNorm"> <ambient> <processes> </processes> </ambient> <lighting> <processes> </processes> </lighting> </material>
The name attribute will be the name displayed for the material in the material manager, not the file name. The processess element may contain ambient and lighting elements. The processes under these elements will be put in the ambient and lighting graphs, respectively. Here's a simple shader that connects a constant color to the ambient lighting output:
<material name="someMaterial"> <processes> <ambient> <process type="ConstantColor" x="-450" y="72"> <settings> <ColorSetting identifier="COLR" r="1" g="1" b="1" a="1" /> </settings> <routes> <route connectTo="AmbientOutput" port="RGB"/> </routes> </process> </ambient> </processes> </material>
Process
The syntax for the process element is as follows
<process type="ProcessType" x="xPos" y="yPos" id="ProcID" />
The ProcessType is one of those defined in Data\Tools\MatXML\MaterialConfig.xcf. You can specify the x and y coordinates of the process in the shader editor, but this is purely cosmetic and not necessary if no one is going to be looking at them. The id is only necessary if you are going to connect any other processes to this process (see Routes).
Settings
Processes can have 0 or more settings. Settings are listed within the <settings> element, like so
<process type="ConstantColor" > <settings> <ColorSetting identifier="COLR" r="1" g="1" b="1" a="1" /> </settings> </process>
All settings need to have the identifier attribute. In the current version, you must know ahead of time what identifier is needed for what setting by looking at the source code, such as ColorProcess::SetSetting().
ColorSetting
This setting has four optional attributes, "r","g","b" and "a". These correspond to the decimal values of the respective color channels. Any missing attributes will be assumed to be 0.
TextSetting
This setting has one required field, value. This field is interpreted however the process chooses to interpret it (such as a float when used as a setting for ConstantScalar.
ResourceSetting
This setting allows you to pass resources (most likely textures) to a process. The path attribute specifies where it is. For example,
<ResourceSetting identifier="TNAM" path="texture/banner" />
At this time, all ResourceSettings are hard-coded to use the TEX resource descriptor. This should be fine unless you have a custom process which uses another resource type
Routes
You'll likely want to connect one process to another, and to do so, you need Routes. The Route element has two required attributes, connectTo, and port. connectTo should either be a process ID as specified by the id attribute in one of your defined process elements, or as one of the output elements as defined in Data\Tools\MatXML\MaterialConfig.xcf. The port needs to be known ahead of time, either by examining the inputs for the target process in the shader editor, or looking at the source code. Here's an example of the TexCoord interpolator being connected to a texture map.
<process type="TextureMap" id="texmap1"> <settings> <ResourceSetting identifier="TNAM" path="texture/banner" /> </settings> </process> <process type="TexCoord1"> <routes> <route connectTo="texmap1" port="TEXC" /> </routes> </process>
The order of processes does not matter. That is, you do not need to declare a process before it is referenced, as the code scans once for processes and then resolves routes afterward. It's possible to connect a single process to multiple routes by adding additional <route> elements.
<process type="TexCoord1"> <routes> <route connectTo="texmap1" port="TEXC" /> <route connectTo="texmap2" port="TEXC" /> </routes> </process>
You may want to specify the "swizzle" for a route. You can do that with the swizzle attribute.
<route connectTo="someProcess" port="A" swizzle="a" />
The swizzle can be up to 4 letters from the set {x, y, z, w, r, g, b, a}.
Parsing Strings
There is support for directly parsing XML strings into material objects.
To call the plugin from your code, add the following line in the Linker > Input > Additional Dependencies field in your project properties:
../MaterialXML/$(OutDir)/MaterialXML.lib
The syntax is the following:
MaterialObject * mat = TheMaterialXMLPlugin->ParseXML(constStringPtr);
Example
Here's a sample XML string for the shader graph for creating an impostor normal/depth map
<material name="impostNorm"> <processes> <ambient> <process type="GenerateImpostorDepth" x="-450" y="-160"> <routes> <route connectTo="AmbientAlphaOutput" port="A"/> </routes> </process> <process type="GenerateImpostorNormal" x="-450" y="72"> <routes> <route connectTo="AmbientOutput" port="RGB"/> </routes> </process> <process type="TextureMap" id="texmap1" x="-450" y="280"> <settings> <ResourceSetting identifier="TNAM" path="texture/banner" /> </settings> <routes> <route connectTo="kill" port="A" swizzle="a" /> </routes> </process> <process type="KillFragment" x="-450" y="450" id="kill" /> <process type="ConstantScalar" x="-750" y="450"> <settings> <TextSetting setting="VALU" value="0.5" /> </settings> <routes> <route connectTo="kill" port="B"/> </routes> </process> <process type="TexCoord1" x="-750" y="72"> <routes> <route connectTo="texmap1" port="TEXC" /> </routes> </process> </ambient> </processes> </material>
ToDo
Currently, there is no support for the settings under the TexCoords tab (animation/scaling). In addition, not all process settings are supported at this time.

