Merge remote-tracking branch 'upstream/development' into STBImageLoading-PR

This commit is contained in:
marauder2k7 2023-12-08 04:29:41 +00:00
commit 89a8a4d190
13 changed files with 243 additions and 159 deletions

View file

@ -433,6 +433,8 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
foreach (TORQUE_LIBRARY ${TORQUE_LINK_LIBRARIES}) foreach (TORQUE_LIBRARY ${TORQUE_LINK_LIBRARIES})
set_target_properties(${TORQUE_LIBRARY} PROPERTIES set_target_properties(${TORQUE_LIBRARY} PROPERTIES
FOLDER "Libraries") FOLDER "Libraries")
# remove warnings from 3rd parties.
target_compile_options(${TORQUE_LIBRARY} PRIVATE "-w")
endforeach() endforeach()
target_compile_definitions(${TORQUE_APP_NAME} PUBLIC ${TORQUE_COMPILE_DEFINITIONS}) target_compile_definitions(${TORQUE_APP_NAME} PUBLIC ${TORQUE_COMPILE_DEFINITIONS})

View file

@ -238,7 +238,7 @@ class ParticleEmitter : public GameBase
const LinearColorF &ambientColor, const LinearColorF &ambientColor,
ParticleVertexType *lVerts ); ParticleVertexType *lVerts );
inline void setupOriented( Particle *part, void setupOriented( Particle *part,
const Point3F &camPos, const Point3F &camPos,
const LinearColorF &ambientColor, const LinearColorF &ambientColor,
ParticleVertexType *lVerts ); ParticleVertexType *lVerts );

View file

