Material technique editing.

This commit is contained in:
Lasse Öörni 2013-07-30 22:57:11 +00:00
parent 6284d0db72
commit 8a94f363ee
7 changed files with 260 additions and 7 deletions

View File

@ -872,6 +872,7 @@ void InitResourcePicker()
resourcePickers.Push(ResourcePicker("Image", imageFilters));
resourcePickers.Push(ResourcePicker("Model", "*.mdl", ACTION_PICK));
resourcePickers.Push(ResourcePicker("Material", materialFilters, ACTION_PICK | ACTION_OPEN | ACTION_EDIT));
resourcePickers.Push(ResourcePicker("Technique", "*.xml"));
resourcePickers.Push(ResourcePicker("Texture2D", textureFilters));
resourcePickers.Push(ResourcePicker("TextureCube", "*.xml"));
resourcePickers.Push(ResourcePicker("ScriptFile", scriptFilters));

View File

@ -28,6 +28,9 @@ void CreateMaterialEditor()
SubscribeToEvent(materialWindow.GetChild("CloseButton", true), "Released", "HideMaterialEditor");
SubscribeToEvent(materialWindow.GetChild("NewParameterDropDown", true), "ItemSelected", "CreateShaderParameter");
SubscribeToEvent(materialWindow.GetChild("DeleteParameterButton", true), "Released", "DeleteShaderParameter");
SubscribeToEvent(materialWindow.GetChild("NewTechniqueButton", true), "Released", "NewTechnique");
SubscribeToEvent(materialWindow.GetChild("DeleteTechniqueButton", true), "Released", "DeleteTechnique");
SubscribeToEvent(materialWindow.GetChild("SortTechniquesButton", true), "Released", "SortTechniques");
}
bool ShowMaterialEditor()
@ -71,10 +74,74 @@ void RefreshMaterialName()
SubscribeToEvent(pickButton, "Released", "PickEditMaterial");
}
void RefreshMaterialTechniques()
void RefreshMaterialTechniques(bool fullUpdate = true)
{
ListView@ list = materialWindow.GetChild("TechniqueList");
list.RemoveAllItems();
if (editMaterial is null)
return;
if (fullUpdate == true)
{
list.RemoveAllItems();
for (uint i = 0; i < editMaterial.numTechniques; ++i)
{
TechniqueEntry entry = editMaterial.techniqueEntries[i];
UIElement@ container = UIElement();
container.SetLayout(LM_HORIZONTAL, 4);
container.SetFixedHeight(ATTR_HEIGHT);
list.AddItem(container);
LineEdit@ nameEdit = CreateAttributeLineEdit(container, null, i, 0);
nameEdit.name = "TechniqueNameEdit" + String(i);
Button@ pickButton = CreateResourcePickerButton(container, null, i, 0, "Pick");
SubscribeToEvent(pickButton, "Released", "PickMaterialTechnique");
Button@ openButton = CreateResourcePickerButton(container, null, i, 0, "Open");
SubscribeToEvent(openButton, "Released", "OpenResource");
if (entry.technique !is null)
nameEdit.text = entry.technique.name;
SubscribeToEvent(nameEdit, "TextFinished", "EditMaterialTechnique");
UIElement@ container2 = UIElement();
container2.SetLayout(LM_HORIZONTAL, 4);
container2.SetFixedHeight(ATTR_HEIGHT);
list.AddItem(container2);
Text@ text = container2.CreateChild("Text");
text.style = "EditorAttributeText";
text.text = "Quality";
LineEdit@ attrEdit = CreateAttributeLineEdit(container2, null, i, 0);
attrEdit.text = String(entry.qualityLevel);
SubscribeToEvent(attrEdit, "TextChanged", "EditTechniqueQuality");
SubscribeToEvent(attrEdit, "TextFinished", "EditTechniqueQuality");
text = container2.CreateChild("Text");
text.style = "EditorAttributeText";
text.text = "LOD Distance";
attrEdit = CreateAttributeLineEdit(container2, null, i, 0);
attrEdit.text = String(entry.lodDistance);
SubscribeToEvent(attrEdit, "TextChanged", "EditTechniqueLodDistance");
SubscribeToEvent(attrEdit, "TextFinished", "EditTechniqueLodDistance");
}
}
else
{
for (uint i = 0; i < editMaterial.numTechniques; ++i)
{
TechniqueEntry entry = editMaterial.techniqueEntries[i];
LineEdit@ nameEdit = materialWindow.GetChild("TechniqueNameEdit" + String(i), true);
if (nameEdit is null)
continue;
nameEdit.text = entry.technique !is null ? entry.technique.name : "";
}
}
}
void RefreshMaterialTextures(bool fullUpdate = true)
@ -95,19 +162,19 @@ void RefreshMaterialTextures(bool fullUpdate = true)
LineEdit@ nameEdit = CreateAttributeLineEdit(container, null, i, 0);
nameEdit.name = "TextureNameEdit" + String(i);
Button@ pickButton = CreateResourcePickerButton(container, null, i, 0, "Pick");
SubscribeToEvent(pickButton, "Released", "PickMaterialTexture");
Button@ openButton = CreateResourcePickerButton(container, null, i, 0, "Open");
SubscribeToEvent(openButton, "Released", "OpenResource");
if (editMaterial !is null)
{
Texture@ texture = editMaterial.textures[i];
if (texture !is null)
nameEdit.text = texture.name;
}
SubscribeToEvent(nameEdit, "TextFinished", "EditMaterialTexture");
}
}
@ -118,7 +185,7 @@ void RefreshMaterialTextures(bool fullUpdate = true)
LineEdit@ nameEdit = materialWindow.GetChild("TextureNameEdit" + String(i), true);
if (nameEdit is null)
continue;
String textureName;
if (editMaterial !is null)
{
@ -425,10 +492,142 @@ void EditMaterialTexture(StringHash eventType, VariantMap& eventData)
editMaterial.textures[index] = texture;
}
else
editMaterial.textures[index] =null;
editMaterial.textures[index] = null;
EndMaterialEdit();
}
void NewTechnique()
{
if (editMaterial is null)
return;
BeginMaterialEdit();
editMaterial.numTechniques = editMaterial.numTechniques + 1;
EndMaterialEdit();
RefreshMaterialTechniques();
}
void DeleteTechnique()
{
if (editMaterial is null || editMaterial.numTechniques < 2)
return;
BeginMaterialEdit();
editMaterial.numTechniques = editMaterial.numTechniques - 1;
EndMaterialEdit();
RefreshMaterialTechniques();
}
void PickMaterialTechnique(StringHash eventType, VariantMap& eventData)
{
if (editMaterial is null)
return;
UIElement@ button = eventData["Element"].GetUIElement();
resourcePickIndex = button.vars["Index"].GetUInt();
@resourcePicker = GetResourcePicker(ShortStringHash("Technique"));
if (resourcePicker is null)
return;
String lastPath = resourcePicker.lastPath;
if (lastPath.empty)
lastPath = sceneResourcePath;
CreateFileSelector("Pick " + resourcePicker.typeName, "OK", "Cancel", lastPath, resourcePicker.filters, resourcePicker.lastFilter);
SubscribeToEvent(uiFileSelector, "FileSelected", "PickMaterialTechniqueDone");
}
void PickMaterialTechniqueDone(StringHash eventType, VariantMap& eventData)
{
StoreResourcePickerPath();
CloseFileSelector();
if (!eventData["OK"].GetBool())
{
@resourcePicker = null;
return;
}
String resourceName = eventData["FileName"].GetString();
Resource@ res = GetPickedResource(resourceName);
if (res !is null && editMaterial !is null)
{
BeginMaterialEdit();
TechniqueEntry entry = editMaterial.techniqueEntries[resourcePickIndex];
editMaterial.SetTechnique(resourcePickIndex, res, entry.qualityLevel, entry.lodDistance);
EndMaterialEdit();
RefreshMaterialTechniques(false);
}
@resourcePicker = null;
}
void EditMaterialTechnique(StringHash eventType, VariantMap& eventData)
{
if (editMaterial is null)
return;
LineEdit@ attrEdit = eventData["Element"].GetUIElement();
String techniqueName = attrEdit.text.Trimmed();
uint index = attrEdit.vars["Index"].GetUInt();
BeginMaterialEdit();
Technique@ newTech;
if (!techniqueName.empty)
newTech = cache.GetResource("Technique", techniqueName);
TechniqueEntry entry = editMaterial.techniqueEntries[index];
editMaterial.SetTechnique(index, newTech, entry.qualityLevel, entry.lodDistance);
EndMaterialEdit();
}
void EditTechniqueQuality(StringHash eventType, VariantMap& eventData)
{
if (editMaterial is null)
return;
LineEdit@ attrEdit = eventData["Element"].GetUIElement();
uint newQualityLevel = attrEdit.text.ToUInt();
uint index = attrEdit.vars["Index"].GetUInt();
BeginMaterialEdit();
TechniqueEntry entry = editMaterial.techniqueEntries[index];
editMaterial.SetTechnique(index, entry.technique, newQualityLevel, entry.lodDistance);
EndMaterialEdit();
}
void EditTechniqueLodDistance(StringHash eventType, VariantMap& eventData)
{
if (editMaterial is null)
return;
LineEdit@ attrEdit = eventData["Element"].GetUIElement();
float newLodDistance = attrEdit.text.ToFloat();
uint index = attrEdit.vars["Index"].GetUInt();
BeginMaterialEdit();
TechniqueEntry entry = editMaterial.techniqueEntries[index];
editMaterial.SetTechnique(index, entry.technique, entry.qualityLevel, newLodDistance);
EndMaterialEdit();
}
void SortTechniques()
{
if (editMaterial is null)
return;
BeginMaterialEdit();
editMaterial.SortTechniques();
EndMaterialEdit();
RefreshMaterialTechniques();
}
void BeginMaterialEdit()

