Merge branch 'development' into defineconsolemethod

Conflicts:
	Engine/source/materials/materialDefinition.cpp
This commit is contained in:
Daniel Buckmaster 2014-12-26 13:22:16 +11:00
commit ae284a89ec
129 changed files with 3742 additions and 1038 deletions

View file

@ -0,0 +1,349 @@
//-----------------------------------------------------------------------------
// 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 "T3D/accumulationVolume.h"
#include "scene/sceneManager.h"
#include "scene/sceneRenderState.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxDrawUtil.h"
#include "gfx/sim/debugDraw.h"
#include "util/tempAlloc.h"
#include "materials/materialDefinition.h"
#include "materials/materialManager.h"
#include "materials/materialFeatureTypes.h"
#include "materials/matInstance.h"
#include "console/consoleTypes.h"
#include "core/stream/bitStream.h"
#include "gfx/gfxDevice.h"
#include "console/console.h"
#include "console/engineAPI.h"
#include "gfx/gfxTextureHandle.h"
#include "scene/sceneContainer.h"
#include "math/mPolyhedron.impl.h"
Vector< SimObjectPtr<SceneObject> > AccumulationVolume::smAccuObjects;
Vector< SimObjectPtr<AccumulationVolume> > AccumulationVolume::smAccuVolumes;
//#define DEBUG_DRAW
IMPLEMENT_CO_NETOBJECT_V1( AccumulationVolume );
ConsoleDocClass( AccumulationVolume,
"@brief An invisible shape that allow objects within it to have an accumulation map.\n\n"
"AccumulationVolume is used to add additional realism to a scene. It's main use is in outdoor scenes "
" where objects could benefit from overlaying environment accumulation textures such as sand, snow, etc.\n\n"
"Objects within the volume must have accumulation enabled in their material. \n\n"
"@ingroup enviroMisc"
);
//-----------------------------------------------------------------------------
AccumulationVolume::AccumulationVolume()
: mTransformDirty( true ),
mSilhouetteExtractor( mPolyhedron )
{
VECTOR_SET_ASSOCIATION( mWSPoints );
VECTOR_SET_ASSOCIATION( mVolumeQueryList );
//mObjectFlags.set( VisualOccluderFlag );
mNetFlags.set( Ghostable | ScopeAlways );
mObjScale.set( 1.f, 1.f, 1.f );
mObjBox.set(
Point3F( -0.5f, -0.5f, -0.5f ),
Point3F( 0.5f, 0.5f, 0.5f )
);
mObjToWorld.identity();
mWorldToObj.identity();
// Accumulation Texture.
mTextureName = "";
mAccuTexture = NULL;
resetWorldBox();
}
AccumulationVolume::~AccumulationVolume()
{
mAccuTexture = NULL;
}
void AccumulationVolume::initPersistFields()
{
addProtectedField( "texture", TypeStringFilename, Offset( mTextureName, AccumulationVolume ),
&_setTexture, &defaultProtectedGetFn, "Accumulation texture." );
Parent::initPersistFields();
}
//-----------------------------------------------------------------------------
void AccumulationVolume::consoleInit()
{
// Disable rendering of occlusion volumes by default.
getStaticClassRep()->mIsRenderEnabled = false;
}
//-----------------------------------------------------------------------------
bool AccumulationVolume::onAdd()
{
if( !Parent::onAdd() )
return false;
// Prepare some client side things.
if ( isClientObject() )
{
smAccuVolumes.push_back(this);
refreshVolumes();
}
// Set up the silhouette extractor.
mSilhouetteExtractor = SilhouetteExtractorType( mPolyhedron );
return true;
}
void AccumulationVolume::onRemove()
{
if ( isClientObject() )
{
smAccuVolumes.remove(this);
refreshVolumes();
}
Parent::onRemove();
}
//-----------------------------------------------------------------------------
void AccumulationVolume::_renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat )
{
Parent::_renderObject( ri, state, overrideMat );
#ifdef DEBUG_DRAW
if( state->isDiffusePass() )
DebugDrawer::get()->drawPolyhedronDebugInfo( mPolyhedron, getTransform(), getScale() );
#endif
}
//-----------------------------------------------------------------------------
void AccumulationVolume::setTransform( const MatrixF& mat )
{
Parent::setTransform( mat );
mTransformDirty = true;
refreshVolumes();
}
//-----------------------------------------------------------------------------
void AccumulationVolume::buildSilhouette( const SceneCameraState& cameraState, Vector< Point3F >& outPoints )
{
// Extract the silhouette of the polyhedron. This works differently
// depending on whether we project orthogonally or in perspective.
TempAlloc< U32 > indices( mPolyhedron.getNumPoints() );
U32 numPoints;
if( cameraState.getFrustum().isOrtho() )
{
// Transform the view direction into object space.
Point3F osViewDir;
getWorldTransform().mulV( cameraState.getViewDirection(), &osViewDir );
// And extract the silhouette.
SilhouetteExtractorOrtho< PolyhedronType > extractor( mPolyhedron );
numPoints = extractor.extractSilhouette( osViewDir, indices, indices.size );
}
else
{
// Create a transform to go from view space to object space.
MatrixF camView( true );
camView.scale( Point3F( 1.0f / getScale().x, 1.0f / getScale().y, 1.0f / getScale().z ) );
camView.mul( getRenderWorldTransform() );
camView.mul( cameraState.getViewWorldMatrix() );
// Do a perspective-correct silhouette extraction.
numPoints = mSilhouetteExtractor.extractSilhouette(
camView,
indices, indices.size );
}
// If we haven't yet, transform the polyhedron's points
// to world space.
if( mTransformDirty )
{
const U32 numPoints = mPolyhedron.getNumPoints();
const PolyhedronType::PointType* points = getPolyhedron().getPoints();
mWSPoints.setSize( numPoints );
for( U32 i = 0; i < numPoints; ++ i )
{
Point3F p = points[ i ];
p.convolve( getScale() );
getTransform().mulP( p, &mWSPoints[ i ] );
}
mTransformDirty = false;
}
// Now store the points.
outPoints.setSize( numPoints );
for( U32 i = 0; i < numPoints; ++ i )
outPoints[ i ] = mWSPoints[ indices[ i ] ];
}
//-----------------------------------------------------------------------------
U32 AccumulationVolume::packUpdate( NetConnection *connection, U32 mask, BitStream *stream )
{
U32 retMask = Parent::packUpdate( connection, mask, stream );
if (stream->writeFlag(mask & InitialUpdateMask))
{
stream->write( mTextureName );
}
return retMask;
}
void AccumulationVolume::unpackUpdate( NetConnection *connection, BitStream *stream )
{
Parent::unpackUpdate( connection, stream );
if (stream->readFlag())
{
stream->read( &mTextureName );
setTexture(mTextureName);
}
}
//-----------------------------------------------------------------------------
void AccumulationVolume::inspectPostApply()
{
Parent::inspectPostApply();
setMaskBits(U32(-1) );
}
void AccumulationVolume::setTexture( const String& name )
{
mTextureName = name;
if ( isClientObject() && mTextureName.isNotEmpty() )
{
mAccuTexture.set(mTextureName, &GFXDefaultStaticDiffuseProfile, "AccumulationVolume::mAccuTexture");
if ( mAccuTexture.isNull() )
Con::warnf( "AccumulationVolume::setTexture - Unable to load texture: %s", mTextureName.c_str() );
}
refreshVolumes();
}
//-----------------------------------------------------------------------------
// Static Functions
//-----------------------------------------------------------------------------
bool AccumulationVolume::_setTexture( void *object, const char *index, const char *data )
{
AccumulationVolume* volume = reinterpret_cast< AccumulationVolume* >( object );
volume->setTexture( data );
return false;
}
void AccumulationVolume::refreshVolumes()
{
// This function tests each accumulation object to
// see if it's within the bounds of an accumulation
// volume. If so, it will pass on the accumulation
// texture of the volume to the object.
// This function should only be called when something
// global like change of volume or material occurs.
// Clear old data.
for (S32 n = 0; n < smAccuObjects.size(); ++n)
{
SimObjectPtr<SceneObject> object = smAccuObjects[n];
if ( object.isValid() )
object->mAccuTex = GFXTexHandle::ZERO;
}
//
for (S32 i = 0; i < smAccuVolumes.size(); ++i)
{
SimObjectPtr<AccumulationVolume> volume = smAccuVolumes[i];
if ( volume.isNull() ) continue;
for (S32 n = 0; n < smAccuObjects.size(); ++n)
{
SimObjectPtr<SceneObject> object = smAccuObjects[n];
if ( object.isNull() ) continue;
if ( volume->containsPoint(object->getPosition()) )
object->mAccuTex = volume->mAccuTexture;
}
}
}
// Accumulation Object Management.
void AccumulationVolume::addObject(SimObjectPtr<SceneObject> object)
{
smAccuObjects.push_back(object);
refreshVolumes();
}
void AccumulationVolume::removeObject(SimObjectPtr<SceneObject> object)
{
smAccuObjects.remove(object);
refreshVolumes();
}
void AccumulationVolume::updateObject(SceneObject* object)
{
// This function is called when an individual object
// has been moved. Tests to see if it's in any of the
// accumulation volumes.
// We use ZERO instead of NULL so the accumulation
// texture will be updated in renderMeshMgr.
object->mAccuTex = GFXTexHandle::ZERO;
for (S32 i = 0; i < smAccuVolumes.size(); ++i)
{
SimObjectPtr<AccumulationVolume> volume = smAccuVolumes[i];
if ( volume.isNull() ) continue;
if ( volume->containsPoint(object->getPosition()) )
object->mAccuTex = volume->mAccuTexture;
}
}

View file

@ -0,0 +1,104 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _ACCUMULATIONVOLUME_H_
#define _ACCUMULATIONVOLUME_H_
#ifndef _SCENEPOLYHEDRALSPACE_H_
#include "scene/scenePolyhedralSpace.h"
#endif
#ifndef _MSILHOUETTEEXTRACTOR_H_
#include "math/mSilhouetteExtractor.h"
#endif
#ifndef _GFXDEVICE_H_
#include "gfx/gfxDevice.h"
#endif
/// A volume in space that blocks visibility.
class AccumulationVolume : public ScenePolyhedralSpace
{
public:
typedef ScenePolyhedralSpace Parent;
protected:
typedef SilhouetteExtractorPerspective< PolyhedronType > SilhouetteExtractorType;
/// Whether the volume's transform has changed and we need to recompute
/// transform-based data.
bool mTransformDirty;
/// World-space points of the volume's polyhedron.
Vector< Point3F > mWSPoints;
/// Silhouette extractor when using perspective projections.
SilhouetteExtractorType mSilhouetteExtractor;
mutable Vector< SceneObject* > mVolumeQueryList;
// Name (path) of the accumulation texture.
String mTextureName;
// SceneSpace.
virtual void _renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat );
public:
GFXTexHandle mAccuTexture;
AccumulationVolume();
~AccumulationVolume();
// SimObject.
DECLARE_CONOBJECT( AccumulationVolume );
DECLARE_DESCRIPTION( "Allows objects in an area to have accumulation effect applied." );
DECLARE_CATEGORY( "3D Scene" );
virtual bool onAdd();
virtual void onRemove();
void inspectPostApply();
void setTexture( const String& name );
// Static Functions.
static void consoleInit();
static void initPersistFields();
static Vector< SimObjectPtr<SceneObject> > smAccuObjects;
static Vector< SimObjectPtr<AccumulationVolume> > smAccuVolumes;
static void addObject(SimObjectPtr<SceneObject> object);
static void removeObject(SimObjectPtr<SceneObject> object);
static void refreshVolumes();
static bool _setTexture( void *object, const char *index, const char *data );
static void updateObject(SceneObject* object);
// Network
U32 packUpdate( NetConnection *, U32 mask, BitStream *stream );
void unpackUpdate( NetConnection *, BitStream *stream );
// SceneObject.
virtual void buildSilhouette( const SceneCameraState& cameraState, Vector< Point3F >& outPoints );
virtual void setTransform( const MatrixF& mat );
};
#endif // !_AccumulationVolume_H_

View file

@ -145,6 +145,7 @@ ParticleEmitterData::ParticleEmitterData()
blendStyle = ParticleRenderInst::BlendUndefined;
sortParticles = false;
renderReflection = true;
glow = false;
reverseOrder = false;
textureName = 0;
textureHandle = 0;
@ -289,6 +290,9 @@ void ParticleEmitterData::initPersistFields()
addField( "renderReflection", TYPEID< bool >(), Offset(renderReflection, ParticleEmitterData),
"Controls whether particles are rendered onto reflective surfaces like water." );
addField("glow", TYPEID< bool >(), Offset(glow, ParticleEmitterData),
"If true, the particles are rendered to the glow buffer as well.");
//@}
endGroup( "ParticleEmitterData" );
@ -356,6 +360,7 @@ void ParticleEmitterData::packData(BitStream* stream)
}
stream->writeFlag(highResOnly);
stream->writeFlag(renderReflection);
stream->writeFlag(glow);
stream->writeInt( blendStyle, 4 );
}
@ -418,6 +423,7 @@ void ParticleEmitterData::unpackData(BitStream* stream)
}
highResOnly = stream->readFlag();
renderReflection = stream->readFlag();
glow = stream->readFlag();
blendStyle = stream->readInt( 4 );
}
@ -909,6 +915,8 @@ void ParticleEmitter::prepRenderImage(SceneRenderState* state)
ri->blendStyle = mDataBlock->blendStyle;
ri->glow = mDataBlock->glow;
// use first particle's texture unless there is an emitter texture to override it
if (mDataBlock->textureHandle)
ri->diffuseTex = &*(mDataBlock->textureHandle);

View file

@ -114,6 +114,7 @@ class ParticleEmitterData : public GameBaseData
GFXTexHandle textureHandle; ///< Emitter texture handle from txrName
bool highResOnly; ///< This particle system should not use the mixed-resolution particle rendering
bool renderReflection; ///< Enables this emitter to render into reflection passes.
bool glow; ///< Renders this emitter into the glow buffer.
bool reload();
};

View file