@ -91,7 +91,7 @@ IMPLEMENT_CALLBACK( GuiObjectView, onMouseLeave, void, (),(),
GuiObjectView::GuiObjectView() GuiObjectView::GuiObjectView()
: mMouseState( None ), : mMouseState( None ),
mLastMousePoint( 0, 0 ), mLastMousePoint( 0, 0 ),
mModel( NULL ), mModelInstance(NULL),
mMaxOrbitDist( 5.0f ), mMaxOrbitDist( 5.0f ),
mMinOrbitDist( 0.0f ), mMinOrbitDist( 0.0f ),
mCameraRotation( 0.0f, 0.0f, 0.0f ), mCameraRotation( 0.0f, 0.0f, 0.0f ),
@ -99,13 +99,13 @@ GuiObjectView::GuiObjectView()
mCameraSpeed( 0.01f ), mCameraSpeed( 0.01f ),
mMountNode( -1 ), mMountNode( -1 ),
mMountNodeName( "mount0" ), mMountNodeName( "mount0" ),
mMountedModel( NULL ), mMountedModelInstance( NULL ),
mAnimationSeq( -1 ), mAnimationSeq( -1 ),
mRunThread( NULL ), mRunThread( NULL ),
mLastRenderTime( 0 ), mLastRenderTime( 0 ),
mLight( NULL ), mLight( NULL ),
mLightColor( 1.0f, 1.0f, 1.0f ), mLightColor( 1.0f, 1.0f, 1.0f ),
mLightAmbient( 0.5f, 0.5f, 0.5f ), mLightAmbient( 1.0f, 1.0f, 1.0f ),
mLightDirection( 0.f, 0.707f, -0.707f ) mLightDirection( 0.f, 0.707f, -0.707f )
{ {
mCameraMatrix.identity(); mCameraMatrix.identity();
@ -117,16 +117,14 @@ GuiObjectView::GuiObjectView()
// By default don't do dynamic reflection // By default don't do dynamic reflection
// updates for this viewport. // updates for this viewport.
mReflectPriority = 0.0f; mReflectPriority = 0.0f;
INIT_ASSET(Model);
INIT_ASSET(MountedModel);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
GuiObjectView::~GuiObjectView() GuiObjectView::~GuiObjectView()
{ {
if( mModel )
SAFE_DELETE( mModel );
if( mMountedModel )
SAFE_DELETE( mMountedModel );
if( mLight ) if( mLight )
SAFE_DELETE( mLight ); SAFE_DELETE( mLight );
} }
@ -137,12 +135,9 @@ void GuiObjectView::initPersistFields()
{ {
docsURL; docsURL;
addGroup( "Model" ); addGroup( "Model" );
INITPERSISTFIELD_SHAPEASSET(Model, GuiObjectView, "The source shape asset.");
addField( "shapeFile", TypeStringFilename, Offset( mModelName, GuiObjectView ),
"The object model shape file to show in the view." );
addField( "skin", TypeRealString, Offset( mSkinName, GuiObjectView ), addField( "skin", TypeRealString, Offset( mSkinName, GuiObjectView ),
"The skin to use on the object model." ); "The skin to use on the object model." );
endGroup( "Model" ); endGroup( "Model" );
addGroup( "Animation" ); addGroup( "Animation" );
@ -153,9 +148,7 @@ void GuiObjectView::initPersistFields()
endGroup( "Animation" ); endGroup( "Animation" );
addGroup( "Mounting" ); addGroup( "Mounting" );
INITPERSISTFIELD_SHAPEASSET(MountedModel, GuiObjectView, "The mounted shape asset.");
addField( "mountedShapeFile", TypeStringFilename, Offset( mMountedModelName, GuiObjectView ),
"Optional shape file to mount on the primary model (e.g. weapon)." );
addField( "mountedSkin", TypeRealString, Offset( mMountSkinName, GuiObjectView ), addField( "mountedSkin", TypeRealString, Offset( mMountSkinName, GuiObjectView ),
"Skin name used on mounted shape file." ); "Skin name used on mounted shape file." );
addField( "mountedNode", TypeRealString, Offset( mMountNodeName, GuiObjectView ), addField( "mountedNode", TypeRealString, Offset( mMountNodeName, GuiObjectView ),
@ -197,9 +190,7 @@ void GuiObjectView::onStaticModified( StringTableEntry slotName, const char* new
{ {
Parent::onStaticModified( slotName, newValue ); Parent::onStaticModified( slotName, newValue );
static StringTableEntry sShapeFile = StringTable->insert( "shapeFile" );
static StringTableEntry sSkin = StringTable->insert( "skin" ); static StringTableEntry sSkin = StringTable->insert( "skin" );
static StringTableEntry sMountedShapeFile = StringTable->insert( "mountedShapeFile" );
static StringTableEntry sMountedSkin = StringTable->insert( "mountedSkin" ); static StringTableEntry sMountedSkin = StringTable->insert( "mountedSkin" );
static StringTableEntry sMountedNode = StringTable->insert( "mountedNode" ); static StringTableEntry sMountedNode = StringTable->insert( "mountedNode" );
static StringTableEntry sLightColor = StringTable->insert( "lightColor" ); static StringTableEntry sLightColor = StringTable->insert( "lightColor" );
@ -211,12 +202,8 @@ void GuiObjectView::onStaticModified( StringTableEntry slotName, const char* new
static StringTableEntry sCameraRotation = StringTable->insert( "cameraRotation" ); static StringTableEntry sCameraRotation = StringTable->insert( "cameraRotation" );
static StringTableEntry sAnimSequence = StringTable->insert( "animSequence" ); static StringTableEntry sAnimSequence = StringTable->insert( "animSequence" );
if( slotName == sShapeFile ) if( slotName == sSkin )
setObjectModel( String( mModelName ) );
else if( slotName == sSkin )
setSkin( String( mSkinName ) ); setSkin( String( mSkinName ) );
else if( slotName == sMountedShapeFile )
setMountedObject( String( mMountedModelName ) );
else if( slotName == sMountedSkin ) else if( slotName == sMountedSkin )
setMountSkin( String( mMountSkinName ) ); setMountSkin( String( mMountSkinName ) );
else if( slotName == sMountedNode ) else if( slotName == sMountedNode )
@ -325,7 +312,7 @@ void GuiObjectView::setObjectAnimation( S32 index )
mAnimationSeq = index; mAnimationSeq = index;
mAnimationSeqName = String(); mAnimationSeqName = String();
if( mModel ) if(mModelInstance)
_initAnimation(); _initAnimation();
} }
@ -336,62 +323,105 @@ void GuiObjectView::setObjectAnimation( const String& sequenceName )
mAnimationSeq = -1; mAnimationSeq = -1;
mAnimationSeqName = sequenceName; mAnimationSeqName = sequenceName;
if( mModel ) if(mModelInstance)
_initAnimation(); _initAnimation();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void GuiObjectView::setObjectModel( const String& modelName ) bool GuiObjectView::setObjectModel( const String& modelName )
{ {
SAFE_DELETE( mModel );
mRunThread = 0; mRunThread = 0;
mModelName = String::EmptyString;
// Load the shape. // Load the shape.
_setModel(modelName);
Resource< TSShape > model = ResourceManager::get().load( modelName ); if( !getModelResource())
if( !model )
{ {
Con::warnf( "GuiObjectView::setObjectModel - Failed to load model '%s'", modelName.c_str() ); Con::warnf( "GuiObjectView::setObjectModel - Failed to load model '%s'", modelName.c_str() );
return; return false;
} }
if (!getModelResource()->preloadMaterialList(getModelResource().getPath())) return false;
// Instantiate it. // Instantiate it.
mModel = new TSShapeInstance( model, true ); mModelInstance = new TSShapeInstance(getModelResource(), true );
mModelName = modelName; mModelInstance->resetMaterialList();
mModelInstance->cloneMaterialList();
if( !mSkinName.isEmpty() ) if( !mSkinName.isEmpty() )
mModel->reSkin( mSkinName ); mModelInstance->reSkin( mSkinName );
TSMaterialList* pMatList = mModelInstance->getMaterialList();
pMatList->setTextureLookupPath(mModelAsset->getShapeFileName());
mModelInstance->initMaterialList();
// Initialize camera values. // Initialize camera values.
mOrbitPos = mModel->getShape()->center; mOrbitPos = getModelResource()->center;
mMinOrbitDist = mModel->getShape()->mRadius; mMinOrbitDist = getModelResource()->mRadius;
// Initialize animation. // Initialize animation.
_initAnimation(); _initAnimation();
_initMount(); _initMount();
return true;
}
void GuiObjectView::onModelChanged()
{
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void GuiObjectView::setSkin( const String& name ) void GuiObjectView::setSkin( const String& name )
{ {
if( mModel ) if(mModelInstance)
mModel->reSkin( name, mSkinName ); mModelInstance->reSkin( name, mSkinName );
mSkinName = name; mSkinName = name;
} }
//------------------------------------------------------------------------------
bool GuiObjectView::setMountedObject( const String& modelName )
{
// Load the model.
_setMountedModel(modelName);
if (!getMountedModelResource())
{
Con::warnf("GuiObjectView::setMountedObject - Failed to load model '%s'", modelName.c_str());
return false;
}
if (!getMountedModelResource()->preloadMaterialList(getMountedModelResource().getPath())) return false;
mMountedModelInstance = new TSShapeInstance(getMountedModelResource(), true);
mMountedModelInstance->resetMaterialList();
mMountedModelInstance->cloneMaterialList();
if( !mMountSkinName.isEmpty() )
mMountedModelInstance->reSkin( mMountSkinName );
mMountedModelInstance->initMaterialList();
if(mMountedModelInstance)
_initMount();
return true;
}
void GuiObjectView::onMountedModelChanged()
{
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void GuiObjectView::setMountSkin(const String& name) void GuiObjectView::setMountSkin(const String& name)
{ {
if( mMountedModel ) if (mMountedModelInstance)
mMountedModel->reSkin( name, mMountSkinName ); mMountedModelInstance->reSkin(name, mMountSkinName);
mMountSkinName = name; mMountSkinName = name;
} }
@ -409,34 +439,7 @@ void GuiObjectView::setMountNode( const String& name )
{ {
mMountNodeName = name; mMountNodeName = name;
if( mModel ) if (mModelInstance)
_initMount();
}
//------------------------------------------------------------------------------
void GuiObjectView::setMountedObject( const String& modelName )
{
SAFE_DELETE( mMountedModel );
mMountedModelName = String::EmptyString;
// Load the model.
Resource< TSShape > model = ResourceManager::get().load( modelName );
if( !model )
{
Con::warnf( "GuiObjectView::setMountedObject - Failed to load object model '%s'",
modelName.c_str() );
return;
}
mMountedModel = new TSShapeInstance( model, true );
mMountedModelName = modelName;
if( !mMountSkinName.isEmpty() )
mMountedModel->reSkin( mMountSkinName );
if( mModel )
_initMount(); _initMount();
} }
@ -483,7 +486,7 @@ void GuiObjectView::onMouseLeave( const GuiEvent & event )
void GuiObjectView::renderWorld( const RectI& updateRect ) void GuiObjectView::renderWorld( const RectI& updateRect )
{ {
if( !mModel ) if( !mModelInstance)
return; return;
GFXTransformSaver _saveTransforms; GFXTransformSaver _saveTransforms;
@ -538,26 +541,26 @@ void GuiObjectView::renderWorld( const RectI& updateRect )
// Render primary model. // Render primary model.
if( mModel ) if(mModelInstance)
{ {
if( mRunThread ) if( mRunThread )
{ {
mModel->advanceTime( dt / 1000.f, mRunThread ); mModelInstance->advanceTime( dt / 1000.f, mRunThread );
mModel->animate(); mModelInstance->animate();
} }
mModel->render( rdata ); mModelInstance->render( rdata );
} }
// Render mounted model. // Render mounted model.
if( mMountedModel && mMountNode != -1 ) if( mMountedModelInstance && mMountNode != -1 )
{ {
GFX->pushWorldMatrix(); GFX->pushWorldMatrix();
GFX->multWorld( mModel->mNodeTransforms[ mMountNode ] ); GFX->multWorld(mModelInstance->mNodeTransforms[ mMountNode ] );
GFX->multWorld( mMountTransform ); GFX->multWorld( mMountTransform );
mMountedModel->render( rdata ); mMountedModelInstance->render( rdata );
GFX->popWorldMatrix(); GFX->popWorldMatrix();
} }
@ -620,7 +623,7 @@ void GuiObjectView::setLightDirection( const Point3F& direction )
void GuiObjectView::_initAnimation() void GuiObjectView::_initAnimation()
{ {
AssertFatal( mModel, "GuiObjectView::_initAnimation - No model loaded!" ); AssertFatal(getModelResource(), "GuiObjectView::_initAnimation - No model loaded!" );
if( mAnimationSeqName.isEmpty() && mAnimationSeq == -1 ) if( mAnimationSeqName.isEmpty() && mAnimationSeq == -1 )
return; return;
@ -629,7 +632,7 @@ void GuiObjectView::_initAnimation()
if( !mAnimationSeqName.isEmpty() ) if( !mAnimationSeqName.isEmpty() )
{ {
mAnimationSeq = mModel->getShape()->findSequence( mAnimationSeqName ); mAnimationSeq = getModelResource()->findSequence( mAnimationSeqName );
if( mAnimationSeq == -1 ) if( mAnimationSeq == -1 )
{ {
@ -646,7 +649,7 @@ void GuiObjectView::_initAnimation()
if( mAnimationSeq != -1 ) if( mAnimationSeq != -1 )
{ {
if( mAnimationSeq >= mModel->getShape()->sequences.size() ) if( mAnimationSeq >= getModelResource()->sequences.size() )
{ {
Con::errorf( "GuiObjectView::_initAnimation - Sequence '%i' out of range for model '%s'", Con::errorf( "GuiObjectView::_initAnimation - Sequence '%i' out of range for model '%s'",
mAnimationSeq, mAnimationSeq,
@ -658,9 +661,9 @@ void GuiObjectView::_initAnimation()
} }
if( !mRunThread ) if( !mRunThread )
mRunThread = mModel->addThread(); mRunThread = mModelInstance->addThread();
mModel->setSequence( mRunThread, mAnimationSeq, 0.f ); mModelInstance->setSequence( mRunThread, mAnimationSeq, 0.f );
} }
mLastRenderTime = Platform::getVirtualMilliseconds(); mLastRenderTime = Platform::getVirtualMilliseconds();
@ -670,9 +673,9 @@ void GuiObjectView::_initAnimation()
void GuiObjectView::_initMount() void GuiObjectView::_initMount()
{ {
AssertFatal( mModel, "GuiObjectView::_initMount - No model loaded!" ); AssertFatal(mModelInstance, "GuiObjectView::_initMount - No model loaded!" );
if( !mMountedModel ) if( !mModelInstance)
return; return;
mMountTransform.identity(); mMountTransform.identity();
@ -681,7 +684,7 @@ void GuiObjectView::_initMount()
if( !mMountNodeName.isEmpty() ) if( !mMountNodeName.isEmpty() )
{ {
mMountNode = mModel->getShape()->findNode( mMountNodeName ); mMountNode = getModelResource()->findNode( mMountNodeName );
if( mMountNode == -1 ) if( mMountNode == -1 )
{ {
Con::errorf( "GuiObjectView::_initMount - No node '%s' on '%s'", Con::errorf( "GuiObjectView::_initMount - No node '%s' on '%s'",
@ -695,7 +698,7 @@ void GuiObjectView::_initMount()
// Make sure mount node is valid. // Make sure mount node is valid.
if( mMountNode != -1 && mMountNode >= mModel->getShape()->nodes.size() ) if( mMountNode != -1 && mMountNode >= getModelResource()->nodes.size() )
{ {
Con::errorf( "GuiObjectView::_initMount - Mount node index '%i' out of range for '%s'", Con::errorf( "GuiObjectView::_initMount - Mount node index '%i' out of range for '%s'",
mMountNode, mMountNode,
@ -708,11 +711,11 @@ void GuiObjectView::_initMount()
// Look up node on the mounted model from // Look up node on the mounted model from
// which to mount to the primary model's node. // which to mount to the primary model's node.
if (!getMountedModelResource()) return;
S32 mountPoint = mMountedModel->getShape()->findNode( "mountPoint" ); S32 mountPoint = getMountedModelResource()->findNode( "mountPoint" );
if( mountPoint != -1 ) if( mountPoint != -1 )
{ {
mMountedModel->getShape()->getNodeWorldTransform( mountPoint, &mMountTransform ), getMountedModelResource()->getNodeWorldTransform(mountPoint, &mMountTransform),
mMountTransform.inverse(); mMountTransform.inverse();
} }
} }
@ -733,12 +736,12 @@ DefineEngineMethod( GuiObjectView, getModel, const char*, (),,
"@return Name of the displayed model.\n\n" "@return Name of the displayed model.\n\n"
"@see GuiControl") "@see GuiControl")
{ {
return Con::getReturnBuffer( object->getModelName() ); return Con::getReturnBuffer( object->getModel() );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
DefineEngineMethod( GuiObjectView, setModel, void, (const char* shapeName),, DefineEngineMethod( GuiObjectView, setModel, bool, (const char* shapeName),,
"@brief Sets the model to be displayed in this control.\n\n" "@brief Sets the model to be displayed in this control.\n\n"
"@param shapeName Name of the model to display.\n" "@param shapeName Name of the model to display.\n"
"@tsexample\n" "@tsexample\n"
@ -749,7 +752,7 @@ DefineEngineMethod( GuiObjectView, setModel, void, (const char* shapeName),,
"@endtsexample\n\n" "@endtsexample\n\n"
"@see GuiControl") "@see GuiControl")
{ {
object->setObjectModel( shapeName ); return object->setObjectModel( shapeName );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -763,7 +766,7 @@ DefineEngineMethod( GuiObjectView, getMountedModel, const char*, (),,
"@return Name of the mounted model.\n\n" "@return Name of the mounted model.\n\n"
"@see GuiControl") "@see GuiControl")
{ {
return Con::getReturnBuffer( object->getMountedModelName() ); return Con::getReturnBuffer( object->getMountedModel() );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -69,12 +69,17 @@ class GuiObjectView : public GuiTSCtrl
/// @name Model /// @name Model
/// @{ /// @{
/// Name of the model loaded for display. ///Model loaded for display.
StringTableEntry mModelName; DECLARE_SHAPEASSET(GuiObjectView, Model, onModelChanged);
static bool _setModelData(void* obj, const char* index, const char* data)\
/// Model being displayed in the view. {
TSShapeInstance* mModel; bool ret = false;
GuiObjectView* object = static_cast<GuiObjectView*>(obj);
ret = object->setObjectModel(StringTable->insert(data));
return ret;
}
void onModelChanged();
TSShapeInstance* mModelInstance;
/// Name of skin to use on model. /// Name of skin to use on model.
String mSkinName; String mSkinName;
@ -103,8 +108,17 @@ class GuiObjectView : public GuiTSCtrl
/// @name Mounting /// @name Mounting
/// @{ /// @{
/// Name of model to mount to the primary model. ///Model to mount to the primary model.
String mMountedModelName; DECLARE_SHAPEASSET(GuiObjectView, MountedModel, onMountedModelChanged);
static bool _setMountedModelData(void* obj, const char* index, const char* data)\
{
bool ret = false;
GuiObjectView* object = static_cast<GuiObjectView*>(obj);
ret = object->setMountedObject(StringTable->insert(data));
return ret;
}
void onMountedModelChanged();
TSShapeInstance* mMountedModelInstance;
/// ///
String mMountSkinName; String mMountSkinName;
@ -115,9 +129,6 @@ class GuiObjectView : public GuiTSCtrl
/// Name of node to mount the secondary model to. Unset by default. /// Name of node to mount the secondary model to. Unset by default.
String mMountNodeName; String mMountNodeName;
/// Model mounted as an image to the primary model.
TSShapeInstance* mMountedModel;
/// ///
MatrixF mMountTransform; MatrixF mMountTransform;
@ -174,12 +185,6 @@ class GuiObjectView : public GuiTSCtrl
/// @name Model /// @name Model
/// @{ /// @{
///
const String& getModelName() const { return mModelName; }
/// Return the instance of the model being rendered in the view.
TSShapeInstance* getModel() const { return mModel; }
/// Return the name of the skin used on the primary model. /// Return the name of the skin used on the primary model.
const String& getSkin() const { return mSkinName; } const String& getSkin() const { return mSkinName; }
@ -187,7 +192,7 @@ class GuiObjectView : public GuiTSCtrl
void setSkin( const String& name ); void setSkin( const String& name );
/// Set the model to show in this view. /// Set the model to show in this view.
void setObjectModel( const String& modelName ); bool setObjectModel( const String& modelName );
/// @} /// @}
@ -207,12 +212,6 @@ class GuiObjectView : public GuiTSCtrl
/// @name Mounting /// @name Mounting
/// @{ /// @{
/// Return the model mounted to the current primary model; NULL if none.
TSShapeInstance* getMountedModel() const { return mMountedModel; }
///
const String& getMountedModelName() const { return mMountedModelName; }
/// Return the name of the skin used on the mounted model. /// Return the name of the skin used on the mounted model.
const String& getMountSkin() const { return mMountSkinName; } const String& getMountSkin() const { return mMountSkinName; }
@ -226,7 +225,7 @@ class GuiObjectView : public GuiTSCtrl
void setMountNode( const String& nodeName ); void setMountNode( const String& nodeName );
/// ///
void setMountedObject( const String& modelName ); bool setMountedObject( const String& modelName );
/// @} /// @}

View file

@ -184,6 +184,10 @@ void ReflectionProbe::initPersistFields()
"@note Only works for shadow mapped lights.\n\n" "@note Only works for shadow mapped lights.\n\n"
"@ingroup Lighting"); "@ingroup Lighting");
Con::addVariable("$Probes::Capturing", TypeBool, &RenderProbeMgr::smBakeReflectionProbes,
"Toggles probe rendering capture state.\n\n"
"@ingroup Lighting");
Con::addVariable("$Light::renderPreviewProbes", TypeBool, &ReflectionProbe::smRenderPreviewProbes, Con::addVariable("$Light::renderPreviewProbes", TypeBool, &ReflectionProbe::smRenderPreviewProbes,
"Toggles rendering of light frustums when the light is selected in the editor.\n\n" "Toggles rendering of light frustums when the light is selected in the editor.\n\n"
"@note Only works for shadow mapped lights.\n\n" "@note Only works for shadow mapped lights.\n\n"
@ -793,7 +797,9 @@ void ReflectionProbe::bake()
if (mReflectionModeType != BakedCubemap) if (mReflectionModeType != BakedCubemap)
return; return;
PROBEMGR->preBake();
PROBEMGR->bakeProbe(this); PROBEMGR->bakeProbe(this);
PROBEMGR->postBake();
setMaskBits(-1); setMaskBits(-1);
} }
@ -823,7 +829,7 @@ void ReflectionProbe::createEditorResources()
void ReflectionProbe::prepRenderImage(SceneRenderState *state) void ReflectionProbe::prepRenderImage(SceneRenderState *state)
{ {
if (!mEnabled || (!RenderProbeMgr::smRenderReflectionProbes && !dStrcmp(Con::getVariable("$Probes::Capturing", "0"),"1"))) if (!mEnabled || (!RenderProbeMgr::smRenderReflectionProbes || RenderProbeMgr::smBakeReflectionProbes))
return; return;
Point3F distVec = getRenderPosition() - state->getCameraPosition(); Point3F distVec = getRenderPosition() - state->getCameraPosition();

View file

@ -1110,8 +1110,11 @@ bool GFXGLShader::initShader( const Torque::Path &file,
} }
if (!_loadShaderFromStream(activeShader, file, &stream, macros)) if (!_loadShaderFromStream(activeShader, file, &stream, macros))
{
if (smLogErrors)
Con::errorf("GFXGLShader::initShader - unable to load shader from stream: '%s'.", file.getFullPath().c_str());
return false; return false;
}
GLint compile; GLint compile;
glGetShaderiv(activeShader, GL_COMPILE_STATUS, &compile); glGetShaderiv(activeShader, GL_COMPILE_STATUS, &compile);
@ -1119,17 +1122,13 @@ bool GFXGLShader::initShader( const Torque::Path &file,
U32 logLength = 0; U32 logLength = 0;
glGetShaderiv(activeShader, GL_INFO_LOG_LENGTH, (GLint*)&logLength); glGetShaderiv(activeShader, GL_INFO_LOG_LENGTH, (GLint*)&logLength);
GLint compileStatus = GL_TRUE;
if ( logLength ) if ( logLength )
{ {
FrameAllocatorMarker fam; FrameAllocatorMarker fam;
char* log = (char*)fam.alloc(logLength); char* log = (char*)fam.alloc(logLength);
glGetShaderInfoLog(activeShader, logLength, NULL, log); glGetShaderInfoLog(activeShader, logLength, NULL, log);
// Always print errors if (compile == GL_FALSE )
glGetShaderiv( activeShader, GL_COMPILE_STATUS, &compileStatus );
if ( compileStatus == GL_FALSE )
{ {
if ( smLogErrors ) if ( smLogErrors )
{ {
@ -1141,7 +1140,7 @@ bool GFXGLShader::initShader( const Torque::Path &file,
Con::warnf( "Program %s: %s", file.getFullPath().c_str(), log ); Con::warnf( "Program %s: %s", file.getFullPath().c_str(), log );
} }
return compileStatus != GL_FALSE; return compile != GL_FALSE;
} }
/// Returns our list of shader constants, the material can get this and just set the constants it knows about /// Returns our list of shader constants, the material can get this and just set the constants it knows about

View file

@ -59,6 +59,8 @@ RenderProbeMgr *RenderProbeMgr::smProbeManager = NULL;
// This variable is a global toggle on if reflection probes should be rendered or not // This variable is a global toggle on if reflection probes should be rendered or not
bool RenderProbeMgr::smRenderReflectionProbes = true; bool RenderProbeMgr::smRenderReflectionProbes = true;
bool RenderProbeMgr::smBakeReflectionProbes = false;
// This variable defines the maximum draw distance of a probe. // This variable defines the maximum draw distance of a probe.
F32 RenderProbeMgr::smMaxProbeDrawDistance = 100; F32 RenderProbeMgr::smMaxProbeDrawDistance = 100;
@ -500,19 +502,50 @@ void RenderProbeMgr::reloadTextures()
void RenderProbeMgr::preBake() void RenderProbeMgr::preBake()
{ {
Con::setVariable("$Probes::Capturing", "1"); RenderProbeMgr::smBakeReflectionProbes = true;
GFXShader::addGlobalMacro("CAPTURING", String("1"));
//Con::setVariable("$Probes::Capturing", "1");
mRenderMaximumNumOfLights = AdvancedLightBinManager::smMaximumNumOfLights; mRenderMaximumNumOfLights = AdvancedLightBinManager::smMaximumNumOfLights;
mRenderUseLightFade = AdvancedLightBinManager::smUseLightFade; mRenderUseLightFade = AdvancedLightBinManager::smUseLightFade;
AdvancedLightBinManager::smMaximumNumOfLights = -1; AdvancedLightBinManager::smMaximumNumOfLights = -1;
AdvancedLightBinManager::smUseLightFade = false; AdvancedLightBinManager::smUseLightFade = false;
//kickstart rendering
LightManager* lm = LIGHTMGR;
if (lm)
{
SceneManager* sm = lm->getSceneManager();
if (sm && sm->getContainer() == &gClientContainer)
{
lm->deactivate();
lm->activate(sm);
} }
}
}
void RenderProbeMgr::postBake() void RenderProbeMgr::postBake()
{ {
Con::setVariable("$Probes::Capturing", "0"); RenderProbeMgr::smBakeReflectionProbes = false;
GFXShader::addGlobalMacro("CAPTURING", String("0"));
//Con::setVariable("$Probes::Capturing", "0");
AdvancedLightBinManager::smMaximumNumOfLights = mRenderMaximumNumOfLights; AdvancedLightBinManager::smMaximumNumOfLights = mRenderMaximumNumOfLights;
AdvancedLightBinManager::smUseLightFade = mRenderUseLightFade; AdvancedLightBinManager::smUseLightFade = mRenderUseLightFade;
//kickstart rendering
LightManager* lm = LIGHTMGR;
if (lm)
{
SceneManager* sm = lm->getSceneManager();
if (sm && sm->getContainer() == &gClientContainer)
{
lm->deactivate();
lm->activate(sm);
} }
}
}
void RenderProbeMgr::bakeProbe(ReflectionProbe* probe) void RenderProbeMgr::bakeProbe(ReflectionProbe* probe)
{ {
GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE); GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE);
@ -520,8 +553,6 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe)
Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!"); Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!");
U32 startMSTime = Platform::getRealMilliseconds(); U32 startMSTime = Platform::getRealMilliseconds();
preBake();
String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/"); String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64); U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
U32 prefilterMipLevels = mLog2(F32(resolution)) + 1; U32 prefilterMipLevels = mLog2(F32(resolution)) + 1;
@ -641,7 +672,6 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe)
if (!renderWithProbes) if (!renderWithProbes)
RenderProbeMgr::smRenderReflectionProbes = probeRenderState; RenderProbeMgr::smRenderReflectionProbes = probeRenderState;
postBake();
cubeRefl.unregisterReflector(); cubeRefl.unregisterReflector();
@ -845,7 +875,7 @@ void RenderProbeMgr::render( SceneRenderState *state )
_setupPerFrameParameters(state); _setupPerFrameParameters(state);
// Early out if nothing to draw. // Early out if nothing to draw.
if ((!RenderProbeMgr::smRenderReflectionProbes && !dStrcmp(Con::getVariable("$Probes::Capturing", "0"), "1")) || (!mHasSkylight && mProbeData.effectiveProbeCount == 0)) if (!RenderProbeMgr::smRenderReflectionProbes || (!mHasSkylight && mProbeData.effectiveProbeCount == 0))
{ {
getProbeArrayEffect()->setSkip(true); getProbeArrayEffect()->setSkip(true);
mActiveProbes.clear(); mActiveProbes.clear();
@ -875,9 +905,6 @@ void RenderProbeMgr::render( SceneRenderState *state )
String probePerFrame = Con::getVariable("$pref::MaxProbesPerFrame", "8"); String probePerFrame = Con::getVariable("$pref::MaxProbesPerFrame", "8");
mProbeArrayEffect->setShaderMacro("MAX_PROBES", probePerFrame); mProbeArrayEffect->setShaderMacro("MAX_PROBES", probePerFrame);
String probeCapturing = Con::getVariable("$Probes::Capturing", "0");
mProbeArrayEffect->setShaderMacro("CAPTURING", probeCapturing);
mProbeArrayEffect->setTexture(3, mBRDFTexture); mProbeArrayEffect->setTexture(3, mBRDFTexture);
mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray); mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray);
mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray); mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray);
@ -953,11 +980,15 @@ void RenderProbeMgr::render( SceneRenderState *state )
DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()), DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()),
"@brief Bakes the cubemaps for a reflection probe\n\n.") "@brief Bakes the cubemaps for a reflection probe\n\n.")
{ {
object->preBake();
if(probe != nullptr) if(probe != nullptr)
object->bakeProbe(probe); object->bakeProbe(probe);
object->postBake();
} }
DefineEngineMethod(RenderProbeMgr, bakeProbes, void, (),, "@brief Iterates over all reflection probes in the scene and bakes their cubemaps\n\n.") DefineEngineMethod(RenderProbeMgr, bakeProbes, void, (),, "@brief Iterates over all reflection probes in the scene and bakes their cubemaps\n\n.")
{ {
object->preBake();
object->bakeProbes(); object->bakeProbes();
object->postBake();
} }

View file

@ -357,6 +357,7 @@ public:
/// </summary> /// </summary>
static bool smRenderReflectionProbes; static bool smRenderReflectionProbes;
static bool smBakeReflectionProbes;
//============================================================================= //=============================================================================
// Utility functions for processing and setting up the probes for rendering // Utility functions for processing and setting up the probes for rendering
//============================================================================= //=============================================================================

View file

@ -355,6 +355,9 @@ void CubeReflector::updateFace( const ReflectParams &params, U32 faceidx, Point3
// store current matrices // store current matrices
GFXTransformSaver saver; GFXTransformSaver saver;
F32 detailAdjustBackup = TSShapeInstance::smDetailAdjust;
TSShapeInstance::smDetailAdjust *= mDesc->detailAdjust;
// set projection to 90 degrees vertical and horizontal // set projection to 90 degrees vertical and horizontal
F32 left, right, top, bottom; F32 left, right, top, bottom;
MathUtils::makeFrustum( &left, &right, &top, &bottom, M_HALFPI_F, 1.0f, mDesc->nearDist ); MathUtils::makeFrustum( &left, &right, &top, &bottom, M_HALFPI_F, 1.0f, mDesc->nearDist );
@ -437,6 +440,7 @@ void CubeReflector::updateFace( const ReflectParams &params, U32 faceidx, Point3
// Clean up. // Clean up.
mRenderTarget->resolve(); mRenderTarget->resolve();
TSShapeInstance::smDetailAdjust = detailAdjustBackup;
} }
F32 CubeReflector::calcFaceScore( const ReflectParams &params, U32 faceidx ) F32 CubeReflector::calcFaceScore( const ReflectParams &params, U32 faceidx )

View file

@ -66,6 +66,10 @@ uniform vec4 albedo;
#define DEBUGVIZ_CONTRIB 0 #define DEBUGVIZ_CONTRIB 0
#endif #endif
#ifndef CAPTURE_LIGHT_FLOOR
#define CAPTURE_LIGHT_FLOOR 0.04
#endif
vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane ) vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane )
{ {
float denum = dot( plane.xyz, direction.xyz ); float denum = dot( plane.xyz, direction.xyz );
@ -234,7 +238,7 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
vec3 Fr = D * F * Vis; vec3 Fr = D * F * Vis;
#if CAPTURING == 1 #if CAPTURING == 1
return saturate(mix(Fd + Fr,surface.f0,surface.metalness)); return mix(Fd + Fr, surface.baseColor.rgb, surface.metalness);
#else #else
return Fd + Fr; return Fd + Fr;
#endif #endif
@ -243,23 +247,38 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
vec3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float shadow) vec3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float shadow)
{ {
vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity, 0.0f); #if CAPTURING == 1
float lightfloor = CAPTURE_LIGHT_FLOOR;
#else
float lightfloor = 0.0;
#endif
vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity, lightfloor);
return evaluateStandardBRDF(surface,surfaceToLight) * factor; return evaluateStandardBRDF(surface,surfaceToLight) * factor;
} }
vec3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, float shadow) vec3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, float shadow)
{ {
#if CAPTURING == 1
float lightfloor = CAPTURE_LIGHT_FLOOR;
#else
float lightfloor = 0.0;
#endif
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity * attenuation, 0.0f); vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity * attenuation, lightfloor);
return evaluateStandardBRDF(surface,surfaceToLight) * factor; return evaluateStandardBRDF(surface,surfaceToLight) * factor;
} }
vec3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, vec3 lightDir, vec2 lightSpotParams, float shadow) vec3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, vec3 lightDir, vec2 lightSpotParams, float shadow)
{ {
#if CAPTURING == 1
float lightfloor = CAPTURE_LIGHT_FLOOR;
#else
float lightfloor = 0.0;
#endif
float attenuation = 1.0f; float attenuation = 1.0f;
attenuation *= getDistanceAtt(surfaceToLight.Lu, radius); attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy); attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy);
vec3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ; vec3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, lightfloor);
return evaluateStandardBRDF(surface,surfaceToLight) * factor; return evaluateStandardBRDF(surface,surfaceToLight) * factor;
} }

View file

@ -68,6 +68,10 @@ uniform float4 albedo;
#define DEBUGVIZ_CONTRIB 0 #define DEBUGVIZ_CONTRIB 0
#endif #endif
#ifndef CAPTURE_LIGHT_FLOOR
#define CAPTURE_LIGHT_FLOOR 0.04
#endif
inline float3 getDistanceVectorToPlane( float3 origin, float3 direction, float4 plane ) inline float3 getDistanceVectorToPlane( float3 origin, float3 direction, float4 plane )
{ {
float denum = dot( plane.xyz, direction.xyz ); float denum = dot( plane.xyz, direction.xyz );
@ -235,7 +239,7 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
float3 Fr = D * F * Vis; float3 Fr = D * F * Vis;
#if CAPTURING == 1 #if CAPTURING == 1
return saturate(lerp(Fd + Fr,surface.f0,surface.metalness)); return lerp(Fd + Fr,surface.baseColor.rgb,surface.metalness);
#else #else
return Fd + Fr; return Fd + Fr;
#endif #endif
@ -244,25 +248,41 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
float3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow) float3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow)
{ {
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity, 0.0f) ; #if CAPTURING == 1
float lightfloor = CAPTURE_LIGHT_FLOOR;
#else
float lightfloor = 0.0;
#endif
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity, lightfloor) ;
return evaluateStandardBRDF(surface,surfaceToLight) * factor; return evaluateStandardBRDF(surface,surfaceToLight) * factor;
} }
float3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float shadow) float3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float shadow)
{ {
#if CAPTURING == 1
float lightfloor = CAPTURE_LIGHT_FLOOR;
#else
float lightfloor = 0.0;
#endif
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ; float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, lightfloor) ;
return evaluateStandardBRDF(surface,surfaceToLight) * factor; return evaluateStandardBRDF(surface,surfaceToLight) * factor;
} }
float3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float3 lightDir, float2 lightSpotParams, float shadow) float3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float3 lightDir, float2 lightSpotParams, float shadow)
{ {
#if CAPTURING == 1
float lightfloor = CAPTURE_LIGHT_FLOOR;
#else
float lightfloor = 0.0;
#endif
float attenuation = 1.0f; float attenuation = 1.0f;
attenuation *= getDistanceAtt(surfaceToLight.Lu, radius); attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy); attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy);
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ; float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, lightfloor) ;
return evaluateStandardBRDF(surface,surfaceToLight) * factor; return evaluateStandardBRDF(surface,surfaceToLight) * factor;
} }
float computeSpecOcclusion( float NdotV , float AO , float roughness ) float computeSpecOcclusion( float NdotV , float AO , float roughness )
{ {
return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO ); return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO );

View file

@ -86,7 +86,7 @@ vec3 ImportanceSampleGGX(vec2 Xi, vec3 N)
vec3 prefilterEnvMap(vec3 R) vec3 prefilterEnvMap(vec3 R)
{ {
int sampleCount = resolution*2; int sampleCount = 1024;
vec3 N = R; vec3 N = R;
vec3 V = R; vec3 V = R;
float totalWeight = 0.0; float totalWeight = 0.0;
@ -107,7 +107,7 @@ vec3 prefilterEnvMap(vec3 R)
float HdotV = max(dot(H, V), 0.0); float HdotV = max(dot(H, V), 0.0);
float pdf = D * NdotH / (4.0 * HdotV) + 0.0001; float pdf = D * NdotH / (4.0 * HdotV) + 0.0001;
float saTexel = 4.0 * M_PI_F / float(6.0 * sampleCount * sampleCount); float saTexel = 4.0 * M_PI_F / float(6.0 * resolution * resolution);
float saSample = 1.0 / (float(sampleCount) * pdf + 0.0001); float saSample = 1.0 / (float(sampleCount) * pdf + 0.0001);
float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel); float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);

View file

@ -88,7 +88,7 @@ float3 ImportanceSampleGGX(float2 Xi, float3 N)
float4 prefilterEnvMap(float3 R) float4 prefilterEnvMap(float3 R)
{ {
int sampleCount = resolution*2; int sampleCount = 1024;
float3 N = R; float3 N = R;
float3 V = R; float3 V = R;
float totalWeight = 0.0; float totalWeight = 0.0;
@ -109,7 +109,7 @@ float4 prefilterEnvMap(float3 R)
float HdotV = max(dot(H, V), 0.0); float HdotV = max(dot(H, V), 0.0);
float pdf = D * NdotH / (4.0 * HdotV) + 0.0001; float pdf = D * NdotH / (4.0 * HdotV) + 0.0001;
float saTexel = 4.0 * M_PI_F / (6.0 * sampleCount * sampleCount); float saTexel = 4.0 * M_PI_F / (6.0 * resolution * resolution);
float saSample = 1.0 / (float(sampleCount) * pdf + 0.0001); float saSample = 1.0 / (float(sampleCount) * pdf + 0.0001);
float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel); float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);