Files
Webcam/include/engine/core/shader_block.h
2026-06-22 11:49:35 +02:00

860 lines
19 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NSHADER_BLOCK__
#define __NSHADER_BLOCK__
#include "core/shader.h"
#include "color/color.h"
#include "math/matrix3.h"
#include "math/matrix4.h"
#include "nstring/nstring.h"
namespace GS {
namespace NML { class Tag; }
namespace Core {
struct ShaderBlockPin;
struct ShaderBlock;
typedef ShaderBlock * pShaderBlock;
/*!
@short Block shader value.
Used by the raytracer software implementation of the shader blocks.
*/
struct ShaderBlockValue
{
enum BlockValueType
{
BlockValueNone = 0,
BlockValueVector,
BlockValueMatrix3,
BlockValueMatrix4,
BlockValueTexture
};
BlockValueType type;
// Can't union those and most of all we don't want runtime allocations here...
Vector4 v;
Matrix3 m3;
Matrix4 m4;
String t;
void Set(const float &_f)
{ v.x = _f; type = BlockValueVector; }
void Set(const Vector4 &_v)
{ v = _v; type = BlockValueVector; }
void Set(const Matrix3 &_m)
{ m3 = _m; type = BlockValueMatrix3; }
void Set(const Matrix4 &_m)
{ m4 = _m; type = BlockValueMatrix4; }
void Set(const char *_t)
{ t = _t; type = BlockValueTexture; }
ShaderBlockValue() : type(BlockValueNone) {}
};
/*!
@short Base render block.
A render block is a component of a render map. It represents an input, an
operator to the render map.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
struct ShaderBlock
{
enum BlockType
{
TypeNone = 0,
// Input blocks.
TypeGeometryVertex,
TypeGeometryNormal,
TypeGeometryUV,
TypeGeometrySkinning,
TypeGeometryVertexColor,
TypeGeometryTangentFrame,
TypeRenderBuffer,
TypeTexture,
TypeTextureSampler,
TypeConstant,
TypeColor,
TypeMaterialParam,
TypeMaterialTexture,
TypeScreenUV,
TypeViewVector,
TypeViewport,
// Matrix blocks.
TypeNormalViewMatrix,
TypeNormalMatrix,
TypeModelViewMatrix,
TypeModelMatrix,
// Operator blocks.
TypeMix,
TypeAdd,
TypeMul,
TypeSub,
TypeDiv,
TypeDot,
TypeCross,
TypeClamp,
TypeNormalize,
TypeSwizzle,
TypeBuild,
TypeSin,
TypeCos,
TypePow,
TypeAbs,
// Packing operators.
TypeUnpackColorToVector,
TypePackVectorToColor,
// Engine parameters.
TypeClock,
TypeInvalid
};
/// Verbose block type.
static const char *BlockTypeToString(BlockType type)
{
switch (type)
{
case TypeNone: return "None";
case TypeGeometryVertex: return "Geometry Vertex";
case TypeGeometryNormal: return "Geometry Normal";
case TypeGeometryUV: return "Geometry UV";
case TypeGeometrySkinning: return "Geometry Skinning";
case TypeGeometryVertexColor: return "Geometry RGB";
case TypeGeometryTangentFrame: return "Geometry Tangent Frame";
case TypeRenderBuffer: return "Render Buffer";
case TypeTexture: return "Texture";
case TypeTextureSampler: return "Texture Sampler";
case TypeConstant: return "Constant";
case TypeColor: return "Color";
case TypeMaterialParam: return "Material Parameter";
case TypeMaterialTexture: return "Material Texture";
case TypeScreenUV: return "Screen UV";
case TypeViewVector: return "View Vector";
case TypeViewport: return "Viewport";
case TypeNormalViewMatrix: return "Normal View Matrix";
case TypeNormalMatrix: return "Normal Matrix "; ///< ! The additional space is NEEDED! (Normal matrix is the name of a legacy version of this node)
case TypeModelViewMatrix: return "Model View Matrix";
case TypeModelMatrix: return "Model Matrix";
case TypeMix: return "Mix";
case TypeAdd: return "Add";
case TypeMul: return "Multiply";
case TypeSub: return "Subtract";
case TypeDiv: return "Divide";
case TypeDot: return "Dot";
case TypeCross: return "Cross";
case TypeClamp: return "Clamp";
case TypeNormalize: return "Normalize";
case TypeSwizzle: return "Swizzle";
case TypeBuild: return "Build";
case TypeSin: return "Sinus";
case TypeCos: return "Cosinus";
case TypePow: return "Pow";
case TypeAbs: return "Abs";
case TypeUnpackColorToVector: return "Unpack color to vector";
case TypePackVectorToColor: return "Pack vector to color";
case TypeClock: return "Clock";
case TypeInvalid: break;
}
return "Invalid";
}
Vector2 pos;
BlockType type;
/*
@name Block input/output.
@{
*/
/// Get input count.
virtual uint GetInputCount() const = 0;
/// Get input block.
virtual ShaderBlock *GetInput(uint n) const = 0;
/// Set input.
virtual bool SetInput(uint n, ShaderBlock *in) = 0;
/// Get input pin.
virtual const ShaderBlockPin *GetInputPin(uint n) const = 0;
/// Get block output pin.
virtual const ShaderBlockPin *GetOutputPin() const = 0;
/// Evaluate block output type.
virtual int GetOutputType() const = 0;
/// @}
/// Get block label.
virtual String GetLabel() const = 0;
/// Get block id.
virtual String GetId() const = 0;
/// Is this block equivalent to another block.
bool IsEquivalent(const ShaderBlock *input_block) const;
/// Gather all of this block children.
void GatherChildren(List <ShaderBlock *> &children);
/// Import block map from metatag.
static Array <pShaderBlock> *BlockMapFromMetaTag(NML::Tag &);
/// Import branch from metatag.
static ShaderBlock *BranchFromMetaTag(NML::Tag &, Array <pShaderBlock> *block_map = 0);
static NML::Tag *BlockMapAsMetaTag(const List <ShaderBlock *> &block_map);
NML::Tag *BranchAsMetaTag(List <ShaderBlock *> &block_map);
NML::Tag *ParamAsMetaTag() const;
ShaderBlock() : type(TypeNone) {}
virtual ~ShaderBlock() {}
};
//------------------------------------------------------------------------------
#define __SpecializeBlock(__LABEL__, __INPUT_COUNT__)\
static ShaderBlockPin input_pin[__INPUT_COUNT__];\
static ShaderBlockPin output_pin;\
\
ShaderBlock *input[__INPUT_COUNT__];\
\
String GetLabel() const\
{ return __LABEL__; }\
uint GetInputCount() const\
{ return __INPUT_COUNT__; }\
bool SetInput(uint n, ShaderBlock *block)\
{\
if (n >= __INPUT_COUNT__)\
return false;\
if (block && !(input_pin[n].compatibility & block->GetOutputType()))\
return false;\
input[n] = block;\
return true;\
}\
ShaderBlock *GetInput(uint n) const\
{ return (n < __INPUT_COUNT__) ? input[n] : 0; }\
const ShaderBlockPin *GetInputPin(uint n) const\
{ return (n < __INPUT_COUNT__) ? &input_pin[n] : 0; }\
const ShaderBlockPin *GetOutputPin() const\
{ return &output_pin; }\
int GetOutputType() const;
#define __SpecializeBlockNoInput(__LABEL__)\
static ShaderBlockPin output_pin;\
\
String GetLabel() const\
{ return __LABEL__; }\
uint GetInputCount() const\
{ return 0; }\
bool SetInput(uint /*n*/, ShaderBlock */*block*/)\
{ return false; }\
ShaderBlock *GetInput(uint /*n*/) const\
{ return 0; }\
const ShaderBlockPin *GetInputPin(uint /*n*/) const\
{ return 0; }\
const ShaderBlockPin *GetOutputPin() const\
{ return &output_pin; }\
int GetOutputType() const;
//------------------------------------------------------------------------------
/*
@short Render block pin description.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
struct ShaderBlockPin
{
const char *name,
*desc;
int compatibility; ///< Pin connection compatibility
};
struct SinusShaderBlock : public ShaderBlock
{
__SpecializeBlock("Sinus", 1)
String GetId() const
{ return "Sin"; }
SinusShaderBlock(ShaderBlock *block = 0)
{
type = TypeSin;
input[0] = block;
}
};
struct CosinusShaderBlock : public ShaderBlock
{
__SpecializeBlock("Cosinus", 1)
String GetId() const
{ return "Cos"; }
CosinusShaderBlock(ShaderBlock *block = 0)
{
type = TypeCos;
input[0] = block;
}
};
struct PowShaderBlock : public ShaderBlock
{
__SpecializeBlock("Pow", 2)
String GetId() const
{ return "Pow"; }
PowShaderBlock(ShaderBlock *v = 0, ShaderBlock *p = 0)
{
type = TypePow;
input[0] = v;
input[1] = p;
}
};
struct AbsShaderBlock : public ShaderBlock
{
__SpecializeBlock("Abs", 1)
String GetId() const
{ return "Abs"; }
AbsShaderBlock(ShaderBlock *v = 0)
{
type = TypeAbs;
input[0] = v;
}
};
struct ClockShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Clock")
String GetId() const
{ return "Clock"; }
ClockShaderBlock()
{ type = TypeClock; }
};
struct ScreenUVShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Screen UV")
String GetId() const
{ return "ScreenUV"; }
ScreenUVShaderBlock()
{ type = TypeScreenUV; }
};
struct ViewVectorShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("View Vector")
String GetId() const
{ return "ViewV"; }
ViewVectorShaderBlock()
{ type = TypeViewVector; }
};
struct ViewportShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Viewport")
String GetId() const
{ return "Viewport"; }
ViewportShaderBlock()
{ type = TypeViewport; }
};
struct NormalViewMatrixShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Normal View Matrix")
String GetId() const
{ return "NormalViewMatrix"; }
NormalViewMatrixShaderBlock()
{ type = TypeNormalViewMatrix; }
};
struct NormalMatrixShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Normal Matrix ")
String GetId() const
{ return "NormalMatrix"; }
NormalMatrixShaderBlock()
{ type = TypeNormalMatrix; }
};
struct ModelViewMatrixShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Model View Matrix ")
String GetId() const
{ return "ModelViewMatrix"; }
ModelViewMatrixShaderBlock()
{ type = TypeModelViewMatrix; }
};
struct ModelMatrixShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Model Matrix")
String GetId() const
{ return "ModelMatrix"; }
ModelMatrixShaderBlock()
{ type = TypeModelMatrix; }
};
struct UnpackColorToVectorShaderBlock : public ShaderBlock
{
__SpecializeBlock("Unpack Color", 1)
String GetId() const
{ return "UnpackColor"; }
UnpackColorToVectorShaderBlock(ShaderBlock *block = 0)
{
type = TypeUnpackColorToVector;
input[0] = block;
}
};
struct PackVectorToColorShaderBlock : public ShaderBlock
{
__SpecializeBlock("Pack Vector", 1)
String GetId() const
{ return "PackVector"; }
PackVectorToColorShaderBlock(ShaderBlock *block = 0)
{
type = TypePackVectorToColor;
input[0] = block;
}
};
struct MixOperatorShaderBlock : public ShaderBlock
{
__SpecializeBlock("Mix", 3)
String GetId() const
{ return "Mix"; }
MixOperatorShaderBlock(ShaderBlock *a = 0, ShaderBlock *b = 0, ShaderBlock *k = 0)
{
type = TypeMix;
input[0] = a; input[1] = b; input[2] = k;
}
};
struct AddOperatorShaderBlock : public ShaderBlock
{
__SpecializeBlock("Add", 2)
String GetId() const
{ return "Add"; }
AddOperatorShaderBlock(ShaderBlock *a = 0, ShaderBlock *b = 0)
{
type = TypeAdd;
input[0] = a; input[1] = b;
}
};
struct MulOperatorShaderBlock : public ShaderBlock
{
__SpecializeBlock("Mul", 2)
String GetId() const
{ return "Mul"; }
MulOperatorShaderBlock(ShaderBlock *a = 0, ShaderBlock *b = 0)
{
type = TypeMul;
input[0] = a; input[1] = b;
}
};
struct SubOperatorShaderBlock : public ShaderBlock
{
__SpecializeBlock("Sub", 2)
String GetId() const
{ return "Sub"; }
SubOperatorShaderBlock(ShaderBlock *a = 0, ShaderBlock *b = 0)
{
type = TypeSub;
input[0] = a; input[1] = b;
}
};
struct DivOperatorShaderBlock : public ShaderBlock
{
__SpecializeBlock("Div", 2)
String GetId() const
{ return "Div"; }
DivOperatorShaderBlock(ShaderBlock *a = 0, ShaderBlock *b = 0)
{
type = TypeDiv;
input[0] = a; input[1] = b;
}
};
struct DotOperatorShaderBlock : public ShaderBlock
{
__SpecializeBlock("Dot", 2)
String GetId() const
{ return "Dot"; }
DotOperatorShaderBlock(ShaderBlock *a = 0, ShaderBlock *b = 0)
{
type = TypeDot;
input[0] = a; input[1] = b;
}
};
struct CrossOperatorShaderBlock : public ShaderBlock
{
__SpecializeBlock("Cross", 2)
String GetId() const
{ return "Cross"; }
CrossOperatorShaderBlock(ShaderBlock *a = 0, ShaderBlock *b = 0)
{
type = TypeCross;
input[0] = a; input[1] = b;
}
};
struct NormalizeOperatorShaderBlock : public ShaderBlock
{
__SpecializeBlock("Normalize", 1)
String GetId() const
{ return "Norm"; }
NormalizeOperatorShaderBlock(ShaderBlock *a = 0)
{
type = TypeNormalize;
input[0] = a;
}
};
struct ClampShaderBlock : public ShaderBlock
{
__SpecializeBlock("Clamp", 3)
String GetId() const
{ return "Clamp"; }
ClampShaderBlock(ShaderBlock *v = 0, ShaderBlock *a = 0, ShaderBlock *b = 0)
{
type = TypeClamp;
input[0] = v; input[1] = a; input[2] = b;
}
};
struct SwizzleShaderBlock : public ShaderBlock
{
enum Swizzle
{
SwizzleNone = 0,
SwizzleX,
SwizzleY,
SwizzleZ,
SwizzleW
};
__SpecializeBlock("Swizzle", 1)
String GetId() const
{ return String::Format("Swizzle%d%d%d%d", swizzle[0], swizzle[1], swizzle[2], swizzle[3]); }
Swizzle swizzle[4];
SwizzleShaderBlock(ShaderBlock *block = 0, Swizzle x = SwizzleNone, Swizzle y = SwizzleNone, Swizzle z = SwizzleNone, Swizzle w = SwizzleNone)
{
type = TypeSwizzle;
swizzle[0] = x; swizzle[1] = y; swizzle[2] = z; swizzle[3] = w;
input[0] = block;
}
};
struct BuildShaderBlock : public ShaderBlock
{
enum Build
{
BuildZero = 0,
BuildOne,
BuildX,
BuildY,
BuildZ,
BuildW
};
__SpecializeBlock("Build", 4)
Build build[4];
String GetId() const
{ return String::Format("Build%d%d%d%d", build[0], build[1], build[2], build[3]); }
BuildShaderBlock(ShaderBlock *a = 0, Build x = BuildX, ShaderBlock *b = 0, Build y = BuildY, ShaderBlock *c = 0, Build z = BuildZ, ShaderBlock *d = 0, Build w = BuildW)
{
type = TypeBuild;
build[0] = x; build[1] = y; build[2] = z; build[3] = w;
input[0] = a; input[1] = b; input[2] = c; input[3] = d;
}
};
struct GeometryUVShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("UV Stream")
int channel;
String GetId() const
{ return String::Format("UV%d", channel); }
GeometryUVShaderBlock(int uv_channel = 0)
{
type = TypeGeometryUV;
channel = uv_channel;
}
};
struct GeometryVertexShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Vertex Stream")
String GetId() const
{ return String("Vertex"); }
GeometryVertexShaderBlock()
{ type = TypeGeometryVertex; }
};
struct GeometryNormalShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Normal Stream")
bool smooth;
String GetId() const
{ return String(smooth ? "NormalSmooth" : "Normal"); }
GeometryNormalShaderBlock()
{
type = TypeGeometryNormal;
smooth = true;
}
};
struct GeometrySkinningShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Skinning Matrix")
String GetId() const
{ return String("SkinMtx"); }
GeometrySkinningShaderBlock()
{ type = TypeGeometrySkinning; }
};
struct GeometryVertexColorShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Vertex Color Stream")
String GetId() const
{ return String("VertexColor"); }
GeometryVertexColorShaderBlock()
{ type = TypeGeometryVertexColor; }
};
struct GeometryTangentFrameShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Tangent Frame")
String GetId() const
{ return String("TangentMtx"); }
GeometryTangentFrameShaderBlock()
{ type = TypeGeometryTangentFrame; }
};
struct RenderBufferShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Render Buffer")
enum RenderBuffer
{
Depth = 0
};
RenderBuffer buffer;
String GetId() const
{ return String("RenderBuffer"); }
RenderBufferShaderBlock(RenderBuffer _buffer = Depth)
{
type = TypeRenderBuffer;
buffer = _buffer;
}
};
struct TextureShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Texture")
enum TextureType
{
Texture2D = 0,
Texture3D,
TextureCube
};
TextureType texture_type;
String texture;
String GetId() const;
TextureShaderBlock(const char *name = 0)
{
type = TypeTexture;
texture = name;
texture_type = Texture2D;
}
};
struct TextureSamplerShaderBlock : public ShaderBlock
{
__SpecializeBlock("Texture Sampler", 2)
enum SamplerType
{
Sampler2D = 0,
Sampler3D,
SamplerCube
};
SamplerType sampler_type;
String GetId() const
{ return String::Format("TexSampler%d", (int)sampler_type); }
TextureSamplerShaderBlock(ShaderBlock *texture = 0, ShaderBlock *uv = 0)
{
type = TypeTextureSampler;
sampler_type = Sampler2D;
input[0] = texture;
input[1] = uv;
}
};
struct MaterialParamShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Material Parameter")
enum MaterialParam
{
MaterialDiffuse = 0,
MaterialSpecular,
MaterialSelf,
MaterialAmbient,
MaterialGlossiness,
MaterialOpacity,
MaterialReflection
};
MaterialParam param;
String GetId() const;
MaterialParamShaderBlock(MaterialParam p = MaterialDiffuse)
{
type = TypeMaterialParam;
param = p;
}
};
struct MaterialTextureShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Material Texture")
enum TextureType
{
Texture2D = 0,
Texture3D,
TextureCube
};
TextureType texture_type;
int slot;
String GetId() const;
MaterialTextureShaderBlock(int n = 0)
{
type = TypeMaterialTexture;
texture_type = Texture2D;
slot = n;
}
};
struct ColorShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Color")
Color color;
String GetId() const
{ return "Color"; }
ColorShaderBlock(float r = 1, float g = 1, float b = 1, float a = 1)
{
type = TypeColor;
color.Set(r, g, b, a);
}
};
struct ConstantShaderBlock : public ShaderBlock
{
__SpecializeBlockNoInput("Constant")
float constant[4];
ShaderInput::DataType constant_type;
String GetId() const;
ConstantShaderBlock()
{
type = TypeConstant; constant_type = ShaderInput::NoData;
constant[0] = constant[1] = constant[2] = constant[3] = 0;
}
ConstantShaderBlock(float v)
{
type = TypeConstant; constant_type = ShaderInput::Float;
constant[0] = v; constant[1] = constant[2] = constant[3] = 0;
}
ConstantShaderBlock(float u, float v)
{
type = TypeConstant; constant_type = ShaderInput::Vector2;
constant[0] = u; constant[1] = v; constant[2] = constant[3] = 0;
}
ConstantShaderBlock(float x, float y, float z)
{
type = TypeConstant; constant_type = ShaderInput::Vector3;
constant[0] = x; constant[1] = y; constant[2] = z; constant[3] = 0;
}
ConstantShaderBlock(float x, float y, float z, float w)
{
type = TypeConstant; constant_type = ShaderInput::Vector4;
constant[0] = x; constant[1] = y; constant[2] = z; constant[3] = w;
}
};
} // Core
} // GS
#endif // __NSHADER_BLOCK__