@ -388,7 +388,9 @@ F32 GameBase::getUpdatePriority(CameraScopeQuery *camInfo, U32 updateMask, S32 u
// Weight by field of view, objects directly in front
// will be weighted 1, objects behind will be 0
F32 dot = mDot(pos,camInfo->orientation);
bool inFov = dot > camInfo->cosFov;
bool inFov = dot > camInfo->cosFov * 1.5f;
F32 wFov = inFov? 1.0f: 0;
// Weight by linear velocity parallel to the viewing plane
@ -406,7 +408,7 @@ F32 GameBase::getUpdatePriority(CameraScopeQuery *camInfo, U32 updateMask, S32 u
// Weight by interest.
F32 wInterest;
if (getTypeMask() & PlayerObjectType)
if (getTypeMask() & (PlayerObjectType || VehicleObjectType ))
wInterest = 0.75f;
else if (getTypeMask() & ProjectileObjectType)
{

View file

@ -35,6 +35,10 @@
#ifndef _DYNAMIC_CONSOLETYPES_H_
#include "console/dynamicTypes.h"
#endif
#ifndef __SCENEMANAGER_H__
#include "scene/sceneManager.h"
#define __SCENEMANAGER_H__
#endif
class NetConnection;
class ProcessList;

View file

@ -226,6 +226,8 @@ GameConnection::GameConnection()
mAddYawToAbsRot = false;
mAddPitchToAbsRot = false;
mVisibleGhostDistance = 0.0f;
clearDisplayDevice();
}
@ -240,6 +242,16 @@ GameConnection::~GameConnection()
//----------------------------------------------------------------------------
void GameConnection::setVisibleGhostDistance(F32 dist)
{
mVisibleGhostDistance = dist;
}
F32 GameConnection::getVisibleGhostDistance()
{
return mVisibleGhostDistance;
}
bool GameConnection::canRemoteCreate()
{
return true;
@ -2199,3 +2211,21 @@ DefineEngineMethod( GameConnection, getControlSchemeAbsoluteRotation, bool, (),,
{
return object->getControlSchemeAbsoluteRotation();
}
DefineEngineMethod( GameConnection, setVisibleGhostDistance, void, (F32 dist),,
"@brief Sets the distance that objects around it will be ghosted. If set to 0, "
"it may be defined by the LevelInfo.\n\n"
"@dist - is the max distance\n\n"
)
{
object->setVisibleGhostDistance(dist);
}
DefineEngineMethod( GameConnection, getVisibleGhostDistance, F32, (),,
"@brief Gets the distance that objects around the connection will be ghosted.\n\n"
"@return S32 of distance.\n\n"
)
{
return object->getVisibleGhostDistance();
}

View file

@ -72,6 +72,8 @@ private:
U32 mMissionCRC; // crc of the current mission file from the server
F32 mVisibleGhostDistance;
private:
U32 mLastControlRequestTime;
S32 mDataBlockModifiedKey;
@ -155,6 +157,9 @@ public:
bool canRemoteCreate();
void setVisibleGhostDistance(F32 dist);
F32 getVisibleGhostDistance();
private:
/// @name Connection State
/// This data is set with setConnectArgs() and setJoinPassword(), and

View file

@ -35,6 +35,8 @@
#include "console/engineAPI.h"
#include "math/mathIO.h"
#include "torqueConfig.h"
IMPLEMENT_CO_NETOBJECT_V1(LevelInfo);
@ -77,6 +79,7 @@ static SFXAmbience sDefaultAmbience;
LevelInfo::LevelInfo()
: mNearClip( 0.1f ),
mVisibleDistance( 1000.0f ),
mVisibleGhostDistance ( 0 ),
mDecalBias( 0.0015f ),
mCanvasClearColor( 255, 0, 255, 255 ),
mSoundAmbience( NULL ),
@ -113,7 +116,8 @@ void LevelInfo::initPersistFields()
addGroup( "Visibility" );
addField( "nearClip", TypeF32, Offset( mNearClip, LevelInfo ), "Closest distance from the camera's position to render the world." );
addField( "visibleDistance", TypeF32, Offset( mVisibleDistance, LevelInfo ), "Furthest distance fromt he camera's position to render the world." );
addField( "visibleDistance", TypeF32, Offset( mVisibleDistance, LevelInfo ), "Furthest distance from the camera's position to render the world." );
addField( "visibleGhostDistance", TypeF32, Offset( mVisibleGhostDistance, LevelInfo ), "Furthest distance from the camera's position to render players. Defaults to visibleDistance." );
addField( "decalBias", TypeF32, Offset( mDecalBias, LevelInfo ),
"NearPlane bias used when rendering Decal and DecalRoad. This should be tuned to the visibleDistance in your level." );
@ -300,6 +304,7 @@ void LevelInfo::_updateSceneGraph()
scene->setNearClip( mNearClip );
scene->setVisibleDistance( mVisibleDistance );
scene->setVisibleGhostDistance( mVisibleGhostDistance );
gDecalBias = mDecalBias;

View file

@ -36,7 +36,6 @@
#include "sfx/sfxCommon.h"
#endif
class SFXAmbience;
class SFXSoundscape;
@ -55,6 +54,8 @@ class LevelInfo : public NetObject
F32 mVisibleDistance;
F32 mVisibleGhostDistance;
F32 mDecalBias;
ColorI mCanvasClearColor;

View file

@ -48,6 +48,7 @@
#include "materials/materialFeatureData.h"
#include "materials/materialFeatureTypes.h"
#include "console/engineAPI.h"
#include "T3D/accumulationVolume.h"
using namespace Torque;
@ -198,10 +199,10 @@ void TSStatic::initPersistFields()
endGroup("Collision");
addGroup( "AlphaFade" );
addField( "Alpha Fade Enable", TypeBool, Offset(mUseAlphaFade, TSStatic), "Turn on/off Alpha Fade" );
addField( "Alpha Fade Start", TypeF32, Offset(mAlphaFadeStart, TSStatic), "Distance of start Alpha Fade" );
addField( "Alpha Fade End", TypeF32, Offset(mAlphaFadeEnd, TSStatic), "Distance of end Alpha Fade" );
addField( "Alpha Fade Inverse", TypeBool, Offset(mInvertAlphaFade, TSStatic), "Invert Alpha Fade's Start & End Distance" );
addField( "alphaFadeEnable", TypeBool, Offset(mUseAlphaFade, TSStatic), "Turn on/off Alpha Fade" );
addField( "alphaFadeStart", TypeF32, Offset(mAlphaFadeStart, TSStatic), "Distance of start Alpha Fade" );
addField( "alphaFadeEnd", TypeF32, Offset(mAlphaFadeEnd, TSStatic), "Distance of end Alpha Fade" );
addField( "alphaFadeInverse", TypeBool, Offset(mInvertAlphaFade, TSStatic), "Invert Alpha Fade's Start & End Distance" );
endGroup( "AlphaFade" );
addGroup("Debug");
@ -293,6 +294,13 @@ bool TSStatic::onAdd()
_updateShouldTick();
// Accumulation
if ( isClientObject() && mShapeInstance )
{
if ( mShapeInstance->hasAccumulation() )
AccumulationVolume::addObject(this);
}
return true;
}
@ -403,6 +411,13 @@ void TSStatic::onRemove()
{
SAFE_DELETE( mPhysicsRep );
// Accumulation
if ( isClientObject() && mShapeInstance )
{
if ( mShapeInstance->hasAccumulation() )
AccumulationVolume::removeObject(this);
}
mConvexList->nukeList();
removeFromScene();
@ -562,6 +577,9 @@ void TSStatic::prepRenderImage( SceneRenderState* state )
rdata.setFadeOverride( 1.0f );
rdata.setOriginSort( mUseOriginSort );
// Acculumation
rdata.setAccuTex(mAccuTex);
// If we have submesh culling enabled then prepare
// the object space frustum to pass to the shape.
Frustum culler;
@ -649,6 +667,13 @@ void TSStatic::setTransform(const MatrixF & mat)
if ( mPhysicsRep )
mPhysicsRep->setTransform( mat );
// Accumulation
if ( isClientObject() && mShapeInstance )
{
if ( mShapeInstance->hasAccumulation() )
AccumulationVolume::updateObject(this);
}
// Since this is a static it's render transform changes 1
// to 1 with it's collision transform... no interpolation.
setRenderTransform(mat);

View file

@ -207,10 +207,6 @@ struct ServerFilter
Favorites = 3,
};
Type type;
char* gameType;
char* missionType;
enum // Query Flags
{
OnlineQuery = 0, // Authenticated with master
@ -226,17 +222,21 @@ struct ServerFilter
CurrentVersion = BIT(7),
NotXenon = BIT(6)
};
//Rearranging the fields according to their sizes
char* gameType;
char* missionType;
U8 queryFlags;
U8 minPlayers;
U8 maxPlayers;
U8 maxBots;
U8 filterFlags;
U8 buddyCount;
U16 minCPU;
U32 regionMask;
U32 maxPing;
U8 filterFlags;
U16 minCPU;
U8 buddyCount;
U32* buddyList;
Type type;
ServerFilter()
{
@ -432,7 +432,7 @@ DefineConsoleFunction( queryAllServers
maxBots,regionMask,maxPing,minCPU,filterFlags,0,&buddyList);
queryLanServers(lanPort, flags, gameType, missionType, minPlayers, maxPlayers, maxBots,
regionMask, maxPing, minCPU, filterFlags);
regionMask, maxPing, minCPU, filterFlags);
dFree(gameType);
dFree(missionType);
@ -456,7 +456,7 @@ DefineConsoleFunction( queryLanServers
clearServerList();
queryLanServers(lanPort, flags, gameType, missionType, minPlayers, maxPlayers, maxBots,
regionMask, maxPing, minCPU, filterFlags);
regionMask, maxPing, minCPU, filterFlags);
}

View file

@ -470,11 +470,11 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer),
"%s(", thisFunctionName);
}
for (i = 0; i < wantedArgc; i++)
for(i = 0; i < wantedArgc; i++)
{
dStrcat(traceBuffer, argv[i + 1]);
if (i != wantedArgc - 1)
dStrcat(traceBuffer, ", ");
dStrcat(traceBuffer, argv[i+1]);
if(i != wantedArgc - 1)
dStrcat(traceBuffer, ", ");
}
dStrcat(traceBuffer, ")");
Con::printf("%s", traceBuffer);
@ -533,9 +533,16 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
}
}
// Reset the console stack frame which at this point will contain
// either nothing or argv[] which we just copied
CSTK.resetFrame();
bool doResetValueStack = !gEvalState.mResetLocked;
gEvalState.mResetLocked = true;
if (gEvalState.mShouldReset)
{
// Ensure all stacks are clean in case anything became unbalanced during the previous execution
STR.clearFrames();
CSTK.clearFrames();
gEvalState.mShouldReset = false;
}
// Grab the state of the telenet debugger here once
// so that the push and pop frames are always balanced.
@ -1817,7 +1824,7 @@ breakContinue:
ConsoleValueRef ret;
if(nsEntry->mFunctionOffset)
ret = nsEntry->mCode->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage);
STR.popFrame();
// Functions are assumed to return strings, so look ahead to see if we can skip the conversion
if(code[ip] == OP_STR_TO_UINT)
@ -1837,7 +1844,7 @@ breakContinue:
}
else
STR.setStringValue((const char*)ret);
// This will clear everything including returnValue
CSTK.popFrame();
STR.clearFunctionOffset();
@ -2219,15 +2226,7 @@ execFinished:
Con::printf("%s", traceBuffer);
}
}
else
{
delete[] globalStrings;
globalStringsMaxLen = 0;
delete[] globalFloats;
globalStrings = NULL;
globalFloats = NULL;
}
smCurrentCodeBlock = saveCodeBlock;
if(saveCodeBlock && saveCodeBlock->name)
{
@ -2235,6 +2234,13 @@ execFinished:
Con::gCurrentRoot = saveCodeBlock->modPath;
}
// Mark the reset flag for the next run if we've finished execution
if (doResetValueStack)
{
gEvalState.mShouldReset = true;
gEvalState.mResetLocked = false;
}
decRefCount();
#ifdef TORQUE_DEBUG

View file

@ -796,6 +796,8 @@ ExprEvalState::ExprEvalState()
currentVariable = NULL;
mStackDepth = 0;
stack.reserve( 64 );
mShouldReset = false;
mResetLocked = false;
}
ExprEvalState::~ExprEvalState()

View file

@ -468,6 +468,8 @@ public:
bool traceOn;
U32 mStackDepth;
bool mShouldReset; ///< Designates if the value stack should be reset
bool mResetLocked; ///< mShouldReset will be set at the end
ExprEvalState();
~ExprEvalState();

View file

@ -29,19 +29,23 @@ extern U32 HashPointer(StringTableEntry e);
SimNameDictionary::SimNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
hashTable = NULL;
#endif
mutex = Mutex::createMutex();
}
SimNameDictionary::~SimNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
delete[] hashTable;
#endif
Mutex::destroyMutex(mutex);
}
void SimNameDictionary::insert(SimObject* obj)
{
if(!obj->objectName)
if(!obj || !obj->objectName)
return;
SimObject* checkForDup = find(obj->objectName);
@ -50,7 +54,7 @@ void SimNameDictionary::insert(SimObject* obj)
Con::warnf("Warning! You have a duplicate datablock name of %s. This can cause problems. You should rename one of them.", obj->objectName);
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
if(!hashTable)
{
hashTable = new SimObject *[DefaultTableSize];
@ -95,12 +99,15 @@ void SimNameDictionary::insert(SimObject* obj)
hashTable = newHashTable;
hashTableSize = newHashTableSize;
}
#else
root[obj->objectName] = obj;
#endif
Mutex::unlockMutex(mutex);
}
SimObject* SimNameDictionary::find(StringTableEntry name)
{
#ifndef USE_NEW_SIMDICTIONARY
// NULL is a valid lookup - it will always return NULL
if(!hashTable)
return NULL;
@ -121,15 +128,22 @@ SimObject* SimNameDictionary::find(StringTableEntry name)
Mutex::unlockMutex(mutex);
return NULL;
#else
Mutex::lockMutex(mutex);
StringDictDef::iterator it = root.find(name);
SimObject* f = (it == root.end() ? NULL : it->second);
Mutex::unlockMutex(mutex);
return f;
#endif
}
void SimNameDictionary::remove(SimObject* obj)
{
if(!obj->objectName)
if(!obj || !obj->objectName)
return;
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
while(*walk)
{
@ -144,7 +158,11 @@ void SimNameDictionary::remove(SimObject* obj)
}
walk = &((*walk)->nextNameObject);
}
#else
const char* name = obj->objectName;
if (root.find(name) != root.end())
root.erase(name);
#endif
Mutex::unlockMutex(mutex);
}
@ -152,28 +170,31 @@ void SimNameDictionary::remove(SimObject* obj)
SimManagerNameDictionary::SimManagerNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
hashTable = new SimObject *[DefaultTableSize];
hashTableSize = DefaultTableSize;
hashEntryCount = 0;
dMemset( hashTable, 0, sizeof( hashTable[ 0 ] ) * hashTableSize );
#endif
mutex = Mutex::createMutex();
}
SimManagerNameDictionary::~SimManagerNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
delete[] hashTable;
#endif
Mutex::destroyMutex(mutex);
}
void SimManagerNameDictionary::insert(SimObject* obj)
{
if(!obj->objectName)
if(!obj || !obj->objectName)
return;
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
S32 idx = HashPointer(obj->objectName) % hashTableSize;
obj->nextManagerNameObject = hashTable[idx];
hashTable[idx] = obj;
@ -209,7 +230,9 @@ void SimManagerNameDictionary::insert(SimObject* obj)
hashTable = newHashTable;
hashTableSize = newHashTableSize;
}
#else
root[obj->objectName] = obj;
#endif
Mutex::unlockMutex(mutex);
}
@ -219,6 +242,7 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name)
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
S32 idx = HashPointer(name) % hashTableSize;
SimObject *walk = hashTable[idx];
while(walk)
@ -230,16 +254,23 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name)
}
walk = walk->nextManagerNameObject;
}
Mutex::unlockMutex(mutex);
return NULL;
#else
StringDictDef::iterator it = root.find(name);
SimObject* f = (it == root.end() ? NULL : it->second);
Mutex::unlockMutex(mutex);
return f;
#endif
}
void SimManagerNameDictionary::remove(SimObject* obj)
{
if(!obj->objectName)
if(!obj || !obj->objectName)
return;
#ifndef USE_NEW_SIMDICTIONARY
Mutex::lockMutex(mutex);
SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
@ -256,7 +287,11 @@ void SimManagerNameDictionary::remove(SimObject* obj)
}
walk = &((*walk)->nextManagerNameObject);
}
#else
StringTableEntry name = obj->objectName;
if (root.find(name) != root.end())
root.erase(name);
#endif
Mutex::unlockMutex(mutex);
}
@ -265,7 +300,9 @@ void SimManagerNameDictionary::remove(SimObject* obj)
SimIdDictionary::SimIdDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize );
#endif
mutex = Mutex::createMutex();
}
@ -274,22 +311,29 @@ SimIdDictionary::~SimIdDictionary()
Mutex::destroyMutex(mutex);
}
void SimIdDictionary::insert(SimObject* obj)
{
Mutex::lockMutex(mutex);
if (!obj)
return;
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
S32 idx = obj->getId() & TableBitMask;
obj->nextIdObject = table[idx];
AssertFatal( obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!" );
table[idx] = obj;
#else
root[obj->getId()] = obj;
#endif
Mutex::unlockMutex(mutex);
}
SimObject* SimIdDictionary::find(S32 id)
{
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
S32 idx = id & TableBitMask;
SimObject *walk = table[idx];
while(walk)
@ -301,22 +345,32 @@ SimObject* SimIdDictionary::find(S32 id)
}
walk = walk->nextIdObject;
}
Mutex::unlockMutex(mutex);
return NULL;
#else
SimObjectIdDictDef::iterator it = root.find(id);
SimObject* f = (it == root.end() ? NULL : it->second);
Mutex::unlockMutex(mutex);
return f;
#endif
}
void SimIdDictionary::remove(SimObject* obj)
{
Mutex::lockMutex(mutex);
if (!obj)
return;
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
SimObject **walk = &table[obj->getId() & TableBitMask];
while(*walk && *walk != obj)
walk = &((*walk)->nextIdObject);
if(*walk)
*walk = obj->nextIdObject;
#else
root.erase(obj->getId());
#endif
Mutex::unlockMutex(mutex);
}

View file

@ -33,8 +33,38 @@
#include "platform/threads/mutex.h"
#endif
#include "torqueConfig.h"
class SimObject;
#ifdef USE_NEW_SIMDICTIONARY
#include <string>
#include <unordered_map>
#ifndef _SIM_H_
#include "console/sim.h"
#endif
struct StringTableEntryHash
{
inline size_t operator()(StringTableEntry val) const
{
return (size_t)val;
}
};
struct StringTableEntryEq
{
inline bool operator()(StringTableEntry s1, StringTableEntry s2) const
{
return s1 == s2;
}
};
typedef std::unordered_map<StringTableEntry, SimObject*, StringTableEntryHash, StringTableEntryEq> StringDictDef;
typedef std::unordered_map<SimObjectId, SimObject*> SimObjectIdDictDef;
#endif
//----------------------------------------------------------------------------
/// Map of names to SimObjects
///
@ -42,6 +72,7 @@ class SimObject;
/// for fast removal of an object given object*
class SimNameDictionary
{
#ifndef USE_NEW_SIMDICTIONARY
enum
{
DefaultTableSize = 29
@ -50,6 +81,9 @@ class SimNameDictionary
SimObject **hashTable; // hash the pointers of the names...
S32 hashTableSize;
S32 hashEntryCount;
#else
StringDictDef root;
#endif
void *mutex;
@ -64,6 +98,7 @@ public:
class SimManagerNameDictionary
{
#ifndef USE_NEW_SIMDICTIONARY
enum
{
DefaultTableSize = 29
@ -72,6 +107,9 @@ class SimManagerNameDictionary
SimObject **hashTable; // hash the pointers of the names...
S32 hashTableSize;
S32 hashEntryCount;
#else
StringDictDef root;
#endif
void *mutex;
@ -91,12 +129,16 @@ public:
/// for fast removal of an object given object*
class SimIdDictionary
{
#ifndef USE_NEW_SIMDICTIONARY
enum
{
DefaultTableSize = 4096,
TableBitMask = 4095
};
SimObject *table[DefaultTableSize];
#else
SimObjectIdDictDef root;
#endif
void *mutex;

View file

@ -162,7 +162,7 @@ ConsoleValue* ConsoleValueStack::pop()
void ConsoleValueStack::pushFrame()
{
//Con::printf("CSTK pushFrame");
//Con::printf("CSTK pushFrame[%i] (%i)", mFrame, mStackPos);
mStackFrames[mFrame++] = mStackPos;
}
@ -181,6 +181,12 @@ void ConsoleValueStack::resetFrame()
//Con::printf("CSTK resetFrame to %i", mStackPos);
}
void ConsoleValueStack::clearFrames()
{
mStackPos = 0;
mFrame = 0;
}
void ConsoleValueStack::popFrame()
{
//Con::printf("CSTK popFrame");

View file

@ -74,6 +74,7 @@ struct StringStack
mBuffer = (char *) dRealloc(mBuffer, mBufferSize);
}
}
void validateArgBufferSize(U32 size)
{
if(size > mArgBufferSize)
@ -82,6 +83,7 @@ struct StringStack
mArgBuffer = (char *) dRealloc(mArgBuffer, mArgBufferSize);
}
}
StringStack()
{
mBufferSize = 0;
@ -95,6 +97,8 @@ struct StringStack
mFunctionOffset = 0;
validateBufferSize(8192);
validateArgBufferSize(2048);
dMemset(mBuffer, '\0', mBufferSize);
dMemset(mArgBuffer, '\0', mArgBufferSize);
}
~StringStack()
{
@ -141,6 +145,7 @@ struct StringStack
/// Clear the function offset.
void clearFunctionOffset()
{
//Con::printf("StringStack mFunctionOffset = 0 (from %i)", mFunctionOffset);
mFunctionOffset = 0;
}
@ -262,9 +267,9 @@ struct StringStack
return ret;
}
void pushFrame()
{
//Con::printf("StringStack pushFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize);
mFrameOffsets[mNumFrames++] = mStartStackSize;
mStartOffsets[mStartStackSize++] = mStart;
mStart += ReturnBufferSpace;
@ -273,11 +278,22 @@ struct StringStack
void popFrame()
{
//Con::printf("StringStack popFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize);
mStartStackSize = mFrameOffsets[--mNumFrames];
mStart = mStartOffsets[mStartStackSize];
mLen = 0;
}
void clearFrames()
{
//Con::printf("StringStack clearFrames");
mNumFrames = 0;
mStart = 0;
mLen = 0;
mStartStackSize = 0;
mFunctionOffset = 0;
}
/// Get the arguments for a function call from the stack.
void getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame = false);
};
@ -309,6 +325,7 @@ public:
void popFrame();
void resetFrame();
void clearFrames();
void getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame = false);

View file

@ -174,7 +174,7 @@ U32 OggVorbisDecoder::read( RawData** buffer, U32 num )
S32 val = S32( pcmData[ c ][ n ] * 32767.f );
if( val > 32767 )
val = 32767;
else if( val < -34768 )
else if( val < -32768 )
val = -32768;
*samplePtr = val;

View file

@ -891,6 +891,10 @@ void WaterObject::onRemove()
{
mPlaneReflector.unregisterReflector();
cleanupMaterials();
PostEffect *underWaterEffect = getUnderwaterEffect( );
if( underWaterEffect )
underWaterEffect->disable( );
}
Parent::onRemove();

View file

