/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "core/shader_tree_compiler.h" #include "core/geometry.h" #include "log/log.h" using namespace GS; using namespace GS::Core; //------------------------------------------------------------------------------ bool ShaderTreeCompiler::GetNewVariable(String &variable, const char *prefix) { variable = String::Format("n_%s%d", prefix ? prefix : "n_var", variable_count++); return true; } CShaderBlock *ShaderTreeCompiler::GetNewCompiledBlock(const ShaderBlock *block) { List ::Item *item = compiled_tree_block.Add(new CShaderBlock(block)); return item ? item->Object() : NULL; } //------------------------------------------------------------------------------ //------------------------------------------------------------------- void ShaderTreeCompiler::AddPrefix(const char *prefix) //------------------------------------------------------------------- { if (prefix) id += prefix; } //------------------------------------------------------------------------------------------------------------------------- CShaderBlock *ShaderTreeCompiler::CompileTemporary(ShaderBlock *block, const char *prefix, ShaderInput::Scope scope) //------------------------------------------------------------------------------------------------------------------------- { temporary_block_list.Add(block); return CompileShaderBlock(block, prefix, scope); } //--------------------------------------------------------------------------------------------------------------------------------- CShaderBlock *ShaderTreeCompiler::CompileShaderBlock(const ShaderBlock *block, const char *prefix, ShaderInput::Scope scope) //--------------------------------------------------------------------------------------------------------------------------------- { if (!block) return NULL; // Id should describe the full tree structure. AddPrefix(prefix); id += block->GetId(); /* Avoid compiling twice a block referenced multiple times. Also geometry input blocks only need to be evaluated once. */ ListForeachPtr(CShaderBlock *, compiled_block, compiled_tree_block) if (compiled_block->block->IsEquivalent(block)) return compiled_block; // Compile as new block. switch (block->type) { case ShaderBlock::TypeConstant: return CompileConstantShaderBlock((const ConstantShaderBlock *)block, scope); case ShaderBlock::TypeColor: return CompileColorShaderBlock((const ColorShaderBlock *)block, scope); case ShaderBlock::TypeMaterialParam: return CompileMaterialParamShaderBlock((const MaterialParamShaderBlock *)block, scope); case ShaderBlock::TypeMaterialTexture: return CompileMaterialTextureShaderBlock((const MaterialTextureShaderBlock *)block, scope); case ShaderBlock::TypeGeometryVertex: return CompileGeometryVertexShaderBlock((const GeometryVertexShaderBlock *)block, scope); case ShaderBlock::TypeGeometryNormal: return CompileGeometryNormalShaderBlock((const GeometryNormalShaderBlock *)block, scope); case ShaderBlock::TypeGeometrySkinning: return CompileGeometrySkinningShaderBlock((const GeometrySkinningShaderBlock *)block, scope); case ShaderBlock::TypeGeometryVertexColor: return CompileGeometryVertexColorShaderBlock((const GeometryVertexColorShaderBlock *)block, scope); case ShaderBlock::TypeGeometryTangentFrame: return CompileGeometryTangentFrameShaderBlock((const GeometryTangentFrameShaderBlock *)block, scope); case ShaderBlock::TypeGeometryUV: return CompileGeometryUVShaderBlock((const GeometryUVShaderBlock *)block, scope); case ShaderBlock::TypeRenderBuffer: return CompileRenderBufferShaderBlock((const RenderBufferShaderBlock *)block, scope); case ShaderBlock::TypeTexture: return CompileTextureShaderBlock((const TextureShaderBlock *)block, scope); case ShaderBlock::TypeTextureSampler: return CompileTextureSamplerShaderBlock((const TextureSamplerShaderBlock *)block, scope); case ShaderBlock::TypeMix: return CompileMixShaderBlock((const MixOperatorShaderBlock *)block, scope); case ShaderBlock::TypeAdd: return CompileAddShaderBlock((const AddOperatorShaderBlock *)block, scope); case ShaderBlock::TypeSub: return CompileSubShaderBlock((const SubOperatorShaderBlock *)block, scope); case ShaderBlock::TypeMul: return CompileMulShaderBlock((const MulOperatorShaderBlock *)block, scope); case ShaderBlock::TypeDiv: return CompileDivShaderBlock((const DivOperatorShaderBlock *)block, scope); case ShaderBlock::TypeSwizzle: return CompileSwizzleShaderBlock((const SwizzleShaderBlock *)block, scope); case ShaderBlock::TypeBuild: return CompileBuildShaderBlock((const BuildShaderBlock *)block, scope); case ShaderBlock::TypeCos: return CompileCosinusShaderBlock((const CosinusShaderBlock *)block, scope); case ShaderBlock::TypeSin: return CompileSinusShaderBlock((const SinusShaderBlock *)block, scope); case ShaderBlock::TypePow: return CompilePowShaderBlock((const PowShaderBlock *)block, scope); case ShaderBlock::TypeAbs: return CompileAbsShaderBlock((const AbsShaderBlock *)block, scope); case ShaderBlock::TypeNormalize: return CompileNormalizeBlock((const NormalizeOperatorShaderBlock *)block, scope); case ShaderBlock::TypeDot: return CompileDotShaderBlock((const DotOperatorShaderBlock *)block, scope); case ShaderBlock::TypeCross: return CompileCrossShaderBlock((const CrossOperatorShaderBlock *)block, scope); case ShaderBlock::TypeClamp: return CompileClampShaderBlock((const ClampShaderBlock *)block, scope); case ShaderBlock::TypePackVectorToColor: return CompilePackVectorToColor((const PackVectorToColorShaderBlock *)block, scope); case ShaderBlock::TypeUnpackColorToVector: return CompileUnpackColorToVector((const UnpackColorToVectorShaderBlock *)block, scope); case ShaderBlock::TypeClock: return CompileClockShaderBlock((const ClockShaderBlock *)block, scope); case ShaderBlock::TypeScreenUV: return CompileScreenUVShaderBlock((const ScreenUVShaderBlock *)block, scope); case ShaderBlock::TypeViewVector: return CompileViewVectorShaderBlock((const ViewVectorShaderBlock *)block, scope); case ShaderBlock::TypeViewport: return CompileViewportShaderBlock((const ViewportShaderBlock *)block, scope); case ShaderBlock::TypeNormalViewMatrix: return CompileNormalViewMatrixShaderBlock((const NormalViewMatrixShaderBlock *)block, scope); case ShaderBlock::TypeNormalMatrix: return CompileNormalMatrixShaderBlock((const NormalMatrixShaderBlock *)block, scope); case ShaderBlock::TypeModelViewMatrix: return CompileModelViewMatrixShaderBlock((const ModelViewMatrixShaderBlock *)block, scope); case ShaderBlock::TypeModelMatrix: return CompileModelMatrixShaderBlock((const ModelMatrixShaderBlock *)block, scope); default: __LOG_E__ << "Unsupported render block type (" << block->type << "), does not known how to compile.\n"; break; } return NULL; } //------------------------------------------------------------------------------ void ShaderTreeCompiler::Free() { id.Clear(); compiled_tree_block.Clear(); temporary_block_list.Clear(); vertex_declaration.Clear(); vertex_source.Clear(); pixel_declaration.Clear(); pixel_source.Clear(); texture_count = 0; variable_count = 0; shader = NULL; } void ShaderTreeCompiler::RestartCompiler(Shader *s) { Free(); shader = s; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ ShaderTreeCompiler::ShaderTreeCompiler() { texture_count = 0; variable_count = 0; } ShaderTreeCompiler::~ShaderTreeCompiler() { Free(); } //------------------------------------------------------------------------------