commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
584
include/engine/core/shader_tree_nml.cpp
Normal file
584
include/engine/core/shader_tree_nml.cpp
Normal file
@ -0,0 +1,584 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "core/shader_tree.h"
|
||||
#include "core/shader_block.h"
|
||||
#include "math/vector_nml.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace GS;
|
||||
using namespace GS::Core;
|
||||
using NML::Tag;
|
||||
|
||||
/// Id of the NOOP shader block.
|
||||
static String __ShaderBlockNoneTagId("None");
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Array <pShaderBlock> *ShaderBlock::BlockMapFromMetaTag(Tag &tag)
|
||||
{
|
||||
if (tag.name != "Map")
|
||||
return NULL;
|
||||
|
||||
// Allocate block map.
|
||||
Array <pShaderBlock> *block_map = new Array <pShaderBlock> (tag.GetChildCount());
|
||||
if (!block_map)
|
||||
__ERR__(__LOG_E__ << "Failed to allocate shader block map.\n", NULL)
|
||||
|
||||
for (uint n = 0; n < block_map->GetCount(); ++n)
|
||||
(*block_map)[n] = NULL;
|
||||
|
||||
// Fill the block map.
|
||||
uint block_count = 0;
|
||||
|
||||
NMLTagForeach(entry_tag, tag)
|
||||
if (entry_tag->name == "Entry")
|
||||
{
|
||||
ShaderBlock *_block = NULL;
|
||||
Tag *type_tag = entry_tag->GetTag("Type"),
|
||||
*parm_tag = entry_tag->GetTag("Param");
|
||||
|
||||
//----------------------------------------------------
|
||||
#define __InstanciateNewShaderBlock(__VAR__, __TYPE__)\
|
||||
__TYPE__ *__VAR__ = new __TYPE__;\
|
||||
_block = __VAR__;
|
||||
|
||||
#define __ValidateShaderBlockParam\
|
||||
if (!parm_tag)\
|
||||
break;
|
||||
//----------------------------------------------------
|
||||
|
||||
if (type_tag)
|
||||
{
|
||||
int type;
|
||||
String type_string(type_tag->GetString());
|
||||
|
||||
// Legacy block type support.
|
||||
if ((type_string == "Sampler 2D") || (type_string == "Sampler Cube"))
|
||||
type_string = "Texture Sampler";
|
||||
if (type_string == "Normal Matrix")
|
||||
type_string = "Normal View Matrix";
|
||||
|
||||
// Locate block.
|
||||
for (type = ShaderBlock::TypeNone; type < ShaderBlock::TypeInvalid; ++type)
|
||||
if (type_string == ShaderBlock::BlockTypeToString((BlockType)type))
|
||||
break;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TypeGeometryUV:
|
||||
{
|
||||
__InstanciateNewShaderBlock(block, GeometryUVShaderBlock)
|
||||
__ValidateShaderBlockParam
|
||||
|
||||
if (Tag *tag = parm_tag->GetTypedTag("Channel;", Variant::VariantInteger))
|
||||
block->channel = tag->GetInteger();
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeTextureSampler:
|
||||
{
|
||||
__InstanciateNewShaderBlock(block, TextureSamplerShaderBlock)
|
||||
__ValidateShaderBlockParam
|
||||
|
||||
if (Tag *tag = parm_tag->GetTypedTag("Type;", Variant::VariantString))
|
||||
{
|
||||
String sampler_type(tag->GetString());
|
||||
|
||||
if (sampler_type == "3D") block->sampler_type = TextureSamplerShaderBlock::Sampler3D;
|
||||
else if (sampler_type == "Cube") block->sampler_type = TextureSamplerShaderBlock::SamplerCube;
|
||||
else block->sampler_type = TextureSamplerShaderBlock::Sampler2D;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeRenderBuffer:
|
||||
{
|
||||
__InstanciateNewShaderBlock(block, RenderBufferShaderBlock)
|
||||
__ValidateShaderBlockParam
|
||||
|
||||
if (Tag *tag = parm_tag->GetTypedTag("Buffer;", Variant::VariantInteger))
|
||||
block->buffer = (RenderBufferShaderBlock::RenderBuffer)tag->GetInteger();
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeTexture:
|
||||
{
|
||||
__InstanciateNewShaderBlock(block, TextureShaderBlock)
|
||||
__ValidateShaderBlockParam
|
||||
|
||||
if (Tag *tag = parm_tag->GetTypedTag("Texture;", Variant::VariantString))
|
||||
block->texture = tag->GetString();
|
||||
|
||||
if (Tag *tag = parm_tag->GetTypedTag("Type;", Variant::VariantString))
|
||||
{
|
||||
String texture_type(tag->GetString());
|
||||
|
||||
if (texture_type == "3D") block->texture_type = TextureShaderBlock::Texture3D;
|
||||
else if (texture_type == "Cube") block->texture_type = TextureShaderBlock::TextureCube;
|
||||
else block->texture_type = TextureShaderBlock::Texture2D;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeConstant:
|
||||
{
|
||||
__InstanciateNewShaderBlock(block, ConstantShaderBlock)
|
||||
__ValidateShaderBlockParam
|
||||
|
||||
if (Tag *tag = parm_tag->GetTypedTag("Type;", Variant::VariantInteger))
|
||||
block->constant_type = (ShaderInput::DataType)tag->GetInteger();
|
||||
|
||||
Vector4 v(0, 0, 0);
|
||||
if (Tag *tag = parm_tag->GetTag("Value;"))
|
||||
v.FromMetaTag(*tag);
|
||||
|
||||
block->constant[0] = v.x;
|
||||
block->constant[1] = v.y;
|
||||
block->constant[2] = v.z;
|
||||
block->constant[3] = v.w;
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeColor:
|
||||
{
|
||||
__InstanciateNewShaderBlock(block, ColorShaderBlock)
|
||||
__ValidateShaderBlockParam
|
||||
|
||||
if (Tag *tag = parm_tag->GetTag("Color;"))
|
||||
block->color.FromMetaTag(*tag);
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeMaterialParam:
|
||||
{
|
||||
__InstanciateNewShaderBlock(block, MaterialParamShaderBlock)
|
||||
__ValidateShaderBlockParam
|
||||
|
||||
if (Tag *tag = parm_tag->GetTypedTag("Param;", Variant::VariantInteger))
|
||||
block->param = (MaterialParamShaderBlock::MaterialParam)tag->GetInteger();
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeMaterialTexture:
|
||||
{
|
||||
__InstanciateNewShaderBlock(block, MaterialTextureShaderBlock)
|
||||
__ValidateShaderBlockParam
|
||||
|
||||
if (Tag *tag = parm_tag->GetTypedTag("Slot;", Variant::VariantInteger))
|
||||
block->slot = tag->GetInteger();
|
||||
|
||||
if (Tag *tag = parm_tag->GetTypedTag("Type;", Variant::VariantString))
|
||||
{
|
||||
String texture_type(tag->GetString());
|
||||
|
||||
if (texture_type == "3D") block->texture_type = MaterialTextureShaderBlock::Texture3D;
|
||||
else if (texture_type == "Cube") block->texture_type = MaterialTextureShaderBlock::TextureCube;
|
||||
else block->texture_type = MaterialTextureShaderBlock::Texture2D;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeSwizzle:
|
||||
{
|
||||
__InstanciateNewShaderBlock(block, SwizzleShaderBlock)
|
||||
__ValidateShaderBlockParam
|
||||
|
||||
const char *swizzle = "nnnn";
|
||||
if (Tag *tag = parm_tag->GetTag("Swizzle;"))
|
||||
swizzle = tag->GetString();
|
||||
|
||||
for (int n = 0; n < 4; ++n)
|
||||
if (swizzle[n] == 'n') block->swizzle[n] = SwizzleShaderBlock::SwizzleNone;
|
||||
else if (swizzle[n] == 'x') block->swizzle[n] = SwizzleShaderBlock::SwizzleX;
|
||||
else if (swizzle[n] == 'y') block->swizzle[n] = SwizzleShaderBlock::SwizzleY;
|
||||
else if (swizzle[n] == 'z') block->swizzle[n] = SwizzleShaderBlock::SwizzleZ;
|
||||
else if (swizzle[n] == 'w') block->swizzle[n] = SwizzleShaderBlock::SwizzleW;
|
||||
else
|
||||
{
|
||||
__LOG_E__ << "Unexpected end of swizzle mask.\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeBuild:
|
||||
{
|
||||
__InstanciateNewShaderBlock(block, BuildShaderBlock)
|
||||
__ValidateShaderBlockParam
|
||||
|
||||
const char *build = "0000";
|
||||
if (Tag *tag = parm_tag->GetTag("Build;"))
|
||||
build = tag->GetString();
|
||||
|
||||
for (int n = 0; n < 4; ++n)
|
||||
if (build[n] == '0') block->build[n] = BuildShaderBlock::BuildZero;
|
||||
else if (build[n] == '1') block->build[n] = BuildShaderBlock::BuildOne;
|
||||
else if (build[n] == 'x') block->build[n] = BuildShaderBlock::BuildX;
|
||||
else if (build[n] == 'y') block->build[n] = BuildShaderBlock::BuildY;
|
||||
else if (build[n] == 'z') block->build[n] = BuildShaderBlock::BuildZ;
|
||||
else if (build[n] == 'w') block->build[n] = BuildShaderBlock::BuildW;
|
||||
else
|
||||
{
|
||||
__LOG_E__ << "Unexpected end of build mask.\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeGeometryVertex: _block = new GeometryVertexShaderBlock; break;
|
||||
case TypeGeometrySkinning: _block = new GeometrySkinningShaderBlock; break;
|
||||
case TypeGeometryNormal: _block = new GeometryNormalShaderBlock; break;
|
||||
case TypeGeometryVertexColor: _block = new GeometryVertexColorShaderBlock; break;
|
||||
case TypeGeometryTangentFrame: _block = new GeometryTangentFrameShaderBlock; break;
|
||||
case TypeScreenUV: _block = new ScreenUVShaderBlock; break;
|
||||
case TypeViewVector: _block = new ViewVectorShaderBlock; break;
|
||||
case TypeViewport: _block = new ViewportShaderBlock; break;
|
||||
case TypeNormalViewMatrix: _block = new NormalViewMatrixShaderBlock; break;
|
||||
case TypeNormalMatrix: _block = new NormalMatrixShaderBlock; break;
|
||||
case TypeModelViewMatrix: _block = new ModelViewMatrixShaderBlock; break;
|
||||
case TypeModelMatrix: _block = new ModelMatrixShaderBlock; break;
|
||||
|
||||
case TypeMix: _block = new MixOperatorShaderBlock; break;
|
||||
case TypeAdd: _block = new AddOperatorShaderBlock; break;
|
||||
case TypeMul: _block = new MulOperatorShaderBlock; break;
|
||||
case TypeSub: _block = new SubOperatorShaderBlock; break;
|
||||
case TypeDiv: _block = new DivOperatorShaderBlock; break;
|
||||
case TypeDot: _block = new DotOperatorShaderBlock; break;
|
||||
case TypeCross: _block = new CrossOperatorShaderBlock; break;
|
||||
case TypeClamp: _block = new ClampShaderBlock; break;
|
||||
case TypeNormalize: _block = new NormalizeOperatorShaderBlock; break;
|
||||
case TypeSin: _block = new SinusShaderBlock; break;
|
||||
case TypeCos: _block = new CosinusShaderBlock; break;
|
||||
case TypePow: _block = new PowShaderBlock; break;
|
||||
case TypeAbs: _block = new AbsShaderBlock; break;
|
||||
case TypeClock: _block = new ClockShaderBlock; break;
|
||||
|
||||
case TypeUnpackColorToVector: _block = new UnpackColorToVectorShaderBlock; break;
|
||||
case TypePackVectorToColor: _block = new PackVectorToColorShaderBlock; break;
|
||||
|
||||
default:
|
||||
__LOG_E__ << "Invalid block type '" << type_string << "'.\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_block)
|
||||
if (Tag *pos_tag = entry_tag->GetTag("Pos"))
|
||||
tVectorFromMetaTag(_block->pos, *pos_tag);
|
||||
|
||||
// Add block to the map.
|
||||
if (block_map->GetCount() > block_count)
|
||||
(*block_map)[block_count++] = _block;
|
||||
else
|
||||
__LOG_E__ << "Block map full, unexpected error.\n";
|
||||
}
|
||||
else __LOG_W__ << "Unexpected tag '" << entry_tag->name << "' in shader map.\n";
|
||||
|
||||
return block_map;
|
||||
}
|
||||
ShaderBlock *ShaderBlock::BranchFromMetaTag(Tag &tag, Array <pShaderBlock> *block_map)
|
||||
{
|
||||
// Load block.
|
||||
Tag *index_tag = tag.GetTypedTag("Index;", Variant::VariantInteger);
|
||||
if (!index_tag)
|
||||
__ERR__(__LOG_E__ << "No block index found.\n", NULL)
|
||||
|
||||
// Load map if none provided.
|
||||
bool drop_map = false;
|
||||
|
||||
if (!block_map)
|
||||
{
|
||||
Tag *map_tag = tag.GetTag("Map;");
|
||||
if (!map_tag)
|
||||
__ERR__(__LOG_E__ << "No map to build shader branch.\n", NULL)
|
||||
|
||||
if ((block_map = BlockMapFromMetaTag(*map_tag)) == NULL)
|
||||
return NULL;
|
||||
|
||||
drop_map = true;
|
||||
}
|
||||
|
||||
// Link block to its inputs.
|
||||
ShaderBlock *block = (*block_map)[index_tag->GetUnsigned()];
|
||||
if (block && block->GetInputCount())
|
||||
if (Tag *inputs_tag = tag.GetTag("Input;"))
|
||||
{
|
||||
int input_count = 0;
|
||||
NMLTagForeach(input_tag, *inputs_tag)
|
||||
if (input_tag && (input_tag->name != __ShaderBlockNoneTagId))
|
||||
block->SetInput(input_count++, ShaderBlock::BranchFromMetaTag(*input_tag, block_map));
|
||||
}
|
||||
|
||||
if (drop_map)
|
||||
_safe_delete(block_map);
|
||||
return block;
|
||||
}
|
||||
bool ShaderTree::FromMetaTag(Tag &tag)
|
||||
{
|
||||
if (tag.name != "ShaderMap")
|
||||
return false;
|
||||
|
||||
// Load import map.
|
||||
Tag *map_tag = tag.GetTag("Map;");
|
||||
Array <pShaderBlock> *block_map = map_tag ? ShaderBlock::BlockMapFromMetaTag(*map_tag) : NULL;
|
||||
|
||||
// Sink block position.
|
||||
if (Tag *pos_tag = tag.GetTag("Pos"))
|
||||
tVectorFromMetaTag(pos, *pos_tag);
|
||||
|
||||
// Read in sinks.
|
||||
Tag *sink_tag;
|
||||
|
||||
if ((sink_tag = tag.GetTag("Vertex:Block;")) != NULL)
|
||||
sink[SinkVertex] = ShaderBlock::BranchFromMetaTag(*sink_tag, block_map);
|
||||
if ((sink_tag = tag.GetTag("Normal:Block;")) != NULL)
|
||||
sink[SinkNormal] = ShaderBlock::BranchFromMetaTag(*sink_tag, block_map);
|
||||
if ((sink_tag = tag.GetTag("Diffuse:Block;")) != NULL)
|
||||
sink[SinkDiffuse] = ShaderBlock::BranchFromMetaTag(*sink_tag, block_map);
|
||||
if ((sink_tag = tag.GetTag("Modulate:Block;")) != NULL)
|
||||
sink[SinkModulate] = ShaderBlock::BranchFromMetaTag(*sink_tag, block_map);
|
||||
if ((sink_tag = tag.GetTag("Specular:Block;")) != NULL)
|
||||
sink[SinkSpecular] = ShaderBlock::BranchFromMetaTag(*sink_tag, block_map);
|
||||
if ((sink_tag = tag.GetTag("Glossiness:Block;")) != NULL)
|
||||
sink[SinkGlossiness] = ShaderBlock::BranchFromMetaTag(*sink_tag, block_map);
|
||||
if ((sink_tag = tag.GetTag("Constant:Block;")) != NULL)
|
||||
sink[SinkConstant] = ShaderBlock::BranchFromMetaTag(*sink_tag, block_map);
|
||||
if ((sink_tag = tag.GetTag("Opacity:Block;")) != NULL)
|
||||
sink[SinkOpacity] = ShaderBlock::BranchFromMetaTag(*sink_tag, block_map);
|
||||
if ((sink_tag = tag.GetTag("Reflection:Block;")) != NULL)
|
||||
sink[SinkReflection] = ShaderBlock::BranchFromMetaTag(*sink_tag, block_map);
|
||||
|
||||
_safe_delete(block_map);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Tag *ShaderBlock::ParamAsMetaTag() const
|
||||
{
|
||||
Tag *parm = new Tag("Param");
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TypeGeometryUV:
|
||||
{
|
||||
GeometryUVShaderBlock *block = (GeometryUVShaderBlock *)this;
|
||||
parm->AddChild("Channel", block->channel);
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeTextureSampler:
|
||||
{
|
||||
TextureSamplerShaderBlock *block = (TextureSamplerShaderBlock *)this;
|
||||
|
||||
switch (block->sampler_type)
|
||||
{
|
||||
default:
|
||||
case TextureSamplerShaderBlock::Sampler2D: parm->AddChild("Type", "2D"); break;
|
||||
case TextureSamplerShaderBlock::Sampler3D: parm->AddChild("Type", "3D"); break;
|
||||
case TextureSamplerShaderBlock::SamplerCube: parm->AddChild("Type", "Cube"); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeRenderBuffer:
|
||||
{
|
||||
RenderBufferShaderBlock *block = (RenderBufferShaderBlock *)this;
|
||||
parm->AddChild("Buffer", (int)block->buffer);
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeTexture:
|
||||
{
|
||||
TextureShaderBlock *block = (TextureShaderBlock *)this;
|
||||
if (!block->texture.IsEmpty())
|
||||
parm->AddChild("Texture", block->texture.c_str());
|
||||
|
||||
switch (block->texture_type)
|
||||
{
|
||||
default:
|
||||
case TextureShaderBlock::Texture2D: parm->AddChild("Type", "2D"); break;
|
||||
case TextureShaderBlock::Texture3D: parm->AddChild("Type", "3D"); break;
|
||||
case TextureShaderBlock::TextureCube: parm->AddChild("Type", "Cube"); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeConstant:
|
||||
{
|
||||
ConstantShaderBlock *block = (ConstantShaderBlock *)this;
|
||||
parm->AddChild("Type", (int)block->constant_type);
|
||||
parm->AddChild(Vector4(block->constant[0], block->constant[1], block->constant[2], block->constant[3]).AsMetaTag("Value", true));
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeColor:
|
||||
{
|
||||
ColorShaderBlock *block = (ColorShaderBlock *)this;
|
||||
parm->AddChild(block->color.AsMetaTag("Color", true));
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeMaterialParam:
|
||||
{
|
||||
MaterialParamShaderBlock *block = (MaterialParamShaderBlock *)this;
|
||||
parm->AddChild("Param", block->param);
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeMaterialTexture:
|
||||
{
|
||||
MaterialTextureShaderBlock *block = (MaterialTextureShaderBlock *)this;
|
||||
parm->AddChild(new Tag("Slot", block->slot));
|
||||
|
||||
switch (block->texture_type)
|
||||
{
|
||||
default:
|
||||
case MaterialTextureShaderBlock::Texture2D: parm->AddChild("Type", "2D"); break;
|
||||
case MaterialTextureShaderBlock::Texture3D: parm->AddChild("Type", "3D"); break;
|
||||
case MaterialTextureShaderBlock::TextureCube: parm->AddChild("Type", "Cube"); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeSwizzle:
|
||||
{
|
||||
SwizzleShaderBlock *block = (SwizzleShaderBlock *)this;
|
||||
|
||||
char swizzle[5];
|
||||
for (int n = 0; n < 4; ++n)
|
||||
switch (block->swizzle[n])
|
||||
{
|
||||
case SwizzleShaderBlock::SwizzleNone: swizzle[n] = 'n'; break;
|
||||
case SwizzleShaderBlock::SwizzleX: swizzle[n] = 'x'; break;
|
||||
case SwizzleShaderBlock::SwizzleY: swizzle[n] = 'y'; break;
|
||||
case SwizzleShaderBlock::SwizzleZ: swizzle[n] = 'z'; break;
|
||||
case SwizzleShaderBlock::SwizzleW: swizzle[n] = 'w'; break;
|
||||
}
|
||||
swizzle[4] = 0;
|
||||
|
||||
parm->AddChild("Swizzle", (const char *)swizzle);
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeBuild:
|
||||
{
|
||||
BuildShaderBlock *block = (BuildShaderBlock *)this;
|
||||
|
||||
char build[5];
|
||||
for (int n = 0; n < 4; ++n)
|
||||
switch (block->build[n])
|
||||
{
|
||||
case BuildShaderBlock::BuildZero: build[n] = '0'; break;
|
||||
case BuildShaderBlock::BuildOne: build[n] = '1'; break;
|
||||
case BuildShaderBlock::BuildX: build[n] = 'x'; break;
|
||||
case BuildShaderBlock::BuildY: build[n] = 'y'; break;
|
||||
case BuildShaderBlock::BuildZ: build[n] = 'z'; break;
|
||||
case BuildShaderBlock::BuildW: build[n] = 'w'; break;
|
||||
}
|
||||
build[4] = 0;
|
||||
|
||||
parm->AddChild("Build", (const char *)build);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return parm;
|
||||
}
|
||||
void ShaderBlock::GatherChildren(List <ShaderBlock *> &children)
|
||||
{
|
||||
if (!children.Find(this))
|
||||
children.Add(this);
|
||||
|
||||
for (uint n = 0; n < GetInputCount(); ++n)
|
||||
if (GetInput(n))
|
||||
GetInput(n)->GatherChildren(children);
|
||||
}
|
||||
Tag *ShaderBlock::BranchAsMetaTag(List <ShaderBlock *> &block_map)
|
||||
{
|
||||
// Locate block in map.
|
||||
uint index = 0;
|
||||
ListForeachPtr(ShaderBlock *, block, block_map)
|
||||
{
|
||||
if (block == this)
|
||||
break;
|
||||
index++;
|
||||
}
|
||||
if (index == block_map.GetCount())
|
||||
return NULL;
|
||||
|
||||
// Export block and inputs.
|
||||
Tag *block = new Tag("Block");
|
||||
block->AddChild("Index", index);
|
||||
|
||||
if (GetInputCount())
|
||||
{
|
||||
Tag *input = block->AddChild("Input");
|
||||
for (uint n = 0; n < GetInputCount(); ++n)
|
||||
input->AddChild(GetInput(n) ? GetInput(n)->BranchAsMetaTag(block_map) : new Tag(__ShaderBlockNoneTagId.c_str()));
|
||||
}
|
||||
return block;
|
||||
}
|
||||
Tag *ShaderBlock::BlockMapAsMetaTag(const List <ShaderBlock *> &block_map)
|
||||
{
|
||||
Tag *map = new Tag("Map");
|
||||
if (!map)
|
||||
__ERR__(__LOG_E__ << "Failed to allocate root tag.\n", NULL);
|
||||
|
||||
ListForeachPtr(ShaderBlock *, block, block_map)
|
||||
if (block)
|
||||
if (Tag *entry = map->AddChild("Entry"))
|
||||
{
|
||||
entry->AddChild("Type", ShaderBlock::BlockTypeToString(block->type));
|
||||
entry->AddChild(tVectorAsMetaTag(block->pos, "Pos"));
|
||||
entry->AddChild(block->ParamAsMetaTag());
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
Tag *ShaderTree::AsMetaTag() const
|
||||
{
|
||||
Tag *map = new Tag("ShaderMap");
|
||||
if (!map)
|
||||
__ERR__(__LOG_E__ << "Could not serialize shader map. Failed to create root tag.\n", NULL);
|
||||
|
||||
// Sink block position.
|
||||
map->AddChild(tVectorAsMetaTag(pos, "Pos"));
|
||||
|
||||
// Build block export map.
|
||||
List <ShaderBlock *> block_map;
|
||||
for (int n = 0; n < SinkInvalid; ++n)
|
||||
if (sink[n])
|
||||
sink[n]->GatherChildren(block_map);
|
||||
|
||||
// Serialize map.
|
||||
map->AddChild(ShaderBlock::BlockMapAsMetaTag(block_map));
|
||||
|
||||
// Serialize all sinks.
|
||||
#define __SerializeShaderMapSink(__SINK__, __LABEL__)\
|
||||
if (__SINK__)\
|
||||
{\
|
||||
Tag *sinktag = map->AddChild(__LABEL__);\
|
||||
sinktag->AddChild((__SINK__)->BranchAsMetaTag(block_map));\
|
||||
}
|
||||
|
||||
// Serialize shader map.
|
||||
__SerializeShaderMapSink(sink[SinkVertex], "Vertex")
|
||||
__SerializeShaderMapSink(sink[SinkNormal], "Normal")
|
||||
__SerializeShaderMapSink(sink[SinkDiffuse], "Diffuse")
|
||||
__SerializeShaderMapSink(sink[SinkModulate], "Modulate")
|
||||
__SerializeShaderMapSink(sink[SinkSpecular], "Specular")
|
||||
__SerializeShaderMapSink(sink[SinkGlossiness], "Glossiness")
|
||||
__SerializeShaderMapSink(sink[SinkConstant], "Constant")
|
||||
__SerializeShaderMapSink(sink[SinkOpacity], "Opacity")
|
||||
__SerializeShaderMapSink(sink[SinkReflection], "Reflection")
|
||||
|
||||
return map;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user