@ -143,7 +143,7 @@ public:
{
glGenBuffers(1, &mBufferName);
PRESERVE_VERTEX_BUFFER();
PRESERVE_BUFFER( mBinding );
glBindBuffer(mBinding, mBufferName);
const U32 cSizeInMB = 10;
@ -195,11 +195,11 @@ public:
}
else if( GFXGL->glUseMap() )
{
PRESERVE_VERTEX_BUFFER();
glBindBuffer(GL_ARRAY_BUFFER, mBufferName);
PRESERVE_BUFFER( mBinding );
glBindBuffer(mBinding, mBufferName);
const GLbitfield access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
outPtr = glMapBufferRange(GL_ARRAY_BUFFER, outOffset, size, access);
outPtr = glMapBufferRange(mBinding, outOffset, size, access);
}
else
{
@ -224,15 +224,15 @@ public:
}
else if( GFXGL->glUseMap() )
{
PRESERVE_VERTEX_BUFFER();
glBindBuffer(GL_ARRAY_BUFFER, mBufferName);
PRESERVE_BUFFER( mBinding );
glBindBuffer(mBinding, mBufferName);
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(mBinding);
}
else
{
PRESERVE_VERTEX_BUFFER();
glBindBuffer(GL_ARRAY_BUFFER, mBufferName);
PRESERVE_BUFFER( mBinding );
glBindBuffer(mBinding, mBufferName);
glBufferSubData( mBinding, _getBufferData.mOffset, _getBufferData.mSize, mFrameAllocator.getlockedPtr() );

View file

@ -182,6 +182,13 @@ GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (GL_ARRAY_BUFFER, GL_ARR
#define PRESERVE_INDEX_BUFFER() \
GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (GL_ELEMENT_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER_BINDING, (GFXGLPreserveInteger::BindFn)glBindBuffer)
#define _GET_BUFFER_BINDING( BINDING ) \
BINDING == GL_ARRAY_BUFFER ? GL_ARRAY_BUFFER_BINDING : ( BINDING == GL_ELEMENT_ARRAY_BUFFER ? GL_ELEMENT_ARRAY_BUFFER_BINDING : 0 )
/// Helper macro to preserve the current element array binding.
#define PRESERVE_BUFFER( BINDING ) \
GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (BINDING, _GET_BUFFER_BINDING(BINDING), (GFXGLPreserveInteger::BindFn)glBindBuffer)
/// ASSERT: Never call glActiveTexture for a "bind to modify" or in a PRESERVER_TEXTURE MACRO scope.
/// Helper macro to preserve the current 1D texture binding.

View file

@ -330,6 +330,58 @@ void DeferredBumpFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
output = meta;
return;
}
else if (fd.features[MFT_AccuMap])
{
Var *bumpSample = (Var *)LangElement::find("bumpSample");
if (bumpSample == NULL)
{
MultiLine *meta = new MultiLine;
Var *texCoord = getInTexCoord("texCoord", "vec2", true, componentList);
Var *bumpMap = getNormalMapTex();
bumpSample = new Var;
bumpSample->setType("vec4");
bumpSample->setName("bumpSample");
LangElement *bumpSampleDecl = new DecOp(bumpSample);
meta->addStatement(new GenOp(" @ = tex2D(@, @);\r\n", bumpSampleDecl, bumpMap, texCoord));
if (fd.features.hasFeature(MFT_DetailNormalMap))
{
Var *bumpMap = (Var*)LangElement::find("detailBumpMap");
if (!bumpMap) {
bumpMap = new Var;
bumpMap->setType("sampler2D");
bumpMap->setName("detailBumpMap");
bumpMap->uniform = true;
bumpMap->sampler = true;
bumpMap->constNum = Var::getTexUnitNum();
}
texCoord = getInTexCoord("detCoord", "vec2", true, componentList);
LangElement *texOp = new GenOp("tex2D(@, @)", bumpMap, texCoord);
Var *detailBump = new Var;
detailBump->setName("detailBump");
detailBump->setType("vec4");
meta->addStatement(expandNormalMap(texOp, new DecOp(detailBump), detailBump, fd));
Var *detailBumpScale = new Var;
detailBumpScale->setType("float");
detailBumpScale->setName("detailBumpStrength");
detailBumpScale->uniform = true;
detailBumpScale->constSortPos = cspPass;
meta->addStatement(new GenOp(" @.xy += @.xy * @;\r\n", bumpSample, detailBump, detailBumpScale));
}
output = meta;
return;
}
}
else if ( fd.materialFeatures[MFT_NormalsOut] ||
fd.features[MFT_ForwardShading] ||
!fd.features[MFT_RTLighting] )
@ -398,7 +450,20 @@ void DeferredBumpFeatGLSL::setTexData( Material::StageData &stageDat,
return;
}
if ( !fd.features[MFT_Parallax] && !fd.features[MFT_SpecularMap] &&
if (!fd.features[MFT_PrePassConditioner] && fd.features[MFT_AccuMap])
{
passData.mTexType[texIndex] = Material::Bump;
passData.mSamplerNames[texIndex] = "bumpMap";
passData.mTexSlot[texIndex++].texObject = stageDat.getTex(MFT_NormalMap);
if (fd.features.hasFeature(MFT_DetailNormalMap))
{
passData.mTexType[texIndex] = Material::DetailBump;
passData.mSamplerNames[texIndex] = "detailBumpMap";
passData.mTexSlot[texIndex++].texObject = stageDat.getTex(MFT_DetailNormalMap);
}
}
else if (!fd.features[MFT_Parallax] && !fd.features[MFT_SpecularMap] &&
( fd.features[MFT_PrePassConditioner] ||
fd.features[MFT_PixSpecular] ) )
{
@ -481,6 +546,14 @@ void DeferredPixelSpecularGLSL::processPix( Vector<ShaderComponent*> &component
AssertFatal( lightInfoSamp && d_specular && d_NL_Att,
"DeferredPixelSpecularGLSL::processPix - Something hosed the deferred features!" );
if (fd.features[MFT_AccuMap]) {
// change specularity where the accu texture is applied
Var *accuPlc = (Var*)LangElement::find("plc");
Var *accuSpecular = (Var*)LangElement::find("accuSpecular");
if (accuPlc != NULL && accuSpecular != NULL)
//d_specular = clamp(lerp( d_specular, accuSpecular * d_specular, plc.a), 0, 1)
meta->addStatement(new GenOp(" @ = clamp( lerp( @, @ * @, @.a), 0, 1);\r\n", d_specular, d_specular, accuSpecular, d_specular, accuPlc));
}
// (a^m)^n = a^(m*n)
meta->addStatement( new GenOp( " @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n",
specDecl, d_specular, specPow, specStrength ) );

View file

@ -330,6 +330,57 @@ void DeferredBumpFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
output = meta;
return;
}
else if (fd.features[MFT_AccuMap])
{
Var *bumpSample = (Var *)LangElement::find( "bumpSample" );
if( bumpSample == NULL )
{
MultiLine *meta = new MultiLine;
Var *texCoord = getInTexCoord( "texCoord", "float2", true, componentList );
Var *bumpMap = getNormalMapTex();
bumpSample = new Var;
bumpSample->setType( "float4" );
bumpSample->setName( "bumpSample" );
LangElement *bumpSampleDecl = new DecOp( bumpSample );
meta->addStatement( new GenOp( " @ = tex2D(@, @);\r\n", bumpSampleDecl, bumpMap, texCoord ) );
if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
{
Var *bumpMap = (Var*)LangElement::find( "detailBumpMap" );
if ( !bumpMap ) {
bumpMap = new Var;
bumpMap->setType( "sampler2D" );
bumpMap->setName( "detailBumpMap" );
bumpMap->uniform = true;
bumpMap->sampler = true;
bumpMap->constNum = Var::getTexUnitNum();
}
texCoord = getInTexCoord( "detCoord", "float2", true, componentList );
LangElement *texOp = new GenOp( "tex2D(@, @)", bumpMap, texCoord );
Var *detailBump = new Var;
detailBump->setName( "detailBump" );
detailBump->setType( "float4" );
meta->addStatement( expandNormalMap( texOp, new DecOp( detailBump ), detailBump, fd ) );
Var *detailBumpScale = new Var;
detailBumpScale->setType( "float" );
detailBumpScale->setName( "detailBumpStrength" );
detailBumpScale->uniform = true;
detailBumpScale->constSortPos = cspPass;
meta->addStatement( new GenOp( " @.xy += @.xy * @;\r\n", bumpSample, detailBump, detailBumpScale ) );
}
output = meta;
return;
}
}
else if ( fd.materialFeatures[MFT_NormalsOut] ||
fd.features[MFT_ForwardShading] ||
!fd.features[MFT_RTLighting] )
@ -398,7 +449,20 @@ void DeferredBumpFeatHLSL::setTexData( Material::StageData &stageDat,
return;
}
if ( !fd.features[MFT_Parallax] && !fd.features[MFT_SpecularMap] &&
if ( !fd.features[MFT_PrePassConditioner] && fd.features[MFT_AccuMap] )
{
passData.mTexType[ texIndex ] = Material::Bump;
passData.mSamplerNames[ texIndex ] = "bumpMap";
passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_NormalMap );
if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
{
passData.mTexType[ texIndex ] = Material::DetailBump;
passData.mSamplerNames[texIndex] = "detailBumpMap";
passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_DetailNormalMap );
}
}
else if ( !fd.features[MFT_Parallax] && !fd.features[MFT_SpecularMap] &&
( fd.features[MFT_PrePassConditioner] ||
fd.features[MFT_PixSpecular] ) )
{
@ -481,6 +545,15 @@ void DeferredPixelSpecularHLSL::processPix( Vector<ShaderComponent*> &component
AssertFatal( lightInfoSamp && d_specular && d_NL_Att,
"DeferredPixelSpecularHLSL::processPix - Something hosed the deferred features!" );
if (fd.features[ MFT_AccuMap ]) {
// change specularity where the accu texture is applied
Var *accuPlc = (Var*) LangElement::find( "plc" );
Var *accuSpecular = (Var*)LangElement::find( "accuSpecular" );
if(accuPlc != NULL && accuSpecular != NULL)
//d_specular = clamp(lerp( d_specular, accuSpecular * d_specular, plc.a), 0, 1)
meta->addStatement( new GenOp( " @ = clamp( lerp( @, @ * @, @.a), 0, 1);\r\n", d_specular, d_specular, accuSpecular, d_specular, accuPlc ) );
}
// (a^m)^n = a^(m*n)
meta->addStatement( new GenOp( " @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n",
specDecl, d_specular, specPow, specStrength ) );

View file

@ -185,6 +185,7 @@ public:
// BTRTODO: This stuff below should probably not be in BaseMatInstance
virtual bool hasGlow() = 0;
virtual bool hasAccumulation() = 0;
virtual U32 getCurPass() = 0;

View file

@ -497,6 +497,14 @@ bool MatInstance::hasGlow()
return false;
}
bool MatInstance::hasAccumulation()
{
if( mProcessedMaterial )
return mProcessedMaterial->hasAccumulation();
else
return false;
}
const FeatureSet& MatInstance::getFeatures() const
{
return mProcessedMaterial->getFeatures();

View file

@ -75,6 +75,7 @@ public:
virtual SimObject* getUserObject() const { return mUserObject; }
virtual Material *getMaterial() { return mMaterial; }
virtual bool hasGlow();
virtual bool hasAccumulation();
virtual U32 getCurPass() { return getMax( mCurPass, 0 ); }
virtual U32 getCurStageNum();
virtual RenderPassData *getPass(U32 pass);

View file

@ -35,6 +35,7 @@
#include "sfx/sfxTrack.h"
#include "sfx/sfxTypes.h"
#include "core/util/safeDelete.h"
#include "T3D/accumulationVolume.h"
IMPLEMENT_CONOBJECT( Material );
@ -120,6 +121,13 @@ Material::Material()
mSpecularStrength[i] = 1.0f;
mPixelSpecular[i] = false;
mAccuEnabled[i] = false;
mAccuScale[i] = 1.0f;
mAccuDirection[i] = 1.0f;
mAccuStrength[i] = 0.6f;
mAccuCoverage[i] = 0.9f;
mAccuSpecular[i] = 16.0f;
mParallaxScale[i] = 0.0f;
mVertLit[i] = false;
@ -251,6 +259,24 @@ void Material::initPersistFields()
"normal map texture. Note that if pixel specular is enabled the DXTnm format will not "
"work with your normal map, unless you are also using a specular map." );
addProtectedField( "accuEnabled", TYPEID< bool >(), Offset( mAccuEnabled, Material ),
&_setAccuEnabled, &defaultProtectedGetFn, MAX_STAGES, "Accumulation texture." );
addField("accuScale", TypeF32, Offset(mAccuScale, Material), MAX_STAGES,
"The scale that is applied to the accu map texture. You can use this to fit the texture to smaller or larger objects.");
addField("accuDirection", TypeF32, Offset(mAccuDirection, Material), MAX_STAGES,
"The direction of the accumulation. Chose whether you want the accu map to go from top to bottom (ie. snow) or upwards (ie. mold).");
addField("accuStrength", TypeF32, Offset(mAccuStrength, Material), MAX_STAGES,
"The strength of the accu map. This changes the transparency of the accu map texture. Make it subtle or add more contrast.");
addField("accuCoverage", TypeF32, Offset(mAccuCoverage, Material), MAX_STAGES,
"The coverage ratio of the accu map texture. Use this to make the entire shape pick up some of the accu map texture or none at all.");
addField("accuSpecular", TypeF32, Offset(mAccuSpecular, Material), MAX_STAGES,
"Changes specularity to this value where the accumulated material is present.");
addField( "specularMap", TypeImageFilename, Offset(mSpecularMapFilename, Material), MAX_STAGES,
"The specular map texture. The RGB channels of this texture provide a per-pixel replacement for the 'specular' parameter on the material. "
"If this texture contains alpha information, the alpha channel of the texture will be used as the gloss map. "
@ -670,4 +696,18 @@ DefineConsoleMethod( Material, setAutoGenerated, void, (bool isAutoGenerated), ,
"setAutoGenerated(bool isAutoGenerated): Set whether or not the Material is autogenerated." )
{
object->setAutoGenerated(isAutoGenerated);
}
// Accumulation
bool Material::_setAccuEnabled( void *object, const char *index, const char *data )
{
Material* mat = reinterpret_cast< Material* >( object );
if ( index )
{
U32 i = dAtoui(index);
mat->mAccuEnabled[i] = dAtob(data);
AccumulationVolume::refreshVolumes();
}
return true;
}

View file

@ -88,6 +88,7 @@ public:
DynamicLightMask,
NormalizeCube,
TexTarget,
AccuMap,
};
enum BlendOp
@ -198,6 +199,12 @@ public:
// Data
//-----------------------------------------------------------------------
FileName mDiffuseMapFilename[MAX_STAGES];
bool mAccuEnabled[MAX_STAGES];
F32 mAccuScale[MAX_STAGES];
F32 mAccuDirection[MAX_STAGES];
F32 mAccuStrength[MAX_STAGES];
F32 mAccuCoverage[MAX_STAGES];
F32 mAccuSpecular[MAX_STAGES];
FileName mOverlayMapFilename[MAX_STAGES];
FileName mLightMapFilename[MAX_STAGES];
FileName mToneMapFilename[MAX_STAGES];
@ -371,6 +378,9 @@ public:
//
static void initPersistFields();
// Accumulation
static bool _setAccuEnabled( void *object, const char *index, const char *data );
DECLARE_CONOBJECT(Material);
protected:

View file

@ -32,6 +32,12 @@ ImplementFeatureType( MFT_TexAnim, MFG_PreTexture, 1.0f, true );
ImplementFeatureType( MFT_Parallax, MFG_PreTexture, 2.0f, true );
ImplementFeatureType( MFT_DiffuseVertColor, MFG_PreTexture, 3.0f, true );
ImplementFeatureType( MFT_AccuScale, MFG_PreTexture, 4.0f, true );
ImplementFeatureType( MFT_AccuDirection, MFG_PreTexture, 4.0f, true );
ImplementFeatureType( MFT_AccuStrength, MFG_PreTexture, 4.0f, true );
ImplementFeatureType( MFT_AccuCoverage, MFG_PreTexture, 4.0f, true );
ImplementFeatureType( MFT_AccuSpecular, MFG_PreTexture, 4.0f, true );
ImplementFeatureType( MFT_DiffuseMap, MFG_Texture, 2.0f, true );
ImplementFeatureType( MFT_OverlayMap, MFG_Texture, 3.0f, true );
ImplementFeatureType( MFT_DetailMap, MFG_Texture, 4.0f, true );
@ -41,6 +47,8 @@ ImplementFeatureType( MFT_SpecularMap, MFG_Texture, 8.0f, true );
ImplementFeatureType( MFT_NormalMap, MFG_Texture, 9.0f, true );
ImplementFeatureType( MFT_DetailNormalMap, MFG_Texture, 10.0f, true );
ImplementFeatureType( MFT_AccuMap, MFG_PreLighting, 2.0f, true );
ImplementFeatureType( MFT_RTLighting, MFG_Lighting, 2.0f, true );
ImplementFeatureType( MFT_SubSurface, MFG_Lighting, 3.0f, true );
ImplementFeatureType( MFT_LightMap, MFG_Lighting, 4.0f, true );

View file

@ -95,6 +95,13 @@ DeclareFeatureType( MFT_DetailMap );
DeclareFeatureType( MFT_DiffuseColor );
DeclareFeatureType( MFT_DetailNormalMap );
DeclareFeatureType( MFT_AccuMap );
DeclareFeatureType( MFT_AccuScale );
DeclareFeatureType( MFT_AccuDirection );
DeclareFeatureType( MFT_AccuStrength );
DeclareFeatureType( MFT_AccuCoverage );
DeclareFeatureType( MFT_AccuSpecular );
/// This feature enables vertex coloring for the diffuse channel.
DeclareFeatureType( MFT_DiffuseVertColor );

View file

@ -49,6 +49,7 @@ ProcessedCustomMaterial::ProcessedCustomMaterial(Material &mat)
mCustomMaterial = static_cast<CustomMaterial*>(mMaterial);
mHasSetStageData = false;
mHasGlow = false;
mHasAccumulation = false;
mMaxStages = 0;
mMaxTex = 0;
}

View file

@ -67,6 +67,7 @@ void ProcessedFFMaterial::_construct()
{
mHasSetStageData = false;
mHasGlow = false;
mHasAccumulation = false;
mIsLightingMaterial = false;
mDefaultHandle = new FFMaterialParameterHandle();
mDefaultParameters = new MaterialParameters();

View file

@ -93,6 +93,7 @@ ProcessedMaterial::ProcessedMaterial()
mCurrentParams( NULL ),
mHasSetStageData( false ),
mHasGlow( false ),
mHasAccumulation( false ),
mMaxStages( 0 ),
mVertexFormat( NULL ),
mUserObject( NULL )

View file

@ -197,6 +197,9 @@ public:
/// Returns true if any pass glows
bool hasGlow() const { return mHasGlow; }
/// Returns true if any pass accumulates
bool hasAccumulation() const { return mHasAccumulation; }
/// Gets the stage number for a pass
U32 getStageFromPass(U32 pass) const
{
@ -244,6 +247,9 @@ protected:
/// If we glow
bool mHasGlow;
/// If we have accumulation.
bool mHasAccumulation;
/// Number of stages (not to be confused with number of passes)
U32 mMaxStages;

View file

@ -55,6 +55,11 @@ void ShaderConstHandles::init( GFXShader *shader, CustomMaterial* mat /*=NULL*/
mSpecularColorSC = shader->getShaderConstHandle(ShaderGenVars::specularColor);
mSpecularPowerSC = shader->getShaderConstHandle(ShaderGenVars::specularPower);
mSpecularStrengthSC = shader->getShaderConstHandle(ShaderGenVars::specularStrength);
mAccuScaleSC = shader->getShaderConstHandle("$accuScale");
mAccuDirectionSC = shader->getShaderConstHandle("$accuDirection");
mAccuStrengthSC = shader->getShaderConstHandle("$accuStrength");
mAccuCoverageSC = shader->getShaderConstHandle("$accuCoverage");
mAccuSpecularSC = shader->getShaderConstHandle("$accuSpecular");
mParallaxInfoSC = shader->getShaderConstHandle("$parallaxInfo");
mFogDataSC = shader->getShaderConstHandle(ShaderGenVars::fogData);
mFogColorSC = shader->getShaderConstHandle(ShaderGenVars::fogColor);
@ -423,6 +428,34 @@ void ProcessedShaderMaterial::_determineFeatures( U32 stageNum,
fd.features.addFeature( MFT_GlossMap );
}
if ( mMaterial->mAccuEnabled[stageNum] )
{
fd.features.addFeature( MFT_AccuMap );
mHasAccumulation = true;
}
// we need both diffuse and normal maps + sm3 to have an accu map
if( fd.features[ MFT_AccuMap ] &&
( !fd.features[ MFT_DiffuseMap ] ||
!fd.features[ MFT_NormalMap ] ||
GFX->getPixelShaderVersion() < 3.0f ) ) {
AssertWarn(false, "SAHARA: Using an Accu Map requires SM 3.0 and a normal map.");
fd.features.removeFeature( MFT_AccuMap );
mHasAccumulation = false;
}
// if we still have the AccuMap feature, we add all accu constant features
if ( fd.features[ MFT_AccuMap ] ) {
// add the dependencies of the accu map
fd.features.addFeature( MFT_AccuScale );
fd.features.addFeature( MFT_AccuDirection );
fd.features.addFeature( MFT_AccuStrength );
fd.features.addFeature( MFT_AccuCoverage );
fd.features.addFeature( MFT_AccuSpecular );
// now remove some features that are not compatible with this
fd.features.removeFeature( MFT_UseInstancing );
}
// Without a base texture use the diffuse color
// feature to ensure some sort of output.
if (!fd.features[MFT_DiffuseMap])
@ -809,6 +842,13 @@ void ProcessedShaderMaterial::setTextureStages( SceneRenderState *state, const S
case Material::BackBuff:
GFX->setTexture( i, sgData.backBuffTex );
break;
case Material::AccuMap:
if ( sgData.accuTex )
GFX->setTexture( i, sgData.accuTex );
else
GFX->setTexture( i, GFXTexHandle::ZERO );
break;
case Material::TexTarget:
{
@ -1137,6 +1177,17 @@ void ProcessedShaderMaterial::_setShaderConstants(SceneRenderState * state, cons
0.0f, 0.0f ); // TODO: Wrap mode flags?
shaderConsts->setSafe(handles->mBumpAtlasTileSC, atlasTileParams);
}
if( handles->mAccuScaleSC->isValid() )
shaderConsts->set( handles->mAccuScaleSC, mMaterial->mAccuScale[stageNum] );
if( handles->mAccuDirectionSC->isValid() )
shaderConsts->set( handles->mAccuDirectionSC, mMaterial->mAccuDirection[stageNum] );
if( handles->mAccuStrengthSC->isValid() )
shaderConsts->set( handles->mAccuStrengthSC, mMaterial->mAccuStrength[stageNum] );
if( handles->mAccuCoverageSC->isValid() )
shaderConsts->set( handles->mAccuCoverageSC, mMaterial->mAccuCoverage[stageNum] );
if( handles->mAccuSpecularSC->isValid() )
shaderConsts->set( handles->mAccuSpecularSC, mMaterial->mAccuSpecular[stageNum] );
}
bool ProcessedShaderMaterial::_hasCubemap(U32 pass)

View file

@ -48,6 +48,11 @@ public:
GFXShaderConstHandle* mSpecularPowerSC;
GFXShaderConstHandle* mSpecularStrengthSC;
GFXShaderConstHandle* mParallaxInfoSC;
GFXShaderConstHandle* mAccuScaleSC;
GFXShaderConstHandle* mAccuDirectionSC;
GFXShaderConstHandle* mAccuStrengthSC;
GFXShaderConstHandle* mAccuCoverageSC;
GFXShaderConstHandle* mAccuSpecularSC;
GFXShaderConstHandle* mFogDataSC;
GFXShaderConstHandle* mFogColorSC;
GFXShaderConstHandle* mDetailScaleSC;

View file

@ -64,6 +64,7 @@ struct SceneData
GFXTextureObject *backBuffTex;
GFXTextureObject *reflectTex;
GFXTextureObject *miscTex;
GFXTextureObject *accuTex;
/// The current lights to use in rendering
/// in order of the light importance.

View file

@ -74,6 +74,9 @@ enum ProcessorType
CPU_AMD_K6_2,
CPU_AMD_K6_3,
CPU_AMD_Athlon,
CPU_AMD_Phenom,
CPU_AMD_PhenomII,
CPU_AMD_Bulldozer,
CPU_AMD_Unknown,
CPU_Cyrix_6x86,
CPU_Cyrix_MediaGX,

View file

@ -92,8 +92,8 @@ public:
exit conditions.
*/
#define AssertFatal(x, y) \
{ if (((bool)(x))==(bool)0) \
{ if ( ::PlatformAssert::processAssert(::PlatformAssert::Fatal, __FILE__, __LINE__, y) ) { ::Platform::debugBreak(); } } }
{ if (((bool)(x))==false) \
{ if ( ::PlatformAssert::processAssert(::PlatformAssert::Fatal, __FILE__, __LINE__, y) ) { ::Platform::debugBreak(); } } }
#else
#define AssertFatal(x, y) { TORQUE_UNUSED(x); TORQUE_UNUSED(y); }

View file

@ -178,6 +178,9 @@ void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo,
pInfo.properties |= (properties & BIT_SSE) ? CPU_PROP_SSE : 0;
pInfo.properties |= ( properties & BIT_SSE2 ) ? CPU_PROP_SSE2 : 0;
pInfo.properties |= (properties & BIT_3DNOW) ? CPU_PROP_3DNOW : 0;
// Phenom and PhenomII support SSE3, SSE4a
pInfo.properties |= ( properties2 & BIT_SSE3 ) ? CPU_PROP_SSE3 : 0;
pInfo.properties |= ( properties2 & BIT_SSE4_1 ) ? CPU_PROP_SSE4_1 : 0;
// switch on processor family code
switch ((processor >> 8) & 0xf)
{
@ -223,6 +226,24 @@ void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo,
pInfo.name = StringTable->insert("AMD Athlon");
break;
// Phenom Family
case 15:
pInfo.type = CPU_AMD_Phenom;
pInfo.name = StringTable->insert("AMD Phenom");
break;
// Phenom II Family
case 16:
pInfo.type = CPU_AMD_PhenomII;
pInfo.name = StringTable->insert("AMD Phenom II");
break;
// Bulldozer Family
case 17:
pInfo.type = CPU_AMD_Bulldozer;
pInfo.name = StringTable->insert("AMD Bulldozer");
break;
default:
pInfo.type = CPU_AMD_Unknown;
pInfo.name = StringTable->insert("AMD (unknown)");

View file

@ -133,6 +133,7 @@ void MenuBar::attachToCanvas(GuiCanvas *owner, S32 pos)
}
HWND hWindow = pWindow->getHWND();
SetMenu(hWindow, hWindowMenu);
DrawMenuBar(hWindow);
}
@ -165,6 +166,7 @@ void MenuBar::removeFromCanvas()
}
HWND hWindow = pWindow->getHWND();
SetMenu(hWindow, NULL);
DrawMenuBar(hWindow);
mCanvas = NULL;

View file

@ -139,7 +139,7 @@ void Platform::fileToLocalTime(const FileTime & ft, LocalTime * lt)
lt->sec = time->wSecond;
lt->min = time->wMinute;
lt->hour = time->wHour;
lt->month = time->wMonth;
lt->month = time->wMonth - 1;
lt->monthday = time->wDay;
lt->weekday = time->wDayOfWeek;
lt->year = (time->wYear < 1900) ? 1900 : (time->wYear - 1900);

View file

@ -164,6 +164,7 @@ void RenderBinManager::setupSGData( MeshRenderInst *ri, SceneData &data )
data.cubemap = ri->cubemap;
data.miscTex = ri->miscTex;
data.reflectTex = ri->reflectTex;
data.accuTex = ri->accuTex;
data.lightmap = ri->lightmap;
data.visibility = ri->visibility;
data.materialHint = ri->materialHint;

View file

@ -22,6 +22,7 @@
#include "platform/platform.h"
#include "renderInstance/renderGlowMgr.h"
#include "renderInstance/renderParticleMgr.h"
#include "scene/sceneManager.h"
#include "scene/sceneRenderState.h"
@ -89,6 +90,9 @@ RenderGlowMgr::RenderGlowMgr()
{
notifyType( RenderPassManager::RIT_Decal );
notifyType( RenderPassManager::RIT_Translucent );
notifyType( RenderPassManager::RIT_Particle );
mParticleRenderMgr = NULL;
mNamedTarget.registerWithName( "glowbuffer" );
mTargetSizeType = WindowSize;
@ -122,6 +126,14 @@ void RenderGlowMgr::addElement( RenderInst *inst )
// manner so we can skip glow in a non-diffuse render pass.
//if ( !mParentManager->getSceneManager()->getSceneState()->isDiffusePass() )
//return RenderBinManager::arSkipped;
ParticleRenderInst *particleInst = NULL;
if(inst->type == RenderPassManager::RIT_Particle)
particleInst = static_cast<ParticleRenderInst*>(inst);
if(particleInst && particleInst->glow)
{
internalAddElement(inst);
return;
}
// Skip it if we don't have a glowing material.
BaseMatInstance *matInst = getMaterial( inst );
@ -171,7 +183,31 @@ void RenderGlowMgr::render( SceneRenderState *state )
for( U32 j=0; j<binSize; )
{
MeshRenderInst *ri = static_cast<MeshRenderInst*>(mElementList[j].inst);
RenderInst *_ri = mElementList[j].inst;
if(_ri->type == RenderPassManager::RIT_Particle)
{
// Find the particle render manager (if we don't have it)
if(mParticleRenderMgr == NULL)
{
RenderPassManager *rpm = state->getRenderPass();
for( U32 i = 0; i < rpm->getManagerCount(); i++ )
{
RenderBinManager *bin = rpm->getManager(i);
if( bin->getRenderInstType() == RenderParticleMgr::RIT_Particles )
{
mParticleRenderMgr = reinterpret_cast<RenderParticleMgr *>(bin);
break;
}
}
}
ParticleRenderInst *ri = static_cast<ParticleRenderInst*>(_ri);
mParticleRenderMgr->renderParticle(ri, state);
j++;
continue;
}
MeshRenderInst *ri = static_cast<MeshRenderInst*>(_ri);
setupSGData( ri, sgData );
@ -191,6 +227,9 @@ void RenderGlowMgr::render( SceneRenderState *state )
U32 a;
for( a=j; a<binSize; a++ )
{
if (mElementList[a].inst->type == RenderPassManager::RIT_Particle)
break;
MeshRenderInst *passRI = static_cast<MeshRenderInst*>(mElementList[a].inst);
if ( newPassNeeded( ri, passRI ) )

View file

@ -26,6 +26,7 @@
#ifndef _TEXTARGETBIN_MGR_H_
#include "renderInstance/renderTexTargetBinManager.h"
#endif
#include <renderInstance/renderParticleMgr.h>
class PostEffect;
@ -82,7 +83,7 @@ protected:
};
SimObjectPtr<PostEffect> mGlowEffect;
RenderParticleMgr *mParticleRenderMgr;
};

View file

@ -115,6 +115,7 @@ void RenderMeshMgr::render(SceneRenderState * state)
GFXCubemap *lastCubemap = NULL;
GFXTextureObject *lastReflectTex = NULL;
GFXTextureObject *lastMiscTex = NULL;
GFXTextureObject *lastAccuTex = NULL;
SceneData sgData;
sgData.init( state );
@ -225,6 +226,15 @@ void RenderMeshMgr::render(SceneRenderState * state)
dirty = true;
}
// Update accumulation texture if it changed.
// Note: accumulation texture can be NULL, and must be updated.
if ( passRI->accuTex != lastAccuTex )
{
sgData.accuTex = passRI->accuTex;
lastAccuTex = lastAccuTex;
dirty = true;
}
if ( dirty )
mat->setTextureStages( state, sgData );

View file

@ -399,64 +399,7 @@ void RenderParticleMgr::renderInstance(ParticleRenderInst *ri, SceneRenderState
mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mModelViewProjSC, *ri->modelViewProj );
}
// We want to turn everything into variation on a pre-multiplied alpha blend
F32 alphaFactor = 0.0f, alphaScale = 1.0f;
switch(ri->blendStyle)
{
// SrcAlpha, InvSrcAlpha
case ParticleRenderInst::BlendNormal:
alphaFactor = 1.0f;
break;
// SrcAlpha, One
case ParticleRenderInst::BlendAdditive:
alphaFactor = 1.0f;
alphaScale = 0.0f;
break;
// SrcColor, One
case ParticleRenderInst::BlendGreyscale:
alphaFactor = -1.0f;
alphaScale = 0.0f;
break;
}
mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mAlphaFactorSC, alphaFactor );
mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mAlphaScaleSC, alphaScale );
mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mFSModelViewProjSC, *ri->modelViewProj );
mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mOneOverFarSC, 1.0f / state->getFarPlane() );
if ( mParticleShaderConsts.mOneOverSoftnessSC->isValid() )
{
F32 oneOverSoftness = 1.0f;
if ( ri->softnessDistance > 0.0f )
oneOverSoftness = 1.0f / ( ri->softnessDistance / state->getFarPlane() );
mParticleShaderConsts.mShaderConsts->set( mParticleShaderConsts.mOneOverSoftnessSC, oneOverSoftness );
}
GFX->setShader( mParticleShader );
GFX->setShaderConstBuffer( mParticleShaderConsts.mShaderConsts );
GFX->setTexture( mParticleShaderConsts.mSamplerDiffuse->getSamplerRegister(), ri->diffuseTex );
// Set up the prepass texture.
if ( mParticleShaderConsts.mPrePassTargetParamsSC->isValid() )
{
GFXTextureObject *texObject = mPrepassTarget ? mPrepassTarget->getTexture(0) : NULL;
GFX->setTexture( mParticleShaderConsts.mSamplerPrePassTex->getSamplerRegister(), texObject );
Point4F rtParams( 0.0f, 0.0f, 1.0f, 1.0f );
if ( texObject )
ScreenSpace::RenderTargetParameters(texObject->getSize(), mPrepassTarget->getViewport(), rtParams);
mParticleShaderConsts.mShaderConsts->set( mParticleShaderConsts.mPrePassTargetParamsSC, rtParams );
}
GFX->setPrimitiveBuffer( *ri->primBuff );
GFX->setVertexBuffer( *ri->vertBuff );
GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, ri->count * 4, 0, ri->count * 2 );
renderParticle(ri, state);
}
else if(ri->systemState == PSS_AwaitingCompositeDraw)
{
@ -494,9 +437,9 @@ void RenderParticleMgr::renderInstance(ParticleRenderInst *ri, SceneRenderState
}
else
{
AssertWarn(false, "No edge texture target defined, if you want to use mixed particle"
AssertFatal(false, "No edge texture target defined, if you want to use mixed particle"
"rendering, then make sure that the EdgeDetectPostEffect is enabled.");
ri->systemState == PSS_AwaitingHighResDraw;
ri->systemState = PSS_AwaitingHighResDraw;
return;
}
@ -530,6 +473,68 @@ void RenderParticleMgr::renderInstance(ParticleRenderInst *ri, SceneRenderState
}
}
void RenderParticleMgr::renderParticle(ParticleRenderInst* ri, SceneRenderState* state)
{
// We want to turn everything into variation on a pre-multiplied alpha blend
F32 alphaFactor = 0.0f, alphaScale = 1.0f;
switch(ri->blendStyle)
{
// SrcAlpha, InvSrcAlpha
case ParticleRenderInst::BlendNormal:
alphaFactor = 1.0f;
break;
// SrcAlpha, One
case ParticleRenderInst::BlendAdditive:
alphaFactor = 1.0f;
alphaScale = 0.0f;
break;
// SrcColor, One
case ParticleRenderInst::BlendGreyscale:
alphaFactor = -1.0f;
alphaScale = 0.0f;
break;
}
mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mAlphaFactorSC, alphaFactor );
mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mAlphaScaleSC, alphaScale );
mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mFSModelViewProjSC, *ri->modelViewProj );
mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mOneOverFarSC, 1.0f / state->getFarPlane() );
if ( mParticleShaderConsts.mOneOverSoftnessSC->isValid() )
{
F32 oneOverSoftness = 1.0f;
if ( ri->softnessDistance > 0.0f )
oneOverSoftness = 1.0f / ( ri->softnessDistance / state->getFarPlane() );
mParticleShaderConsts.mShaderConsts->set( mParticleShaderConsts.mOneOverSoftnessSC, oneOverSoftness );
}
GFX->setShader( mParticleShader );
GFX->setShaderConstBuffer( mParticleShaderConsts.mShaderConsts );
GFX->setTexture( mParticleShaderConsts.mSamplerDiffuse->getSamplerRegister(), ri->diffuseTex );
// Set up the prepass texture.
if ( mParticleShaderConsts.mPrePassTargetParamsSC->isValid() )
{
GFXTextureObject *texObject = mPrepassTarget ? mPrepassTarget->getTexture(0) : NULL;
GFX->setTexture( mParticleShaderConsts.mSamplerPrePassTex->getSamplerRegister(), texObject );
Point4F rtParams( 0.0f, 0.0f, 1.0f, 1.0f );
if ( texObject )
ScreenSpace::RenderTargetParameters(texObject->getSize(), mPrepassTarget->getViewport(), rtParams);
mParticleShaderConsts.mShaderConsts->set( mParticleShaderConsts.mPrePassTargetParamsSC, rtParams );
}
GFX->setPrimitiveBuffer( *ri->primBuff );
GFX->setVertexBuffer( *ri->vertBuff );
GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, ri->count * 4, 0, ri->count * 2 );
}
bool RenderParticleMgr::_initShader()
{
ShaderData *shaderData = NULL;

View file

@ -77,7 +77,9 @@ protected:
// Not only a helper method, but a method for the RenderTranslucentMgr to
// request a particle system draw
void renderInstance(ParticleRenderInst *ri, SceneRenderState *state);
public:
void renderParticle(ParticleRenderInst *ri, SceneRenderState *state);
protected:
bool mOffscreenRenderEnabled;
/// The prepass render target used for the

View file

@ -366,6 +366,7 @@ struct MeshRenderInst : public RenderInst
GFXTextureObject *backBuffTex;
GFXTextureObject *reflectTex;
GFXTextureObject *miscTex;
GFXTextureObject *accuTex;
GFXCubemap *cubemap;
void clear();
@ -392,6 +393,8 @@ struct ParticleRenderInst : public RenderInst
/// The total particle count to render.
S32 count;
bool glow;
/// The combined model, camera, and projection transform.
const MatrixF *modelViewProj;

View file

@ -40,7 +40,6 @@
// For player object bounds workaround.
#include "T3D/player.h"
extern bool gEditingMission;
@ -113,6 +112,7 @@ SceneManager::SceneManager( bool isClient )
mDisplayTargetResolution( 0, 0 ),
mDefaultRenderPass( NULL ),
mVisibleDistance( 500.f ),
mVisibleGhostDistance( 0 ),
mNearClip( 0.1f ),
mAmbientLightColor( ColorF( 0.1f, 0.1f, 0.1f, 1.0f ) ),
mZoneManager( NULL )

View file

@ -141,6 +141,7 @@ class SceneManager
F32 mVisibleDistance;
F32 mVisibleGhostDistance;
F32 mNearClip;
FogData mFogData;
@ -317,6 +318,9 @@ class SceneManager
/// Returns the default visible distance for the scene.
F32 getVisibleDistance() { return mVisibleDistance; }
void setVisibleGhostDistance( F32 dist ) { mVisibleGhostDistance = dist; }
F32 getVisibleGhostDistance() { return mVisibleGhostDistance;}
/// Used by LevelInfo to set the default near clip plane
/// for rendering the scene.
///

View file

@ -42,6 +42,8 @@
#include "math/mathIO.h"
#include "math/mTransform.h"
#include "T3D/gameBase/gameProcess.h"
#include "T3D/gameBase/gameConnection.h"
#include "T3D/accumulationVolume.h"
IMPLEMENT_CONOBJECT(SceneObject);
@ -140,6 +142,8 @@ SceneObject::SceneObject()
mObjectFlags.set( RenderEnabledFlag | SelectionEnabledFlag );
mIsScopeAlways = false;
mAccuTex = NULL;
}
//-----------------------------------------------------------------------------
@ -151,6 +155,7 @@ SceneObject::~SceneObject()
AssertFatal( !mSceneObjectLinks,
"SceneObject::~SceneObject() - object is still linked to SceneTrackers" );
mAccuTex = NULL;
unlink();
}
@ -664,6 +669,12 @@ static void scopeCallback( SceneObject* obj, void* conPtr )
void SceneObject::onCameraScopeQuery( NetConnection* connection, CameraScopeQuery* query )
{
SceneManager* sceneManager = getSceneManager();
GameConnection* conn = dynamic_cast<GameConnection*> (connection);
if (conn && (query->visibleDistance = conn->getVisibleGhostDistance()) == 0.0f)
if ((query->visibleDistance = sceneManager->getVisibleGhostDistance()) == 0.0f)
query->visibleDistance = sceneManager->getVisibleDistance();
// Object itself is in scope.
if( this->isScopeable() )

View file

@ -51,6 +51,10 @@
#include "scene/sceneContainer.h"
#endif
#ifndef _GFXDEVICE_H_
#include "gfx/gfxDevice.h"
#endif
class SceneManager;
class SceneRenderState;
@ -765,8 +769,14 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
static bool _setFieldRotation( void *object, const char *index, const char *data );
static bool _setFieldScale( void *object, const char *index, const char *data );
static bool _setMountPID( void* object, const char* index, const char* data );
static bool _setAccuEnabled( void *object, const char *index, const char *data );
/// @}
// Accumulation Texture
// Note: This was placed in SceneObject to both ShapeBase and TSStatic could support it.
public:
GFXTextureObject* mAccuTex;
};
#endif // _SCENEOBJECT_H_

