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

View file

@ -114,6 +114,7 @@ class ParticleEmitterData : public GameBaseData
GFXTexHandle textureHandle; ///< Emitter texture handle from txrName GFXTexHandle textureHandle; ///< Emitter texture handle from txrName
bool highResOnly; ///< This particle system should not use the mixed-resolution particle rendering bool highResOnly; ///< This particle system should not use the mixed-resolution particle rendering
bool renderReflection; ///< Enables this emitter to render into reflection passes. bool renderReflection; ///< Enables this emitter to render into reflection passes.
bool glow; ///< Renders this emitter into the glow buffer.
bool reload(); 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 // Weight by field of view, objects directly in front
// will be weighted 1, objects behind will be 0 // will be weighted 1, objects behind will be 0
F32 dot = mDot(pos,camInfo->orientation); F32 dot = mDot(pos,camInfo->orientation);
bool inFov = dot > camInfo->cosFov;
bool inFov = dot > camInfo->cosFov * 1.5f;
F32 wFov = inFov? 1.0f: 0; F32 wFov = inFov? 1.0f: 0;
// Weight by linear velocity parallel to the viewing plane // 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. // Weight by interest.
F32 wInterest; F32 wInterest;
if (getTypeMask() & PlayerObjectType) if (getTypeMask() & (PlayerObjectType || VehicleObjectType ))
wInterest = 0.75f; wInterest = 0.75f;
else if (getTypeMask() & ProjectileObjectType) else if (getTypeMask() & ProjectileObjectType)
{ {

View file

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

View file

@ -226,6 +226,8 @@ GameConnection::GameConnection()
mAddYawToAbsRot = false; mAddYawToAbsRot = false;
mAddPitchToAbsRot = false; mAddPitchToAbsRot = false;
mVisibleGhostDistance = 0.0f;
clearDisplayDevice(); clearDisplayDevice();
} }
@ -240,6 +242,16 @@ GameConnection::~GameConnection()
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void GameConnection::setVisibleGhostDistance(F32 dist)
{
mVisibleGhostDistance = dist;
}
F32 GameConnection::getVisibleGhostDistance()
{
return mVisibleGhostDistance;
}
bool GameConnection::canRemoteCreate() bool GameConnection::canRemoteCreate()
{ {
return true; return true;
@ -2199,3 +2211,21 @@ DefineEngineMethod( GameConnection, getControlSchemeAbsoluteRotation, bool, (),,
{ {
return object->getControlSchemeAbsoluteRotation(); 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 U32 mMissionCRC; // crc of the current mission file from the server
F32 mVisibleGhostDistance;
private: private:
U32 mLastControlRequestTime; U32 mLastControlRequestTime;
S32 mDataBlockModifiedKey; S32 mDataBlockModifiedKey;
@ -155,6 +157,9 @@ public:
bool canRemoteCreate(); bool canRemoteCreate();
void setVisibleGhostDistance(F32 dist);
F32 getVisibleGhostDistance();
private: private:
/// @name Connection State /// @name Connection State
/// This data is set with setConnectArgs() and setJoinPassword(), and /// This data is set with setConnectArgs() and setJoinPassword(), and

View file

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

View file

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

View file

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

View file

@ -207,10 +207,6 @@ struct ServerFilter
Favorites = 3, Favorites = 3,
}; };
Type type;
char* gameType;
char* missionType;
enum // Query Flags enum // Query Flags
{ {
OnlineQuery = 0, // Authenticated with master OnlineQuery = 0, // Authenticated with master
@ -227,16 +223,20 @@ struct ServerFilter
NotXenon = BIT(6) NotXenon = BIT(6)
}; };
//Rearranging the fields according to their sizes
char* gameType;
char* missionType;
U8 queryFlags; U8 queryFlags;
U8 minPlayers; U8 minPlayers;
U8 maxPlayers; U8 maxPlayers;
U8 maxBots; U8 maxBots;
U8 filterFlags;
U8 buddyCount;
U16 minCPU;
U32 regionMask; U32 regionMask;
U32 maxPing; U32 maxPing;
U8 filterFlags;
U16 minCPU;
U8 buddyCount;
U32* buddyList; U32* buddyList;
Type type;
ServerFilter() ServerFilter()
{ {

View file

@ -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 bool doResetValueStack = !gEvalState.mResetLocked;
// either nothing or argv[] which we just copied gEvalState.mResetLocked = true;
CSTK.resetFrame();
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 // Grab the state of the telenet debugger here once
// so that the push and pop frames are always balanced. // so that the push and pop frames are always balanced.
@ -2219,15 +2226,7 @@ execFinished:
Con::printf("%s", traceBuffer); Con::printf("%s", traceBuffer);
} }
} }
else
{
delete[] globalStrings;
globalStringsMaxLen = 0;
delete[] globalFloats;
globalStrings = NULL;
globalFloats = NULL;
}
smCurrentCodeBlock = saveCodeBlock; smCurrentCodeBlock = saveCodeBlock;
if(saveCodeBlock && saveCodeBlock->name) if(saveCodeBlock && saveCodeBlock->name)
{ {
@ -2235,6 +2234,13 @@ execFinished:
Con::gCurrentRoot = saveCodeBlock->modPath; 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(); decRefCount();
#ifdef TORQUE_DEBUG #ifdef TORQUE_DEBUG

View file

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

View file

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

View file

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

View file

@ -33,8 +33,38 @@
#include "platform/threads/mutex.h" #include "platform/threads/mutex.h"
#endif #endif
#include "torqueConfig.h"
class SimObject; 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 /// Map of names to SimObjects
/// ///
@ -42,6 +72,7 @@ class SimObject;
/// for fast removal of an object given object* /// for fast removal of an object given object*
class SimNameDictionary class SimNameDictionary
{ {
#ifndef USE_NEW_SIMDICTIONARY
enum enum
{ {
DefaultTableSize = 29 DefaultTableSize = 29
@ -50,6 +81,9 @@ class SimNameDictionary
SimObject **hashTable; // hash the pointers of the names... SimObject **hashTable; // hash the pointers of the names...
S32 hashTableSize; S32 hashTableSize;
S32 hashEntryCount; S32 hashEntryCount;
#else
StringDictDef root;
#endif
void *mutex; void *mutex;
@ -64,6 +98,7 @@ public:
class SimManagerNameDictionary class SimManagerNameDictionary
{ {
#ifndef USE_NEW_SIMDICTIONARY
enum enum
{ {
DefaultTableSize = 29 DefaultTableSize = 29
@ -72,6 +107,9 @@ class SimManagerNameDictionary
SimObject **hashTable; // hash the pointers of the names... SimObject **hashTable; // hash the pointers of the names...
S32 hashTableSize; S32 hashTableSize;
S32 hashEntryCount; S32 hashEntryCount;
#else
StringDictDef root;
#endif
void *mutex; void *mutex;
@ -91,12 +129,16 @@ public:
/// for fast removal of an object given object* /// for fast removal of an object given object*
class SimIdDictionary class SimIdDictionary
{ {
#ifndef USE_NEW_SIMDICTIONARY
enum enum
{ {
DefaultTableSize = 4096, DefaultTableSize = 4096,
TableBitMask = 4095 TableBitMask = 4095
}; };
SimObject *table[DefaultTableSize]; SimObject *table[DefaultTableSize];
#else
SimObjectIdDictDef root;
#endif
void *mutex; void *mutex;

View file

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

View file

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

View file

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

View file

@ -143,7 +143,7 @@ public:
{ {
glGenBuffers(1, &mBufferName); glGenBuffers(1, &mBufferName);
PRESERVE_VERTEX_BUFFER(); PRESERVE_BUFFER( mBinding );
glBindBuffer(mBinding, mBufferName); glBindBuffer(mBinding, mBufferName);
const U32 cSizeInMB = 10; const U32 cSizeInMB = 10;
@ -195,11 +195,11 @@ public:
} }
else if( GFXGL->glUseMap() ) else if( GFXGL->glUseMap() )
{ {
PRESERVE_VERTEX_BUFFER(); PRESERVE_BUFFER( mBinding );
glBindBuffer(GL_ARRAY_BUFFER, mBufferName); glBindBuffer(mBinding, mBufferName);
const GLbitfield access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; 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 else
{ {
@ -224,15 +224,15 @@ public:
} }
else if( GFXGL->glUseMap() ) else if( GFXGL->glUseMap() )
{ {
PRESERVE_VERTEX_BUFFER(); PRESERVE_BUFFER( mBinding );
glBindBuffer(GL_ARRAY_BUFFER, mBufferName); glBindBuffer(mBinding, mBufferName);
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(mBinding);
} }
else else
{ {
PRESERVE_VERTEX_BUFFER(); PRESERVE_BUFFER( mBinding );
glBindBuffer(GL_ARRAY_BUFFER, mBufferName); glBindBuffer(mBinding, mBufferName);
glBufferSubData( mBinding, _getBufferData.mOffset, _getBufferData.mSize, mFrameAllocator.getlockedPtr() ); 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() \ #define PRESERVE_INDEX_BUFFER() \
GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (GL_ELEMENT_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER_BINDING, (GFXGLPreserveInteger::BindFn)glBindBuffer) 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. /// 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. /// Helper macro to preserve the current 1D texture binding.

View file

@ -330,6 +330,58 @@ void DeferredBumpFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
output = meta; output = meta;
return; 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] || else if ( fd.materialFeatures[MFT_NormalsOut] ||
fd.features[MFT_ForwardShading] || fd.features[MFT_ForwardShading] ||
!fd.features[MFT_RTLighting] ) !fd.features[MFT_RTLighting] )
@ -398,7 +450,20 @@ void DeferredBumpFeatGLSL::setTexData( Material::StageData &stageDat,
return; 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_PrePassConditioner] ||
fd.features[MFT_PixSpecular] ) ) fd.features[MFT_PixSpecular] ) )
{ {
@ -481,6 +546,14 @@ void DeferredPixelSpecularGLSL::processPix( Vector<ShaderComponent*> &component
AssertFatal( lightInfoSamp && d_specular && d_NL_Att, AssertFatal( lightInfoSamp && d_specular && d_NL_Att,
"DeferredPixelSpecularGLSL::processPix - Something hosed the deferred features!" ); "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) // (a^m)^n = a^(m*n)
meta->addStatement( new GenOp( " @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n", meta->addStatement( new GenOp( " @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n",
specDecl, d_specular, specPow, specStrength ) ); specDecl, d_specular, specPow, specStrength ) );

View file

@ -330,6 +330,57 @@ void DeferredBumpFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
output = meta; output = meta;
return; 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] || else if ( fd.materialFeatures[MFT_NormalsOut] ||
fd.features[MFT_ForwardShading] || fd.features[MFT_ForwardShading] ||
!fd.features[MFT_RTLighting] ) !fd.features[MFT_RTLighting] )
@ -398,7 +449,20 @@ void DeferredBumpFeatHLSL::setTexData( Material::StageData &stageDat,
return; 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_PrePassConditioner] ||
fd.features[MFT_PixSpecular] ) ) fd.features[MFT_PixSpecular] ) )
{ {
@ -481,6 +545,15 @@ void DeferredPixelSpecularHLSL::processPix( Vector<ShaderComponent*> &component
AssertFatal( lightInfoSamp && d_specular && d_NL_Att, AssertFatal( lightInfoSamp && d_specular && d_NL_Att,
"DeferredPixelSpecularHLSL::processPix - Something hosed the deferred features!" ); "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) // (a^m)^n = a^(m*n)
meta->addStatement( new GenOp( " @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n", meta->addStatement( new GenOp( " @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n",
specDecl, d_specular, specPow, specStrength ) ); specDecl, d_specular, specPow, specStrength ) );

View file

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

View file

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

View file

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

View file

@ -35,6 +35,7 @@
#include "sfx/sfxTrack.h" #include "sfx/sfxTrack.h"
#include "sfx/sfxTypes.h" #include "sfx/sfxTypes.h"
#include "core/util/safeDelete.h" #include "core/util/safeDelete.h"
#include "T3D/accumulationVolume.h"
IMPLEMENT_CONOBJECT( Material ); IMPLEMENT_CONOBJECT( Material );
@ -120,6 +121,13 @@ Material::Material()
mSpecularStrength[i] = 1.0f; mSpecularStrength[i] = 1.0f;
mPixelSpecular[i] = false; 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; mParallaxScale[i] = 0.0f;
mVertLit[i] = false; 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 " "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." ); "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, 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. " "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. " "If this texture contains alpha information, the alpha channel of the texture will be used as the gloss map. "
@ -671,3 +697,17 @@ DefineConsoleMethod( Material, setAutoGenerated, void, (bool isAutoGenerated), ,
{ {
object->setAutoGenerated(isAutoGenerated); 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, DynamicLightMask,
NormalizeCube, NormalizeCube,
TexTarget, TexTarget,
AccuMap,
}; };
enum BlendOp enum BlendOp
@ -198,6 +199,12 @@ public:
// Data // Data
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
FileName mDiffuseMapFilename[MAX_STAGES]; 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 mOverlayMapFilename[MAX_STAGES];
FileName mLightMapFilename[MAX_STAGES]; FileName mLightMapFilename[MAX_STAGES];
FileName mToneMapFilename[MAX_STAGES]; FileName mToneMapFilename[MAX_STAGES];
@ -371,6 +378,9 @@ public:
// //
static void initPersistFields(); static void initPersistFields();
// Accumulation
static bool _setAccuEnabled( void *object, const char *index, const char *data );
DECLARE_CONOBJECT(Material); DECLARE_CONOBJECT(Material);
protected: 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_Parallax, MFG_PreTexture, 2.0f, true );
ImplementFeatureType( MFT_DiffuseVertColor, MFG_PreTexture, 3.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_DiffuseMap, MFG_Texture, 2.0f, true );
ImplementFeatureType( MFT_OverlayMap, MFG_Texture, 3.0f, true ); ImplementFeatureType( MFT_OverlayMap, MFG_Texture, 3.0f, true );
ImplementFeatureType( MFT_DetailMap, MFG_Texture, 4.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_NormalMap, MFG_Texture, 9.0f, true );
ImplementFeatureType( MFT_DetailNormalMap, MFG_Texture, 10.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_RTLighting, MFG_Lighting, 2.0f, true );
ImplementFeatureType( MFT_SubSurface, MFG_Lighting, 3.0f, true ); ImplementFeatureType( MFT_SubSurface, MFG_Lighting, 3.0f, true );
ImplementFeatureType( MFT_LightMap, MFG_Lighting, 4.0f, true ); ImplementFeatureType( MFT_LightMap, MFG_Lighting, 4.0f, true );

View file

@ -95,6 +95,13 @@ DeclareFeatureType( MFT_DetailMap );
DeclareFeatureType( MFT_DiffuseColor ); DeclareFeatureType( MFT_DiffuseColor );
DeclareFeatureType( MFT_DetailNormalMap ); 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. /// This feature enables vertex coloring for the diffuse channel.
DeclareFeatureType( MFT_DiffuseVertColor ); DeclareFeatureType( MFT_DiffuseVertColor );

View file

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

View file

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

View file

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

View file

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

View file

@ -55,6 +55,11 @@ void ShaderConstHandles::init( GFXShader *shader, CustomMaterial* mat /*=NULL*/
mSpecularColorSC = shader->getShaderConstHandle(ShaderGenVars::specularColor); mSpecularColorSC = shader->getShaderConstHandle(ShaderGenVars::specularColor);
mSpecularPowerSC = shader->getShaderConstHandle(ShaderGenVars::specularPower); mSpecularPowerSC = shader->getShaderConstHandle(ShaderGenVars::specularPower);
mSpecularStrengthSC = shader->getShaderConstHandle(ShaderGenVars::specularStrength); 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"); mParallaxInfoSC = shader->getShaderConstHandle("$parallaxInfo");
mFogDataSC = shader->getShaderConstHandle(ShaderGenVars::fogData); mFogDataSC = shader->getShaderConstHandle(ShaderGenVars::fogData);
mFogColorSC = shader->getShaderConstHandle(ShaderGenVars::fogColor); mFogColorSC = shader->getShaderConstHandle(ShaderGenVars::fogColor);
@ -423,6 +428,34 @@ void ProcessedShaderMaterial::_determineFeatures( U32 stageNum,
fd.features.addFeature( MFT_GlossMap ); 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 // Without a base texture use the diffuse color
// feature to ensure some sort of output. // feature to ensure some sort of output.
if (!fd.features[MFT_DiffuseMap]) if (!fd.features[MFT_DiffuseMap])
@ -810,6 +843,13 @@ void ProcessedShaderMaterial::setTextureStages( SceneRenderState *state, const S
GFX->setTexture( i, sgData.backBuffTex ); GFX->setTexture( i, sgData.backBuffTex );
break; break;
case Material::AccuMap:
if ( sgData.accuTex )
GFX->setTexture( i, sgData.accuTex );
else
GFX->setTexture( i, GFXTexHandle::ZERO );
break;
case Material::TexTarget: case Material::TexTarget:
{ {
texTarget = rpd->mTexSlot[i].texTarget; texTarget = rpd->mTexSlot[i].texTarget;
@ -1137,6 +1177,17 @@ void ProcessedShaderMaterial::_setShaderConstants(SceneRenderState * state, cons
0.0f, 0.0f ); // TODO: Wrap mode flags? 0.0f, 0.0f ); // TODO: Wrap mode flags?
shaderConsts->setSafe(handles->mBumpAtlasTileSC, atlasTileParams); 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) bool ProcessedShaderMaterial::_hasCubemap(U32 pass)

View file

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

View file

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

View file

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

View file

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

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_SSE) ? CPU_PROP_SSE : 0;
pInfo.properties |= ( properties & BIT_SSE2 ) ? CPU_PROP_SSE2 : 0; pInfo.properties |= ( properties & BIT_SSE2 ) ? CPU_PROP_SSE2 : 0;
pInfo.properties |= (properties & BIT_3DNOW) ? CPU_PROP_3DNOW : 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 on processor family code
switch ((processor >> 8) & 0xf) switch ((processor >> 8) & 0xf)
{ {
@ -223,6 +226,24 @@ void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo,
pInfo.name = StringTable->insert("AMD Athlon"); pInfo.name = StringTable->insert("AMD Athlon");
break; 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: default:
pInfo.type = CPU_AMD_Unknown; pInfo.type = CPU_AMD_Unknown;
pInfo.name = StringTable->insert("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(); HWND hWindow = pWindow->getHWND();
SetMenu(hWindow, hWindowMenu);
DrawMenuBar(hWindow); DrawMenuBar(hWindow);
} }
@ -165,6 +166,7 @@ void MenuBar::removeFromCanvas()
} }
HWND hWindow = pWindow->getHWND(); HWND hWindow = pWindow->getHWND();
SetMenu(hWindow, NULL);
DrawMenuBar(hWindow); DrawMenuBar(hWindow);
mCanvas = NULL; mCanvas = NULL;

View file

@ -139,7 +139,7 @@ void Platform::fileToLocalTime(const FileTime & ft, LocalTime * lt)
lt->sec = time->wSecond; lt->sec = time->wSecond;
lt->min = time->wMinute; lt->min = time->wMinute;
lt->hour = time->wHour; lt->hour = time->wHour;
lt->month = time->wMonth; lt->month = time->wMonth - 1;
lt->monthday = time->wDay; lt->monthday = time->wDay;
lt->weekday = time->wDayOfWeek; lt->weekday = time->wDayOfWeek;
lt->year = (time->wYear < 1900) ? 1900 : (time->wYear - 1900); 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.cubemap = ri->cubemap;
data.miscTex = ri->miscTex; data.miscTex = ri->miscTex;
data.reflectTex = ri->reflectTex; data.reflectTex = ri->reflectTex;
data.accuTex = ri->accuTex;
data.lightmap = ri->lightmap; data.lightmap = ri->lightmap;
data.visibility = ri->visibility; data.visibility = ri->visibility;
data.materialHint = ri->materialHint; data.materialHint = ri->materialHint;

View file

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

View file

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

View file

@ -115,6 +115,7 @@ void RenderMeshMgr::render(SceneRenderState * state)
GFXCubemap *lastCubemap = NULL; GFXCubemap *lastCubemap = NULL;
GFXTextureObject *lastReflectTex = NULL; GFXTextureObject *lastReflectTex = NULL;
GFXTextureObject *lastMiscTex = NULL; GFXTextureObject *lastMiscTex = NULL;
GFXTextureObject *lastAccuTex = NULL;
SceneData sgData; SceneData sgData;
sgData.init( state ); sgData.init( state );
@ -225,6 +226,15 @@ void RenderMeshMgr::render(SceneRenderState * state)
dirty = true; 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 ) if ( dirty )
mat->setTextureStages( state, sgData ); mat->setTextureStages( state, sgData );

View file

@ -399,6 +399,82 @@ void RenderParticleMgr::renderInstance(ParticleRenderInst *ri, SceneRenderState
mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mModelViewProjSC, *ri->modelViewProj ); mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mModelViewProjSC, *ri->modelViewProj );
} }
renderParticle(ri, state);
}
else if(ri->systemState == PSS_AwaitingCompositeDraw)
{
OffscreenSystemEntry &systemEntry = mOffscreenSystems[ri->targetIndex];
// If this system has already been composited this frame, skip it
if(systemEntry.drawnThisFrame)
return;
// Non-target render, composite the particle system back into the scene
GFX->setVertexBuffer(mScreenQuadVertBuff);
GFX->setPrimitiveBuffer(mScreenQuadPrimBuff);
// Set up shader constants
mParticleCompositeShaderConsts.mShaderConsts->setSafe( mParticleCompositeShaderConsts.mScreenRect, *((Point4F *)&systemEntry.screenRect) );
// Set offscreen texture
Point4F rtParams;
GFXTextureObject *particleSource = mNamedTarget.getTexture();
GFX->setTexture( mParticleCompositeShaderConsts.mSamplerColorSource->getSamplerRegister(), particleSource );
if(particleSource)
{
ScreenSpace::RenderTargetParameters(particleSource->getSize(), mNamedTarget.getViewport(), rtParams);
mParticleCompositeShaderConsts.mShaderConsts->setSafe( mParticleCompositeShaderConsts.mOffscreenTargetParamsSC, rtParams );
}
// And edges
GFXTextureObject *texObject = mEdgeTarget ? mEdgeTarget->getTexture() : NULL;
GFX->setTexture( mParticleCompositeShaderConsts.mSamplerEdgeSource->getSamplerRegister(), texObject );
if(texObject)
{
ScreenSpace::RenderTargetParameters(texObject->getSize(), mEdgeTarget->getViewport(), rtParams);
mParticleCompositeShaderConsts.mShaderConsts->setSafe( mParticleCompositeShaderConsts.mEdgeTargetParamsSC, rtParams );
}
else
{
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;
return;
}
// Set shader and constant buffer
GFX->setShader( mParticleCompositeShader );
GFX->setShaderConstBuffer( mParticleCompositeShaderConsts.mShaderConsts );
// Draw to stencil buffer only to clear the stencil values
GFX->setStateBlock( mStencilClearSB );
GFX->drawIndexedPrimitive( GFXTriangleStrip, 0, 0, 4, 0, 2 );
// composite particle system back into the scene
GFX->setStateBlock( _getCompositeStateBlock(ri) );
GFX->drawIndexedPrimitive( GFXTriangleStrip, 0, 0, 4, 0, 2 );
// Re-draw the particle systems in high-res, but only to the stenciled
// areas which were enabled via the edge buffer
for( Vector<ParticleRenderInst *>::const_iterator itr = systemEntry.pInstances.begin();
itr != systemEntry.pInstances.end(); itr++ )
{
ParticleRenderInst *pri = *itr;
if(pri->systemState == PSS_AwaitingCompositeDraw)
{
pri->systemState = PSS_AwaitingMixedResDraw;
renderInstance(pri, state);
}
}
// Mark this system as having been composited this frame
systemEntry.drawnThisFrame = true;
}
}
void RenderParticleMgr::renderParticle(ParticleRenderInst* ri, SceneRenderState* state)
{
// We want to turn everything into variation on a pre-multiplied alpha blend // We want to turn everything into variation on a pre-multiplied alpha blend
F32 alphaFactor = 0.0f, alphaScale = 1.0f; F32 alphaFactor = 0.0f, alphaScale = 1.0f;
switch(ri->blendStyle) switch(ri->blendStyle)
@ -458,77 +534,6 @@ void RenderParticleMgr::renderInstance(ParticleRenderInst *ri, SceneRenderState
GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, ri->count * 4, 0, ri->count * 2 ); GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, ri->count * 4, 0, ri->count * 2 );
} }
else if(ri->systemState == PSS_AwaitingCompositeDraw)
{
OffscreenSystemEntry &systemEntry = mOffscreenSystems[ri->targetIndex];
// If this system has already been composited this frame, skip it
if(systemEntry.drawnThisFrame)
return;
// Non-target render, composite the particle system back into the scene
GFX->setVertexBuffer(mScreenQuadVertBuff);
GFX->setPrimitiveBuffer(mScreenQuadPrimBuff);
// Set up shader constants
mParticleCompositeShaderConsts.mShaderConsts->setSafe( mParticleCompositeShaderConsts.mScreenRect, *((Point4F *)&systemEntry.screenRect) );
// Set offscreen texture
Point4F rtParams;
GFXTextureObject *particleSource = mNamedTarget.getTexture();
GFX->setTexture( mParticleCompositeShaderConsts.mSamplerColorSource->getSamplerRegister(), particleSource );
if(particleSource)
{
ScreenSpace::RenderTargetParameters(particleSource->getSize(), mNamedTarget.getViewport(), rtParams);
mParticleCompositeShaderConsts.mShaderConsts->setSafe( mParticleCompositeShaderConsts.mOffscreenTargetParamsSC, rtParams );
}
// And edges
GFXTextureObject *texObject = mEdgeTarget ? mEdgeTarget->getTexture() : NULL;
GFX->setTexture( mParticleCompositeShaderConsts.mSamplerEdgeSource->getSamplerRegister(), texObject );
if(texObject)
{
ScreenSpace::RenderTargetParameters(texObject->getSize(), mEdgeTarget->getViewport(), rtParams);
mParticleCompositeShaderConsts.mShaderConsts->setSafe( mParticleCompositeShaderConsts.mEdgeTargetParamsSC, rtParams );
}
else
{
AssertWarn(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;
return;
}
// Set shader and constant buffer
GFX->setShader( mParticleCompositeShader );
GFX->setShaderConstBuffer( mParticleCompositeShaderConsts.mShaderConsts );
// Draw to stencil buffer only to clear the stencil values
GFX->setStateBlock( mStencilClearSB );
GFX->drawIndexedPrimitive( GFXTriangleStrip, 0, 0, 4, 0, 2 );
// composite particle system back into the scene
GFX->setStateBlock( _getCompositeStateBlock(ri) );
GFX->drawIndexedPrimitive( GFXTriangleStrip, 0, 0, 4, 0, 2 );
// Re-draw the particle systems in high-res, but only to the stenciled
// areas which were enabled via the edge buffer
for( Vector<ParticleRenderInst *>::const_iterator itr = systemEntry.pInstances.begin();
itr != systemEntry.pInstances.end(); itr++ )
{
ParticleRenderInst *pri = *itr;
if(pri->systemState == PSS_AwaitingCompositeDraw)
{
pri->systemState = PSS_AwaitingMixedResDraw;
renderInstance(pri, state);
}
}
// Mark this system as having been composited this frame
systemEntry.drawnThisFrame = true;
}
}
bool RenderParticleMgr::_initShader() bool RenderParticleMgr::_initShader()
{ {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -51,6 +51,10 @@
#include "scene/sceneContainer.h" #include "scene/sceneContainer.h"
#endif #endif
#ifndef _GFXDEVICE_H_
#include "gfx/gfxDevice.h"
#endif
class SceneManager; class SceneManager;
class SceneRenderState; 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 _setFieldRotation( void *object, const char *index, const char *data );
static bool _setFieldScale( 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 _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_ #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" ); cubeVertPos->setType( "vec3" );
LangElement *cubeVertPosDecl = new DecOp( cubeVertPos ); 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" ) ) ); cubeVertPosDecl, cubeTrans, LangElement::find( "position" ) ) );
// cube normal // cube normal
@ -1694,6 +1694,9 @@ void ReflectCubeFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
meta->addStatement( new GenOp( " @ = ( tMul( (@), vec4(@, 0) ) ).xyz;\r\n", meta->addStatement( new GenOp( " @ = ( tMul( (@), vec4(@, 0) ) ).xyz;\r\n",
cubeNormDecl, cubeTrans, inNormal ) ); cubeNormDecl, cubeTrans, inNormal ) );
meta->addStatement( new GenOp( " @ = bool(length(@)) ? normalize(@) : @;\r\n",
cubeNormal, cubeNormal, cubeNormal, cubeNormal ) );
// grab the eye position // grab the eye position
Var *eyePos = (Var*)LangElement::find( "eyePosWorld" ); Var *eyePos = (Var*)LangElement::find( "eyePosWorld" );
if ( !eyePos ) if ( !eyePos )
@ -1703,23 +1706,14 @@ void ReflectCubeFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
eyePos->constSortPos = cspPass; 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 // eye to vert
Var * eyeToVert = new Var; Var * eyeToVert = new Var;
eyeToVert->setName( "eyeToVert" ); eyeToVert->setName( "eyeToVert" );
eyeToVert->setType( "vec3" ); eyeToVert->setType( "vec3" );
LangElement *e2vDecl = new DecOp( eyeToVert ); LangElement *e2vDecl = new DecOp( eyeToVert );
meta->addStatement( new GenOp( " @ = @ - ( @ - @ );\r\n", meta->addStatement( new GenOp( " @ = @ - @;\r\n",
e2vDecl, cubeVertPos, eyePos, cubePos ) ); e2vDecl, cubeVertPos, eyePos ) );
// grab connector texcoord register // grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );

View file

@ -32,6 +32,7 @@
#include "shaderGen/GLSL/paraboloidGLSL.h" #include "shaderGen/GLSL/paraboloidGLSL.h"
#include "materials/materialFeatureTypes.h" #include "materials/materialFeatureTypes.h"
#include "core/module.h" #include "core/module.h"
#include "shaderGen/GLSL/accuFeatureGLSL.h"
static ShaderGen::ShaderGenInitDelegate sInitDelegate; static ShaderGen::ShaderGenInitDelegate sInitDelegate;
@ -62,6 +63,7 @@ void _initShaderGenGLSL( ShaderGen *shaderGen )
FEATUREMGR->registerFeature( MFT_CubeMap, new ReflectCubeFeatGLSL ); FEATUREMGR->registerFeature( MFT_CubeMap, new ReflectCubeFeatGLSL );
FEATUREMGR->registerFeature( MFT_PixSpecular, new PixelSpecularGLSL ); FEATUREMGR->registerFeature( MFT_PixSpecular, new PixelSpecularGLSL );
FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapGLSL ); FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapGLSL );
FEATUREMGR->registerFeature( MFT_AccuMap, new AccuTexFeatGLSL );
FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureGLSL( "Gloss Map" ) ); FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureGLSL( "Gloss Map" ) );
FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureGLSL( "Translucent" ) ); FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureGLSL( "Translucent" ) );
FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatGLSL ); 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" ); cubeVertPos->setType( "float3" );
LangElement *cubeVertPosDecl = new DecOp( cubeVertPos ); 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" ) ) ); cubeVertPosDecl, cubeTrans, LangElement::find( "position" ) ) );
// cube normal // cube normal
@ -1702,23 +1702,14 @@ void ReflectCubeFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
eyePos->constSortPos = cspPass; 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 // eye to vert
Var * eyeToVert = new Var; Var * eyeToVert = new Var;
eyeToVert->setName( "eyeToVert" ); eyeToVert->setName( "eyeToVert" );
eyeToVert->setType( "float3" ); eyeToVert->setType( "float3" );
LangElement *e2vDecl = new DecOp( eyeToVert ); LangElement *e2vDecl = new DecOp( eyeToVert );
meta->addStatement( new GenOp( " @ = @ - ( @ - @ );\r\n", meta->addStatement( new GenOp( " @ = @ - @;\r\n",
e2vDecl, cubeVertPos, eyePos, cubePos ) ); e2vDecl, cubeVertPos, eyePos ) );
// grab connector texcoord register // grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );

View file

@ -32,7 +32,7 @@
#include "shaderGen/HLSL/paraboloidHLSL.h" #include "shaderGen/HLSL/paraboloidHLSL.h"
#include "materials/materialFeatureTypes.h" #include "materials/materialFeatureTypes.h"
#include "core/module.h" #include "core/module.h"
#include "shaderGen/HLSL/accuFeatureHLSL.h"
static ShaderGen::ShaderGenInitDelegate sInitDelegate; static ShaderGen::ShaderGenInitDelegate sInitDelegate;
@ -66,6 +66,7 @@ void _initShaderGenHLSL( ShaderGen *shaderGen )
FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatHLSL ); FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatHLSL );
FEATUREMGR->registerFeature( MFT_Fog, new FogFeatHLSL ); FEATUREMGR->registerFeature( MFT_Fog, new FogFeatHLSL );
FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapHLSL ); FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapHLSL );
FEATUREMGR->registerFeature( MFT_AccuMap, new AccuTexFeatHLSL );
FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureHLSL( "Gloss Map" ) ); FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureHLSL( "Gloss Map" ) );
FEATUREMGR->registerFeature( MFT_LightbufferMRT, new NamedFeatureHLSL( "Lightbuffer MRT" ) ); FEATUREMGR->registerFeature( MFT_LightbufferMRT, new NamedFeatureHLSL( "Lightbuffer MRT" ) );
FEATUREMGR->registerFeature( MFT_RenderTarget1_Zero, new RenderTargetZeroHLSL( ShaderFeature::RenderTarget1 ) ); 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(); const U32 detailIndex = getProcessIndex();
Var *inTex = getVertTexCoord( "texCoord" ); Var *inTex = getVertTexCoord( "texCoord" );
// new terrain
bool hasNormal = fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex);
MultiLine *meta = new MultiLine; MultiLine *meta = new MultiLine;
// We need the negative tangent space view vector // 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", meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) ); 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. // Get a var and accumulate the blend amount.
Var *blendTotal = (Var*)LangElement::find( "blendTotal" ); Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
if ( !blendTotal ) if ( !blendTotal )
@ -550,96 +458,7 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
} }
// Add to the blend total. // Add to the blend total.
meta->addStatement( new GenOp( " @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) ); meta->addStatement( new GenOp( " @ += @;\r\n", 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
// If we had a parallax feature... then factor in the parallax // If we had a parallax feature... then factor in the parallax
// amount so that it fades out with the layer blending. // amount so that it fades out with the layer blending.
@ -676,36 +495,58 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
return; 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 // If we're using SM 3.0 then take advantage of
// dynamic branching to skip layers per-pixel. // dynamic branching to skip layers per-pixel.
if ( GFX->getPixelShaderVersion() >= 3.0f ) if ( GFX->getPixelShaderVersion() >= 3.0f )
meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) ); meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) );
meta->addStatement( new GenOp( " {\r\n" ) ); 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", meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) ); detailColor, detailInfo, inDet ) );
// New terrain Var *baseColor = (Var*)LangElement::find( "baseColor" );
if (hasNormal) Var *outColor = (Var*)LangElement::find( "col" );
{
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"));
}
meta->addStatement(new GenOp(" @ += @ * @;\r\n", outColor, detailColor, detailBlend)); meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n",
outColor, outColor, baseColor, 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( " }\r\n" ) ); meta->addStatement( new GenOp( " }\r\n" ) );
@ -971,9 +812,13 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) ); detailColor, detailInfo, inDet ) );
Var *baseColor = (Var*)LangElement::find( "baseColor" );
Var *outColor = (Var*)LangElement::find( "col" ); 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" ) ); meta->addStatement( new GenOp( " }\r\n" ) );
output = meta; output = meta;
@ -1075,36 +920,15 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
texOp = new GenOp( "tex2D(@, @.xy)", normalMap, inDet ); texOp = new GenOp( "tex2D(@, @.xy)", normalMap, inDet );
// create bump normal // create bump normal
// New terrain Var *bumpNorm = new Var;
Var *bumpNorm = (Var*)LangElement::find("bumpNormal");
bool bumpNormWasDefined = bumpNorm ? true : false;
LangElement *bumpNormDecl = bumpNorm;
if (!bumpNormWasDefined)
{
bumpNorm = new Var;
bumpNorm->setName( "bumpNormal" ); bumpNorm->setName( "bumpNormal" );
bumpNorm->setType("float4"); bumpNorm->setType( "vec4" );
bumpNormDecl = new DecOp(bumpNorm);
}
LangElement *bumpNormDecl = new DecOp( bumpNorm );
meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) ); 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... // Normalize is done later...
// Note: The reverse mul order is intentional. Affine matrix. // 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", meta->addStatement( new GenOp( " @ = lerp( @, tMul( @.xyz, @ ), min( @, @.w ) );\r\n",
gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet ) ); 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->detailInfoVConst = pass->shader->getShaderConstHandle( avar( "$detailScaleAndFade%d", i ) );
matInfo->detailInfoPConst = pass->shader->getShaderConstHandle( avar( "$detailIdStrengthParallax%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 ) ); matInfo->detailTexConst = pass->shader->getShaderConstHandle( avar( "$detailMap%d", i ) );
if ( matInfo->detailTexConst->isValid() ) if ( matInfo->detailTexConst->isValid() )
{ {
@ -715,11 +711,6 @@ void TerrainCellMaterial::_updateMaterialConsts( Pass *pass )
pass->consts->setSafe( matInfo->detailInfoVConst, detailScaleAndFade ); pass->consts->setSafe( matInfo->detailInfoVConst, detailScaleAndFade );
pass->consts->setSafe( matInfo->detailInfoPConst, detailIdStrengthParallax ); 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 // macro texture info
F32 macroSize = matInfo->mat->getMacroSize(); F32 macroSize = matInfo->mat->getMacroSize();

View file

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

View file

@ -65,8 +65,7 @@ TerrainMaterial::TerrainMaterial()
mMacroSize( 200.0f ), mMacroSize( 200.0f ),
mMacroStrength( 0.7f ), mMacroStrength( 0.7f ),
mMacroDistance( 500.0f ), mMacroDistance( 500.0f ),
mParallaxScale(0.0f), mParallaxScale( 0.0f )
mBlendDepth(0.4f)
{ {
} }
@ -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 " 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" ); "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(); Parent::initPersistFields();
// Gotta call this at least once or it won't get created! // Gotta call this at least once or it won't get created!

View file

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

View file

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

View file

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

View file

@ -27,7 +27,9 @@
#include "math/mMatrix.h" #include "math/mMatrix.h"
#endif #endif
#ifndef _GFXDEVICE_H_
#include "gfx/gfxDevice.h"
#endif
class SceneRenderState; class SceneRenderState;
class GFXCubemap; class GFXCubemap;
@ -103,8 +105,14 @@ protected:
/// are forward lit and need lights. /// are forward lit and need lights.
LightQuery *mLightQuery; LightQuery *mLightQuery;
// The accumulation texture provided by an accumulation
// volume. This is passed down per-object.
GFXTextureObject* mAccuTex;
public: public:
TSRenderState(); TSRenderState();
TSRenderState( const TSRenderState &state ); TSRenderState( const TSRenderState &state );
@ -147,6 +155,10 @@ public:
void setLightQuery( LightQuery *query ) { mLightQuery = query; } void setLightQuery( LightQuery *query ) { mLightQuery = query; }
LightQuery* getLightQuery() const { return mLightQuery; } 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 "gfx/gfxDrawUtil.h"
#include "core/module.h" #include "core/module.h"
MODULE_BEGIN( TSShapeInstance ) MODULE_BEGIN( TSShapeInstance )
MODULE_INIT 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 *mData; ///< available for use by app...initialized to 0
void prepCollision(); void prepCollision();
//-------------------------------------------------------------------------------------
// accumulation
//-------------------------------------------------------------------------------------
bool hasAccumulation();
}; };

View file

@ -121,6 +121,7 @@ void ImposterCaptureMaterialHook::init( BaseMatInstance *inMat )
features.addFeature( MFT_IsDXTnm ); features.addFeature( MFT_IsDXTnm );
features.addFeature( MFT_NormalMap ); features.addFeature( MFT_NormalMap );
features.addFeature( MFT_NormalsOut ); features.addFeature( MFT_NormalsOut );
features.addFeature( MFT_AccuMap );
mNormalsMatInst = MATMGR->createMatInstance( matName ); mNormalsMatInst = MATMGR->createMatInstance( matName );
mNormalsMatInst->getFeaturesDelegate().bind( &ImposterCaptureMaterialHook::_overrideFeatures ); mNormalsMatInst->getFeaturesDelegate().bind( &ImposterCaptureMaterialHook::_overrideFeatures );
mNormalsMatInst->init( features, inMat->getVertexFormat() ); 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. // 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": case "FMOD":
return 1; return 1;
case "XAudio":
if( %providerB !$= "FMOD" )
return 1;
else
return -1;
// Prefer OpenAL over anything but FMOD. // Prefer OpenAL over anything but FMOD.
case "OpenAL": case "OpenAL":
if( %providerB $= "FMOD" ) if( %providerB $= "FMOD" && %providerB !$= "XAudio")
return -1; return -1;
else else
return 1; return 1;
// As long as the XAudio SFX provider still has issues, // DSound is just about deprecated, so make that one the last fallback
// choose stable DSound over it.
case "DirectSound": case "DirectSound":
if( %providerB $= "FMOD" || %providerB $= "OpenAL" ) if( %providerB $= "FMOD" || %providerB $= "OpenAL" && %providerB !$= "XAudio")
return -1; return -1;
else else
return 0; return 0;
case "XAudio":
if( %providerB !$= "FMOD" && %providerB !$= "OpenAL" && %providerB !$= "DirectSound" )
return 1;
else
return -1;
default: default:
return -1; return -1;
} }

