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,13 +78,16 @@ CMaterial* CMaterial::Clone()
|
|||
return pOut;
|
||||
}
|
||||
|
||||
void CMaterial::GenerateShader()
|
||||
void CMaterial::GenerateShader(bool AllowRegen /*= true*/)
|
||||
{
|
||||
delete mpShader;
|
||||
mpShader = CShaderGenerator::GenerateShader(*this);
|
||||
if (mShaderStatus != eShaderExists || AllowRegen)
|
||||
{
|
||||
delete mpShader;
|
||||
mpShader = CShaderGenerator::GenerateShader(*this);
|
||||
|
||||
if (!mpShader->IsValidProgram()) mShaderStatus = eShaderFailed;
|
||||
else mShaderStatus = eShaderExists;
|
||||
if (!mpShader->IsValidProgram()) mShaderStatus = eShaderFailed;
|
||||
else mShaderStatus = eShaderExists;
|
||||
}
|
||||
}
|
||||
|
||||
bool CMaterial::SetCurrent(FRenderOptions Options)
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
CMaterial(EGame version, FVertexDescription vtxDesc);
|
||||
~CMaterial();
|
||||
CMaterial* Clone();
|
||||
void GenerateShader();
|
||||
void GenerateShader(bool AllowRegen = true);
|
||||
bool SetCurrent(FRenderOptions Options);
|
||||
u64 HashParameters();
|
||||
void Update();
|
||||
|
|
|
@ -75,6 +75,20 @@ void CModel::BufferGL()
|
|||
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()
|
||||
{
|
||||
mVBO.Clear();
|
||||
|
|
|
@ -23,6 +23,7 @@ public:
|
|||
~CModel();
|
||||
|
||||
void BufferGL();
|
||||
void GenerateMaterialShaders();
|
||||
void ClearGLBuffer();
|
||||
void Draw(FRenderOptions Options, u32 MatSet);
|
||||
void DrawSurface(FRenderOptions Options, u32 Surface, u32 MatSet);
|
||||
|
|
|
@ -89,6 +89,12 @@ void CStaticModel::BufferGL()
|
|||
mBuffered = true;
|
||||
}
|
||||
|
||||
void CStaticModel::GenerateMaterialShaders()
|
||||
{
|
||||
if (mpMaterial)
|
||||
mpMaterial->GenerateShader(false);
|
||||
}
|
||||
|
||||
void CStaticModel::ClearGLBuffer()
|
||||
{
|
||||
mVBO.Clear();
|
||||
|
|
|
@ -22,6 +22,7 @@ public:
|
|||
void AddSurface(SSurface *pSurface);
|
||||
|
||||
void BufferGL();
|
||||
void GenerateMaterialShaders();
|
||||
void ClearGLBuffer();
|
||||
void Draw(FRenderOptions Options);
|
||||
void DrawSurface(FRenderOptions Options, u32 Surface);
|
||||
|
|
|
@ -19,6 +19,15 @@ ENodeType CModelNode::NodeType()
|
|||
return eModelNode;
|
||||
}
|
||||
|
||||
void CModelNode::PostLoad()
|
||||
{
|
||||
if (mpModel)
|
||||
{
|
||||
mpModel->BufferGL();
|
||||
mpModel->GenerateMaterialShaders();
|
||||
}
|
||||
}
|
||||
|
||||
void CModelNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||
{
|
||||
if (!mpModel) return;
|
||||
|
|
|
@ -18,6 +18,7 @@ public:
|
|||
explicit CModelNode(CScene *pScene, CSceneNode *pParent = 0, CModel *pModel = 0);
|
||||
|
||||
virtual ENodeType NodeType();
|
||||
virtual void PostLoad();
|
||||
virtual void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||
virtual void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||
virtual void DrawSelection();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "CScene.h"
|
||||
#include "CSceneIterator.h"
|
||||
#include "Core/Render/CGraphics.h"
|
||||
#include "Core/Resource/CResCache.h"
|
||||
#include "Core/Resource/CPoiToWorld.h"
|
||||
|
@ -14,6 +15,7 @@
|
|||
|
||||
CScene::CScene()
|
||||
: mSplitTerrain(true)
|
||||
, mRanPostLoad(false)
|
||||
, mNumNodes(0)
|
||||
, mpSceneRootNode(new CRootNode(this, nullptr))
|
||||
, mpArea(nullptr)
|
||||
|
@ -177,6 +179,7 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
|||
}
|
||||
}
|
||||
|
||||
mRanPostLoad = false;
|
||||
Log::Write( TString::FromInt32(CSceneNode::NumNodes()) + " nodes" );
|
||||
}
|
||||
|
||||
|
@ -185,6 +188,12 @@ void CScene::SetActiveWorld(CWorld* pWorld)
|
|||
mpWorld = pWorld;
|
||||
}
|
||||
|
||||
void CScene::PostLoad()
|
||||
{
|
||||
mpSceneRootNode->OnLoadFinished();
|
||||
mRanPostLoad = true;
|
||||
}
|
||||
|
||||
void CScene::ClearScene()
|
||||
{
|
||||
if (mpAreaRootNode)
|
||||
|
@ -202,6 +211,10 @@ void CScene::ClearScene()
|
|||
|
||||
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
|
||||
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
|
||||
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
|
||||
|
|
|
@ -25,6 +25,7 @@ class CScene
|
|||
friend class CSceneIterator;
|
||||
|
||||
bool mSplitTerrain;
|
||||
bool mRanPostLoad;
|
||||
|
||||
u32 mNumNodes;
|
||||
CRootNode *mpSceneRootNode;
|
||||
|
@ -52,6 +53,7 @@ public:
|
|||
CLightNode* CreateLightNode(CLight *pLight);
|
||||
void SetActiveArea(CGameArea *pArea);
|
||||
void SetActiveWorld(CWorld *pWorld);
|
||||
void PostLoad();
|
||||
void ClearScene();
|
||||
void AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo);
|
||||
SRayIntersection SceneRayCast(const CRay& rkRay, const SViewInfo& rkViewInfo);
|
||||
|
|
|
@ -36,6 +36,11 @@ public:
|
|||
return mpCurNode;
|
||||
}
|
||||
|
||||
inline operator bool() const
|
||||
{
|
||||
return DoneIterating();
|
||||
}
|
||||
|
||||
inline CSceneNode* operator*() const
|
||||
{
|
||||
return mpCurNode;
|
||||
|
|
|
@ -80,6 +80,14 @@ CColor CSceneNode::WireframeColor() const
|
|||
}
|
||||
|
||||
// ************ MAIN FUNCTIONALITY ************
|
||||
void CSceneNode::OnLoadFinished()
|
||||
{
|
||||
PostLoad();
|
||||
|
||||
for (auto it = mChildren.begin(); it != mChildren.end(); it++)
|
||||
(*it)->OnLoadFinished();
|
||||
}
|
||||
|
||||
void CSceneNode::Unparent()
|
||||
{
|
||||
// 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 WireframeColor() const;
|
||||
|
||||
void OnLoadFinished();
|
||||
void Unparent();
|
||||
void RemoveChild(CSceneNode *pChild);
|
||||
void DeleteChildren();
|
||||
|
@ -121,14 +122,8 @@ public:
|
|||
void SetVisible(bool Visible);
|
||||
|
||||
// Static
|
||||
static int NumNodes();
|
||||
inline static int NumNodes() { return smNumNodes; }
|
||||
static CColor skSelectionTint;
|
||||
};
|
||||
|
||||
// ************ INLINE FUNCTIONS ************
|
||||
inline int CSceneNode::NumNodes()
|
||||
{
|
||||
return smNumNodes;
|
||||
}
|
||||
|
||||
#endif // CSCENENODE_H
|
||||
|
|
|
@ -74,6 +74,15 @@ ENodeType CScriptNode::NodeType()
|
|||
return eScriptNode;
|
||||
}
|
||||
|
||||
void CScriptNode::PostLoad()
|
||||
{
|
||||
if (mpActiveModel)
|
||||
{
|
||||
mpActiveModel->BufferGL();
|
||||
mpActiveModel->GenerateMaterialShaders();
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptNode::OnTransformed()
|
||||
{
|
||||
if (mpInstance)
|
||||
|
|
|
@ -27,6 +27,7 @@ class CScriptNode : public CSceneNode
|
|||
public:
|
||||
CScriptNode(CScene *pScene, CSceneNode *pParent = 0, CScriptObject *pObject = 0);
|
||||
ENodeType NodeType();
|
||||
void PostLoad();
|
||||
void OnTransformed();
|
||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||
|
|
|
@ -19,6 +19,15 @@ ENodeType CStaticNode::NodeType()
|
|||
return eStaticNode;
|
||||
}
|
||||
|
||||
void CStaticNode::PostLoad()
|
||||
{
|
||||
if (mpModel)
|
||||
{
|
||||
mpModel->BufferGL();
|
||||
mpModel->GenerateMaterialShaders();
|
||||
}
|
||||
}
|
||||
|
||||
void CStaticNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||
{
|
||||
if (!mpModel) return;
|
||||
|
|
|
@ -11,6 +11,7 @@ class CStaticNode : public CSceneNode
|
|||
public:
|
||||
CStaticNode(CScene *pScene, CSceneNode *pParent = 0, CStaticModel *pModel = 0);
|
||||
ENodeType NodeType();
|
||||
void PostLoad();
|
||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||
void DrawSelection();
|
||||
|
|
Loading…
Reference in New Issue