From 124f7171bdff6619cd3d1dcb6bd56b32dae778a3 Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Sun, 6 Nov 2005 05:05:07 +0000 Subject: [PATCH] More reliable texture blending. Resource unloading. Minor fixes. This was SVN commit r3106. --- source/graphics/GameView.cpp | 6 +-- source/graphics/ObjectManager.cpp | 34 ++++++++++------ source/graphics/ObjectManager.h | 1 + source/graphics/Terrain.cpp | 14 ++++--- source/graphics/Terrain.h | 4 +- source/graphics/TextureManager.cpp | 16 ++++++-- source/graphics/TextureManager.h | 2 + source/renderer/PatchRData.cpp | 3 +- source/renderer/TransparencyRenderer.cpp | 4 +- .../ScenarioEditor/Sections/Map/Map.cpp | 14 +++++++ .../Sections/Terrain/Terrain.cpp | 29 +++++++++----- .../GameInterface/Handlers/CameraCtrl.cpp | 2 + .../GameInterface/Handlers/Elevation.cpp | 6 +-- .../atlas/GameInterface/Handlers/Map.cpp | 7 ++++ .../Handlers/TerrainHandlers.cpp | 40 ++++--------------- .../atlas/GameInterface/InputProcessor.cpp | 3 ++ source/tools/atlas/GameInterface/Messages.h | 4 ++ 17 files changed, 112 insertions(+), 77 deletions(-) diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index 330169f072..194f33d0b3 100755 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -301,10 +301,8 @@ void CGameView::RenderNoCull() void CGameView::UnloadResources() { - // Should probably do something like: - // g_TexMan.UnloadTerrainTextures(); - // g_ObjMan.UnloadObjects(); - + g_ObjMan.UnloadObjects(); + g_TexMan.UnloadTerrainTextures(); g_Renderer.UnloadAlphaMaps(); g_Renderer.UnloadWaterTextures(); } diff --git a/source/graphics/ObjectManager.cpp b/source/graphics/ObjectManager.cpp index 9f15f68c77..dd6fb8e4a3 100755 --- a/source/graphics/ObjectManager.cpp +++ b/source/graphics/ObjectManager.cpp @@ -37,19 +37,7 @@ template static void delete_pair_2nd(std::pair v) { CObjectManager::~CObjectManager() { - for (size_t i = 0; i < m_ObjectTypes.size(); i++) { - std::for_each( - m_ObjectTypes[i].m_Objects.begin(), - m_ObjectTypes[i].m_Objects.end(), - delete_pair_2nd - ); - std::for_each( - m_ObjectTypes[i].m_ObjectBases.begin(), - m_ObjectTypes[i].m_ObjectBases.end(), - delete_pair_2nd - ); - } - delete m_SelectedThing; + UnloadObjects(); } @@ -176,6 +164,26 @@ int CObjectManager::LoadObjects() return 0; } +void CObjectManager::UnloadObjects() +{ + for (size_t i = 0; i < m_ObjectTypes.size(); i++) { + std::for_each( + m_ObjectTypes[i].m_Objects.begin(), + m_ObjectTypes[i].m_Objects.end(), + delete_pair_2nd + ); + std::for_each( + m_ObjectTypes[i].m_ObjectBases.begin(), + m_ObjectTypes[i].m_ObjectBases.end(), + delete_pair_2nd + ); + } + m_ObjectTypes.clear(); + + delete m_SelectedThing; + m_SelectedThing = NULL; +} + ////////////////////////////////////////////////////////////////////////// // For ScEd: diff --git a/source/graphics/ObjectManager.h b/source/graphics/ObjectManager.h index 618a2b2a3d..822273bcb0 100755 --- a/source/graphics/ObjectManager.h +++ b/source/graphics/ObjectManager.h @@ -58,6 +58,7 @@ public: ~CObjectManager(); int LoadObjects(); + void UnloadObjects(); void AddObjectType(const char* name); diff --git a/source/graphics/Terrain.cpp b/source/graphics/Terrain.cpp index e733e94686..53a054e97f 100755 --- a/source/graphics/Terrain.cpp +++ b/source/graphics/Terrain.cpp @@ -398,7 +398,7 @@ float CTerrain::FlattenArea(float x0,float x1,float z0,float z1) /////////////////////////////////////////////////////////////////////////////// -void CTerrain::MakeDirty(int x0, int z0, int x1, int z1) +void CTerrain::MakeDirty(int x0, int z0, int x1, int z1, int dirtyFlags) { // flag vertex data as dirty for affected patches, and rebuild bounds of these patches int px0 = clamp((x0/PATCH_SIZE)-1, 0, (int)m_MapSizePatches); @@ -408,19 +408,21 @@ void CTerrain::MakeDirty(int x0, int z0, int x1, int z1) for (int j = pz0; j < pz1; j++) { for (int i = px0; i < px1; i++) { CPatch* patch = GetPatch(i,j); - patch->CalcBounds(); - patch->SetDirty(RENDERDATA_UPDATE_VERTICES); + if (dirtyFlags & RENDERDATA_UPDATE_VERTICES) + patch->CalcBounds(); + patch->SetDirty(dirtyFlags); } } } -void CTerrain::MakeDirty() +void CTerrain::MakeDirty(int dirtyFlags) { for (u32 j = 0; j < m_MapSizePatches; j++) { for (u32 i = 0; i < m_MapSizePatches; i++) { CPatch* patch = GetPatch(i,j); - patch->CalcBounds(); - patch->SetDirty(RENDERDATA_UPDATE_VERTICES); + if (dirtyFlags & RENDERDATA_UPDATE_VERTICES) + patch->CalcBounds(); + patch->SetDirty(dirtyFlags); } } } diff --git a/source/graphics/Terrain.h b/source/graphics/Terrain.h index 0777d654b9..82aab6ee3e 100755 --- a/source/graphics/Terrain.h +++ b/source/graphics/Terrain.h @@ -77,9 +77,9 @@ public: float FlattenArea(float x0,float x1,float z0,float z1); // mark a specific square of tiles as dirty - use this after modifying the heightmap - void MakeDirty(int x0, int z0, int x1, int z1); + void MakeDirty(int x0, int z0, int x1, int z1, int dirtyFlags); // mark the entire map as dirty - void MakeDirty(); + void MakeDirty(int dirtyFlags); private: // delete any data allocated by this terrain diff --git a/source/graphics/TextureManager.cpp b/source/graphics/TextureManager.cpp index c561e4fbbf..0d16efbfa0 100755 --- a/source/graphics/TextureManager.cpp +++ b/source/graphics/TextureManager.cpp @@ -28,16 +28,24 @@ CTextureManager::CTextureManager(): CTextureManager::~CTextureManager() { - for (size_t i=0;isecond; ++it; } + m_TerrainGroups.clear(); + + m_LastGroupIndex = 0; } CTextureEntry* CTextureManager::FindTexture(CStr tag) diff --git a/source/graphics/TextureManager.h b/source/graphics/TextureManager.h index 99e2a88c09..29dd54fdc0 100755 --- a/source/graphics/TextureManager.h +++ b/source/graphics/TextureManager.h @@ -83,6 +83,8 @@ public: // Find all XML's in the directory (with subdirs) and try to load them as // terrain XML's int LoadTerrainTextures(); + + void UnloadTerrainTextures(); CTextureEntry* FindTexture(CStr tag); CTextureEntry* FindTexture(Handle handle); diff --git a/source/renderer/PatchRData.cpp b/source/renderer/PatchRData.cpp index 79219bdbae..87c797bbc1 100755 --- a/source/renderer/PatchRData.cpp +++ b/source/renderer/PatchRData.cpp @@ -86,6 +86,7 @@ void CPatchRData::BuildBlends() m_BlendIndices.clear(); m_BlendSplats.clear(); m_BlendVertices.clear(); + m_BlendVertexIndices.clear(); // get index of this patch (unused) //int px=m_Patch->m_X; @@ -110,7 +111,7 @@ void CPatchRData::BuildBlends() for (int m=-1;m<=1;m++) { for (int k=-1;k<=1;k++) { CMiniPatch* nmp=terrain->GetTile(gx+k,gz+m); - if (nmp) { + if (nmp && nmp->Tex1 != mp->Tex1) { if (nmp->Tex1Priority>mp->Tex1Priority || (nmp->Tex1Priority==mp->Tex1Priority && nmp->Tex1>mp->Tex1)) { STex tex; tex.m_Handle=nmp->Tex1; diff --git a/source/renderer/TransparencyRenderer.cpp b/source/renderer/TransparencyRenderer.cpp index d4444edc52..ca9bad922d 100755 --- a/source/renderer/TransparencyRenderer.cpp +++ b/source/renderer/TransparencyRenderer.cpp @@ -601,7 +601,7 @@ void TransparentRenderModifier::PrepareTexture(uint UNUSED(pass), CTexture* text void TransparentRenderModifier::PrepareModel(uint UNUSED(pass), CModel* UNUSED(model)) { - // No per-model setup nececssary + // No per-model setup necessary } @@ -654,5 +654,5 @@ void TransparentShadowRenderModifier::PrepareTexture(uint UNUSED(pass), CTexture void TransparentShadowRenderModifier::PrepareModel(uint UNUSED(pass), CModel* UNUSED(model)) { - // No per-model setup nececssary + // No per-model setup necessary } diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp index 5d8b7c2304..0d13a56cd0 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp @@ -28,6 +28,19 @@ static void LoadMap(void*) // TODO: Make this a non-undoable command } +static void SaveMap(void*) +{ + wxFileDialog dlg (NULL, wxFileSelectorPromptStr, Datafile::GetDataDirectory()+_T("/mods/official/maps/scenarios"), + _T(""), _T("PMP files (*.pmp)|*.pmp|All files (*.*)|*.*"), wxSAVE|wxOVERWRITE_PROMPT); + + if (dlg.ShowModal() == wxID_OK) + { + // TODO: Work when the map is not in .../maps/scenarios/ + std::wstring map = dlg.GetFilename().c_str(); + POST_MESSAGE(SaveMap(map)); + } +} + static void GenerateMap(void*) { POST_MESSAGE(GenerateMap(9)); @@ -56,6 +69,7 @@ MapSidebar::MapSidebar(wxWindow* parent) // TODO: Intercept arrow keys and send them to the GL window m_MainSizer->Add(new ActionButton(this, _T("Load existing map"), &LoadMap, NULL)); + m_MainSizer->Add(new ActionButton(this, _T("Save map"), &SaveMap, NULL)); m_MainSizer->Add(new ActionButton(this, _T("Generate empty map"), &GenerateMap, NULL)); { diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp index 32307793b9..c893a37202 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp @@ -52,20 +52,25 @@ class TextureNotebookPage : public wxPanel { public: TextureNotebookPage(wxWindow* parent, const wxString& name) - : wxPanel(parent, wxID_ANY), m_Name(name), m_Loaded(false) + : wxPanel(parent, wxID_ANY), m_Name(name), m_ListCtrl(NULL) { } void OnDisplay() { - if (m_Loaded) + if (m_ListCtrl) + { + int sel = m_ListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (sel != -1) + SetSelection(m_ListCtrl->GetItemData(sel)); return; + } m_TextureNames.Clear(); wxSizer* sizer = new wxBoxSizer(wxVERTICAL); - wxListCtrl* list = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ICON | wxLC_SINGLE_SEL | wxLC_AUTOARRANGE); + m_ListCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ICON | wxLC_SINGLE_SEL | wxLC_AUTOARRANGE); const int imageWidth = 64; const int imageHeight = 32; @@ -93,25 +98,29 @@ public: item.SetId(i); item.SetImage(i); - list->InsertItem(item); + m_ListCtrl->InsertItem(item); ++i; } - list->AssignImageList(imglist, wxIMAGE_LIST_NORMAL); + m_ListCtrl->AssignImageList(imglist, wxIMAGE_LIST_NORMAL); - sizer->Add(list, wxSizerFlags().Expand().Proportion(1)); + sizer->Add(m_ListCtrl, wxSizerFlags().Expand().Proportion(1)); SetSizer(sizer); Layout(); // required to make things size correctly - - m_Loaded = true; } void OnSelect(wxListEvent& evt) { - g_SelectedTexture = m_TextureNames[evt.GetData()]; + SetSelection(evt.GetData()); + } + + void SetSelection(int n) + { + if (n >= 0 && n < (int)m_TextureNames.GetCount()) + g_SelectedTexture = m_TextureNames[n]; } private: - bool m_Loaded; + wxListCtrl* m_ListCtrl; wxString m_Name; wxArrayString m_TextureNames; diff --git a/source/tools/atlas/GameInterface/Handlers/CameraCtrl.cpp b/source/tools/atlas/GameInterface/Handlers/CameraCtrl.cpp index 9d43e30691..d20d00f3b1 100644 --- a/source/tools/atlas/GameInterface/Handlers/CameraCtrl.cpp +++ b/source/tools/atlas/GameInterface/Handlers/CameraCtrl.cpp @@ -63,6 +63,7 @@ MESSAGEHANDLER(Scroll) g_Game->GetView()->GetCamera()->BuildCameraRay(x, y, origin, dir); dir *= targetDistance; camera.Translate(targetPos - dir - origin); + g_Game->GetView()->GetCamera()->UpdateFrustum(); } else { @@ -115,6 +116,7 @@ MESSAGEHANDLER(RotateAround) camera._21 = 0.f; // (_21 = Y component returned by GetLeft()) camera.Translate(focusPos + offset); + g_Game->GetView()->GetCamera()->UpdateFrustum(); lastX = x; lastY = y; diff --git a/source/tools/atlas/GameInterface/Handlers/Elevation.cpp b/source/tools/atlas/GameInterface/Handlers/Elevation.cpp index 3f1d2113c7..a2a9d9b363 100644 --- a/source/tools/atlas/GameInterface/Handlers/Elevation.cpp +++ b/source/tools/atlas/GameInterface/Handlers/Elevation.cpp @@ -88,19 +88,19 @@ BEGIN_COMMAND(AlterElevation) m_TerrainDelta.RaiseVertex(x0+dx, y0+dy, amount*b); } - g_Game->GetWorld()->GetTerrain()->MakeDirty(x0, y0, x0+g_CurrentBrush.m_W, y0+g_CurrentBrush.m_H); + g_Game->GetWorld()->GetTerrain()->MakeDirty(x0, y0, x0+g_CurrentBrush.m_W, y0+g_CurrentBrush.m_H, RENDERDATA_UPDATE_VERTICES); } void Undo() { m_TerrainDelta.Undo(); - g_Game->GetWorld()->GetTerrain()->MakeDirty(); + g_Game->GetWorld()->GetTerrain()->MakeDirty(RENDERDATA_UPDATE_VERTICES); } void Redo() { m_TerrainDelta.Redo(); - g_Game->GetWorld()->GetTerrain()->MakeDirty(); + g_Game->GetWorld()->GetTerrain()->MakeDirty(RENDERDATA_UPDATE_VERTICES); } void MergeWithSelf(cAlterElevation* prev) diff --git a/source/tools/atlas/GameInterface/Handlers/Map.cpp b/source/tools/atlas/GameInterface/Handlers/Map.cpp index 2cf9b71712..2d601eb822 100644 --- a/source/tools/atlas/GameInterface/Handlers/Map.cpp +++ b/source/tools/atlas/GameInterface/Handlers/Map.cpp @@ -5,6 +5,7 @@ #include "graphics/Patch.h" #include "graphics/TextureManager.h" #include "graphics/TextureEntry.h" +#include "graphics/MapWriter.h" #include "ps/Game.h" #include "ps/GameAttributes.h" #include "ps/Loader.h" @@ -96,4 +97,10 @@ MESSAGEHANDLER(LoadMap) StartGame(); } +MESSAGEHANDLER(SaveMap) +{ + CMapWriter writer; + writer.SaveMap(CStr(L"maps/scenarios/" + msg->filename), g_Game->GetWorld()->GetTerrain(), &g_LightEnv, g_Game->GetWorld()->GetUnitManager()); +} + } diff --git a/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp index 3227db2885..d1e80def20 100644 --- a/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp @@ -115,43 +115,19 @@ BEGIN_COMMAND(PaintTerrain) if ((unsigned)x >= m_VertsPerSide-1 || (unsigned)y >= m_VertsPerSide-1) return; - set(x,y, TerrainTile(tex, priority == ePaintTerrainPriority::HIGH ? 1 : -1)); -/* (TODO: fix all this) // Priority system: If the new tile should have a high priority, // set it to one plus the maximum priority of all surrounding tiles - // TODO: the blending system is broken when adjacent tiles have - // the same priority but different textures - int greatestSame = 0; - int greatestDiff = 0; + // (so that it's definitely the highest). + // Similar for low priority. + int greatest = 0; int scale = (priority == ePaintTerrainPriority::HIGH ? +1 : -1); CMiniPatch* tile; -#define TILE(dx, dy) \ - tile = m_Terrain->GetTile(x dx, y dy); \ - if (tile) { \ - if (tile->Tex1 == tex && tile->Tex1Priority*scale > greatestSame) \ - greatestSame = tile->Tex1Priority*scale; \ - else if (tile->Tex1 != tex && tile->Tex1Priority*scale > greatestDiff) \ - greatestDiff = tile->Tex1Priority*scale; \ - } +#define TILE(dx, dy) tile = m_Terrain->GetTile(x dx, y dy); if (tile && tile->Tex1Priority*scale > greatest) greatest = tile->Tex1Priority*scale; TILE(-1, -1) TILE(+0, -1) TILE(+1, -1) TILE(-1, +0) TILE(+1, +0) TILE(-1, +1) TILE(+0, +1) TILE(+1, +1) #undef TILE - // If the greatest priority is of the same texture as this one, - // give this one the same priority (to minimise confusion in the - // blending system) - if (greatestSame > greatestDiff) - { - tile = m_Terrain->GetTile(x,y); - // Don't bother updating tiles that are exactly the same - // (e.g. when dragging big brushes around) - if (tile->Tex1 != tex || tile->Tex1Priority != greatestSame) - set(x,y, TerrainTile(tex, greatestSame*scale)); - } - // Set this texture to have a priority greater than the surrounding ones - else - set(x,y, TerrainTile(tex, (greatestDiff+1)*scale)); -*/ + set(x,y, TerrainTile(tex, (greatest+1)*scale)); } protected: @@ -204,19 +180,19 @@ BEGIN_COMMAND(PaintTerrain) m_TerrainDelta.PaintTile(x0+dx, y0+dy, texture, d->priority); } - g_Game->GetWorld()->GetTerrain()->MakeDirty(x0, y0, x0+g_CurrentBrush.m_W, y0+g_CurrentBrush.m_H); + g_Game->GetWorld()->GetTerrain()->MakeDirty(x0, y0, x0+g_CurrentBrush.m_W, y0+g_CurrentBrush.m_H, RENDERDATA_UPDATE_INDICES); } void Undo() { m_TerrainDelta.Undo(); - g_Game->GetWorld()->GetTerrain()->MakeDirty(); + g_Game->GetWorld()->GetTerrain()->MakeDirty(RENDERDATA_UPDATE_INDICES); } void Redo() { m_TerrainDelta.Redo(); - g_Game->GetWorld()->GetTerrain()->MakeDirty(); + g_Game->GetWorld()->GetTerrain()->MakeDirty(RENDERDATA_UPDATE_INDICES); } void MergeWithSelf(cPaintTerrain* prev) diff --git a/source/tools/atlas/GameInterface/InputProcessor.cpp b/source/tools/atlas/GameInterface/InputProcessor.cpp index 998b50f451..a6a856d2db 100644 --- a/source/tools/atlas/GameInterface/InputProcessor.cpp +++ b/source/tools/atlas/GameInterface/InputProcessor.cpp @@ -66,5 +66,8 @@ bool InputProcessor::ProcessInput(GameLoopState* state) moved = true; } + if (moved) + camera->UpdateFrustum(); + return moved; } diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h index bc7e41df79..317b6ce6ec 100644 --- a/source/tools/atlas/GameInterface/Messages.h +++ b/source/tools/atlas/GameInterface/Messages.h @@ -30,6 +30,10 @@ MESSAGE(LoadMap, ((std::wstring, filename)) ); +MESSAGE(SaveMap, + ((std::wstring, filename)) + ); + ////////////////////////////////////////////////////////////////////////// MESSAGE(RenderStyle,