From c14765989eafe2400ac97424efbdc248a463d74c Mon Sep 17 00:00:00 2001 From: prefect Date: Sun, 24 Sep 2006 11:25:11 +0000 Subject: [PATCH] # Introduce a Scene abstraction that allows the renderer to query visibility from multiple virtual camera positions. This is the first step towards fixing #142 This was SVN commit r4385. --- source/graphics/GameView.cpp | 42 ++++------- source/graphics/GameView.h | 18 ++--- source/ps/GameSetup/GameSetup.cpp | 7 -- source/renderer/Renderer.cpp | 24 ++++--- source/renderer/Renderer.h | 30 +++++--- source/renderer/Scene.cpp | 33 +++++++++ source/renderer/Scene.h | 69 +++++++++++++++++++ .../tools/atlas/GameInterface/ActorViewer.cpp | 29 ++++---- 8 files changed, 168 insertions(+), 84 deletions(-) create mode 100644 source/renderer/Scene.cpp create mode 100644 source/renderer/Scene.h diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index 5f8e1bcf49..5350a1ad9b 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -156,19 +156,16 @@ void CGameView::Render() CheckLightEnv(); - MICROLOG(L"render terrain"); - PROFILE_START( "render terrain" ); - RenderTerrain(m_pWorld->GetTerrain()); - PROFILE_END( "render terrain" ); - MICROLOG(L"render models"); - PROFILE_START( "render models" ); - RenderModels(m_pWorld->GetUnitManager(), m_pWorld->GetProjectileManager()); - PROFILE_END( "render models" ); + g_Renderer.RenderScene(this); } -void CGameView::RenderTerrain(CTerrain *pTerrain) +/////////////////////////////////////////////////////////// +// This callback is part of the Scene interface +// Submit all objects visible in the given frustum +void CGameView::EnumerateObjects(const CFrustum& frustum, SceneCollector* c) { - CFrustum frustum = m_CullCamera.GetFrustum(); + PROFILE_START( "submit terrain" ); + CTerrain* pTerrain = m_pWorld->GetTerrain(); u32 patchesPerSide=pTerrain->GetPatchesPerSide(); for (uint j=0; jSubmit(patch); } } } -} + PROFILE_END( "submit terrain" ); -void CGameView::RenderModels(CUnitManager *pUnitMan, CProjectileManager *pProjectileMan) -{ - CFrustum frustum = m_CullCamera.GetFrustum(); + PROFILE_START( "submit models" ); + CUnitManager* pUnitMan = m_pWorld->GetUnitManager(); + CProjectileManager* pProjectileMan = m_pWorld->GetProjectileManager(); CLOSManager* losMgr = m_pWorld->GetLOSManager(); const std::vector& units=pUnitMan->GetUnits(); @@ -223,7 +220,7 @@ void CGameView::RenderModels(CUnitManager *pUnitMan, CProjectileManager *pProjec } PROFILE( "submit models" ); - SubmitModelRecursive(model); + c->SubmitRecursive(model); } } @@ -242,9 +239,10 @@ void CGameView::RenderModels(CUnitManager *pUnitMan, CProjectileManager *pProjec && losMgr->GetStatus(centre.X, centre.Z, g_Game->GetLocalPlayer()) & LOS_VISIBLE) { PROFILE( "submit projectiles" ); - SubmitModelRecursive(projectiles[i]->GetModel()); + c->SubmitRecursive(projectiles[i]->GetModel()); } } + PROFILE_END( "submit models" ); } @@ -294,16 +292,6 @@ void CGameView::CameraLock(float x, float y, float z, bool smooth) } -void CGameView::SubmitModelRecursive(CModel* model) -{ - g_Renderer.Submit(model); - - const std::vector& props=model->GetProps(); - for (uint i=0;iSetDirty(RENDERDATA_UPDATE_COLOR); diff --git a/source/graphics/GameView.h b/source/graphics/GameView.h index f13a78198e..b319811970 100644 --- a/source/graphics/GameView.h +++ b/source/graphics/GameView.h @@ -13,6 +13,8 @@ extern float g_YMinOffset; #include "lib/input.h" +#include "renderer/Scene.h" + class CGame; class CGameAttributes; class CWorld; @@ -22,7 +24,7 @@ class CProjectileManager; class CModel; class CEntity; -class CGameView: public CJSObject +class CGameView : public CJSObject, private Scene { public: static const float defaultFOV, defaultNear, defaultFar; @@ -103,17 +105,9 @@ private: // Check whether lighting environment has changed and update vertex data if necessary void CheckLightEnv(); - // RenderTerrain: iterate through all terrain patches and submit all patches - // in viewing frustum to the renderer, for terrain, water and LOS painting - void RenderTerrain(CTerrain *pTerrain); - - // RenderModels: iterate through model list and submit all models in viewing - // frustum to the Renderer - void RenderModels(CUnitManager *pUnitMan, CProjectileManager *pProjectileManager); - - // SubmitModelRecursive: recurse down given model, submitting it and all its - // descendents to the renderer - void SubmitModelRecursive(CModel *pModel); + //BEGIN: Implementation of Scene + void EnumerateObjects(const CFrustum& frustum, SceneCollector* c); + //END: Implementation of Scene // InitResources(): Load all graphics resources (textures, actor objects and // alpha maps) required by the game diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 1083f5993a..145cc7c7a4 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -294,13 +294,6 @@ void Render() { g_Game->GetView()->Render(); - oglCheck(); - - MICROLOG(L"flush frame"); - PROFILE_START( "flush frame" ); - g_Renderer.FlushFrame(); - PROFILE_END( "flush frame" ); - glPushAttrib( GL_ENABLE_BIT ); glDisable( GL_LIGHTING ); glDisable( GL_TEXTURE_2D ); diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 5909390ab3..7099bc60d8 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -1185,8 +1185,8 @@ void CRenderer::RenderRefractions() /////////////////////////////////////////////////////////////////////////////////////////////////// -// FlushFrame: force rendering of any batched objects -void CRenderer::FlushFrame() +// RenderSubmissions: force rendering of any batched objects +void CRenderer::RenderSubmissions() { oglCheck(); @@ -1378,7 +1378,7 @@ void CRenderer::Submit(CPatch* patch) m->terrainRenderer->Submit(patch); } -void CRenderer::Submit(CModel* model) +void CRenderer::SubmitNonRecursive(CModel* model) { if (model->GetFlags() & MODELFLAG_CASTSHADOWS) { PROFILE( "updating shadow bounds" ); @@ -1413,16 +1413,20 @@ void CRenderer::Submit(CModel* model) } } -void CRenderer::Submit(CSprite* UNUSED(sprite)) -{ -} -void CRenderer::Submit(CParticleSys* UNUSED(psys)) +/////////////////////////////////////////////////////////// +// Render the given scene +void CRenderer::RenderScene(Scene *scene) { -} + CFrustum frustum = m_CullCamera.GetFrustum(); -void CRenderer::Submit(COverlay* UNUSED(overlay)) -{ + MICROLOG(L"collect objects"); + scene->EnumerateObjects(frustum, this); + + oglCheck(); + + MICROLOG(L"flush objects"); + RenderSubmissions(); } diff --git a/source/renderer/Renderer.h b/source/renderer/Renderer.h index 6e2ebfb536..37276309ac 100644 --- a/source/renderer/Renderer.h +++ b/source/renderer/Renderer.h @@ -21,6 +21,7 @@ #include "scripting/ScriptableObject.h" #include "renderer/ModelRenderer.h" +#include "renderer/Scene.h" // necessary declarations class CPatch; @@ -76,7 +77,10 @@ struct SVertex2D // CRenderer: base renderer class - primary interface to the rendering engine struct CRendererInternals; -class CRenderer : public Singleton, public CJSObject +class CRenderer : + public Singleton, + public CJSObject, + private SceneCollector { public: // various enumerations and renderer related constants @@ -178,8 +182,6 @@ public: // signal frame start void BeginFrame(); - // render any batched objects - void FlushFrame(); // signal frame end void EndFrame(); @@ -190,7 +192,7 @@ public: int GetFrameCounter() const { return m_FrameCounter; } /** - * SetSceneCamera: Set up the camera used for the scene in this frame; this includes + * Set up the camera used for rendering the next scene; this includes * setting OpenGL state like viewport, projection and modelview matrices. * * @param viewCamera this camera determines the eye position for rendering @@ -202,13 +204,11 @@ public: // set the viewport void SetViewport(const SViewPort &); - // submission of objects for rendering; the passed matrix indicating the transform must be scoped such that it is valid beyond - // the call to frame end, as must the object itself - void Submit(CPatch* patch); - void Submit(CModel* model); - void Submit(CSprite* sprite); - void Submit(CParticleSys* psys); - void Submit(COverlay* overlay); + /** + * Render the given scene immediately. + * @param scene a Scene object describing what should be rendered. + */ + void RenderScene(Scene* scene); // basic primitive rendering operations in 2 and 3D; handy for debugging stuff, but also useful in // editor tools (eg for highlighting specific terrain patches) @@ -333,6 +333,14 @@ protected: jsval JSI_GetSky(JSContext*); void JSI_SetSky(JSContext* ctx, jsval newval); + //BEGIN: Implementation of SceneCollector + void Submit(CPatch* patch); + void SubmitNonRecursive(CModel* model); + //END: Implementation of SceneCollector + + // render any batched objects + void RenderSubmissions(); + // patch rendering stuff void RenderPatches(); diff --git a/source/renderer/Scene.cpp b/source/renderer/Scene.cpp new file mode 100644 index 0000000000..0a3ad15a7a --- /dev/null +++ b/source/renderer/Scene.cpp @@ -0,0 +1,33 @@ +/** + * File : Scene.cpp + * Project : graphics + * Description : This file contains default implementations and utilities + * : to be used together with the Scene interface and related + * : classes. + * + * @note This file would fit just as well into the graphics/ subdirectory. + * + * @author Nicolai Haehnle + **/ + +#include "precompiled.h" + +#include "graphics/Model.h" + +#include "renderer/Scene.h" + + + +/////////////////////////////////////////////////////////// +// Default implementation traverses the model recursively and uses +// SubmitNonRecursive for the actual work. +void SceneCollector::SubmitRecursive(CModel* model) +{ + SubmitNonRecursive(model); + + const std::vector& props = model->GetProps(); + for (uint i=0;i + **/ + +#ifndef RENDERER_SCENE_H +#define RENDERER_SCENE_H + +class CFrustum; +class CModel; +class CPatch; + +class SceneCollector; + +/** + * This interface describes a scene to the renderer. + * + * @see CRenderer::RenderScene + */ +class Scene { +public: + /** + * Send all objects that can be seen when rendering the given frustum + * to the scene collector. + * @param frustum The frustum that will be used for rendering. + * @param c The scene collector that should receive objects inside the frustum + * that are visible. + */ + virtual void EnumerateObjects(const CFrustum& frustum, SceneCollector* c) = 0; +}; + + +/** + * This interface accepts renderable objects. + * + * @see Scene::EnumerateObjects + */ +class SceneCollector { +public: + /** + * Submit a terrain patch that is part of the scene. + */ + virtual void Submit(CPatch* patch) = 0; + + /** + * Submit a model that is part of the scene, + * without submitting attached models. + */ + virtual void SubmitNonRecursive(CModel* model) = 0; + + /** + * Submit a model that is part of the scene, + * including attached sub-models. + * + * @note This function is implemented using SubmitNonRecursive, + * so you shouldn't have to reimplement it. + */ + virtual void SubmitRecursive(CModel* model); +}; + + +#endif // RENDERER_SCENE_H diff --git a/source/tools/atlas/GameInterface/ActorViewer.cpp b/source/tools/atlas/GameInterface/ActorViewer.cpp index 9f53281645..9a3935e5b2 100644 --- a/source/tools/atlas/GameInterface/ActorViewer.cpp +++ b/source/tools/atlas/GameInterface/ActorViewer.cpp @@ -15,9 +15,10 @@ #include "maths/MathUtil.h" #include "ps/GameSetup/Config.h" #include "renderer/Renderer.h" +#include "renderer/Scene.h" #include "renderer/SkyManager.h" -struct ActorViewerImpl +struct ActorViewerImpl : public Scene { CUnit* Unit; CStrW CurrentUnitID; @@ -25,6 +26,15 @@ struct ActorViewerImpl float CurrentSpeed; CTerrain Terrain; + + // Simplistic implementation of the Scene interface + void EnumerateObjects(const CFrustum& UNUSED(frustum), SceneCollector* c) + { + c->Submit(Terrain.GetPatch(0, 0)); + + if (Unit) + c->SubmitRecursive(Unit->GetModel()); + } }; ActorViewer::ActorViewer() @@ -123,16 +133,6 @@ void ActorViewer::SetActor(const CStrW& id, const CStrW& animation) m.CurrentUnitAnim = animation; } -// TODO: don't have this duplicated from GameView -void SubmitModelRecursive(CModel* model) -{ - g_Renderer.Submit(model); - - const std::vector& props = model->GetProps(); - for (size_t i = 0; i < props.size(); ++i) - SubmitModelRecursive(props[i].m_Model); -} - void ActorViewer::Render() { m.Terrain.MakeDirty(RENDERDATA_UPDATE_COLOR); @@ -156,12 +156,7 @@ void ActorViewer::Render() g_Renderer.SetSceneCamera(camera, camera); - g_Renderer.Submit(m.Terrain.GetPatch(0, 0)); - - if (m.Unit) - SubmitModelRecursive(m.Unit->GetModel()); - - g_Renderer.FlushFrame(); + g_Renderer.RenderScene(&m); g_Renderer.EndFrame();