123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "platform/platform.h"
- #include "forest/glsl/windDeformationGLSL.h"
- #include "forest/windDeformation.h"
- #include "forest/forestItem.h"
- #include "forest/forestWindMgr.h"
- #include "materials/sceneData.h"
- #include "scene/sceneRenderState.h"
- #include "shaderGen/shaderGen.h"
- #include "shaderGen/featureMgr.h"
- #include "shaderGen/langElement.h"
- #include "shaderGen/shaderOp.h"
- #include "shaderGen/shaderGenVars.h"
- #include "gfx/gfxStructs.h"
- #include "core/module.h"
- static void _onRegisterFeatures( GFXAdapterType type )
- {
- if ( type != OpenGL )
- return;
- FEATUREMGR->registerFeature( MFT_WindEffect, new WindDeformationGLSL );
- }
- MODULE_BEGIN( WindDeformationGLSL )
- MODULE_INIT_AFTER( ShaderGen )
-
- MODULE_INIT
- {
- SHADERGEN->getFeatureInitSignal().notify( _onRegisterFeatures );
- }
- MODULE_END;
- WindDeformationGLSL::WindDeformationGLSL()
- : mDep(ShaderGen::smCommonShaderPath + String("/gl/wind.glsl" ))
- {
- addDependency( &mDep );
- }
- void WindDeformationGLSL::determineFeature( Material *material,
- const GFXVertexFormat *vertexFormat,
- U32 stageNum,
- const FeatureType &type,
- const FeatureSet &features,
- MaterialFeatureData *outFeatureData )
- {
- bool enabled = vertexFormat->hasColor() && features.hasFeature( MFT_WindEffect );
- outFeatureData->features.setFeature( type, enabled );
- }
- void WindDeformationGLSL::processVert( Vector<ShaderComponent*> &componentList,
- const MaterialFeatureData &fd )
- {
- MultiLine *meta = new MultiLine;
- output = meta;
- // We combined all the tree parameters into one float4 to
- // save constant space and reduce the memory copied to the
- // card.
- //
- // .x = bend scale
- // .y = branch amplitude
- // .z = detail amplitude
- // .w = detail frequency
- //
- Var *windParams = new Var( "windParams", "vec4" );
- windParams->uniform = true;
- windParams->constSortPos = cspPotentialPrimitive;
- // If we're instancing then we need to instance the wind direction
- // and speed as its unique for each tree instance.
- Var *windDirAndSpeed;
- if ( fd.features[MFT_UseInstancing] )
- {
- ShaderConnector *vertStruct = dynamic_cast<ShaderConnector *>( componentList[C_VERT_STRUCT] );
- windDirAndSpeed = vertStruct->getElement( RT_TEXCOORD );
- windDirAndSpeed->setStructName( "IN" );
- windDirAndSpeed->setName( "inst_windDirAndSpeed" );
- windDirAndSpeed->setType( "vec3" );
- mInstancingFormat->addElement( "windDirAndSpeed", GFXDeclType_Float3, windDirAndSpeed->constNum );
- }
- else
- {
- windDirAndSpeed = new Var( "windDirAndSpeed", "vec3" );
- windDirAndSpeed->uniform = true;
- windDirAndSpeed->constSortPos = cspPrimitive;
- }
- Var *accumTime = (Var*)LangElement::find( "accumTime" );
- if ( !accumTime )
- {
- accumTime = new Var( "accumTime", "float" );
- accumTime->uniform = true;
- accumTime->constSortPos = cspPass;
- }
- // Get the transform to world space.
- Var *objTrans = getObjTrans( componentList, fd.features[MFT_UseInstancing], meta );
- // First check for an input position from a previous feature
- // then look for the default vertex position.
- Var *inPosition = (Var*)LangElement::find( "inPosition" );
- if ( !inPosition )
- inPosition = (Var*)LangElement::find( "position" );
- // Copy the input position to the output first as
- // the wind effects are conditional.
- Var *outPosition = (Var*)LangElement::find( "inPosition" );
- if ( !outPosition )
- {
- outPosition = new Var;
- outPosition->setType( "vec3" );
- outPosition->setName( "inPosition" );
- meta->addStatement( new GenOp(" @ = @.xyz;\r\n", new DecOp( outPosition ), inPosition ) );
- }
- // Get the incoming color data
- Var *inColor = (Var*)LangElement::find( "diffuse" );
- // Do a dynamic branch based on wind force.
- if ( GFX->getPixelShaderVersion() >= 3.0f )
- meta->addStatement( new GenOp(" if ( any( bvec3(@) ) ) {\r\n", windDirAndSpeed ) );
- // Do the branch and detail bending first so that
- // it can work in pure object space of the tree.
- LangElement *effect =
- new GenOp( "windBranchBending( "
- "@, " // vPos
- "normalize( IN_normal ), " // vNormal
- "@, " // fTime
- "@.z, " // fWindSpeed
- "@.g, " // fBranchPhase
- "@.y, " // fBranchAmp
- "@.r, " // fBranchAtten
- "dot( @[3], vec4(1) ), " // fDetailPhase
- "@.z, " // fDetailAmp
- "@.w, " // fDetailFreq
-
- "@.b )", // fEdgeAtten
- outPosition, // vPos
- // vNormal
- accumTime, // fTime
- windDirAndSpeed, // fWindSpeed
- inColor, // fBranchPhase
- windParams, // fBranchAmp
- inColor, // fBranchAtten
- objTrans, // fDetailPhase
- windParams, // fDetailAmp
- windParams, // fDetailFreq
- inColor ); // fEdgeAtten
- meta->addStatement( new GenOp( " @ = @;\r\n", outPosition, effect ) );
- // Now do the trunk bending.
- meta->addStatement( new GenOp(" @ = windTrunkBending( @, @.xy, @.z * @.x );\r\n",
- outPosition, outPosition, windDirAndSpeed, outPosition, windParams ) );
- // End the dynamic branch.
- if ( GFX->getPixelShaderVersion() >= 3.0f )
- meta->addStatement( new GenOp(" } // [branch]\r\n" ) );
- }
- ShaderFeatureConstHandles* WindDeformationGLSL::createConstHandles( GFXShader *shader, SimObject *userObject )
- {
- WindDeformationConstHandles *handles = new WindDeformationConstHandles();
- handles->init( shader );
- return handles;
- }
|