/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __SHADER_TREE_COMPILER__ #define __SHADER_TREE_COMPILER__ #include "core/shader.h" #include "core/shader_block.h" namespace GS { namespace Core { /// Compiled shader block. struct CShaderBlock { String variable; const ShaderBlock *block; ShaderInput::DataType output; CShaderBlock(const ShaderBlock *render_block) : block(render_block), output(ShaderInput::NoData) { block = render_block; output = ShaderInput::NoData; } }; /*! @short Shader tree compiler. Compile a shader tree to a shader. @author Emmanuel Julien (ejulien@gsworks.fr) */ class ShaderTreeCompiler { /*! @name Specialized interface. @{ */ protected: virtual CShaderBlock *CompileConstantShaderBlock(const ConstantShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileColorShaderBlock(const ColorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileMaterialParamShaderBlock(const MaterialParamShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileMaterialTextureShaderBlock(const MaterialTextureShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileGeometryVertexShaderBlock(const GeometryVertexShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileGeometryUVShaderBlock(const GeometryUVShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileGeometryNormalShaderBlock(const GeometryNormalShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileGeometrySkinningShaderBlock(const GeometrySkinningShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileGeometryVertexColorShaderBlock(const GeometryVertexColorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileGeometryTangentFrameShaderBlock(const GeometryTangentFrameShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileRenderBufferShaderBlock(const RenderBufferShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileTextureShaderBlock(const TextureShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileTextureSamplerShaderBlock(const TextureSamplerShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileMixShaderBlock(const MixOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileAddShaderBlock(const AddOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileSubShaderBlock(const SubOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileMulShaderBlock(const MulOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileDivShaderBlock(const DivOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileDotShaderBlock(const DotOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileCrossShaderBlock(const CrossOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileClampShaderBlock(const ClampShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileNormalizeBlock(const NormalizeOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileSwizzleShaderBlock(const SwizzleShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileBuildShaderBlock(const BuildShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileCosinusShaderBlock(const CosinusShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileSinusShaderBlock(const SinusShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompilePowShaderBlock(const PowShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileAbsShaderBlock(const AbsShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileUnpackColorToVector(const UnpackColorToVectorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompilePackVectorToColor(const PackVectorToColorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileClockShaderBlock(const ClockShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileScreenUVShaderBlock(const ScreenUVShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileViewVectorShaderBlock(const ViewVectorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileViewportShaderBlock(const ViewportShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileNormalViewMatrixShaderBlock(const NormalViewMatrixShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileNormalMatrixShaderBlock(const NormalMatrixShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileModelViewMatrixShaderBlock(const ModelViewMatrixShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; virtual CShaderBlock *CompileModelMatrixShaderBlock(const ModelMatrixShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel) = 0; /// @} protected: String id; uint variable_count, texture_count; Shader *shader; AutoList temporary_block_list; AutoList compiled_tree_block; bool GetNewVariable(String &constant, const char *prefix = 0); CShaderBlock *GetNewCompiledBlock(const ShaderBlock *); String vertex_declaration, vertex_source, pixel_declaration, pixel_source; public: /// Get current shader id. const String &GetId() const { return id; } /// Restart compiler. Derived implementations should call the base class first. void RestartCompiler(Shader *); /// Compile a shader block. CShaderBlock *CompileShaderBlock(const ShaderBlock *, const char *prefix = 0, ShaderInput::Scope = ShaderInput::Pixel); /// Compile a temporary block. Compiler takes ownership of the block. CShaderBlock *CompileTemporary(ShaderBlock *, const char *prefix = 0, ShaderInput::Scope = ShaderInput::Pixel); /// Add a custom prefix to the shader name. void AddPrefix(const char *); /// Add code to the vertex shader declaration. void AddVertexDeclaration(const char *d) { vertex_declaration += d; } /// Add code to the vertex shader. void AddVertexShader(const char *d) { vertex_source += d; } /// Add code to the fragment shader declaration. void AddPixelDeclaration(const char *d) { pixel_declaration += d; } /// Add code to the fragment shader. void AddPixelShader(const char *d) { pixel_source += d; } /// Get vertex program. const String &GetVertexSource() const { return vertex_source; } /// Get fragment program. const String &GetPixelSource() const { return pixel_source; } /// Complete a compilation, retrieve the shader. virtual Shader *Finish() = 0; /// Free all compiler stats. void Free(); ShaderTreeCompiler(); virtual ~ShaderTreeCompiler(); }; } //Core } // GS #endif // __SHADER_TREE_COMPILER__