1
0
forked from 0ad/0ad

# 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.
This commit is contained in:
prefect 2006-09-24 11:25:11 +00:00
parent d1188604c4
commit c14765989e
8 changed files with 168 additions and 84 deletions

View File

@ -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; j<patchesPerSide; j++) {
for (uint i=0; i<patchesPerSide; i++) {
@ -182,15 +179,15 @@ void CGameView::RenderTerrain(CTerrain *pTerrain)
}
if (!m_Culling || frustum.IsBoxVisible (CVector3D(0,0,0), bounds)) {
g_Renderer.Submit(patch);
c->Submit(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<CUnit*>& 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<CModel::Prop>& props=model->GetProps();
for (uint i=0;i<props.size();i++) {
SubmitModelRecursive(props[i].m_Model);
}
}
static void MarkUpdateColorRecursive(CModel* model)
{
model->SetDirty(RENDERDATA_UPDATE_COLOR);

View File

@ -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<CGameView>
class CGameView : public CJSObject<CGameView>, 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

View File

@ -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 );

View File

@ -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();
}

View File

@ -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<CRenderer>, public CJSObject<CRenderer>
class CRenderer :
public Singleton<CRenderer>,
public CJSObject<CRenderer>,
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();

33
source/renderer/Scene.cpp Normal file
View File

@ -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 <nicolai@wildfiregames.com>
**/
#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<CModel::Prop>& props = model->GetProps();
for (uint i=0;i<props.size();i++) {
SubmitRecursive(props[i].m_Model);
}
}

69
source/renderer/Scene.h Normal file
View File

@ -0,0 +1,69 @@
/**
* File : Scene.h
* Project : graphics
* Description : This file contains the interfaces that are used to send a
* : scene to the renderer, and for the renderer to query objects
* : in that scene.
*
* @note This file would fit just as well into the graphics/ subdirectory.
*
* @author Nicolai Haehnle <nicolai@wildfiregames.com>
**/
#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

View File

@ -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<CModel::Prop>& 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();