shaderFeature.h
Engine/source/shaderGen/shaderFeature.h
Classes:
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23#ifndef _SHADERFEATURE_H_ 24#define _SHADERFEATURE_H_ 25 26#ifndef _MATERIALDEFINITION_H_ 27#include "materials/materialDefinition.h" 28#endif 29#ifndef _SHADERCOMP_H_ 30#include "shaderGen/shaderComp.h" 31#endif 32#ifndef _SHADER_DEPENDENCY_H_ 33#include "shaderGen/shaderDependency.h" 34#endif 35 36class MultiLine; 37struct LangElement; 38struct MaterialFeatureData; 39class GFXShaderConstBuffer; 40struct RenderPassData; 41struct SceneData; 42class SceneRenderState; 43class GFXShader; 44class GFXVertexFormat; 45 46 47/// 48class ShaderFeatureConstHandles 49{ 50public: 51 52 virtual ~ShaderFeatureConstHandles() { } 53 54 virtual void init( GFXShader *shader ) = 0; 55 56 virtual void setConsts( SceneRenderState *state, 57 const SceneData &sgData, 58 GFXShaderConstBuffer *buffer ) = 0; 59}; 60 61//************************************************************************** 62/*! 63 The ShaderFeature class is the base class for every procedurally generated 64 feature. Each feature the engine recognizes is part of the MaterialFeatureType 65 enum. That structure is used to indicate which features are present in a shader 66 to be generated. This is useful as many ShaderFeatures will output different 67 code depending on what other features are going to be in the shader. 68 69 Shaders are generated using the ShaderFeature interface, so all of the 70 descendants interact pretty much the same way. 71 72*/ 73//************************************************************************** 74 75 76//************************************************************************** 77// Shader Feature 78//************************************************************************** 79class ShaderFeature 80{ 81public: 82 83 // Bitfield which allows a shader feature to say which render targets it outputs 84 // data to (could be more than one). 85 enum OutputTarget 86 { 87 DefaultTarget = 1 << 0, 88 RenderTarget1 = 1 << 1, 89 RenderTarget2 = 1 << 2, 90 RenderTarget3 = 1 << 3, 91 RenderTarget4 = 1 << 4, 92 RenderTarget5 = 1 << 5, 93 }; 94 95protected: 96 97 LangElement *output; 98 99 /// The list of unique shader dependencies. 100 Vector<const ShaderDependency*> mDependencies; 101 102 /// 103 S32 mProcessIndex; 104 105public: 106 107 // TODO: Make this protected and give it a proper API. 108 const GFXVertexFormat *mVertexFormat; 109 110 // TODO: Make this protected and give it a proper API. 111 GFXVertexFormat *mInstancingFormat; 112 113public: 114 115 //************************************************************************** 116 /*! 117 The Resources structure is used by ShaderFeature to indicate how many 118 hardware "resources" it needs. Resources are things such as how 119 many textures it uses and how many texture registers it needs to pass 120 information from the vertex to the pixel shader. 121 122 The Resources data can change depending what hardware is available. For 123 instance, pixel 1.x level hardware may need more texture registers than 124 pixel 2.0+ hardware because each texture register can only be used with 125 its respective texture sampler. 126 127 The data in Resources is used to determine how many features can be 128 squeezed into a singe shader. If a feature requires too many resources 129 to fit into the current shader, it will be put into another pass. 130 */ 131 //************************************************************************** 132 struct Resources 133 { 134 U32 numTex; 135 U32 numTexReg; 136 137 Resources() 138 { 139 dMemset( this, 0, sizeof( Resources ) ); 140 } 141 }; 142 143 144 //----------------------------------------------------------------------- 145 // Base functions 146 //----------------------------------------------------------------------- 147 148 ShaderFeature() 149 : output( NULL ), 150 mProcessIndex( 0 ), 151 mVertexFormat( NULL ), 152 mInstancingFormat( NULL ) 153 { 154 } 155 156 virtual ~ShaderFeature() {} 157 158 /// returns output from a processed vertex or pixel shader 159 LangElement* getOutput() const { return output; } 160 161 /// 162 void setProcessIndex( S32 index ) { mProcessIndex = index; } 163 164 /// 165 S32 getProcessIndex() const { return mProcessIndex; } 166 167 //----------------------------------------------------------------------- 168 // Virtual Functions 169 //----------------------------------------------------------------------- 170 171 /// Get the incoming base texture coords - useful for bumpmap and detail maps 172 virtual Var* getVertTexCoord( const String &name ) = 0; 173 174 /// Set up a texture space matrix - to pass into pixel shader 175 virtual LangElement * setupTexSpaceMat( Vector<ShaderComponent*> &componentList, 176 Var **texSpaceMat ) = 0; 177 178 /// Expand and assign a normal map. This takes care of compressed normal maps as well. 179 virtual LangElement * expandNormalMap( LangElement *sampleNormalOp, 180 LangElement *normalDecl, LangElement *normalVar, const MaterialFeatureData &fd ) = 0; 181 182 /// Helper function for applying the color to shader output. 183 /// 184 /// @param elem The rbg or rgba color to assign. 185 /// 186 /// @param blend The type of blending to perform. 187 /// 188 /// @param lerpElem The optional lerp parameter when doing a LerpAlpha blend, 189 /// if not set then the elem is used. 190 /// 191 virtual LangElement* assignColor( LangElement *elem, 192 Material::BlendOp blend, 193 LangElement *lerpElem = NULL, 194 ShaderFeature::OutputTarget outputTarget = ShaderFeature::DefaultTarget ) = 0; 195 196 197 //----------------------------------------------------------------------- 198 /*! 199 Process vertex shader - This function is used by each feature to 200 generate a list of LangElements that can be traversed and "printed" 201 to generate the actual shader code. The 'output' member is the head 202 of that list. 203 204 The componentList is used mostly for access to the "Connector" 205 structure which is used to pass data from the vertex to the pixel 206 shader. 207 208 The MaterialFeatureData parameter is used to determine what other 209 features are present for the shader being generated. 210 */ 211 //----------------------------------------------------------------------- 212 virtual void processVert( Vector<ShaderComponent*> &componentList, 213 const MaterialFeatureData &fd ) 214 { output = NULL; } 215 216 //----------------------------------------------------------------------- 217 /*! 218 Process pixel shader - This function is used by each feature to 219 generate a list of LangElements that can be traversed and "printed" 220 to generate the actual shader code. The 'output' member is the head 221 of that list. 222 223 The componentList is used mostly for access to the "Connector" 224 structure which is used to pass data from the vertex to the pixel 225 shader. 226 227 The MaterialFeatureData parameter is used to determine what other 228 features are present for the shader being generated. 229 */ 230 //----------------------------------------------------------------------- 231 virtual void processPix( Vector<ShaderComponent*> &componentList, 232 const MaterialFeatureData &fd ) 233 { output = NULL; } 234 235 /// Allows the feature to add macros to pixel shader compiles. 236 virtual void processPixMacros( Vector<GFXShaderMacro> ¯os, const MaterialFeatureData &fd ) {}; 237 238 /// Allows the feature to add macros to vertex shader compiles. 239 virtual void processVertMacros( Vector<GFXShaderMacro> ¯os, const MaterialFeatureData &fd ) {}; 240 241 /// Identifies what type of blending a feature uses. This is used to 242 /// group features with the same blend operation together in a multipass 243 /// situation. 244 virtual Material::BlendOp getBlendOp() { return Material::Add; } 245 246 /// Returns the resource requirements of this feature based on what 247 /// other features are present. The "resources" are things such as 248 /// texture units, and texture registers of which there can be 249 /// very limited numbers. The resources can vary depending on hardware 250 /// and what other features are present. 251 virtual Resources getResources( const MaterialFeatureData &fd ); 252 253 /// Fills texture related info in RenderPassData for this feature. It 254 /// takes into account the current pass (passData) as well as what other 255 /// data is available to the material stage (stageDat). 256 /// 257 /// For instance, ReflectCubeFeatHLSL would like to modulate its output 258 /// by the alpha channel of another texture. If the current pass does 259 /// not contain a diffuse or bump texture, but the Material does, then 260 /// this function allows it to use one of those textures in the current 261 /// pass. 262 virtual void setTexData( Material::StageData &stageDat, 263 const MaterialFeatureData &fd, 264 RenderPassData &passData, 265 U32 &texIndex ){}; 266 267 /// Returns the name of this feature. 268 virtual String getName() = 0; 269 270 /// Adds a dependency to this shader feature. 271 virtual void addDependency( const ShaderDependency *depends ); 272 273 /// Gets the dependency list for this shader feature. 274 virtual const Vector<const ShaderDependency*> &getDependencies() const { return mDependencies; } 275 276 /// Returns the output variable name for this feature if it applies. 277 virtual const char* getOutputVarName() const { return NULL; } 278 279 /// Gets the render target this shader feature is assigning data to. 280 virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return DefaultTarget; } 281 282 /// Returns the name of output targer var. 283 const char* getOutputTargetVarName( OutputTarget target = DefaultTarget ) const; 284 285 // Called from ProcessedShaderMaterial::determineFeatures to enable/disable features. 286 virtual void determineFeature( Material *material, 287 const GFXVertexFormat *vertexFormat, 288 U32 stageNum, 289 const FeatureType &type, 290 const FeatureSet &features, 291 MaterialFeatureData *outFeatureData ) { } 292 293 // 294 virtual ShaderFeatureConstHandles* createConstHandles( GFXShader *shader, SimObject *userObject ) { return NULL; } 295 296 /// Called after processing the vertex and processing the pixel 297 /// to cleanup any temporary structures stored in the feature. 298 virtual void reset() { output = NULL; mProcessIndex = 0; mInstancingFormat = NULL; mVertexFormat = NULL; } 299 300 /// A simpler helper function which either finds 301 /// the existing local var or creates one. 302 static Var* findOrCreateLocal( const char *name, 303 const char *type, 304 MultiLine *multi ); 305 // Set the instancing format 306 void setInstancingFormat(GFXVertexFormat *format); 307}; 308 309#endif // _SHADERFEATURE_H_ 310