diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index 66bdd8c874..c646e0a60c 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -159,6 +159,7 @@ public: : Game(game), ColladaManager(), MeshManager(ColladaManager), SkeletonAnimManager(ColladaManager), ObjectManager(MeshManager, SkeletonAnimManager, *game->GetSimulation2()), + LOSTexture(*game->GetSimulation2()), ViewCamera(), CullCamera(), LockCullCamera(false), @@ -467,7 +468,7 @@ void CGameView::BeginFrame() void CGameView::Render() { - g_Renderer.RenderScene(this); + g_Renderer.RenderScene(*this); } /////////////////////////////////////////////////////////// diff --git a/source/graphics/GameView.h b/source/graphics/GameView.h index b70af3b8a6..b5e252d642 100644 --- a/source/graphics/GameView.h +++ b/source/graphics/GameView.h @@ -51,10 +51,13 @@ private: // Check whether lighting environment has changed and update vertex data if necessary void CheckLightEnv(); +public: //BEGIN: Implementation of Scene - void EnumerateObjects(const CFrustum& frustum, SceneCollector* c); + virtual void EnumerateObjects(const CFrustum& frustum, SceneCollector* c); + virtual CLOSTexture& GetLOSTexture(); //END: Implementation of Scene +private: // InitResources(): Load all graphics resources (textures, actor objects and // alpha maps) required by the game //void InitResources(); @@ -90,7 +93,6 @@ public: CCamera *GetCamera(); CCinemaManager* GetCinema(); - CLOSTexture& GetLOSTexture(); JSObject* GetScript(); static void ScriptingInit(); diff --git a/source/graphics/LOSTexture.cpp b/source/graphics/LOSTexture.cpp index 6d8a2ca54c..8048b70b7c 100644 --- a/source/graphics/LOSTexture.cpp +++ b/source/graphics/LOSTexture.cpp @@ -27,6 +27,7 @@ #include "renderer/Renderer.h" #include "simulation2/Simulation2.h" #include "simulation2/components/ICmpRangeManager.h" +#include "simulation2/components/ICmpTerrain.h" /* @@ -47,8 +48,8 @@ The blurred bitmap is then uploaded into a GL texture for use by the renderer. // Blur with a NxN filter, where N = g_BlurSize must be an odd number. static const size_t g_BlurSize = 7; -CLOSTexture::CLOSTexture() : - m_Dirty(true), m_Texture(0), m_MapSize(0), m_TextureSize(0) +CLOSTexture::CLOSTexture(CSimulation2& simulation) : + m_Simulation(simulation), m_Dirty(true), m_Texture(0), m_MapSize(0), m_TextureSize(0) { } @@ -102,8 +103,12 @@ const float* CLOSTexture::GetMinimapTextureMatrix() void CLOSTexture::ConstructTexture(int unit) { - CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); - m_MapSize = terrain->GetVerticesPerSide(); + CmpPtr cmpTerrain(m_Simulation, SYSTEM_ENTITY); + if (cmpTerrain.null()) + return; + + m_MapSize = cmpTerrain->GetVerticesPerSide(); + m_TextureSize = (GLsizei)round_up_to_pow2((size_t)m_MapSize + g_BlurSize - 1); glGenTextures(1, &m_Texture); @@ -152,7 +157,7 @@ void CLOSTexture::RecomputeTexture(int unit) std::vector losData; losData.resize(GetBitmapSize(m_MapSize, m_MapSize)); - CmpPtr cmpRangeManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); + CmpPtr cmpRangeManager(m_Simulation, SYSTEM_ENTITY); if (cmpRangeManager.null()) return; diff --git a/source/graphics/LOSTexture.h b/source/graphics/LOSTexture.h index 6a6f147dba..a84c25e83d 100644 --- a/source/graphics/LOSTexture.h +++ b/source/graphics/LOSTexture.h @@ -20,6 +20,8 @@ #include "maths/Matrix3D.h" #include "simulation2/components/ICmpRangeManager.h" +class CSimulation2; + /** * Maintains the LOS (fog-of-war / shroud-of-darkness) texture, used for * rendering and for the minimap. @@ -30,7 +32,7 @@ class CLOSTexture friend class TestLOSTexture; public: - CLOSTexture(); + CLOSTexture(CSimulation2& simulation); ~CLOSTexture(); /** @@ -75,6 +77,8 @@ private: size_t GetBitmapSize(size_t w, size_t h); void GenerateBitmap(ICmpRangeManager::CLosQuerier los, u8* losData, size_t w, size_t h); + CSimulation2& m_Simulation; + bool m_Dirty; GLuint m_Texture; diff --git a/source/graphics/ObjectEntry.cpp b/source/graphics/ObjectEntry.cpp index 405ca13e5a..25054abb09 100644 --- a/source/graphics/ObjectEntry.cpp +++ b/source/graphics/ObjectEntry.cpp @@ -88,7 +88,7 @@ bool CObjectEntry::BuildVariation(const std::vector >& selections variation.decal.m_SizeX, variation.decal.m_SizeZ, variation.decal.m_Angle, variation.decal.m_OffsetX, variation.decal.m_OffsetZ, m_Base->m_Properties.m_FloatOnWater); - m_Model = new CModelDecal(g_Game->GetWorld()->GetTerrain(), decal); + m_Model = new CModelDecal(objectManager.GetTerrain(), decal); return true; } diff --git a/source/graphics/ObjectManager.cpp b/source/graphics/ObjectManager.cpp index 9d6be8a8f9..fae028a440 100644 --- a/source/graphics/ObjectManager.cpp +++ b/source/graphics/ObjectManager.cpp @@ -26,6 +26,7 @@ #include "ps/Profile.h" #include "ps/Filesystem.h" #include "simulation2/Simulation2.h" +#include "simulation2/components/ICmpTerrain.h" #include "simulation2/components/ICmpVisual.h" template @@ -155,6 +156,13 @@ CObjectEntry* CObjectManager::FindObjectVariation(CObjectBase* base, const std:: return obj; } +CTerrain* CObjectManager::GetTerrain() +{ + CmpPtr cmpTerrain(m_Simulation, SYSTEM_ENTITY); + if (cmpTerrain.null()) + return NULL; + return cmpTerrain->GetCTerrain(); +} void CObjectManager::DeleteObject(CObjectEntry* entry) { diff --git a/source/graphics/ObjectManager.h b/source/graphics/ObjectManager.h index ff13354245..e687ea3950 100644 --- a/source/graphics/ObjectManager.h +++ b/source/graphics/ObjectManager.h @@ -30,6 +30,7 @@ class CObjectBase; class CObjectEntry; class CSkeletonAnimManager; class CSimulation2; +class CTerrain; /////////////////////////////////////////////////////////////////////////////////////////// // CObjectManager: manager class for all possible actor types @@ -72,6 +73,12 @@ public: CObjectEntry* FindObjectVariation(const CStrW& objname, const std::vector >& selections); CObjectEntry* FindObjectVariation(CObjectBase* base, const std::vector >& selections); + /** + * Get the terrain object that actors managed by this manager should be linked + * with (primarily for the purpose of decals) + */ + CTerrain* GetTerrain(); + /** * Reload any scripts that were loaded from the given filename. * (This is used to implement hotloading.) diff --git a/source/renderer/RenderModifiers.cpp b/source/renderer/RenderModifiers.cpp index f4df4033fe..767f453490 100644 --- a/source/renderer/RenderModifiers.cpp +++ b/source/renderer/RenderModifiers.cpp @@ -337,7 +337,7 @@ int ShaderRenderModifier::BeginPass(int pass) if (shader->HasTexture("losTex")) { - CLOSTexture& los = g_Game->GetView()->GetLOSTexture(); + CLOSTexture& los = g_Renderer.GetScene().GetLOSTexture(); shader->BindTexture("losTex", los.GetTexture()); // Don't bother sending the whole matrix, we just need two floats (scale and translation) shader->Uniform("losTransform", los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f); diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 760d056e95..ae7758c1c3 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -459,6 +459,8 @@ CRenderer::CRenderer() m_LightEnv = NULL; + m_CurrentScene = NULL; + m_hCompositeAlphaMap = 0; AddLocalProperty(L"fancyWater", &m_Options.m_FancyWater, false); @@ -1832,19 +1834,28 @@ void CRenderer::SubmitNonRecursive(CModel* model) /////////////////////////////////////////////////////////// // Render the given scene -void CRenderer::RenderScene(Scene *scene) +void CRenderer::RenderScene(Scene& scene) { + m_CurrentScene = &scene; + CFrustum frustum = m_CullCamera.GetFrustum(); - scene->EnumerateObjects(frustum, this); + scene.EnumerateObjects(frustum, this); m->particleManager.RenderSubmit(*this, frustum); ogl_WarnIfError(); RenderSubmissions(); + + m_CurrentScene = NULL; } +Scene& CRenderer::GetScene() +{ + debug_assert(m_CurrentScene); + return *m_CurrentScene; +} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // BindTexture: bind a GL texture object to current active unit diff --git a/source/renderer/Renderer.h b/source/renderer/Renderer.h index 1caceecbf1..5e73e2b283 100644 --- a/source/renderer/Renderer.h +++ b/source/renderer/Renderer.h @@ -204,7 +204,13 @@ public: * Render the given scene immediately. * @param scene a Scene object describing what should be rendered. */ - void RenderScene(Scene* scene); + void RenderScene(Scene& scene); + + /** + * Return the scene that is currently being rendered. + * Only valid when the renderer is in a RenderScene call. + */ + Scene& GetScene(); /** * Render text overlays on top of the scene. @@ -398,6 +404,9 @@ protected: */ CCamera m_CullCamera; + // only valid inside a call to RenderScene + Scene* m_CurrentScene; + // color used to clear screen in BeginFrame float m_ClearColor[4]; // current lighting setup diff --git a/source/renderer/Scene.h b/source/renderer/Scene.h index 7153cfd4bd..762b7a8f88 100644 --- a/source/renderer/Scene.h +++ b/source/renderer/Scene.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -34,6 +34,7 @@ class CModelAbstract; class CModelDecal; class CParticleEmitter; class CPatch; +class CLOSTexture; struct SOverlayLine; struct SOverlaySprite; @@ -57,6 +58,11 @@ public: * that are visible. */ virtual void EnumerateObjects(const CFrustum& frustum, SceneCollector* c) = 0; + + /** + * Return the LOS texture to be used for rendering this scene. + */ + virtual CLOSTexture& GetLOSTexture() = 0; }; diff --git a/source/renderer/TerrainRenderer.cpp b/source/renderer/TerrainRenderer.cpp index 30ecf1cfe9..d54d85f4d1 100644 --- a/source/renderer/TerrainRenderer.cpp +++ b/source/renderer/TerrainRenderer.cpp @@ -276,7 +276,7 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow) 1.f }; - CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); + CLOSTexture& losTexture = g_Renderer.GetScene().GetLOSTexture(); int streamflags = STREAM_POS|STREAM_COLOR|STREAM_POSTOUV0; @@ -516,7 +516,7 @@ void TerrainRenderer::PrepareShader(const CShaderProgramPtr& shader, ShadowMap* shader->Uniform("shadowTransform", shadow->GetTextureMatrix()); } - CLOSTexture& los = g_Game->GetView()->GetLOSTexture(); + CLOSTexture& los = g_Renderer.GetScene().GetLOSTexture(); shader->BindTexture("losTex", los.GetTexture()); shader->Uniform("losTransform", los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f); @@ -679,9 +679,9 @@ void TerrainRenderer::RenderWater() m->fancyWaterShader = h; } } - CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); + CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); // TODO: stop using g_Game - CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); + CLOSTexture& losTexture = g_Renderer.GetScene().GetLOSTexture(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); diff --git a/source/simulation2/components/CCmpTerrain.cpp b/source/simulation2/components/CCmpTerrain.cpp index 94459672fc..fb9fcafc89 100644 --- a/source/simulation2/components/CCmpTerrain.cpp +++ b/source/simulation2/components/CCmpTerrain.cpp @@ -79,6 +79,16 @@ public: return m_Terrain->GetExactGroundLevel(x, z); } + virtual uint32_t GetVerticesPerSide() + { + return m_Terrain->GetVerticesPerSide(); + } + + virtual CTerrain* GetCTerrain() + { + return m_Terrain; + } + virtual void ReloadTerrain() { // TODO: should refactor this code to be nicer diff --git a/source/simulation2/components/ICmpTerrain.h b/source/simulation2/components/ICmpTerrain.h index 749a2c8c6c..f3f9f475ce 100644 --- a/source/simulation2/components/ICmpTerrain.h +++ b/source/simulation2/components/ICmpTerrain.h @@ -24,6 +24,8 @@ #include "maths/FixedVector3D.h" +class CTerrain; + class ICmpTerrain : public IComponent { public: @@ -33,6 +35,10 @@ public: virtual float GetExactGroundLevel(float x, float z) = 0; + virtual uint32_t GetVerticesPerSide() = 0; + + virtual CTerrain* GetCTerrain() = 0; + /** * Call when the underlying CTerrain has been modified behind our backs. * (TODO: eventually we should manage the CTerrain in this class so nobody diff --git a/source/tools/atlas/GameInterface/ActorViewer.cpp b/source/tools/atlas/GameInterface/ActorViewer.cpp index 163e5eb713..46ab493a9f 100644 --- a/source/tools/atlas/GameInterface/ActorViewer.cpp +++ b/source/tools/atlas/GameInterface/ActorViewer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -22,8 +22,10 @@ #include "View.h" #include "graphics/ColladaManager.h" +#include "graphics/LOSTexture.h" #include "graphics/Model.h" #include "graphics/ObjectManager.h" +#include "graphics/ParticleManager.h" #include "graphics/Patch.h" #include "graphics/SkeletonAnimManager.h" #include "graphics/Terrain.h" @@ -49,9 +51,16 @@ struct ActorViewerImpl : public Scene { NONCOPYABLE(ActorViewerImpl); public: - ActorViewerImpl() - : Entity(INVALID_ENTITY), Terrain(), ColladaManager(), MeshManager(ColladaManager), SkeletonAnimManager(ColladaManager), - UnitManager(), Simulation2(&UnitManager, &Terrain), ObjectManager(MeshManager, SkeletonAnimManager, Simulation2) + ActorViewerImpl() : + Entity(INVALID_ENTITY), + Terrain(), + ColladaManager(), + MeshManager(ColladaManager), + SkeletonAnimManager(ColladaManager), + UnitManager(), + Simulation2(&UnitManager, &Terrain), + ObjectManager(MeshManager, SkeletonAnimManager, Simulation2), + LOSTexture(Simulation2) { UnitManager.SetObjectManager(ObjectManager); } @@ -74,15 +83,26 @@ public: CObjectManager ObjectManager; CUnitManager UnitManager; CSimulation2 Simulation2; + CLOSTexture LOSTexture; // Simplistic implementation of the Scene interface - void EnumerateObjects(const CFrustum& frustum, SceneCollector* c) + virtual void EnumerateObjects(const CFrustum& frustum, SceneCollector* c) { if (GroundEnabled) - c->Submit(Terrain.GetPatch(0, 0)); + { + for (ssize_t pj = 0; pj < Terrain.GetPatchesPerSide(); ++pj) + for (ssize_t pi = 0; pi < Terrain.GetPatchesPerSide(); ++pi) + c->Submit(Terrain.GetPatch(pi, pj)); + } Simulation2.RenderSubmit(*c, frustum, false); } + + virtual CLOSTexture& GetLOSTexture() + { + return LOSTexture; + } + }; ActorViewer::ActorViewer() @@ -91,22 +111,28 @@ ActorViewer::ActorViewer() m.WalkEnabled = false; m.GroundEnabled = true; m.ShadowsEnabled = g_Renderer.GetOptionBool(CRenderer::OPT_SHADOWS); - m.Background = SColor4ub(255, 255, 255, 255); + m.Background = SColor4ub(0, 0, 0, 255); // Create a tiny empty piece of terrain, just so we can put shadows // on it without having to think too hard - m.Terrain.Initialize(1, NULL); + m.Terrain.Initialize(2, NULL); CTerrainTextureEntry* tex = g_TexMan.FindTexture("whiteness"); if (tex) { - CPatch* patch = m.Terrain.GetPatch(0, 0); - for (ssize_t i = 0; i < PATCH_SIZE; ++i) + for (ssize_t pi = 0; pi < m.Terrain.GetPatchesPerSide(); ++pi) { - for (ssize_t j = 0; j < PATCH_SIZE; ++j) + for (ssize_t pj = 0; pj < m.Terrain.GetPatchesPerSide(); ++pj) { - CMiniPatch& mp = patch->m_MiniPatches[i][j]; - mp.Tex = tex; - mp.Priority = 0; + CPatch* patch = m.Terrain.GetPatch(pi, pj); + for (ssize_t i = 0; i < PATCH_SIZE; ++i) + { + for (ssize_t j = 0; j < PATCH_SIZE; ++j) + { + CMiniPatch& mp = patch->m_MiniPatches[i][j]; + mp.Tex = tex; + mp.Priority = 0; + } + } } } } @@ -178,7 +204,8 @@ void ActorViewer::SetActor(const CStrW& name, const CStrW& animation) CmpPtr cmpPosition(m.Simulation2, m.Entity); if (!cmpPosition.null()) { - cmpPosition->JumpTo(entity_pos_t::FromInt(CELL_SIZE*PATCH_SIZE/2), entity_pos_t::FromInt(CELL_SIZE*PATCH_SIZE/2)); + ssize_t c = CELL_SIZE * m.Terrain.GetPatchesPerSide()*PATCH_SIZE/2; + cmpPosition->JumpTo(entity_pos_t::FromInt(c), entity_pos_t::FromInt(c)); cmpPosition->SetYRotation(entity_angle_t::FromFloat((float)M_PI)); } needsAnimReload = true; @@ -301,7 +328,7 @@ void ActorViewer::Render() cmpVisual->GetBounds().GetCentre(centre); else centre.Y = 0.f; - centre.X = centre.Z = CELL_SIZE * PATCH_SIZE/2; + centre.X = centre.Z = CELL_SIZE * m.Terrain.GetPatchesPerSide()*PATCH_SIZE/2; CCamera camera = View::GetView_Actor()->GetCamera(); camera.m_Orientation.Translate(centre.X, centre.Y, centre.Z); @@ -309,7 +336,7 @@ void ActorViewer::Render() g_Renderer.SetSceneCamera(camera, camera); - g_Renderer.RenderScene(&m); + g_Renderer.RenderScene(m); // .... @@ -352,6 +379,7 @@ void ActorViewer::Update(float dt) { m.Simulation2.Update((int)(dt*1000)); m.Simulation2.Interpolate(dt, 0); + g_Renderer.GetParticleManager().Interpolate(dt); if (m.WalkEnabled && m.CurrentSpeed) { @@ -362,8 +390,9 @@ void ActorViewer::Update(float dt) float z = cmpPosition->GetPosition().Z.ToFloat(); z -= m.CurrentSpeed*dt; // Wrap at the edges, so it doesn't run off into the horizon - if (z < CELL_SIZE*PATCH_SIZE * 0.4f) - z = CELL_SIZE*PATCH_SIZE * 0.6f; + ssize_t c = CELL_SIZE * m.Terrain.GetPatchesPerSide()*PATCH_SIZE/2; + if (z < c - CELL_SIZE*PATCH_SIZE * 0.1f) + z = c + CELL_SIZE*PATCH_SIZE * 0.1f; cmpPosition->JumpTo(cmpPosition->GetPosition().X, entity_pos_t::FromFloat(z)); } }