View File

@ -31,6 +31,39 @@
<element type="ListView">
<attribute name="Name" value="TechniqueList" />
</element>
<element>
<attribute name="Name" value="TechniqueButtonContainer" />
<attribute name="Min Size" value="0 16" />
<attribute name="Max Size" value="2147483647 16" />
<attribute name="Layout Mode" value="Horizontal" />
<element type="Button">
<attribute name="Name" value="NewTechniqueButton" />
<attribute name="Layout Mode" value="Horizontal" />
<attribute name="Layout Border" value="1 1 1 1" />
<element type="Text">
<attribute name="Text" value="New" />
<attribute name="Text Alignment" value="Center" />
</element>
</element>
<element type="Button">
<attribute name="Name" value="DeleteTechniqueButton" />
<attribute name="Layout Mode" value="Horizontal" />
<attribute name="Layout Border" value="1 1 1 1" />
<element type="Text">
<attribute name="Text" value="Del" />
<attribute name="Text Alignment" value="Center" />
</element>
</element>
<element type="Button">
<attribute name="Name" value="SortTechniquesButton" />
<attribute name="Layout Mode" value="Horizontal" />
<attribute name="Layout Border" value="1 1 1 1" />
<element type="Text">
<attribute name="Text" value="Sort" />
<attribute name="Text Alignment" value="Center" />
</element>
</element>
</element>
<element type="BorderImage" style="EditorDivider" />
<element type="Text">
<attribute name="Text" value="Textures" />

