mirror of
https://github.com/BlackMATov/unity-flash-tools.git
synced 2025-12-16 22:19:31 +07:00
going to open source
This commit is contained in:
252
Assets/FlashTools/Scripts/Editor/FTEditor/SwfMaterialCache.cs
Normal file
252
Assets/FlashTools/Scripts/Editor/FTEditor/SwfMaterialCache.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEditor;
|
||||
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor {
|
||||
class SwfMaterialCache {
|
||||
|
||||
const string SwfSimpleShaderName = "SwfSimpleShader";
|
||||
const string SwfMaskedShaderName = "SwfMaskedShader";
|
||||
const string SwfSimpleGrabShaderName = "SwfSimpleGrabShader";
|
||||
const string SwfMaskedGrabShaderName = "SwfMaskedGrabShader";
|
||||
const string SwfIncrMaskShaderName = "SwfIncrMaskShader";
|
||||
const string SwfDecrMaskShaderName = "SwfDecrMaskShader";
|
||||
|
||||
static Dictionary<string, Shader> ShaderCache = new Dictionary<string, Shader>();
|
||||
static Shader GetShaderByName(string shader_name) {
|
||||
Shader shader;
|
||||
if ( !ShaderCache.TryGetValue(shader_name, out shader) || !shader ) {
|
||||
shader = SafeLoadShader(shader_name);
|
||||
ShaderCache.Add(shader_name, shader);
|
||||
}
|
||||
shader.hideFlags = HideFlags.HideInInspector;
|
||||
return shader;
|
||||
}
|
||||
|
||||
static Dictionary<string, Material> MaterialCache = new Dictionary<string, Material>();
|
||||
static Material GetMaterialByPath(
|
||||
string material_path,
|
||||
Shader material_shader,
|
||||
System.Func<Material, Material> fill_material)
|
||||
{
|
||||
Material material;
|
||||
if ( !MaterialCache.TryGetValue(material_path, out material) || !material ) {
|
||||
material = SafeLoadMaterial(material_path, material_shader, fill_material);
|
||||
MaterialCache.Add(material_path, material);
|
||||
}
|
||||
material.hideFlags = HideFlags.HideInInspector;
|
||||
return material;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Functions
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
public static Material GetSimpleMaterial(
|
||||
SwfBlendModeData.Types blend_mode)
|
||||
{
|
||||
return LoadOrCreateMaterial(
|
||||
SelectShader(false, blend_mode),
|
||||
(dir_path, filename) => {
|
||||
return string.Format(
|
||||
"{0}/{1}_{2}.mat",
|
||||
dir_path, filename, blend_mode);
|
||||
},
|
||||
material => FillMaterial(material, blend_mode, 0));
|
||||
}
|
||||
|
||||
public static Material GetMaskedMaterial(
|
||||
SwfBlendModeData.Types blend_mode,
|
||||
int stencil_id)
|
||||
{
|
||||
return LoadOrCreateMaterial(
|
||||
SelectShader(true, blend_mode),
|
||||
(dir_path, filename) => {
|
||||
return string.Format(
|
||||
"{0}/{1}_{2}_{3}.mat",
|
||||
dir_path, filename, blend_mode, stencil_id);
|
||||
},
|
||||
material => FillMaterial(material, blend_mode, stencil_id));
|
||||
}
|
||||
|
||||
public static Material GetIncrMaskMaterial() {
|
||||
return LoadOrCreateMaterial(
|
||||
GetShaderByName(SwfIncrMaskShaderName),
|
||||
(dir_path, filename) => {
|
||||
return string.Format(
|
||||
"{0}/{1}.mat",
|
||||
dir_path, filename);
|
||||
},
|
||||
material => material);
|
||||
}
|
||||
|
||||
public static Material GetDecrMaskMaterial() {
|
||||
return LoadOrCreateMaterial(
|
||||
GetShaderByName(SwfDecrMaskShaderName),
|
||||
(dir_path, filename) => {
|
||||
return string.Format(
|
||||
"{0}/{1}.mat",
|
||||
dir_path, filename);
|
||||
},
|
||||
material => material);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Private
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static Shader SafeLoadShader(string shader_name) {
|
||||
var filter = string.Format("t:Shader {0}", shader_name);
|
||||
var shader = SwfEditorUtils.LoadFirstAssetByFilter<Shader>(filter);
|
||||
if ( !shader ) {
|
||||
throw new UnityException(string.Format(
|
||||
"SwfMaterialCache. Shader not found: {0}",
|
||||
shader_name));
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
static Material SafeLoadMaterial(
|
||||
string material_path,
|
||||
Shader material_shader,
|
||||
System.Func<Material, Material> fill_material)
|
||||
{
|
||||
var material = AssetDatabase.LoadAssetAtPath<Material>(material_path);
|
||||
if ( !material ) {
|
||||
material = fill_material(new Material(material_shader));
|
||||
material.hideFlags = HideFlags.HideInInspector;
|
||||
AssetDatabase.CreateAsset(material, material_path);
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
static Material LoadOrCreateMaterial(
|
||||
Shader shader,
|
||||
System.Func<string, string, string> path_factory,
|
||||
System.Func<Material, Material> fill_material)
|
||||
{
|
||||
var shader_path = AssetDatabase.GetAssetPath(shader);
|
||||
var shader_dir = Path.GetDirectoryName(shader_path);
|
||||
var generated_dir = Path.Combine(shader_dir, "Generated");
|
||||
if ( !AssetDatabase.IsValidFolder(generated_dir) ) {
|
||||
AssetDatabase.CreateFolder(shader_dir, "Generated");
|
||||
}
|
||||
var material_path = path_factory(
|
||||
generated_dir,
|
||||
Path.GetFileNameWithoutExtension(shader_path));
|
||||
return GetMaterialByPath(material_path, shader, fill_material);
|
||||
}
|
||||
|
||||
static Shader SelectShader(bool masked, SwfBlendModeData.Types blend_mode) {
|
||||
switch ( blend_mode ) {
|
||||
case SwfBlendModeData.Types.Normal:
|
||||
case SwfBlendModeData.Types.Layer:
|
||||
case SwfBlendModeData.Types.Multiply:
|
||||
case SwfBlendModeData.Types.Screen:
|
||||
case SwfBlendModeData.Types.Lighten:
|
||||
case SwfBlendModeData.Types.Add:
|
||||
case SwfBlendModeData.Types.Subtract:
|
||||
return GetShaderByName(masked ? SwfMaskedShaderName : SwfSimpleShaderName);
|
||||
case SwfBlendModeData.Types.Darken:
|
||||
case SwfBlendModeData.Types.Difference:
|
||||
case SwfBlendModeData.Types.Invert:
|
||||
case SwfBlendModeData.Types.Overlay:
|
||||
case SwfBlendModeData.Types.Hardlight:
|
||||
return GetShaderByName(masked ? SwfMaskedGrabShaderName : SwfSimpleGrabShaderName);
|
||||
default:
|
||||
throw new UnityException(string.Format(
|
||||
"SwfMaterialCache. Incorrect blend mode: {0}",
|
||||
blend_mode));
|
||||
}
|
||||
}
|
||||
|
||||
static Material FillMaterial(
|
||||
Material material,
|
||||
SwfBlendModeData.Types blend_mode,
|
||||
int stencil_id)
|
||||
{
|
||||
switch ( blend_mode ) {
|
||||
case SwfBlendModeData.Types.Normal:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Layer:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Multiply:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.DstColor);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Screen:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.OneMinusDstColor);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.One);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Lighten:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Max);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Darken:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.EnableKeyword("SWF_DARKEN_BLEND");
|
||||
break;
|
||||
case SwfBlendModeData.Types.Difference:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.EnableKeyword("SWF_DIFFERENCE_BLEND");
|
||||
break;
|
||||
case SwfBlendModeData.Types.Add:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.One);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Subtract:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.ReverseSubtract);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.One);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Invert:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.EnableKeyword("SWF_INVERT_BLEND");
|
||||
break;
|
||||
case SwfBlendModeData.Types.Overlay:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.EnableKeyword("SWF_OVERLAY_BLEND");
|
||||
break;
|
||||
case SwfBlendModeData.Types.Hardlight:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.EnableKeyword("SWF_HARDLIGHT_BLEND");
|
||||
break;
|
||||
default:
|
||||
throw new UnityException(string.Format(
|
||||
"SwfMaterialCache. Incorrect blend mode: {0}",
|
||||
blend_mode));
|
||||
}
|
||||
material.SetInt("_StencilID", stencil_id);
|
||||
return material;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user