View file

@ -0,0 +1,241 @@
//-----------------------------------------------------------------------------
// 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 "shaderGen/GLSL/accuFeatureGLSL.h"
#include "shaderGen/shaderFeature.h"
#include "shaderGen/shaderOp.h"
#include "shaderGen/featureMgr.h"
#include "materials/materialFeatureTypes.h"
#include "gfx/gfxDevice.h"
#include "materials/processedMaterial.h"
//****************************************************************************
// Accu Texture
//****************************************************************************
void AccuTexFeatGLSL::processVert(Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
getOutTexCoord( "texCoord",
"vec2",
true,
false,
meta,
componentList );
getOutObjToTangentSpace( componentList, meta, fd );
addOutAccuVec( componentList, meta );
output = meta;
}
void AccuTexFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
output = meta;
// OUT.col
Var *color = (Var*) LangElement::find( "col" );
if (!color)
{
output = new GenOp(" //NULL COLOR!");
return;
}
// accu map
Var *accuMap = new Var;
accuMap->setType( "sampler2D" );
accuMap->setName( "accuMap" );
accuMap->uniform = true;
accuMap->sampler = true;
accuMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
// accuColor var
Var *accuColor = new Var;
accuColor->setType( "vec4" );
accuColor->setName( "accuColor" );
LangElement *colorAccuDecl = new DecOp( accuColor );
// plc (placement)
Var *accuPlc = new Var;
accuPlc->setType( "vec4" );
accuPlc->setName( "plc" );
LangElement *plcAccu = new DecOp( accuPlc );
// accu constants
Var *accuScale = (Var*)LangElement::find( "accuScale" );
if ( !accuScale ) {
accuScale = new Var;
accuScale->setType( "float" );
accuScale->setName( "accuScale" );
accuScale->uniform = true;
accuScale->sampler = false;
accuScale->constSortPos = cspPotentialPrimitive;
}
Var *accuDirection = (Var*)LangElement::find( "accuDirection" );
if ( !accuDirection ) {
accuDirection = new Var;
accuDirection->setType( "float" );
accuDirection->setName( "accuDirection" );
accuDirection->uniform = true;
accuDirection->sampler = false;
accuDirection->constSortPos = cspPotentialPrimitive;
}
Var *accuStrength = (Var*)LangElement::find( "accuStrength" );
if ( !accuStrength ) {
accuStrength = new Var;
accuStrength->setType( "float" );
accuStrength->setName( "accuStrength" );
accuStrength->uniform = true;
accuStrength->sampler = false;
accuStrength->constSortPos = cspPotentialPrimitive;
}
Var *accuCoverage = (Var*)LangElement::find( "accuCoverage" );
if ( !accuCoverage ) {
accuCoverage = new Var;
accuCoverage->setType( "float" );
accuCoverage->setName( "accuCoverage" );
accuCoverage->uniform = true;
accuCoverage->sampler = false;
accuCoverage->constSortPos = cspPotentialPrimitive;
}
Var *accuSpecular = (Var*)LangElement::find( "accuSpecular" );
if ( !accuSpecular ) {
accuSpecular = new Var;
accuSpecular->setType( "float" );
accuSpecular->setName( "accuSpecular" );
accuSpecular->uniform = true;
accuSpecular->sampler = false;
accuSpecular->constSortPos = cspPotentialPrimitive;
}
Var *inTex = getInTexCoord( "texCoord", "vec2", true, componentList );
Var *accuVec = getInTexCoord( "accuVec", "vec3", true, componentList );
Var *bumpNorm = (Var *)LangElement::find( "bumpSample" );
if( bumpNorm == NULL ) {
bumpNorm = (Var *)LangElement::find( "bumpNormal" );
if (!bumpNorm)
{
output = new GenOp(" //NULL bumpNormal!");
return;
}
}
// get the accu pixel color
meta->addStatement( new GenOp( " @ = tex2D(@, @ * @);\r\n", colorAccuDecl, accuMap, inTex, accuScale ) );
// scale up normals
meta->addStatement( new GenOp( " @.xyz = @.xyz * 2.0 - 0.5;\r\n", bumpNorm, bumpNorm ) );
// assign direction
meta->addStatement( new GenOp( " @.z *= @*2.0;\r\n", accuVec, accuDirection ) );
// saturate based on strength
meta->addStatement( new GenOp( " @ = saturate( float4(dot( float3(@), @.xyz * pow(@, 5) ) ));\r\n", plcAccu, bumpNorm, accuVec, accuStrength ) );
// add coverage
meta->addStatement( new GenOp( " @.a += (2 * pow(@/2, 5)) - 0.5;\r\n", accuPlc, accuCoverage ) );
// clamp to a sensible value
meta->addStatement( new GenOp( " @.a = clamp(@.a, 0, 1);\r\n", accuPlc, accuPlc ) );
// light
Var *lightColor = (Var*) LangElement::find( "d_lightcolor" );
if(lightColor != NULL)
meta->addStatement( new GenOp( " @ *= float4(@, 1.0);\r\n\r\n", accuColor, lightColor ) );
// lerp with current pixel - use the accu alpha as well
meta->addStatement( new GenOp( " @ = mix( @, @, @.a * @.a);\r\n", color, color, accuColor, accuPlc, accuColor ) );
// the result should always be opaque
meta->addStatement( new GenOp( " @.a = 1.0;\r\n", color ) );
}
void AccuTexFeatGLSL::setTexData(Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex )
{
//GFXTextureObject *tex = stageDat.getTex( MFT_AccuMap );
//if ( tex )
//{
passData.mSamplerNames[texIndex] = "accuMap";
passData.mTexType[ texIndex++ ] = Material::AccuMap;
//passData.mTexSlot[ texIndex++ ].texObject = tex;
//}
}
void AccuTexFeatGLSL::getAccuVec(MultiLine *meta, LangElement *accuVec)
{
// Get the transform to world space.
Var *objTrans = (Var*)LangElement::find( "objTrans" );
if ( !objTrans )
{
objTrans = new Var;
objTrans->setType( "float4x4" );
objTrans->setName( "objTrans" );
objTrans->uniform = true;
objTrans->constSortPos = cspPrimitive;
}
// accu obj trans
Var *aobjTrans = new Var;
aobjTrans->setType( "float4x4" );
aobjTrans->setName( "accuObjTrans" );
LangElement *accuObjTransDecl = new DecOp( aobjTrans );
Var *outObjToTangentSpace = (Var*)LangElement::find( "objToTangentSpace" );
Var *tav = new Var;
tav->setType( "float4" );
tav->setName( "tAccuVec" );
LangElement *tavDecl = new DecOp( tav );
meta->addStatement( new GenOp( " @ = float4(0,0,1,0);\r\n", tavDecl ) );
meta->addStatement( new GenOp( " @ = transpose(@);\r\n", accuObjTransDecl, objTrans ) );
meta->addStatement( new GenOp( " @ = tMul(@, @);\r\n", tav, aobjTrans, tav ) );
meta->addStatement( new GenOp( " @.xyz = tMul(@, @.xyz);\r\n", tav, outObjToTangentSpace, tav ) );
meta->addStatement( new GenOp( " @.y *= -1;\r\n", tav ) );
meta->addStatement( new GenOp( " @ = @.xyz;\r\n", accuVec, tav ) );
}
Var* AccuTexFeatGLSL::addOutAccuVec(Vector<ShaderComponent*> &componentList, MultiLine *meta)
{
Var *outAccuVec = (Var*)LangElement::find( "accuVec" );
if ( !outAccuVec )
{
// Setup the connector.
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
outAccuVec = connectComp->getElement( RT_TEXCOORD );
outAccuVec->setName( "accuVec" );
outAccuVec->setStructName( "OUT" );
outAccuVec->setType( "float3" );
outAccuVec->mapsToSampler = false;
getAccuVec( meta, outAccuVec );
}
return outAccuVec;
}