View File

@ -2078,6 +2078,7 @@ Methods:<br>
- void SetUVTransform(const Vector2&, float, const Vector2&)
- void SetUVTransform(const Vector2&, float, float)
- void RemoveShaderParameter(const String&)
- void SortTechniques()
- Material@ Clone(const String& arg0 = String ( )) const
Properties:<br>

View File

@ -84,6 +84,14 @@ TextureUnit ParseTextureUnitName(const String& name)
static TechniqueEntry noEntry;
bool CompareTechniqueEntries(const TechniqueEntry& lhs, const TechniqueEntry& rhs)
{
if (lhs.lodDistance_ != rhs.lodDistance_)
return lhs.lodDistance_ > rhs.lodDistance_;
else
return lhs.qualityLevel_ > rhs.qualityLevel_;
}
TechniqueEntry::TechniqueEntry() :
qualityLevel_(0),
lodDistance_(0.0f)
@ -176,6 +184,8 @@ bool Material::Load(const XMLElement& source)
techniqueElem = techniqueElem.GetNext("technique");
}
SortTechniques();
XMLElement textureElem = source.GetChild("texture");
while (textureElem)
{
@ -426,6 +436,11 @@ SharedPtr<Material> Material::Clone(const String& cloneName) const
return ret;
}
void Material::SortTechniques()
{
Sort(techniques_.Begin(), techniques_.End(), CompareTechniqueEntries);
}
void Material::MarkForAuxView(unsigned frameNumber)
{
auxViewFrameNumber_ = frameNumber;

View File

@ -109,6 +109,8 @@ public:
void ReleaseShaders();
/// Clone material.
SharedPtr<Material> Clone(const String& cloneName = String::EMPTY) const;
/// Ensure that material techniques are listed in correct order.
void SortTechniques();
/// Mark material for auxiliary view rendering.
void MarkForAuxView(unsigned frameNumber);

View File

@ -600,6 +600,7 @@ static void RegisterMaterial(asIScriptEngine* engine)
engine->RegisterObjectBehaviour("TechniqueEntry", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructTechniqueEntry), asCALL_CDECL_OBJLAST);
engine->RegisterObjectBehaviour("TechniqueEntry", asBEHAVE_CONSTRUCT, "void f(const TechniqueEntry&in)", asFUNCTION(ConstructTechniqueEntry), asCALL_CDECL_OBJLAST);
engine->RegisterObjectBehaviour("TechniqueEntry", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructTechniqueEntry), asCALL_CDECL_OBJLAST);
engine->RegisterObjectMethod("TechniqueEntry", "TechniqueEntry& opAssign(const TechniqueEntry&in)", asMETHOD(TechniqueEntry, operator =), asCALL_THISCALL);
engine->RegisterObjectMethod("TechniqueEntry", "void set_technique(Technique@+)", asFUNCTION(TechniqueEntrySetTechnique), asCALL_CDECL_OBJLAST);
engine->RegisterObjectMethod("TechniqueEntry", "Technique@+ get_technique() const", asFUNCTION(TechniqueEntryGetTechnique), asCALL_CDECL_OBJLAST);
engine->RegisterObjectProperty("TechniqueEntry", "int qualityLevel", offsetof(TechniqueEntry, qualityLevel_));
@ -612,6 +613,7 @@ static void RegisterMaterial(asIScriptEngine* engine)
engine->RegisterObjectMethod("Material", "void SetUVTransform(const Vector2&in, float, const Vector2&in)", asMETHODPR(Material, SetUVTransform, (const Vector2&, float, const Vector2&), void), asCALL_THISCALL);
engine->RegisterObjectMethod("Material", "void SetUVTransform(const Vector2&in, float, float)", asMETHODPR(Material, SetUVTransform, (const Vector2&, float, float), void), asCALL_THISCALL);
engine->RegisterObjectMethod("Material", "void RemoveShaderParameter(const String&in)", asMETHOD(Material, RemoveShaderParameter), asCALL_THISCALL);
engine->RegisterObjectMethod("Material", "void SortTechniques()", asMETHOD(Material, SortTechniques), asCALL_THISCALL);
engine->RegisterObjectMethod("Material", "Material@ Clone(const String&in cloneName = String()) const", asFUNCTION(MaterialClone), asCALL_CDECL_OBJLAST);
engine->RegisterObjectMethod("Material", "void set_numTechniques(uint)", asMETHOD(Material, SetNumTechniques), asCALL_THISCALL);
engine->RegisterObjectMethod("Material", "uint get_numTechniques() const", asMETHOD(Material, GetNumTechniques), asCALL_THISCALL);