Added PostLoad methods to ensure all models have created vertex buffers and all materials have generated shaders before the user gains control of the camera, to fix hitching issues
This commit is contained in:
parent
6d55444cc2
commit
739e3c51bf
|
@ -78,7 +78,9 @@ CMaterial* CMaterial::Clone()
|
||||||
return pOut;
|
return pOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMaterial::GenerateShader()
|
void CMaterial::GenerateShader(bool AllowRegen /*= true*/)
|
||||||
|
{
|
||||||
|
if (mShaderStatus != eShaderExists || AllowRegen)
|
||||||
{
|
{
|
||||||
delete mpShader;
|
delete mpShader;
|
||||||
mpShader = CShaderGenerator::GenerateShader(*this);
|
mpShader = CShaderGenerator::GenerateShader(*this);
|
||||||
|
@ -86,6 +88,7 @@ void CMaterial::GenerateShader()
|
||||||
if (!mpShader->IsValidProgram()) mShaderStatus = eShaderFailed;
|
if (!mpShader->IsValidProgram()) mShaderStatus = eShaderFailed;
|
||||||
else mShaderStatus = eShaderExists;
|
else mShaderStatus = eShaderExists;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CMaterial::SetCurrent(FRenderOptions Options)
|
bool CMaterial::SetCurrent(FRenderOptions Options)
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,7 +76,7 @@ public:
|
||||||
CMaterial(EGame version, FVertexDescription vtxDesc);
|
CMaterial(EGame version, FVertexDescription vtxDesc);
|
||||||
~CMaterial();
|
~CMaterial();
|
||||||
CMaterial* Clone();
|
CMaterial* Clone();
|
||||||
void GenerateShader();
|
void GenerateShader(bool AllowRegen = true);
|
||||||
bool SetCurrent(FRenderOptions Options);
|
bool SetCurrent(FRenderOptions Options);
|
||||||
u64 HashParameters();
|
u64 HashParameters();
|
||||||
void Update();
|
void Update();
|
||||||
|
|
|
@ -75,6 +75,20 @@ void CModel::BufferGL()
|
||||||
mBuffered = true;
|
mBuffered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CModel::GenerateMaterialShaders()
|
||||||
|
{
|
||||||
|
for (u32 iSet = 0; iSet < mMaterialSets.size(); iSet++)
|
||||||
|
{
|
||||||
|
CMaterialSet *pSet = mMaterialSets[iSet];
|
||||||
|
|
||||||
|
for (u32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
|
||||||
|
{
|
||||||
|
CMaterial *pMat = pSet->MaterialByIndex(iMat);
|
||||||
|
pMat->GenerateShader(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CModel::ClearGLBuffer()
|
void CModel::ClearGLBuffer()
|
||||||
{
|
{
|
||||||
mVBO.Clear();
|
mVBO.Clear();
|
||||||
|
|
|
@ -23,6 +23,7 @@ public:
|
||||||
~CModel();
|
~CModel();
|
||||||
|
|
||||||
void BufferGL();
|
void BufferGL();
|
||||||
|
void GenerateMaterialShaders();
|
||||||
void ClearGLBuffer();
|
void ClearGLBuffer();
|
||||||
void Draw(FRenderOptions Options, u32 MatSet);
|
void Draw(FRenderOptions Options, u32 MatSet);
|
||||||
void DrawSurface(FRenderOptions Options, u32 Surface, u32 MatSet);
|
void DrawSurface(FRenderOptions Options, u32 Surface, u32 MatSet);
|
||||||
|
|
|
@ -89,6 +89,12 @@ void CStaticModel::BufferGL()
|
||||||
mBuffered = true;
|
mBuffered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CStaticModel::GenerateMaterialShaders()
|
||||||
|
{
|
||||||
|
if (mpMaterial)
|
||||||
|
mpMaterial->GenerateShader(false);
|
||||||
|
}
|
||||||
|
|
||||||
void CStaticModel::ClearGLBuffer()
|
void CStaticModel::ClearGLBuffer()
|
||||||
{
|
{
|
||||||
mVBO.Clear();
|
mVBO.Clear();
|
||||||
|
|
|
@ -22,6 +22,7 @@ public:
|
||||||
void AddSurface(SSurface *pSurface);
|
void AddSurface(SSurface *pSurface);
|
||||||
|
|
||||||
void BufferGL();
|
void BufferGL();
|
||||||
|
void GenerateMaterialShaders();
|
||||||
void ClearGLBuffer();
|
void ClearGLBuffer();
|
||||||
void Draw(FRenderOptions Options);
|
void Draw(FRenderOptions Options);
|
||||||
void DrawSurface(FRenderOptions Options, u32 Surface);
|
void DrawSurface(FRenderOptions Options, u32 Surface);
|
||||||
|
|
|
@ -19,6 +19,15 @@ ENodeType CModelNode::NodeType()
|
||||||
return eModelNode;
|
return eModelNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CModelNode::PostLoad()
|
||||||
|
{
|
||||||
|
if (mpModel)
|
||||||
|
{
|
||||||
|
mpModel->BufferGL();
|
||||||
|
mpModel->GenerateMaterialShaders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CModelNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
void CModelNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||||
{
|
{
|
||||||
if (!mpModel) return;
|
if (!mpModel) return;
|
||||||
|
|
|
@ -18,6 +18,7 @@ public:
|
||||||
explicit CModelNode(CScene *pScene, CSceneNode *pParent = 0, CModel *pModel = 0);
|
explicit CModelNode(CScene *pScene, CSceneNode *pParent = 0, CModel *pModel = 0);
|
||||||
|
|
||||||
virtual ENodeType NodeType();
|
virtual ENodeType NodeType();
|
||||||
|
virtual void PostLoad();
|
||||||
virtual void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
virtual void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||||
virtual void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
virtual void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||||
virtual void DrawSelection();
|
virtual void DrawSelection();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "CScene.h"
|
#include "CScene.h"
|
||||||
|
#include "CSceneIterator.h"
|
||||||
#include "Core/Render/CGraphics.h"
|
#include "Core/Render/CGraphics.h"
|
||||||
#include "Core/Resource/CResCache.h"
|
#include "Core/Resource/CResCache.h"
|
||||||
#include "Core/Resource/CPoiToWorld.h"
|
#include "Core/Resource/CPoiToWorld.h"
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
|
|
||||||
CScene::CScene()
|
CScene::CScene()
|
||||||
: mSplitTerrain(true)
|
: mSplitTerrain(true)
|
||||||
|
, mRanPostLoad(false)
|
||||||
, mNumNodes(0)
|
, mNumNodes(0)
|
||||||
, mpSceneRootNode(new CRootNode(this, nullptr))
|
, mpSceneRootNode(new CRootNode(this, nullptr))
|
||||||
, mpArea(nullptr)
|
, mpArea(nullptr)
|
||||||
|
@ -177,6 +179,7 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mRanPostLoad = false;
|
||||||
Log::Write( TString::FromInt32(CSceneNode::NumNodes()) + " nodes" );
|
Log::Write( TString::FromInt32(CSceneNode::NumNodes()) + " nodes" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +188,12 @@ void CScene::SetActiveWorld(CWorld* pWorld)
|
||||||
mpWorld = pWorld;
|
mpWorld = pWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CScene::PostLoad()
|
||||||
|
{
|
||||||
|
mpSceneRootNode->OnLoadFinished();
|
||||||
|
mRanPostLoad = true;
|
||||||
|
}
|
||||||
|
|
||||||
void CScene::ClearScene()
|
void CScene::ClearScene()
|
||||||
{
|
{
|
||||||
if (mpAreaRootNode)
|
if (mpAreaRootNode)
|
||||||
|
@ -202,6 +211,10 @@ void CScene::ClearScene()
|
||||||
|
|
||||||
void CScene::AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
void CScene::AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||||
{
|
{
|
||||||
|
// Call PostLoad the first time the scene is rendered to ensure the OpenGL context has been created before it runs.
|
||||||
|
if (!mRanPostLoad)
|
||||||
|
PostLoad();
|
||||||
|
|
||||||
// Override show flags in game mode
|
// Override show flags in game mode
|
||||||
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
|
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
|
||||||
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
|
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
|
||||||
|
|
|
@ -25,6 +25,7 @@ class CScene
|
||||||
friend class CSceneIterator;
|
friend class CSceneIterator;
|
||||||
|
|
||||||
bool mSplitTerrain;
|
bool mSplitTerrain;
|
||||||
|
bool mRanPostLoad;
|
||||||
|
|
||||||
u32 mNumNodes;
|
u32 mNumNodes;
|
||||||
CRootNode *mpSceneRootNode;
|
CRootNode *mpSceneRootNode;
|
||||||
|
@ -52,6 +53,7 @@ public:
|
||||||
CLightNode* CreateLightNode(CLight *pLight);
|
CLightNode* CreateLightNode(CLight *pLight);
|
||||||
void SetActiveArea(CGameArea *pArea);
|
void SetActiveArea(CGameArea *pArea);
|
||||||
void SetActiveWorld(CWorld *pWorld);
|
void SetActiveWorld(CWorld *pWorld);
|
||||||
|
void PostLoad();
|
||||||
void ClearScene();
|
void ClearScene();
|
||||||
void AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo);
|
void AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo);
|
||||||
SRayIntersection SceneRayCast(const CRay& rkRay, const SViewInfo& rkViewInfo);
|
SRayIntersection SceneRayCast(const CRay& rkRay, const SViewInfo& rkViewInfo);
|
||||||
|
|
|
@ -36,6 +36,11 @@ public:
|
||||||
return mpCurNode;
|
return mpCurNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline operator bool() const
|
||||||
|
{
|
||||||
|
return DoneIterating();
|
||||||
|
}
|
||||||
|
|
||||||
inline CSceneNode* operator*() const
|
inline CSceneNode* operator*() const
|
||||||
{
|
{
|
||||||
return mpCurNode;
|
return mpCurNode;
|
||||||
|
|
|
@ -80,6 +80,14 @@ CColor CSceneNode::WireframeColor() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ MAIN FUNCTIONALITY ************
|
// ************ MAIN FUNCTIONALITY ************
|
||||||
|
void CSceneNode::OnLoadFinished()
|
||||||
|
{
|
||||||
|
PostLoad();
|
||||||
|
|
||||||
|
for (auto it = mChildren.begin(); it != mChildren.end(); it++)
|
||||||
|
(*it)->OnLoadFinished();
|
||||||
|
}
|
||||||
|
|
||||||
void CSceneNode::Unparent()
|
void CSceneNode::Unparent()
|
||||||
{
|
{
|
||||||
// May eventually want to reset XForm so global position = local position
|
// May eventually want to reset XForm so global position = local position
|
||||||
|
|
|
@ -67,6 +67,7 @@ public:
|
||||||
virtual CColor TintColor(const SViewInfo& ViewInfo) const;
|
virtual CColor TintColor(const SViewInfo& ViewInfo) const;
|
||||||
virtual CColor WireframeColor() const;
|
virtual CColor WireframeColor() const;
|
||||||
|
|
||||||
|
void OnLoadFinished();
|
||||||
void Unparent();
|
void Unparent();
|
||||||
void RemoveChild(CSceneNode *pChild);
|
void RemoveChild(CSceneNode *pChild);
|
||||||
void DeleteChildren();
|
void DeleteChildren();
|
||||||
|
@ -121,14 +122,8 @@ public:
|
||||||
void SetVisible(bool Visible);
|
void SetVisible(bool Visible);
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static int NumNodes();
|
inline static int NumNodes() { return smNumNodes; }
|
||||||
static CColor skSelectionTint;
|
static CColor skSelectionTint;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ************ INLINE FUNCTIONS ************
|
|
||||||
inline int CSceneNode::NumNodes()
|
|
||||||
{
|
|
||||||
return smNumNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CSCENENODE_H
|
#endif // CSCENENODE_H
|
||||||
|
|
|
@ -74,6 +74,15 @@ ENodeType CScriptNode::NodeType()
|
||||||
return eScriptNode;
|
return eScriptNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CScriptNode::PostLoad()
|
||||||
|
{
|
||||||
|
if (mpActiveModel)
|
||||||
|
{
|
||||||
|
mpActiveModel->BufferGL();
|
||||||
|
mpActiveModel->GenerateMaterialShaders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CScriptNode::OnTransformed()
|
void CScriptNode::OnTransformed()
|
||||||
{
|
{
|
||||||
if (mpInstance)
|
if (mpInstance)
|
||||||
|
|
|
@ -27,6 +27,7 @@ class CScriptNode : public CSceneNode
|
||||||
public:
|
public:
|
||||||
CScriptNode(CScene *pScene, CSceneNode *pParent = 0, CScriptObject *pObject = 0);
|
CScriptNode(CScene *pScene, CSceneNode *pParent = 0, CScriptObject *pObject = 0);
|
||||||
ENodeType NodeType();
|
ENodeType NodeType();
|
||||||
|
void PostLoad();
|
||||||
void OnTransformed();
|
void OnTransformed();
|
||||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||||
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||||
|
|
|
@ -19,6 +19,15 @@ ENodeType CStaticNode::NodeType()
|
||||||
return eStaticNode;
|
return eStaticNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CStaticNode::PostLoad()
|
||||||
|
{
|
||||||
|
if (mpModel)
|
||||||
|
{
|
||||||
|
mpModel->BufferGL();
|
||||||
|
mpModel->GenerateMaterialShaders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CStaticNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
void CStaticNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||||
{
|
{
|
||||||
if (!mpModel) return;
|
if (!mpModel) return;
|
||||||
|
|
|
@ -11,6 +11,7 @@ class CStaticNode : public CSceneNode
|
||||||
public:
|
public:
|
||||||
CStaticNode(CScene *pScene, CSceneNode *pParent = 0, CStaticModel *pModel = 0);
|
CStaticNode(CScene *pScene, CSceneNode *pParent = 0, CStaticModel *pModel = 0);
|
||||||
ENodeType NodeType();
|
ENodeType NodeType();
|
||||||
|
void PostLoad();
|
||||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||||
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||||
void DrawSelection();
|
void DrawSelection();
|
||||||
|
|
Loading…
Reference in New Issue