View file

@ -46,6 +46,10 @@ $PostFXManager::Settings::HDR::keyValue = "0.18";
$PostFXManager::Settings::HDR::minLuminace = "0.001"; $PostFXManager::Settings::HDR::minLuminace = "0.001";
$PostFXManager::Settings::HDR::whiteCutoff = "1"; $PostFXManager::Settings::HDR::whiteCutoff = "1";
$PostFXManager::Settings::LightRays::brightScalar = "0.75"; $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::blurDepthTol = "0.001";
$PostFXManager::Settings::SSAO::blurNormalTol = "0.95"; $PostFXManager::Settings::SSAO::blurNormalTol = "0.95";
$PostFXManager::Settings::SSAO::lDepthMax = "2"; $PostFXManager::Settings::SSAO::lDepthMax = "2";

View file

@ -1694,7 +1694,7 @@
ticks = "1000"; ticks = "1000";
snap = "0"; snap = "0";
value = "0.75"; value = "0.75";
position = "96 96"; position = "96 46";
extent = "264 17"; extent = "264 17";
minExtent = "8 2"; minExtent = "8 2";
horizSizing = "right"; horizSizing = "right";
@ -1717,7 +1717,7 @@
anchorBottom = "0"; anchorBottom = "0";
anchorLeft = "1"; anchorLeft = "1";
anchorRight = "0"; anchorRight = "0";
position = "26 98"; position = "26 48";
extent = "87 15"; extent = "87 15";
minExtent = "8 2"; minExtent = "8 2";
horizSizing = "right"; horizSizing = "right";
@ -1732,6 +1732,187 @@
canSave = "1"; canSave = "1";
canSaveDynamicFields = "0"; 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";
vertSizing = "bottom";
profile = "GuiSliderBoxProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
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 76";
extent = "87 15";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiTextProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
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";
canSaveDynamicFields = "0";
};
new GuiCheckBoxCtrl(ppOptionsEnableLightRays) { new GuiCheckBoxCtrl(ppOptionsEnableLightRays) {
useInactiveState = "0"; useInactiveState = "0";
text = "Enable"; text = "Enable";

View file

@ -301,12 +301,37 @@ function ppOptionsHDREffectsBlueShiftColorBaseColor::onAction(%this)
} }
//Light rays Slider Controls //Light rays Brightness Slider Controls
function ppOptionsLightRaysBrightScalar::onMouseDragged(%this) function ppOptionsLightRaysBrightScalar::onMouseDragged(%this)
{ {
$LightRayPostFX::brightScalar = %this.value; $LightRayPostFX::brightScalar = %this.value;
%this.ToolTip = "Value : " @ %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() function ppOptionsUpdateDOFSettings()
{ {

View file

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

View file

@ -654,7 +654,6 @@
bitmap = "tools/gui/images/delete"; bitmap = "tools/gui/images/delete";
}; };
}; };
}; };
}; };
new GuiRolloutCtrl(advancedTextureMapsRollout) { 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() { new GuiRolloutCtrl() {
class = "BehaviorQuickEditRollout"; class = "BehaviorQuickEditRollout";
superclass = LBQuickEditRollout; superclass = LBQuickEditRollout;

View file

@ -886,6 +886,17 @@ function MaterialEditorGui::guiSync( %this, %material )
MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap( (%material).specularMap[%layer] ); 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-->detailScaleTextEdit.setText( getWord((%material).detailScale[%layer], 0) );
MaterialEditorPropertiesWindow-->detailNormalStrengthTextEdit.setText( getWord((%material).detailNormalMapStrength[%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-->SequenceSliderFPS.setValue( (%material).sequenceFramePerSec[%layer] );
MaterialEditorPropertiesWindow-->SequenceSliderSSS.setValue( %numFrames ); MaterialEditorPropertiesWindow-->SequenceSliderSSS.setValue( %numFrames );
// Accumulation
MaterialEditorPropertiesWindow-->accuCheckbox.setValue((%material).accuEnabled[%layer]);
%this.preventUndo = false; %this.preventUndo = false;
} }
@ -2249,3 +2263,10 @@ function MaterialEditorMapThumbnail::onRightClick( %this )
%popup.showPopup( Canvas ); %popup.showPopup( Canvas );
} }
// Accumulation
function MaterialEditorGui::updateAccuCheckbox(%this, %value)
{
MaterialEditorGui.updateActiveMaterial("accuEnabled[" @ MaterialEditorGui.currentLayer @ "]", %value);
MaterialEditorGui.guiSync( materialEd_previewMaterial );
}

View file

@ -543,6 +543,33 @@ $PE_guielement_ext_colorpicker = "18 18";
altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue() );"; 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 stack
}; // end "basic" rollout }; // end "basic" rollout
new GuiRolloutCtrl() { new GuiRolloutCtrl() {

View file

@ -101,6 +101,8 @@ function PE_EmitterEditor::guiSync( %this )
PE_EmitterEditor-->PEE_useEmitterSizes.setValue( %data.useEmitterSizes ); PE_EmitterEditor-->PEE_useEmitterSizes.setValue( %data.useEmitterSizes );
PE_EmitterEditor-->PEE_useEmitterColors.setValue( %data.useEmitterColors ); PE_EmitterEditor-->PEE_useEmitterColors.setValue( %data.useEmitterColors );
PE_EmitterEditor-->PEE_glow.setValue( %data.glow );
// Sync up particle selectors. // Sync up particle selectors.
for( %index = 0; %index < 4; %index ++ ) for( %index = 0; %index < 4; %index ++ )

View file

@ -210,7 +210,7 @@
new GuiBitmapCtrl() { new GuiBitmapCtrl() {
Enabled = "1"; Enabled = "1";
Profile = "ToolsGuiDefaultProfile"; Profile = "ToolsGuiDefaultProfile";
position = "250 3"; position = "270 3";
Extent = "2 26"; Extent = "2 26";
MinExtent = "1 1"; MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png"; bitmap = "tools/gui/images/separator-h.png";
@ -222,7 +222,7 @@
Profile = "ToolsGuiDefaultProfile"; Profile = "ToolsGuiDefaultProfile";
HorizSizing = "right"; HorizSizing = "right";
VertSizing = "bottom"; VertSizing = "bottom";
Position = "242 5"; Position = "262 5";
Extent = "256 50"; Extent = "256 50";
MinExtent = "8 2"; MinExtent = "8 2";
canSave = "1"; canSave = "1";
@ -370,7 +370,7 @@
new GuiBitmapCtrl() { new GuiBitmapCtrl() {
Enabled = "1"; Enabled = "1";
Profile = "ToolsGuiDefaultProfile"; Profile = "ToolsGuiDefaultProfile";
position = "495 3"; position = "525 3";
Extent = "2 26"; Extent = "2 26";
MinExtent = "1 1"; MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png"; bitmap = "tools/gui/images/separator-h.png";
@ -382,7 +382,7 @@
Profile = "ToolsGuiTransparentProfile"; Profile = "ToolsGuiTransparentProfile";
HorizSizing = "right"; HorizSizing = "right";
VertSizing = "bottom"; VertSizing = "bottom";
position = "510 5"; position = "540 5";
Extent = "120 50"; Extent = "120 50";
MinExtent = "8 2"; MinExtent = "8 2";
canSave = "1"; canSave = "1";
@ -454,53 +454,6 @@
bitmap = "tools/gui/images/dropslider"; 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 --- //--- OBJECT WRITE END ---
@ -681,3 +634,4 @@ new GuiMouseEventCtrl(PaintBrushSoftnessSliderCtrlContainer,EditorGuiGroup) {
value = "0"; value = "0";
}; };
}; };

View file

@ -20,8 +20,8 @@
HorizSizing = "center"; HorizSizing = "center";
VertSizing = "center"; VertSizing = "center";
position = "221 151"; position = "221 151";
Extent = "394 452"; Extent = "394 432";
MinExtent = "358 452"; MinExtent = "358 432";
canSave = "1"; canSave = "1";
Visible = "1"; Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile"; tooltipprofile = "ToolsGuiToolTipProfile";
@ -106,7 +106,7 @@
HorizSizing = "left"; HorizSizing = "left";
VertSizing = "height"; VertSizing = "height";
position = "202 26"; position = "202 26";
Extent = "185 383"; Extent = "185 363";
MinExtent = "8 2"; MinExtent = "8 2";
canSave = "1"; canSave = "1";
Visible = "1"; Visible = "1";
@ -439,7 +439,7 @@
HorizSizing = "width"; HorizSizing = "width";
VertSizing = "bottom"; VertSizing = "bottom";
position = "6 295"; position = "6 295";
Extent = "185 80"; Extent = "185 50";
MinExtent = "8 2"; MinExtent = "8 2";
canSave = "1"; canSave = "1";
Visible = "1"; Visible = "1";
@ -621,78 +621,6 @@
sinkAllKeyEvents = "0"; sinkAllKeyEvents = "0";
passwordMask = "*"; 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() { new GuiBitmapCtrl() {
@ -1332,7 +1260,7 @@
HorizSizing = "width"; HorizSizing = "width";
VertSizing = "height"; VertSizing = "height";
position = "6 42"; position = "6 42";
Extent = "189 393"; Extent = "189 373";
MinExtent = "8 2"; MinExtent = "8 2";
canSave = "1"; canSave = "1";
Visible = "1"; Visible = "1";
@ -1346,7 +1274,7 @@
HorizSizing = "width"; HorizSizing = "width";
VertSizing = "height"; VertSizing = "height";
position = "0 0"; position = "0 0";
Extent = "189 394"; Extent = "189 374";
MinExtent = "8 2"; MinExtent = "8 2";
canSave = "1"; canSave = "1";
Visible = "1"; Visible = "1";
@ -1405,7 +1333,7 @@
Profile = "ToolsGuiButtonProfile"; Profile = "ToolsGuiButtonProfile";
HorizSizing = "left"; HorizSizing = "left";
VertSizing = "top"; VertSizing = "top";
position = "202 414"; position = "202 394";
Extent = "98 22"; Extent = "98 22";
MinExtent = "8 2"; MinExtent = "8 2";
canSave = "1"; canSave = "1";
@ -1424,7 +1352,7 @@
Profile = "ToolsGuiButtonProfile"; Profile = "ToolsGuiButtonProfile";
HorizSizing = "left"; HorizSizing = "left";
VertSizing = "top"; VertSizing = "top";
position = "307 414"; position = "307 394";
Extent = "80 22"; Extent = "80 22";
MinExtent = "8 2"; MinExtent = "8 2";
canSave = "1"; canSave = "1";
@ -1444,7 +1372,7 @@
HorizSizing = "left"; HorizSizing = "left";
VertSizing = "height"; VertSizing = "height";
position = "199 23"; position = "199 23";
Extent = "190 287"; Extent = "190 267";
isContainer = true; isContainer = true;
Visible = false; Visible = false;
bitmap = "tools/gui/images/inactive-overlay"; bitmap = "tools/gui/images/inactive-overlay";

View file

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

View file

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

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