View file

@ -0,0 +1,185 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _ACCUFEATUREGLSL_H_
#define _ACCUFEATUREGLSL_H_
#ifndef _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
#include "shaderGen/GLSL/shaderFeatureGLSL.h"
#endif
#ifndef _LANG_ELEMENT_H_
#include "shaderGen/langElement.h"
#endif
#ifndef _GFXDEVICE_H_
#include "gfx/gfxDevice.h"
#endif
#ifndef _FEATUREMGR_H_
#include "shaderGen/featureMgr.h"
#endif
#ifndef _MATERIALFEATURETYPES_H_
#include "materials/materialFeatureTypes.h"
#endif
#ifndef _MATERIALFEATUREDATA_H_
#include "materials/materialFeatureData.h"
#endif
/// Accu texture
class AccuTexFeatGLSL : public ShaderFeatureGLSL
{
public:
//****************************************************************************
// Accu Texture
//****************************************************************************
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
void getAccuVec( MultiLine *meta, LangElement *accuVec );
Var* addOutAccuVec( Vector<ShaderComponent*> &componentList, MultiLine *meta );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd )
{
Resources res;
res.numTex = 1;
res.numTexReg = 1;
return res;
}
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Accu Texture";
}
};
class AccuScaleFeature : public ShaderFeatureGLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Find the constant value
Var *accuScale = (Var *)( LangElement::find("accuScale") );
if( accuScale == NULL )
{
accuScale = new Var;
accuScale->setType( "float" );
accuScale->setName( "accuScale" );
accuScale->constSortPos = cspPotentialPrimitive;
accuScale->uniform = true;
}
}
virtual String getName() { return "Accu Scale"; }
};
class AccuDirectionFeature : public ShaderFeatureGLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Find the constant value
Var *accuDirection = (Var *)( LangElement::find("accuDirection") );
if( accuDirection == NULL )
{
accuDirection = new Var;
accuDirection->setType( "float" );
accuDirection->setName( "accuDirection" );
accuDirection->constSortPos = cspPotentialPrimitive;
accuDirection->uniform = true;
}
}
virtual String getName() { return "Accu Direction"; }
};
class AccuStrengthFeature : public ShaderFeatureGLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Find the constant value
Var *accuStrength = (Var *)( LangElement::find("accuStrength") );
if( accuStrength == NULL )
{
accuStrength = new Var;
accuStrength->setType( "float" );
accuStrength->setName( "accuStrength" );
accuStrength->constSortPos = cspPotentialPrimitive;
accuStrength->uniform = true;
}
}
virtual String getName() { return "Accu Strength"; }
};
class AccuCoverageFeature : public ShaderFeatureGLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Find the constant value
Var *accuCoverage = (Var *)( LangElement::find("accuCoverage") );
if( accuCoverage == NULL )
{
accuCoverage = new Var;
accuCoverage->setType( "float" );
accuCoverage->setName( "accuCoverage" );
accuCoverage->constSortPos = cspPotentialPrimitive;
accuCoverage->uniform = true;
}
}
virtual String getName() { return "Accu Coverage"; }
};
class AccuSpecularFeature : public ShaderFeatureGLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Find the constant value
Var *accuSpecular = (Var *)( LangElement::find("accuSpecular") );
if( accuSpecular == NULL )
{
accuSpecular = new Var;
accuSpecular->setType( "float" );
accuSpecular->setName( "accuSpecular" );
accuSpecular->constSortPos = cspPotentialPrimitive;
accuSpecular->uniform = true;
}
}
virtual String getName() { return "Accu Specular"; }
};
#endif

View file

@ -1682,7 +1682,7 @@ void ReflectCubeFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
cubeVertPos->setType( "vec3" );
LangElement *cubeVertPosDecl = new DecOp( cubeVertPos );
meta->addStatement( new GenOp( " @ = tMul(mat3( @ ), @).xyz;\r\n",
meta->addStatement( new GenOp( " @ = tMul( @, float4(@,1)).xyz;\r\n",
cubeVertPosDecl, cubeTrans, LangElement::find( "position" ) ) );
// cube normal
@ -1694,6 +1694,9 @@ void ReflectCubeFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
meta->addStatement( new GenOp( " @ = ( tMul( (@), vec4(@, 0) ) ).xyz;\r\n",
cubeNormDecl, cubeTrans, inNormal ) );
meta->addStatement( new GenOp( " @ = bool(length(@)) ? normalize(@) : @;\r\n",
cubeNormal, cubeNormal, cubeNormal, cubeNormal ) );
// grab the eye position
Var *eyePos = (Var*)LangElement::find( "eyePosWorld" );
if ( !eyePos )
@ -1703,23 +1706,14 @@ void ReflectCubeFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
eyePos->constSortPos = cspPass;
}
// cube position
Var * cubePos = new Var;
cubePos->setName( "cubePos" );
cubePos->setType( "vec3" );
LangElement *cubePosDecl = new DecOp( cubePos );
meta->addStatement( new GenOp( " @ = vec3( @[3][0], @[3][1], @[3][2] );\r\n",
cubePosDecl, cubeTrans, cubeTrans, cubeTrans ) );
// eye to vert
Var * eyeToVert = new Var;
eyeToVert->setName( "eyeToVert" );
eyeToVert->setType( "vec3" );
LangElement *e2vDecl = new DecOp( eyeToVert );
meta->addStatement( new GenOp( " @ = @ - ( @ - @ );\r\n",
e2vDecl, cubeVertPos, eyePos, cubePos ) );
meta->addStatement( new GenOp( " @ = @ - @;\r\n",
e2vDecl, cubeVertPos, eyePos ) );
// grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );

View file

@ -32,6 +32,7 @@
#include "shaderGen/GLSL/paraboloidGLSL.h"
#include "materials/materialFeatureTypes.h"
#include "core/module.h"
#include "shaderGen/GLSL/accuFeatureGLSL.h"
static ShaderGen::ShaderGenInitDelegate sInitDelegate;
@ -62,6 +63,7 @@ void _initShaderGenGLSL( ShaderGen *shaderGen )
FEATUREMGR->registerFeature( MFT_CubeMap, new ReflectCubeFeatGLSL );
FEATUREMGR->registerFeature( MFT_PixSpecular, new PixelSpecularGLSL );
FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapGLSL );
FEATUREMGR->registerFeature( MFT_AccuMap, new AccuTexFeatGLSL );
FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureGLSL( "Gloss Map" ) );
FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureGLSL( "Translucent" ) );
FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatGLSL );

View file

@ -0,0 +1,238 @@
//-----------------------------------------------------------------------------
// 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 "shaderGen/HLSL/accuFeatureHLSL.h"
#include "shaderGen/shaderFeature.h"
#include "shaderGen/shaderOp.h"
#include "shaderGen/featureMgr.h"
#include "materials/materialFeatureTypes.h"
#include "gfx/gfxDevice.h"
#include "materials/processedMaterial.h"
//****************************************************************************
// Accu Texture
//****************************************************************************
void AccuTexFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
getOutTexCoord( "texCoord",
"float2",
true,
false,
meta,
componentList );
getOutObjToTangentSpace( componentList, meta, fd );
addOutAccuVec( componentList, meta );
output = meta;
}
void AccuTexFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
output = meta;
// OUT.col
Var *color = (Var*) LangElement::find( "col" );
if (!color)
{
output = new GenOp(" //NULL COLOR!");
return;
}
// accu map
Var *accuMap = new Var;
accuMap->setType( "sampler2D" );
accuMap->setName( "accuMap" );
accuMap->uniform = true;
accuMap->sampler = true;
accuMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
// accuColor var
Var *accuColor = new Var;
accuColor->setType( "float4" );
accuColor->setName( "accuColor" );
LangElement *colorAccuDecl = new DecOp( accuColor );
// plc (placement)
Var *accuPlc = new Var;
accuPlc->setType( "float4" );
accuPlc->setName( "plc" );
LangElement *plcAccu = new DecOp( accuPlc );
// accu constants
Var *accuScale = (Var*)LangElement::find( "accuScale" );
if ( !accuScale ) {
accuScale = new Var;
accuScale->setType( "float" );
accuScale->setName( "accuScale" );
accuScale->uniform = true;
accuScale->sampler = false;
accuScale->constSortPos = cspPotentialPrimitive;
}
Var *accuDirection = (Var*)LangElement::find( "accuDirection" );
if ( !accuDirection ) {
accuDirection = new Var;
accuDirection->setType( "float" );
accuDirection->setName( "accuDirection" );
accuDirection->uniform = true;
accuDirection->sampler = false;
accuDirection->constSortPos = cspPotentialPrimitive;
}
Var *accuStrength = (Var*)LangElement::find( "accuStrength" );
if ( !accuStrength ) {
accuStrength = new Var;
accuStrength->setType( "float" );
accuStrength->setName( "accuStrength" );
accuStrength->uniform = true;
accuStrength->sampler = false;
accuStrength->constSortPos = cspPotentialPrimitive;
}
Var *accuCoverage = (Var*)LangElement::find( "accuCoverage" );
if ( !accuCoverage ) {
accuCoverage = new Var;
accuCoverage->setType( "float" );
accuCoverage->setName( "accuCoverage" );
accuCoverage->uniform = true;
accuCoverage->sampler = false;
accuCoverage->constSortPos = cspPotentialPrimitive;
}
Var *accuSpecular = (Var*)LangElement::find( "accuSpecular" );
if ( !accuSpecular ) {
accuSpecular = new Var;
accuSpecular->setType( "float" );
accuSpecular->setName( "accuSpecular" );
accuSpecular->uniform = true;
accuSpecular->sampler = false;
accuSpecular->constSortPos = cspPotentialPrimitive;
}
Var *inTex = getInTexCoord( "texCoord", "float2", true, componentList );
Var *accuVec = getInTexCoord( "accuVec", "float3", true, componentList );
Var *bumpNorm = (Var *)LangElement::find( "bumpSample" );
if( bumpNorm == NULL ) {
bumpNorm = (Var *)LangElement::find( "bumpNormal" );
if (!bumpNorm)
return;
}
// get the accu pixel color
meta->addStatement( new GenOp( " @ = tex2D(@, @ * @);\r\n", colorAccuDecl, accuMap, inTex, accuScale ) );
// scale up normals
meta->addStatement( new GenOp( " @.xyz = @.xyz * 2.0 - 0.5;\r\n", bumpNorm, bumpNorm ) );
// assign direction
meta->addStatement( new GenOp( " @.z *= @*2.0;\r\n", accuVec, accuDirection ) );
// saturate based on strength
meta->addStatement( new GenOp( " @ = saturate( dot( @, @.xyz * pow(@, 5) ) );\r\n", plcAccu, bumpNorm, accuVec, accuStrength ) );
// add coverage
meta->addStatement( new GenOp( " @.a += (2 * pow(@/2, 5)) - 0.5;\r\n", accuPlc, accuCoverage ) );
// clamp to a sensible value
meta->addStatement( new GenOp( " @.a = clamp(@.a, 0, 1);\r\n", accuPlc, accuPlc ) );
// light
Var *lightColor = (Var*) LangElement::find( "d_lightcolor" );
if(lightColor != NULL)
meta->addStatement( new GenOp( " @ *= float4(@, 1.0);\r\n\r\n", accuColor, lightColor ) );
// lerp with current pixel - use the accu alpha as well
meta->addStatement( new GenOp( " @ = lerp( @, @, @.a * @.a);\r\n", color, color, accuColor, accuPlc, accuColor ) );
// the result should always be opaque
meta->addStatement( new GenOp( " @.a = 1.0;\r\n", color ) );
}
void AccuTexFeatHLSL::setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex )
{
//GFXTextureObject *tex = stageDat.getTex( MFT_AccuMap );
//if ( tex )
//{
passData.mSamplerNames[ texIndex ] = "AccuMap";
passData.mTexType[ texIndex++ ] = Material::AccuMap;
//}
}
void AccuTexFeatHLSL::getAccuVec( MultiLine *meta, LangElement *accuVec )
{
// Get the transform to world space.
Var *objTrans = (Var*)LangElement::find( "objTrans" );
if ( !objTrans )
{
objTrans = new Var;
objTrans->setType( "float4x4" );
objTrans->setName( "objTrans" );
objTrans->uniform = true;
objTrans->constSortPos = cspPrimitive;
}
// accu obj trans
Var *aobjTrans = new Var;
aobjTrans->setType( "float4x4" );
aobjTrans->setName( "accuObjTrans" );
LangElement *accuObjTransDecl = new DecOp( aobjTrans );
Var *outObjToTangentSpace = (Var*)LangElement::find( "objToTangentSpace" );
Var *tav = new Var;
tav->setType( "float4" );
tav->setName( "tAccuVec" );
LangElement *tavDecl = new DecOp( tav );
meta->addStatement( new GenOp( " @ = float4(0,0,1,0);\r\n", tavDecl ) );
meta->addStatement( new GenOp( " @ = transpose(@);\r\n", accuObjTransDecl, objTrans ) );
meta->addStatement( new GenOp( " @ = mul(@, @);\r\n", tav, aobjTrans, tav ) );
meta->addStatement( new GenOp( " @.xyz = mul(@, @.xyz);\r\n", tav, outObjToTangentSpace, tav ) );
meta->addStatement( new GenOp( " @.y *= -1;\r\n", tav ) );
meta->addStatement( new GenOp( " @ = @.xyz;\r\n", accuVec, tav ) );
}
Var* AccuTexFeatHLSL::addOutAccuVec( Vector<ShaderComponent*> &componentList, MultiLine *meta )
{
Var *outAccuVec = (Var*)LangElement::find( "accuVec" );
if ( !outAccuVec )
{
// Setup the connector.
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
outAccuVec = connectComp->getElement( RT_TEXCOORD );
outAccuVec->setName( "accuVec" );
outAccuVec->setStructName( "OUT" );
outAccuVec->setType( "float3" );
outAccuVec->mapsToSampler = false;
getAccuVec( meta, outAccuVec );
}
return outAccuVec;
}

View file

@ -0,0 +1,185 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _ACCUFEATUREHLSL_H_
#define _ACCUFEATUREHLSL_H_
#ifndef _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_
#include "shaderGen/HLSL/shaderFeatureHLSL.h"
#endif
#ifndef _LANG_ELEMENT_H_
#include "shaderGen/langElement.h"
#endif
#ifndef _GFXDEVICE_H_
#include "gfx/gfxDevice.h"
#endif
#ifndef _FEATUREMGR_H_
#include "shaderGen/featureMgr.h"
#endif
#ifndef _MATERIALFEATURETYPES_H_
#include "materials/materialFeatureTypes.h"
#endif
#ifndef _MATERIALFEATUREDATA_H_
#include "materials/materialFeatureData.h"
#endif
/// Accu texture
class AccuTexFeatHLSL : public ShaderFeatureHLSL
{
public:
//****************************************************************************
// Accu Texture
//****************************************************************************
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
void getAccuVec( MultiLine *meta, LangElement *accuVec );
Var* addOutAccuVec( Vector<ShaderComponent*> &componentList, MultiLine *meta );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd )
{
Resources res;
res.numTex = 1;
res.numTexReg = 1;
return res;
}
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Accu Texture";
}
};
class AccuScaleFeature : public ShaderFeatureHLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Find the constant value
Var *accuScale = (Var *)( LangElement::find("accuScale") );
if( accuScale == NULL )
{
accuScale = new Var;
accuScale->setType( "float" );
accuScale->setName( "accuScale" );
accuScale->constSortPos = cspPotentialPrimitive;
accuScale->uniform = true;
}
}
virtual String getName() { return "Accu Scale"; }
};
class AccuDirectionFeature : public ShaderFeatureHLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Find the constant value
Var *accuDirection = (Var *)( LangElement::find("accuDirection") );
if( accuDirection == NULL )
{
accuDirection = new Var;
accuDirection->setType( "float" );
accuDirection->setName( "accuDirection" );
accuDirection->constSortPos = cspPotentialPrimitive;
accuDirection->uniform = true;
}
}
virtual String getName() { return "Accu Direction"; }
};
class AccuStrengthFeature : public ShaderFeatureHLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Find the constant value
Var *accuStrength = (Var *)( LangElement::find("accuStrength") );
if( accuStrength == NULL )
{
accuStrength = new Var;
accuStrength->setType( "float" );
accuStrength->setName( "accuStrength" );
accuStrength->constSortPos = cspPotentialPrimitive;
accuStrength->uniform = true;
}
}
virtual String getName() { return "Accu Strength"; }
};
class AccuCoverageFeature : public ShaderFeatureHLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Find the constant value
Var *accuCoverage = (Var *)( LangElement::find("accuCoverage") );
if( accuCoverage == NULL )
{
accuCoverage = new Var;
accuCoverage->setType( "float" );
accuCoverage->setName( "accuCoverage" );
accuCoverage->constSortPos = cspPotentialPrimitive;
accuCoverage->uniform = true;
}
}
virtual String getName() { return "Accu Coverage"; }
};
class AccuSpecularFeature : public ShaderFeatureHLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Find the constant value
Var *accuSpecular = (Var *)( LangElement::find("accuSpecular") );
if( accuSpecular == NULL )
{
accuSpecular = new Var;
accuSpecular->setType( "float" );
accuSpecular->setName( "accuSpecular" );
accuSpecular->constSortPos = cspPotentialPrimitive;
accuSpecular->uniform = true;
}
}
virtual String getName() { return "Accu Specular"; }
};
#endif

View file

@ -1681,7 +1681,7 @@ void ReflectCubeFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
cubeVertPos->setType( "float3" );
LangElement *cubeVertPosDecl = new DecOp( cubeVertPos );
meta->addStatement( new GenOp( " @ = mul((float3x3)@, @).xyz;\r\n",
meta->addStatement( new GenOp( " @ = mul(@, float4(@,1)).xyz;\r\n",
cubeVertPosDecl, cubeTrans, LangElement::find( "position" ) ) );
// cube normal
@ -1702,23 +1702,14 @@ void ReflectCubeFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
eyePos->constSortPos = cspPass;
}
// cube position
Var * cubePos = new Var;
cubePos->setName( "cubePos" );
cubePos->setType( "float3" );
LangElement *cubePosDecl = new DecOp( cubePos );
meta->addStatement( new GenOp( " @ = float3( @[0][3], @[1][3], @[2][3] );\r\n",
cubePosDecl, cubeTrans, cubeTrans, cubeTrans ) );
// eye to vert
Var * eyeToVert = new Var;
eyeToVert->setName( "eyeToVert" );
eyeToVert->setType( "float3" );
LangElement *e2vDecl = new DecOp( eyeToVert );
meta->addStatement( new GenOp( " @ = @ - ( @ - @ );\r\n",
e2vDecl, cubeVertPos, eyePos, cubePos ) );
meta->addStatement( new GenOp( " @ = @ - @;\r\n",
e2vDecl, cubeVertPos, eyePos ) );
// grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );

View file

@ -32,7 +32,7 @@
#include "shaderGen/HLSL/paraboloidHLSL.h"
#include "materials/materialFeatureTypes.h"
#include "core/module.h"
#include "shaderGen/HLSL/accuFeatureHLSL.h"
static ShaderGen::ShaderGenInitDelegate sInitDelegate;
@ -66,6 +66,7 @@ void _initShaderGenHLSL( ShaderGen *shaderGen )
FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatHLSL );
FEATUREMGR->registerFeature( MFT_Fog, new FogFeatHLSL );
FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapHLSL );
FEATUREMGR->registerFeature( MFT_AccuMap, new AccuTexFeatHLSL );
FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureHLSL( "Gloss Map" ) );
FEATUREMGR->registerFeature( MFT_LightbufferMRT, new NamedFeatureHLSL( "Lightbuffer MRT" ) );
FEATUREMGR->registerFeature( MFT_RenderTarget1_Zero, new RenderTargetZeroHLSL( ShaderFeature::RenderTarget1 ) );

View file

@ -379,9 +379,6 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
const U32 detailIndex = getProcessIndex();
Var *inTex = getVertTexCoord( "texCoord" );
// new terrain
bool hasNormal = fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex);
MultiLine *meta = new MultiLine;
// We need the negative tangent space view vector
@ -450,95 +447,6 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
// New terrain
Var *lerpBlend = (Var*)LangElement::find("lerpBlend");
if (!lerpBlend)
{
lerpBlend = new Var;
lerpBlend->setType("float");
lerpBlend->setName("lerpBlend");
lerpBlend->uniform = true;
lerpBlend->constSortPos = cspPrimitive;
}
Var *blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", detailIndex));
if (!blendDepth)
{
blendDepth = new Var;
blendDepth->setType("float");
blendDepth->setName(String::ToString("blendDepth%d", detailIndex));
blendDepth->uniform = true;
blendDepth->constSortPos = cspPrimitive;
}
Var *baseColor = (Var*)LangElement::find("baseColor");
Var *outColor = (Var*)LangElement::find(getOutputTargetVarName(DefaultTarget));
if (!outColor)
{
// create color var
outColor = new Var;
outColor->setType("float4");
outColor->setName("col");
outColor->setStructName("OUT");
meta->addStatement(new GenOp(" @;\r\n", outColor));
}
Var *detailColor = (Var*)LangElement::find("detailColor");
if (!detailColor)
{
detailColor = new Var;
detailColor->setType("float4");
detailColor->setName("detailColor");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(detailColor)));
}
// Get the detail texture.
Var *detailMap = new Var;
detailMap->setType("sampler2D");
detailMap->setName(String::ToString("detailMap%d", detailIndex));
detailMap->uniform = true;
detailMap->sampler = true;
detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
// Get the normal map texture.
Var *normalMap = _getNormalMapTex();
// Issue happens somewhere here -----
// Sample the normal map.
//
// We take two normal samples and lerp between them for
// side projection layers... else a single sample.
LangElement *texOp;
// Note that we're doing the standard greyscale detail
// map technique here which can darken and lighten the
// diffuse texture.
//
// We take two color samples and lerp between them for
// side projection layers... else a single sample.
//
if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
{
meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet, detailMap, inDet, inTex));
texOp = new GenOp("lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )",
normalMap, inDet, normalMap, inDet, inTex);
}
else
{
meta->addStatement(new GenOp(" @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet));
texOp = new GenOp("tex2D(@, @.xy)", normalMap, inDet);
}
// New terrain
// Get a var and accumulate the blend amount.
Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
if ( !blendTotal )
@ -550,96 +458,7 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
}
// Add to the blend total.
meta->addStatement( new GenOp( " @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) );
// New terrain
Var *bumpNorm = (Var*)LangElement::find("bumpNormal");
Var *invBlend = (Var*)LangElement::find("invBlend");
Var *currentAlpha = (Var*)LangElement::find("currentAlpha");
Var *ma = (Var*)LangElement::find("ma");
Var *b1 = (Var*)LangElement::find("b1");
Var *b2 = (Var*)LangElement::find("b2");
// Get a var and accumulate the blend amount.
if (!currentAlpha)
{
currentAlpha = new Var;
currentAlpha->setName("currentAlpha");
currentAlpha->setType("float");
meta->addStatement(new GenOp(" @ = 0;\r\n", new DecOp(currentAlpha)));
}
if (hasNormal)
{
// create bump normal
bool bumpNormWasDefined = bumpNorm ? true : false;
LangElement *bumpNormDecl = bumpNorm;
if (!bumpNormWasDefined)
{
bumpNorm = new Var;
bumpNorm->setName("bumpNormal");
bumpNorm->setType("float4");
bumpNormDecl = new DecOp(bumpNorm);
}
meta->addStatement(new GenOp(" @ = @;\r\n", bumpNormDecl, texOp));
meta->addStatement(new GenOp(" @.a = max(@.a, 0.000001);\r\n", bumpNorm, bumpNorm));
// -----
// Get a var and accumulate the blend amount.
if (!invBlend)
{
invBlend = new Var;
invBlend->setName("invBlend");
invBlend->setType("float");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(invBlend)));
}
// Get a var and accumulate the blend amount.
if (!ma)
{
ma = new Var;
ma->setName("ma");
ma->setType("float");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(ma)));
}
// Get a var and accumulate the blend amount.
if (!b1)
{
b1 = new Var;
b1->setName("b1");
b1->setType("float");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(b1)));
}
// Get a var and accumulate the blend amount.
if (!b2)
{
b2 = new Var;
b2->setName("b2");
b2->setType("float");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(b2)));
}
meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n { \r\n", lerpBlend));
meta->addStatement(new GenOp(" @ = 1-@;\r\n", invBlend, detailBlend));
meta->addStatement(new GenOp(" @ = max(@.a + @, @ + @) - @;\r\n", ma, bumpNorm, detailBlend, currentAlpha, invBlend, blendDepth));
meta->addStatement(new GenOp(" @ = max(@.a + @ - @, 0);\r\n", b1, bumpNorm, detailBlend, ma));
meta->addStatement(new GenOp(" @ = max(@ + @ - @, 0);\r\n", b2, currentAlpha, invBlend, ma));
meta->addStatement(new GenOp(" }\r\n"));
}
else
{
meta->addStatement(new GenOp(" @ = max(@,@);\r\n", currentAlpha, currentAlpha, detailBlend));
}
// New terrain
meta->addStatement( new GenOp( " @ += @;\r\n", blendTotal, detailBlend ) );
// If we had a parallax feature... then factor in the parallax
// amount so that it fades out with the layer blending.
@ -676,36 +495,58 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
return;
}
// used as texture unit num here
Var *detailColor = (Var*)LangElement::find( "detailColor" );
if ( !detailColor )
{
detailColor = new Var;
detailColor->setType( "vec4" );
detailColor->setName( "detailColor" );
meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
}
// Get the detail texture.
Var *detailMap = new Var;
detailMap->setType( "sampler2D" );
detailMap->setName( String::ToString( "detailMap%d", detailIndex ) );
detailMap->uniform = true;
detailMap->sampler = true;
detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
// If we're using SM 3.0 then take advantage of
// dynamic branching to skip layers per-pixel.
if ( GFX->getPixelShaderVersion() >= 3.0f )
meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) );
meta->addStatement( new GenOp( " {\r\n" ) );
// Note that we're doing the standard greyscale detail
// map technique here which can darken and lighten the
// diffuse texture.
//
// We take two color samples and lerp between them for
// side projection layers... else a single sample.
//
if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) )
{
meta->addStatement( new GenOp( " @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet, detailMap, inDet, inTex ) );
}
else
{
meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet ) );
}
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) );
// New terrain
if (hasNormal)
{
meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n", lerpBlend));
meta->addStatement(new GenOp(" @.rgb = ((@ + @).rgb * @ + @.rgb * @) / (@ + @);\r\n", outColor, baseColor, detailColor, b1, outColor, b2, b1, b2));
meta->addStatement(new GenOp(" else\r\n"));
}
Var *baseColor = (Var*)LangElement::find( "baseColor" );
Var *outColor = (Var*)LangElement::find( "col" );
meta->addStatement(new GenOp(" @ += @ * @;\r\n", outColor, detailColor, detailBlend));
// New terrain
if (hasNormal)
{
meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n", lerpBlend));
meta->addStatement(new GenOp(" @ = (@.a * @ + @ * @) / (@ + @);\r\n", currentAlpha, bumpNorm, b1, currentAlpha, b2, b1, b2));
}
meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n",
outColor, outColor, baseColor, detailColor, detailBlend ) );
meta->addStatement( new GenOp( " }\r\n" ) );
@ -971,9 +812,13 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) );
Var *baseColor = (Var*)LangElement::find( "baseColor" );
Var *outColor = (Var*)LangElement::find( "col" );
meta->addStatement(new GenOp(" @ += @ * @;\r\n", outColor, detailColor, detailBlend));
meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n",
outColor, outColor, outColor, detailColor, detailBlend ) );
//outColor, outColor, baseColor, detailColor, detailBlend ) );
meta->addStatement( new GenOp( " }\r\n" ) );
output = meta;
@ -1075,36 +920,15 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
texOp = new GenOp( "tex2D(@, @.xy)", normalMap, inDet );
// create bump normal
// New terrain
Var *bumpNorm = (Var*)LangElement::find("bumpNormal");
bool bumpNormWasDefined = bumpNorm ? true : false;
LangElement *bumpNormDecl = bumpNorm;
if (!bumpNormWasDefined)
{
bumpNorm = new Var;
bumpNorm->setName("bumpNormal");
bumpNorm->setType("float4");
bumpNormDecl = new DecOp(bumpNorm);
}
Var *bumpNorm = new Var;
bumpNorm->setName( "bumpNormal" );
bumpNorm->setType( "vec4" );
LangElement *bumpNormDecl = new DecOp( bumpNorm );
meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) );
// New terrain
Var *lerpBlend = (Var*)LangElement::find("lerpBlend");
AssertFatal(lerpBlend, "The lerpBlend is missing!");
Var *b1 = (Var*)LangElement::find("b1");
AssertFatal(b1, "The b1 is missing!");
Var *b2 = (Var*)LangElement::find("b2");
AssertFatal(b2, "The b2 is missing!");
// Normalize is done later...
// Note: The reverse mul order is intentional. Affine matrix.
// New terrain
meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n", lerpBlend));
meta->addStatement(new GenOp(" @ = (tMul( @.xyz, @ ).rgb * @ + @.rgb * @) / (@ + @);\r\n", gbNormal, bumpNorm, viewToTangent, b1, gbNormal, b2, b1, b2));
meta->addStatement(new GenOp(" else\r\n"));
meta->addStatement( new GenOp( " @ = lerp( @, tMul( @.xyz, @ ), min( @, @.w ) );\r\n",
gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet ) );

View file

@ -574,10 +574,6 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
matInfo->detailInfoVConst = pass->shader->getShaderConstHandle( avar( "$detailScaleAndFade%d", i ) );
matInfo->detailInfoPConst = pass->shader->getShaderConstHandle( avar( "$detailIdStrengthParallax%d", i ) );
// New blending
matInfo->lerpBlend = pass->shader->getShaderConstHandle("$lerpBlend");
matInfo->blendDepth = pass->shader->getShaderConstHandle(avar("$blendDepth%d", i));
matInfo->detailTexConst = pass->shader->getShaderConstHandle( avar( "$detailMap%d", i ) );
if ( matInfo->detailTexConst->isValid() )
{
@ -715,11 +711,6 @@ void TerrainCellMaterial::_updateMaterialConsts( Pass *pass )
pass->consts->setSafe( matInfo->detailInfoVConst, detailScaleAndFade );
pass->consts->setSafe( matInfo->detailInfoPConst, detailIdStrengthParallax );
// New blending
bool lerpBlend = Con::getBoolVariable("$Pref::Terrain::LerpBlend", true);
pass->consts->setSafe(matInfo->lerpBlend, lerpBlend ? 1.0f : 0.0f);
pass->consts->setSafe(matInfo->blendDepth, matInfo->mat->getBlendDepth());
// macro texture info
F32 macroSize = matInfo->mat->getMacroSize();

View file

@ -80,10 +80,6 @@ protected:
GFXShaderConstHandle *detailInfoVConst;
GFXShaderConstHandle *detailInfoPConst;
// New blending
GFXShaderConstHandle *lerpBlend;
GFXShaderConstHandle *blendDepth;
GFXShaderConstHandle *macroInfoVConst;
GFXShaderConstHandle *macroInfoPConst;
};

View file

@ -65,8 +65,7 @@ TerrainMaterial::TerrainMaterial()
mMacroSize( 200.0f ),
mMacroStrength( 0.7f ),
mMacroDistance( 500.0f ),
mParallaxScale(0.0f),
mBlendDepth(0.4f)
mParallaxScale( 0.0f )
{
}
@ -98,9 +97,6 @@ void TerrainMaterial::initPersistFields()
addField( "parallaxScale", TypeF32, Offset( mParallaxScale, TerrainMaterial ), "Used to scale the height from the normal map to give some self "
"occlusion effect (aka parallax) to the terrain material" );
addField("blendDepth", TypeF32, Offset(mBlendDepth, TerrainMaterial), "Depth for blending the textures using the new blending method by Lukas Joergensen."
"Higher numbers = larger blend radius.");
Parent::initPersistFields();
// Gotta call this at least once or it won't get created!

View file

@ -74,11 +74,6 @@ protected:
///
F32 mParallaxScale;
/// Depth for blending the textures using the new
/// blending method. Higher numbers = larger blend
/// radius.
F32 mBlendDepth;
public:
TerrainMaterial();
@ -124,8 +119,6 @@ public:
F32 getParallaxScale() const { return mParallaxScale; }
F32 getBlendDepth() const { return mBlendDepth; }
};
#endif // _TERRMATERIAL_H_

View file

@ -165,6 +165,9 @@ void TSMesh::innerRender( TSMaterialList *materials, const TSRenderState &rdata,
MeshRenderInst *coreRI = renderPass->allocInst<MeshRenderInst>();
coreRI->type = RenderPassManager::RIT_Mesh;
// Pass accumulation texture along.
coreRI->accuTex = rdata.getAccuTex();
const MatrixF &objToWorld = GFX->getWorldMatrix();
// Sort by the center point or the bounds.
@ -2428,7 +2431,7 @@ void TSMesh::_createVBIB( TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb
pInfo.startIndex = draw.start;
// Use the first index to determine which 16-bit address space we are operating in
pInfo.startVertex = indices[draw.start] & 0xFFFF0000;
pInfo.minIndex = pInfo.startVertex;
pInfo.minIndex = 0; // minIndex are zero based index relative to startVertex. See @GFXDevice
pInfo.numVertices = getMin((U32)0x10000, mNumVerts - pInfo.startVertex);
break;
@ -2439,7 +2442,7 @@ void TSMesh::_createVBIB( TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb
pInfo.startIndex = draw.start;
// Use the first index to determine which 16-bit address space we are operating in
pInfo.startVertex = indices[draw.start] & 0xFFFF0000;
pInfo.minIndex = pInfo.startVertex;
pInfo.minIndex = 0; // minIndex are zero based index relative to startVertex. See @GFXDevice
pInfo.numVertices = getMin((U32)0x10000, mNumVerts - pInfo.startVertex);
break;

View file

@ -33,7 +33,8 @@ TSRenderState::TSRenderState()
mMaterialHint( NULL ),
mCuller( NULL ),
mLightQuery( NULL ),
mUseOriginSort( false )
mUseOriginSort( false ),
mAccuTex( NULL )
{
}

View file

@ -27,7 +27,9 @@
#include "math/mMatrix.h"
#endif
#ifndef _GFXDEVICE_H_
#include "gfx/gfxDevice.h"
#endif
class SceneRenderState;
class GFXCubemap;
@ -103,8 +105,14 @@ protected:
/// are forward lit and need lights.
LightQuery *mLightQuery;
// The accumulation texture provided by an accumulation
// volume. This is passed down per-object.
GFXTextureObject* mAccuTex;
public:
TSRenderState();
TSRenderState( const TSRenderState &state );
@ -147,6 +155,10 @@ public:
void setLightQuery( LightQuery *query ) { mLightQuery = query; }
LightQuery* getLightQuery() const { return mLightQuery; }
///@see mAccuTex
void setAccuTex( GFXTextureObject* query ) { mAccuTex = query; }
GFXTextureObject* getAccuTex() const { return mAccuTex; }
/// @}
};

View file

@ -39,7 +39,6 @@
#include "gfx/gfxDrawUtil.h"
#include "core/module.h"
MODULE_BEGIN( TSShapeInstance )
MODULE_INIT
@ -783,3 +782,16 @@ void TSShapeInstance::prepCollision()
}
}
// Returns true is the shape contains any materials with accumulation enabled.
bool TSShapeInstance::hasAccumulation()
{
bool result = false;
for ( U32 i = 0; i < mMaterialList->size(); ++i )
{
BaseMatInstance* mat = mMaterialList->getMaterialInst(i);
if ( mat->hasAccumulation() )
result = true;
}
return result;
}

View file

@ -671,6 +671,12 @@ protected:
void *mData; ///< available for use by app...initialized to 0
void prepCollision();
//-------------------------------------------------------------------------------------
// accumulation
//-------------------------------------------------------------------------------------
bool hasAccumulation();
};

View file

@ -121,6 +121,7 @@ void ImposterCaptureMaterialHook::init( BaseMatInstance *inMat )
features.addFeature( MFT_IsDXTnm );
features.addFeature( MFT_NormalMap );
features.addFeature( MFT_NormalsOut );
features.addFeature( MFT_AccuMap );
mNormalsMatInst = MATMGR->createMatInstance( matName );
mNormalsMatInst->getFeaturesDelegate().bind( &ImposterCaptureMaterialHook::_overrideFeatures );
mNormalsMatInst->init( features, inMat->getVertexFormat() );

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 561 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 699 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 610 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 780 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 627 KiB

View file

@ -20,228 +20,3 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Sample grass
// ----------------------------------------------------------------------------
singleton Material(TerrainFX_grass1)
{
mapTo = "grass1";
footstepSoundId = 0;
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
effectColor[0] = "0.42 0.42 0 1";
effectColor[1] = "0.42 0.42 0 1";
impactSoundId = "0";
};
new TerrainMaterial()
{
internalName = "grass1";
diffuseMap = "art/terrains/Example/grass1";
detailMap = "art/terrains/Example/grass1_d";
detailSize = "10";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "200";
normalMap = "art/terrains/Example/grass1_n";
detailDistance = "1000";
};
singleton Material(TerrainFX_grass2)
{
mapTo = "grass2";
footstepSoundId = 0;
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
effectColor[0] = "0.42 0.42 0 1";
effectColor[1] = "0.42 0.42 0 1";
impactSoundId = "0";
};
new TerrainMaterial()
{
internalName = "grass2";
diffuseMap = "art/terrains/Example/grass2";
detailMap = "art/terrains/Example/grass2_d";
detailSize = "10";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "200";
};
singleton Material(TerrainFX_grass1dry)
{
mapTo = "grass1_dry";
footstepSoundId = 0;
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
effectColor[0] = "0.63 0.55 0 1";
};
new TerrainMaterial()
{
internalName = "grass1_dry";
diffuseMap = "art/terrains/Example/grass1_dry";
detailMap = "art/terrains/Example/grass1_dry_d";
detailSize = "10";
detailDistance = "100";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "250";
detailStrength = "2";
normalMap = "art/terrains/Example/grass1_dry_n";
};
singleton Material(TerrainFX_dirt_grass)
{
mapTo = "dirt_grass";
footstepSoundId = 0;
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
effectColor[0] = "0.63 0.55 0 1";
diffuseMap = "art/terrains/Example/dirt_grass";
diffuseSize = "200";
normalMap = "art/terrains/Example/dirt_grass_n";
detailMap = "art/terrains/Example/dirt_grass_d";
detailDistance = "100";
internalName = "dirt_grass";
isManaged = "1";
detailBrightness = "1";
enabled = "1";
};
new TerrainMaterial()
{
internalName = "dirt_grass";
diffuseMap = "art/terrains/Example/dirt_grass";
detailMap = "art/terrains/Example/dirt_grass_d";
detailSize = "5";
detailDistance = "100";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "200";
};
// ----------------------------------------------------------------------------
// Sample rock
// ----------------------------------------------------------------------------
singleton Material(TerrainFX_rocktest)
{
mapTo = "rocktest";
footstepSoundId = "1";
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
impactSoundId = "1";
effectColor[0] = "0.25 0.25 0.25 1";
effectColor[1] = "0.25 0.25 0.25 0";
diffuseMap = "art/terrains/Example/rocktest";
diffuseSize = "400";
normalMap = "art/terrains/Example/rocktest_n";
detailMap = "art/terrains/Example/rocktest_d";
detailSize = "10";
detailDistance = "100";
internalName = "rocktest";
isManaged = "1";
detailBrightness = "1";
enabled = "1";
};
new TerrainMaterial()
{
internalName = "rocktest";
diffuseMap = "art/terrains/Example/rocktest";
detailMap = "art/terrains/Example/rocktest_d";
detailSize = "10";
detailDistance = "100";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "400";
};
// ----------------------------------------------------------------------------
// Sample rock
// ----------------------------------------------------------------------------
singleton Material(TerrainFX_stone)
{
mapTo = "stone";
footstepSoundId = "1";
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
impactSoundId = "1";
effectColor[0] = "0.25 0.25 0.25 1";
effectColor[1] = "0.25 0.25 0.25 0";
diffuseMap = "art/terrains/Example/stone";
diffuseSize = "400";
normalMap = "art/terrains/Example/stone_n";
detailMap = "art/terrains/Example/stone_d";
detailSize = "10";
detailDistance = "100";
internalName = "stone";
isManaged = "1";
detailBrightness = "1";
enabled = "1";
};
new TerrainMaterial()
{
internalName = "stone";
diffuseMap = "art/terrains/Example/stone";
detailMap = "art/terrains/Example/stone_d";
detailSize = "10";
detailDistance = "100";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "400";
useSideProjection = "0";
};
// ----------------------------------------------------------------------------
// Sample sand
// ----------------------------------------------------------------------------
singleton Material(TerrainFX_sand)
{
mapTo = "sand";
footstepSoundId = "3";
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
specularPower[0] = "1";
effectColor[0] = "0.84 0.71 0.5 1";
effectColor[1] = "0.84 0.71 0.5 0.349";
};
new TerrainMaterial()
{
internalName = "sand";
diffuseMap = "art/terrains/Example/sand";
detailMap = "art/terrains/Example/sand_d";
detailSize = "10";
detailDistance = "100";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "200";
normalMap = "art/terrains/Example/sand_n";
};

View file

@ -239,27 +239,26 @@ function sfxCompareProvider( %providerA, %providerB )
case "FMOD":
return 1;
case "XAudio":
if( %providerB !$= "FMOD" )
return 1;
else
return -1;
// Prefer OpenAL over anything but FMOD.
case "OpenAL":
if( %providerB $= "FMOD" )
if( %providerB $= "FMOD" && %providerB !$= "XAudio")
return -1;
else
return 1;
// As long as the XAudio SFX provider still has issues,
// choose stable DSound over it.
// DSound is just about deprecated, so make that one the last fallback
case "DirectSound":
if( %providerB $= "FMOD" || %providerB $= "OpenAL" )
if( %providerB $= "FMOD" || %providerB $= "OpenAL" && %providerB !$= "XAudio")
return -1;
else
return 0;
case "XAudio":
if( %providerB !$= "FMOD" && %providerB !$= "OpenAL" && %providerB !$= "DirectSound" )
return 1;
else
return -1;
default:
return -1;
}

View file

@ -46,6 +46,10 @@ $PostFXManager::Settings::HDR::keyValue = "0.18";
$PostFXManager::Settings::HDR::minLuminace = "0.001";
$PostFXManager::Settings::HDR::whiteCutoff = "1";
$PostFXManager::Settings::LightRays::brightScalar = "0.75";
$PostFXManager::Settings::LightRays::decay = "1.0";
$PostFXManager::Settings::LightRays::density = "0.94";
$PostFXManager::Settings::LightRays::numSamples = "40";
$PostFXManager::Settings::LightRays::weight = "5.65";
$PostFXManager::Settings::SSAO::blurDepthTol = "0.001";
$PostFXManager::Settings::SSAO::blurNormalTol = "0.95";
$PostFXManager::Settings::SSAO::lDepthMax = "2";

View file

@ -1689,12 +1689,56 @@
canSave = "1";
canSaveDynamicFields = "0";
new GuiSliderCtrl(ppOptionsLightRaysBrightScalar) {
new GuiSliderCtrl(ppOptionsLightRaysBrightScalar) {
range = "0 5";
ticks = "1000";
snap = "0";
value = "0.75";
position = "96 96";
position = "96 46";
extent = "264 17";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiSliderBoxProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextCtrl(ppOptionsLightRaysBrightnessScalarLabel) {
text = "Brightness";
maxLength = "1024";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "1";
anchorBottom = "0";
anchorLeft = "1";
anchorRight = "0";
position = "26 48";
extent = "87 15";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiTextProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
tooltip = "Controls how bright the rays and the object casting them are in the scene.";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiSliderCtrl(ppOptionsLightRaysSampleScalar) {
range = "20 512";
ticks = "512";
snap = "0";
value = "40";
position = "96 75";
extent = "264 17";
minExtent = "8 2";
horizSizing = "right";
@ -1708,16 +1752,17 @@
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextCtrl(ppOptionsLightRaysBrightnessScalarLabel) {
text = "Brightness";
maxLength = "1024";
new GuiTextCtrl(ppOptionsLightRaysSampleScalarLabel) {
text = "Samples";
maxLength = "512";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "1";
anchorBottom = "0";
anchorLeft = "1";
anchorRight = "0";
position = "26 98";
position = "26 76";
extent = "87 15";
minExtent = "8 2";
horizSizing = "right";
@ -1726,7 +1771,143 @@
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
tooltip = "Controls how bright the rays and the object casting them are in the scene.";
tooltip = "Controls the number of samples for the shader.";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiSliderCtrl(ppOptionsLightRaysDensityScalar) {
range = "0.01 1";
ticks = "1000";
snap = "0";
value = "0.94";
position = "96 105";
extent = "264 17";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiSliderBoxProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextCtrl(ppOptionsLightRaysDensityScalarLabel) {
text = "Density";
maxLength = "1000";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "1";
anchorBottom = "0";
anchorLeft = "1";
anchorRight = "0";
position = "26 106";
extent = "87 15";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiTextProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
tooltip = "Controls the density of the rays.";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiSliderCtrl(ppOptionsLightRaysWeightScalar) {
range = "0.1 10";
ticks = "1000";
snap = "0";
value = "5.65";
position = "96 135";
extent = "264 17";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiSliderBoxProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextCtrl(ppOptionsLightRaysWeightScalarLabel) {
text = "Weight";
maxLength = "1000";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "1";
anchorBottom = "0";
anchorLeft = "1";
anchorRight = "0";
position = "26 136";
extent = "87 15";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiTextProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
tooltip = "Controls the weight of the rays.";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiSliderCtrl(ppOptionsLightRaysDecayScalar) {
range = "0.01 1";
ticks = "1000";
snap = "0";
value = "1.0";
position = "96 165";
extent = "264 17";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiSliderBoxProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextCtrl(ppOptionsLightRaysDecayScalarLabel) {
text = "Decay";
maxLength = "1000";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "1";
anchorBottom = "0";
anchorLeft = "1";
anchorRight = "0";
position = "26 166";
extent = "87 15";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiTextProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
tooltip = "Controls the decay of the rays.";
hovertime = "1000";
isContainer = "0";
canSave = "1";

View file

@ -301,12 +301,37 @@ function ppOptionsHDREffectsBlueShiftColorBaseColor::onAction(%this)
}
//Light rays Slider Controls
//Light rays Brightness Slider Controls
function ppOptionsLightRaysBrightScalar::onMouseDragged(%this)
{
$LightRayPostFX::brightScalar = %this.value;
%this.ToolTip = "Value : " @ %this.value;
}
//Light rays Number of Samples Slider Control
function ppOptionsLightRaysSampleScalar::onMouseDragged(%this)
{
$LightRayPostFX::numSamples = %this.value;
%this.ToolTip = "Value : " @ %this.value;
}
//Light rays Density Slider Control
function ppOptionsLightRaysDensityScalar::onMouseDragged(%this)
{
$LightRayPostFX::density = %this.value;
%this.ToolTip = "Value : " @ %this.value;
}
//Light rays Weight Slider Control
function ppOptionsLightRaysWeightScalar::onMouseDragged(%this)
{
$LightRayPostFX::weight = %this.value;
%this.ToolTip = "Value : " @ %this.value;
}
//Light rays Decay Slider Control
function ppOptionsLightRaysDecayScalar::onMouseDragged(%this)
{
$LightRayPostFX::decay = %this.value;
%this.ToolTip = "Value : " @ %this.value;
}
function ppOptionsUpdateDOFSettings()
{

View file

@ -186,6 +186,11 @@ function PostFXManager::settingsRefreshLightrays(%this)
ppOptionsEnableLightRays.setValue($PostFXManager::PostFX::EnableLightRays);
ppOptionsLightRaysBrightScalar.setValue($LightRayPostFX::brightScalar);
ppOptionsLightRaysSampleScalar.setValue($LightRayPostFX::numSamples);
ppOptionsLightRaysDensityScalar.setValue($LightRayPostFX::density);
ppOptionsLightRaysWeightScalar.setValue($LightRayPostFX::weight);
ppOptionsLightRaysDecayScalar.setValue($LightRayPostFX::decay);
}
function PostFXManager::settingsRefreshDOF(%this)
@ -280,6 +285,11 @@ function PostFXManager::settingsApplyFromPreset(%this)
//Light rays settings
$LightRayPostFX::brightScalar = $PostFXManager::Settings::LightRays::brightScalar;
$LightRayPostFX::numSamples = $PostFXManager::Settings::LightRays::numSamples;
$LightRayPostFX::density = $PostFXManager::Settings::LightRays::density;
$LightRayPostFX::weight = $PostFXManager::Settings::LightRays::weight;
$LightRayPostFX::decay = $PostFXManager::Settings::LightRays::decay;
//DOF settings
$DOFPostFx::EnableAutoFocus = $PostFXManager::Settings::DOF::EnableAutoFocus;
$DOFPostFx::BlurMin = $PostFXManager::Settings::DOF::BlurMin;
@ -357,6 +367,11 @@ function PostFXManager::settingsApplyLightRays(%this)
{
$PostFXManager::Settings::LightRays::brightScalar = $LightRayPostFX::brightScalar;
$PostFXManager::Settings::LightRays::numSamples = $LightRayPostFX::numSamples;
$PostFXManager::Settings::LightRays::density = $LightRayPostFX::density;
$PostFXManager::Settings::LightRays::weight = $LightRayPostFX::weight;
$PostFXManager::Settings::LightRays::decay = $LightRayPostFX::decay;
postVerbose("% - PostFX Manager - Settings Saved - Light Rays");
}

View file

@ -654,7 +654,6 @@
bitmap = "tools/gui/images/delete";
};
};
};
};
new GuiRolloutCtrl(advancedTextureMapsRollout) {
@ -1483,6 +1482,482 @@
};
};
};
new GuiRolloutCtrl() {
class = "BehaviorQuickEditRollout";
superclass = LBQuickEditRollout;
Profile = "GuiRolloutProfile";
HorizSizing = "width";
VertSizing = "bottom";
Position = "0 0";
Extent = "195 0";
Caption = "Accumulation Properties";
Margin = "-1 0 0 0";
DragSizable = false;
container = true;
parentRollout = %this.rollout;
object = %behavior;
new GuiStackControl() {
StackingType = "Vertical";
HorizStacking = "Left to Right";
VertStacking = "Top to Bottom";
Padding = "0";
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "1";
Profile = "GuiDefaultProfile";
HorizSizing = "width";
VertSizing = "bottom";
Position = "1 3";
Extent = "195 16";
MinExtent = "16 16";
canSave = "1";
isDecoy = "0";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
new GuiContainer(){ // enable/disable
profile="GuiTransparentProfile";
isContainer = "1";
position = "0 0";
Extent = "195 24";
HorizSizing = "width";
new GuiCheckBoxCtrl() {
canSaveDynamicFields = "0";
internalName = "accuCheckbox";
Enabled = "1";
isContainer = "0";
Profile = "ToolsGuiCheckBoxProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "8 7";
Extent = "57 16";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "MaterialEditorGui.updateAccuCheckbox($ThisControl.getValue());";
tooltipprofile = "ToolsGuiDefaultProfile";
ToolTip = "Enables the use of Pixel Specular for this layer.";
hovertime = "1000";
text = "Enable";
groupNum = "-1";
buttonType = "ToggleButton";
useMouseEvents = "0";
useInactiveState = "0";
};
};
new GuiContainer(){ // scale
profile="GuiTransparentProfile";
isContainer = "1";
position = "0 0";
Extent = "195 24";
HorizSizing = "width";
new GuiTextCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "GuiTextRightProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "8 3";
Extent = "54 16";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Scale";
maxLength = "1024";
};
new GuiControl() {
class = "AggregateControl";
position = "70 3";
Extent = "96 20";
new GuiSliderCtrl() {
canSaveDynamicFields = "0";
internalName = "accuScaleSlider";
Enabled = "1";
isContainer = "0";
Profile = "GuiSliderProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 2";
Extent = "61 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "MaterialEditorGui.updateActiveMaterial(\"accuScale[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuScale[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
tooltipprofile = "GuiDefaultProfile";
ToolTip = "Sets the scale of the accu map.";
hovertime = "1000";
range = "0.03125 32";
ticks = "0";
value = "1";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
internalName = "accuScaleTextEdit";
Enabled = "1";
isContainer = "0";
Profile = "GuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "64 0";
Extent = "29 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuScale[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
hovertime = "1000";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "1";
maxLength = "3";
};
};
};
new GuiContainer(){ // direction
profile="GuiTransparentProfile";
isContainer = "1";
position = "0 0";
Extent = "195 24";
HorizSizing = "width";
new GuiTextCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "GuiTextRightProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "8 3";
Extent = "54 16";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Direction";
maxLength = "1024";
};
new GuiControl() {
class = "AggregateControl";
position = "70 3";
Extent = "96 20";
new GuiSliderCtrl() {
canSaveDynamicFields = "0";
internalName = "accuDirectionSlider";
Enabled = "1";
isContainer = "0";
Profile = "GuiSliderProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 2";
Extent = "61 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "MaterialEditorGui.updateActiveMaterial(\"accuDirection[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuDirection[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
tooltipprofile = "GuiDefaultProfile";
ToolTip = "Sets the direction of the accu map.";
hovertime = "1000";
range = "-1 1";
ticks = "0";
value = "-1";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
internalName = "accuDirectionTextEdit";
Enabled = "1";
isContainer = "0";
Profile = "GuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "64 0";
Extent = "29 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuDirection[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
hovertime = "1000";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "-1";
maxLength = "3";
};
};
};
new GuiContainer(){ // strength
profile="GuiTransparentProfile";
isContainer = "1";
position = "0 0";
Extent = "195 24";
HorizSizing = "width";
new GuiTextCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "GuiTextRightProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "8 3";
Extent = "54 16";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Strength";
maxLength = "1024";
};
new GuiControl() {
class = "AggregateControl";
position = "70 3";
Extent = "96 20";
new GuiSliderCtrl() {
canSaveDynamicFields = "0";
internalName = "accuStrengthSlider";
Enabled = "1";
isContainer = "0";
Profile = "GuiSliderProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 2";
Extent = "61 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "MaterialEditorGui.updateActiveMaterial(\"accuStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
tooltipprofile = "GuiDefaultProfile";
ToolTip = "Sets the strength of the accu map.";
hovertime = "1000";
range = "0 1";
ticks = "0";
value = "0.6";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
internalName = "accuStrengthTextEdit";
Enabled = "1";
isContainer = "0";
Profile = "GuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "64 0";
Extent = "29 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
hovertime = "1000";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "0.6";
maxLength = "3";
};
};
};
new GuiContainer(){ // coverage
profile="GuiTransparentProfile";
isContainer = "1";
position = "0 0";
Extent = "195 24";
HorizSizing = "width";
new GuiTextCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "GuiTextRightProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "8 3";
Extent = "54 16";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Coverage";
maxLength = "1024";
};
new GuiControl() {
class = "AggregateControl";
position = "70 3";
Extent = "96 20";
new GuiSliderCtrl() {
canSaveDynamicFields = "0";
internalName = "accuCoverageSlider";
Enabled = "1";
isContainer = "0";
Profile = "GuiSliderProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 2";
Extent = "61 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "MaterialEditorGui.updateActiveMaterial(\"accuCoverage[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuCoverage[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
tooltipprofile = "GuiDefaultProfile";
ToolTip = "Sets the coverage of the accu map.";
hovertime = "1000";
range = "0 2";
ticks = "0";
value = "1";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
internalName = "accuCoverageTextEdit";
Enabled = "1";
isContainer = "0";
Profile = "GuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "64 0";
Extent = "29 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuCoverage[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
hovertime = "1000";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "1";
maxLength = "3";
};
};
};
new GuiContainer(){ // specular
profile="GuiTransparentProfile";
isContainer = "1";
position = "0 0";
Extent = "195 24";
HorizSizing = "width";
new GuiTextCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "GuiTextRightProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "8 3";
Extent = "54 16";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Specular scale";
maxLength = "1024";
};
new GuiControl() {
class = "AggregateControl";
position = "70 3";
Extent = "96 20";
new GuiSliderCtrl() {
canSaveDynamicFields = "0";
internalName = "accuSpecularSlider";
Enabled = "1";
isContainer = "0";
Profile = "GuiSliderProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 2";
Extent = "61 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "MaterialEditorGui.updateActiveMaterial(\"accuSpecular[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuSpecular[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
tooltipprofile = "GuiDefaultProfile";
ToolTip = "Sets the specular scale over the accu map.";
hovertime = "1000";
range = "0 2";
ticks = "0";
value = "1";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
internalName = "accuSpecularTextEdit";
Enabled = "1";
isContainer = "0";
Profile = "GuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "64 0";
Extent = "29 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuSpecular[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
hovertime = "1000";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "1";
maxLength = "3";
};
};
};
};
};
new GuiRolloutCtrl() {
class = "BehaviorQuickEditRollout";
superclass = LBQuickEditRollout;

View file

@ -886,6 +886,17 @@ function MaterialEditorGui::guiSync( %this, %material )
MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap( (%material).specularMap[%layer] );
}
MaterialEditorPropertiesWindow-->accuScaleTextEdit.setText((%material).accuScale[%layer]);
MaterialEditorPropertiesWindow-->accuScaleTextEdit.setText((%material).accuScale[%layer]);
MaterialEditorPropertiesWindow-->accuDirectionTextEdit.setText((%material).accuDirection[%layer]);
MaterialEditorPropertiesWindow-->accuDirectionTextEdit.setText((%material).accuDirection[%layer]);
MaterialEditorPropertiesWindow-->accuStrengthTextEdit.setText((%material).accuStrength[%layer]);
MaterialEditorPropertiesWindow-->accuStrengthTextEdit.setText((%material).accuStrength[%layer]);
MaterialEditorPropertiesWindow-->accuCoverageTextEdit.setText((%material).accuCoverage[%layer]);
MaterialEditorPropertiesWindow-->accuCoverageTextEdit.setText((%material).accuCoverage[%layer]);
MaterialEditorPropertiesWindow-->accuSpecularTextEdit.setText((%material).accuSpecular[%layer]);
MaterialEditorPropertiesWindow-->accuSpecularTextEdit.setText((%material).accuSpecular[%layer]);
MaterialEditorPropertiesWindow-->detailScaleTextEdit.setText( getWord((%material).detailScale[%layer], 0) );
MaterialEditorPropertiesWindow-->detailNormalStrengthTextEdit.setText( getWord((%material).detailNormalMapStrength[%layer], 0) );
@ -966,6 +977,9 @@ function MaterialEditorGui::guiSync( %this, %material )
MaterialEditorPropertiesWindow-->SequenceSliderFPS.setValue( (%material).sequenceFramePerSec[%layer] );
MaterialEditorPropertiesWindow-->SequenceSliderSSS.setValue( %numFrames );
// Accumulation
MaterialEditorPropertiesWindow-->accuCheckbox.setValue((%material).accuEnabled[%layer]);
%this.preventUndo = false;
}
@ -2249,3 +2263,10 @@ function MaterialEditorMapThumbnail::onRightClick( %this )
%popup.showPopup( Canvas );
}
// Accumulation
function MaterialEditorGui::updateAccuCheckbox(%this, %value)
{
MaterialEditorGui.updateActiveMaterial("accuEnabled[" @ MaterialEditorGui.currentLayer @ "]", %value);
MaterialEditorGui.guiSync( materialEd_previewMaterial );
}

View file

@ -442,7 +442,7 @@ $PE_guielement_ext_colorpicker = "18 18";
text = "";
};
};
new GuiControl(){ // Spacer ----------------------------
isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
new GuiBitmapCtrl(){
@ -543,6 +543,33 @@ $PE_guielement_ext_colorpicker = "18 18";
altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue() );";
};
};
new GuiControl(){ // Particle glow
isContainer = "1";
HorizSizing = "width";
VertSizing = "bottom";
Position = $PE_guielement_pos_single_container ;
Extent = $PE_guielement_ext_single_container ;
new GuiTextCtrl() {
Profile = "ToolsGuiTextProfile";
HorizSizing = "width";
VertSizing = "bottom";
position = $PE_guielement_pos_name;
Extent = $PE_guielement_ext_checkbox_name;
text = "Glow";
};
new GuiCheckBoxCtrl() {
internalName = "PEE_glow";
Profile = "ToolsGuiCheckBoxProfile";
HorizSizing = "left";
VertSizing = "bottom";
position = $PE_guielement_pos_checkbox;
Extent = $PE_guielement_ext_checkbox;
Command = "PE_EmitterEditor.updateEmitter( \"glow\", $ThisControl.getValue());";
text = "";
};
};
};// end stack
}; // end "basic" rollout
new GuiRolloutCtrl() {

View file

@ -100,6 +100,8 @@ function PE_EmitterEditor::guiSync( %this )
PE_EmitterEditor-->PEE_reverseOrder.setValue( %data.reverseOrder );
PE_EmitterEditor-->PEE_useEmitterSizes.setValue( %data.useEmitterSizes );
PE_EmitterEditor-->PEE_useEmitterColors.setValue( %data.useEmitterColors );
PE_EmitterEditor-->PEE_glow.setValue( %data.glow );
// Sync up particle selectors.

View file

@ -210,7 +210,7 @@
new GuiBitmapCtrl() {
Enabled = "1";
Profile = "ToolsGuiDefaultProfile";
position = "250 3";
position = "270 3";
Extent = "2 26";
MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png";
@ -222,7 +222,7 @@
Profile = "ToolsGuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "242 5";
Position = "262 5";
Extent = "256 50";
MinExtent = "8 2";
canSave = "1";
@ -370,7 +370,7 @@
new GuiBitmapCtrl() {
Enabled = "1";
Profile = "ToolsGuiDefaultProfile";
position = "495 3";
position = "525 3";
Extent = "2 26";
MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png";
@ -382,7 +382,7 @@
Profile = "ToolsGuiTransparentProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "510 5";
position = "540 5";
Extent = "120 50";
MinExtent = "8 2";
canSave = "1";
@ -454,53 +454,6 @@
bitmap = "tools/gui/images/dropslider";
};
};
new GuiBitmapCtrl() {
Enabled = "1";
Profile = "ToolsGuiDefaultProfile";
position = "618 3";
Extent = "2 26";
MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png";
};
new GuiControl(LerpBlendCheckButtonContainer,EditorGuiGroup) {
position = "628 5";
extent = "70 50";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "ToolsGuiTransparentProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "1";
canSave = "1";
canSaveDynamicFields = "0";
new GuiCheckBoxCtrl() {
text = " LerpBlend";
groupNum = "-1";
buttonType = "ToggleButton";
useMouseEvents = "0";
position = "0 2";
extent = "140 18";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiCheckBoxProfile";
visible = "1";
active = "1";
command = "ETerrainEditor.toggleBlendType($ThisControl);";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "LerpBlendCheckBox";
canSave = "1";
canSaveDynamicFields = "0";
};
};
};
};
//--- OBJECT WRITE END ---
@ -681,3 +634,4 @@ new GuiMouseEventCtrl(PaintBrushSoftnessSliderCtrlContainer,EditorGuiGroup) {
value = "0";
};
};

View file

@ -20,8 +20,8 @@
HorizSizing = "center";
VertSizing = "center";
position = "221 151";
Extent = "394 452";
MinExtent = "358 452";
Extent = "394 432";
MinExtent = "358 432";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
@ -106,7 +106,7 @@
HorizSizing = "left";
VertSizing = "height";
position = "202 26";
Extent = "185 383";
Extent = "185 363";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -439,7 +439,7 @@
HorizSizing = "width";
VertSizing = "bottom";
position = "6 295";
Extent = "185 80";
Extent = "185 50";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -621,78 +621,6 @@
sinkAllKeyEvents = "0";
passwordMask = "*";
};
new GuiSliderCtrl(TerrainMaterialDlgBlendDepthSlider) {
range = "0.01 0.99";
ticks = "0";
snap = "0";
value = "0.5";
position = "39 61";
extent = "70 14";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiSliderProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "blendDepthSliderCtrl";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextCtrl() {
text = "Blend Depth";
maxLength = "1024";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "1";
anchorBottom = "0";
anchorLeft = "1";
anchorRight = "0";
position = "115 61";
extent = "58 15";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiTextProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "1";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextEditCtrl(TerrainMaterialDlgBlendDepthTextEdit) {
historySize = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
password = "0";
passwordMask = "*";
text = "0.3";
maxLength = "1024";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "0";
anchorBottom = "0";
anchorLeft = "0";
anchorRight = "0";
position = "1 59";
extent = "35 18";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "ToolsGuiTextEditProfile";
visible = "1";
active = "1";
tooltipProfile = "ToolsGuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "blendDepthTextEditCtrl";
canSave = "1";
canSaveDynamicFields = "0";
};
};
new GuiBitmapCtrl() {
@ -1332,7 +1260,7 @@
HorizSizing = "width";
VertSizing = "height";
position = "6 42";
Extent = "189 393";
Extent = "189 373";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -1346,7 +1274,7 @@
HorizSizing = "width";
VertSizing = "height";
position = "0 0";
Extent = "189 394";
Extent = "189 374";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -1405,7 +1333,7 @@
Profile = "ToolsGuiButtonProfile";
HorizSizing = "left";
VertSizing = "top";
position = "202 414";
position = "202 394";
Extent = "98 22";
MinExtent = "8 2";
canSave = "1";
@ -1424,7 +1352,7 @@
Profile = "ToolsGuiButtonProfile";
HorizSizing = "left";
VertSizing = "top";
position = "307 414";
position = "307 394";
Extent = "80 22";
MinExtent = "8 2";
canSave = "1";
@ -1444,7 +1372,7 @@
HorizSizing = "left";
VertSizing = "height";
position = "199 23";
Extent = "190 287";
Extent = "190 267";
isContainer = true;
Visible = false;
bitmap = "tools/gui/images/inactive-overlay";
@ -1461,4 +1389,4 @@
};
};
};
//--- OBJECT WRITE END ---
//--- OBJECT WRITE END ---

View file

@ -83,6 +83,7 @@ function EWCreatorWindow::init( %this )
%this.registerMissionObject( "SpawnSphere", "Observer Spawn Sphere", "ObserverDropPoint" );
%this.registerMissionObject( "SFXSpace", "Sound Space" );
%this.registerMissionObject( "OcclusionVolume", "Occlusion Volume" );
%this.registerMissionObject( "AccumulationVolume", "Accumulation Volume" );
%this.registerMissionObject("NavMesh", "Navigation mesh");
%this.registerMissionObject("NavPath", "Path");

View file

@ -222,8 +222,6 @@ function EPainter::setup( %this, %matIndex )
ETerrainEditor.setAction( ETerrainEditor.currentAction );
EditorGuiStatusBar.setInfo(ETerrainEditor.currentActionDesc);
ETerrainEditor.renderVertexSelection = true;
EWTerrainPainterToolbar-->LerpBlendCheckBox.setValue($Pref::Terrain::LerpBlend);
}
function onNeedRelight()
@ -259,11 +257,6 @@ function TerrainEditor::toggleBrushType( %this, %brush )
%this.setBrushType( %brush.internalName );
}
function TerrainEditor::toggleBlendType( %this, %check )
{
$Pref::Terrain::LerpBlend = %check.getValue();
}
function TerrainEditor::offsetBrush(%this, %x, %y)
{
%curPos = %this.getBrushPos();

Some files were not shown because too many files have changed in this diff Show more