diff --git a/Source/Render/tilemap/TileMap.cpp b/Source/Render/tilemap/TileMap.cpp index 7ad94dce..248d26da 100644 --- a/Source/Render/tilemap/TileMap.cpp +++ b/Source/Render/tilemap/TileMap.cpp @@ -179,7 +179,6 @@ cTileMap::cTileMap(cScene* pScene,TerraInterface* terra_) : cUnkObj(KIND_TILEMAP TexturePoolSize = 512; tilesize.set(0,0,0); - pTileMapRender=NULL; ShadowDrawNode=pScene->CreateCamera(); LightDrawNode=new cCameraPlanarLight(pScene); @@ -199,7 +198,11 @@ cTileMap::~cTileMap() gb_RenderDevice->DeleteTilemap(this); if(Tile) { delete [] Tile; Tile=nullptr; } MTDONE(lock_update_rect); - xassert(pTileMapRender == nullptr); + + for (auto& p : pTileMapRender) + { + xassert(p == nullptr); + } } int cTileMap::CheckLightMapType() @@ -313,10 +316,19 @@ void cTileMap::PreDraw(cCamera *DrawNode) DrawNode->Attach(SCENENODE_OBJECT_TILEMAP,this); - cTileMapRender* render = GetTilemapRender(); - if (render) { - render->PreDraw(DrawNode); - } + for (auto& render : pTileMapRender) + { + if (render) { + render->PreDraw(DrawNode); + } + } + + for (int y=0; y < GetTileNumber().y; y++) { + for (int x = 0; x < GetTileNumber().x; x++) { + auto& Tile = GetTile(x, y); + Tile.ClearAttribute(ATTRTILE_UPDATELOD); + } + } } void cTileMap::Draw(cCamera *DrawNode) @@ -324,7 +336,7 @@ void cTileMap::Draw(cCamera *DrawNode) if(!Option_ShowType[SHOW_TILEMAP]) return; - cTileMapRender* render = GetTilemapRender(); + cTileMapRender* render = GetTilemapRender(RenderType::DIRECT); if (!render) return; if(DrawNode->GetAttribute(ATTRCAMERA_SHADOW)) @@ -334,14 +346,23 @@ void cTileMap::Draw(cCamera *DrawNode) else if(DrawNode->GetAttribute(ATTRCAMERA_SHADOWMAP)) { if(Option_ShadowType==SHADOW_MAP_SELF) { - render->DrawBump(DrawNode, ALPHA_TEST, TILEMAP_ALL, true); + cTileMapRender* shadowRender = GetTilemapRender(RenderType::SHADOW); + if (shadowRender) + { + shadowRender->DrawBump(DrawNode, ALPHA_TEST, TILEMAP_ALL, true); + } } } else if(DrawNode->GetAttribute(ATTRCAMERA_REFLECTION)) - { // рисовать отражение - gb_RenderDevice->SetRenderState(RS_ALPHA_TEST_MODE, ALPHATEST_GT_254/*GetRefSurface()*/); - render->DrawBump(DrawNode, ALPHA_TEST, TILEMAP_NOZEROPLAST, false); - gb_RenderDevice->SetRenderState(RS_ALPHA_TEST_MODE, ALPHATEST_GT_0); + { + // рисовать отражение + cTileMapRender* reflectionRender = GetTilemapRender(RenderType::REFLECTION); + if (reflectionRender) + { + gb_RenderDevice->SetRenderState(RS_ALPHA_TEST_MODE, ALPHATEST_GT_254/*GetRefSurface()*/); + reflectionRender->DrawBump(DrawNode, ALPHA_TEST, TILEMAP_NOZEROPLAST, false); + gb_RenderDevice->SetRenderState(RS_ALPHA_TEST_MODE, ALPHATEST_GT_0); + } }else { if(GetAttribute(ATTRUNKOBJ_REFLECTION)) { diff --git a/Source/Render/tilemap/TileMap.h b/Source/Render/tilemap/TileMap.h index 47889d91..d7016796 100644 --- a/Source/Render/tilemap/TileMap.h +++ b/Source/Render/tilemap/TileMap.h @@ -1,6 +1,8 @@ #ifndef PERIMETER_TILEMAP_H #define PERIMETER_TILEMAP_H +#include + class cScene; typedef std::vector Vect2sVect; @@ -30,12 +32,7 @@ struct sTile : public sAttribute zmin=255;zmax=0; } - inline int GetDraw() { return GetAttribute(ATTRTILE_DRAWLOD); } inline int GetUpdate() { return GetAttribute(ATTRTILE_UPDATELOD); } - inline void SetDraw() { SetAttribute(ATTRTILE_DRAWLOD); } - - inline void ClearDraw() { ClearAttribute(ATTRTILE_DRAWLOD); } - inline void ClearUpdate() { ClearAttribute(ATTRTILE_UPDATELOD); } }; typedef std::vector* > CurrentRegion; @@ -45,6 +42,18 @@ class cTileMapRender; class Column; class cTileMap : public cUnkObj { +public: + enum class RenderType + { + REFLECTION, SHADOW, DIRECT + }; + static inline const std::array RenderTypes{ + RenderType::REFLECTION, + RenderType::SHADOW, + RenderType::DIRECT + }; + +private: friend class cScene; sTile* Tile; @@ -54,7 +63,7 @@ class cTileMap : public cUnkObj Vect3d tilesize; - cTileMapRender* pTileMapRender = nullptr; + std::array pTileMapRender{}; cCamera* ShadowDrawNode; cCamera* LightDrawNode; @@ -119,11 +128,19 @@ class cTileMap : public cUnkObj zeroplast_color[player]=color; } - void SetTilemapRender(cTileMapRender* p) { - VISASSERT(p == nullptr || pTileMapRender == nullptr); - pTileMapRender=p; + void SetTilemapRender(RenderType type, cTileMapRender* p) + { + const auto index = static_cast(type); + VISASSERT(index < pTileMapRender.size()); + VISASSERT(p == nullptr || pTileMapRender[index] == nullptr); + pTileMapRender[index] = p; }; - cTileMapRender* GetTilemapRender(){return pTileMapRender;} + cTileMapRender* GetTilemapRender(RenderType type) + { + const auto index = static_cast(type); + VISASSERT(index < pTileMapRender.size()); + return pTileMapRender[index]; + } TerraInterface* GetTerra(){return terra;} diff --git a/Source/Render/tilemap/TileMapBumpTile.cpp b/Source/Render/tilemap/TileMapBumpTile.cpp index 4047cc05..b5365561 100644 --- a/Source/Render/tilemap/TileMapBumpTile.cpp +++ b/Source/Render/tilemap/TileMapBumpTile.cpp @@ -17,10 +17,11 @@ float sBumpTile::SetVertexZ(TerraInterface* terra,int x,int y) return zi; } -sBumpTile::sBumpTile(cTileMap* tilemap, cTilemapTexturePool* pool, int lod, int xpos, int ypos) +sBumpTile::sBumpTile(cTileMap* tilemap, cTileMapRender* render, cTilemapTexturePool* pool, int lod, int xpos, int ypos) { this->tilemap = tilemap; - cTileMapRender* render = tilemap->GetTilemapRender(); + this->render = render; + tile_pos.set(xpos,ypos); texPool = pool; texPage = texPool->allocPage(); @@ -45,7 +46,7 @@ sBumpTile::sBumpTile(cTileMap* tilemap, cTilemapTexturePool* pool, int lod, int sBumpTile::~sBumpTile() { - tilemap->GetTilemapRender()->GetVertexPool()->DeletePage(vtx); + render->GetVertexPool()->DeletePage(vtx); texPool->freePage(texPage); DeleteIndex(); @@ -55,7 +56,7 @@ void sBumpTile::DeleteIndex() { for (auto& i : index) { if (i.index.page >= 0) { - tilemap->GetTilemapRender()->GetIndexPool()->DeletePage(i.index); + render->GetIndexPool()->DeletePage(i.index); } } index.clear(); @@ -68,7 +69,7 @@ uint8_t* sBumpTile::LockTex(int& Pitch) uint8_t *sBumpTile::LockVB() { - return static_cast(tilemap->GetTilemapRender()->GetVertexPool()->LockPage(vtx)); + return static_cast(render->GetVertexPool()->LockPage(vtx)); } void sBumpTile::UnlockTex() @@ -78,7 +79,7 @@ void sBumpTile::UnlockTex() void sBumpTile::UnlockVB() { - tilemap->GetTilemapRender()->GetVertexPool()->UnlockPage(vtx); + render->GetVertexPool()->UnlockPage(vtx); } inline int IUCLAMP(int val,int clamp) @@ -127,7 +128,6 @@ void sBumpTile::CalcPoint() Column** columns = tilemap->GetColumn(); Vect2i pos=tile_pos; - cTileMapRender* render = tilemap->GetTilemapRender(); render->IncUpdate(this); int tilenumber = tilemap->GetZeroplastNumber(); diff --git a/Source/Render/tilemap/TileMapBumpTile.h b/Source/Render/tilemap/TileMapBumpTile.h index 74401119..f4319b88 100644 --- a/Source/Render/tilemap/TileMapBumpTile.h +++ b/Source/Render/tilemap/TileMapBumpTile.h @@ -51,6 +51,7 @@ struct sBumpTile int age, LOD; class cTileMap *tilemap; + cTileMapRender* render; class cTilemapTexturePool* texPool; int texPage = 0; @@ -70,7 +71,7 @@ struct sBumpTile protected: float vStart, vStep, uStart, uStep; public: - sBumpTile(cTileMap* TileMap, cTilemapTexturePool* pool, int lod, int xpos, int ypos); + sBumpTile(cTileMap* TileMap, cTileMapRender* render, cTilemapTexturePool* pool, int lod, int xpos, int ypos); ~sBumpTile(); uint8_t* LockTex(int& Pitch); uint8_t* LockVB(); diff --git a/Source/Render/tilemap/TileMapRender.cpp b/Source/Render/tilemap/TileMapRender.cpp index 11f8d846..d35b5725 100644 --- a/Source/Render/tilemap/TileMapRender.cpp +++ b/Source/Render/tilemap/TileMapRender.cpp @@ -1,3 +1,4 @@ +#include #include "StdAfxRD.h" #include "PoolManager.h" #include "TileMap.h" @@ -12,20 +13,27 @@ int cInterfaceRenderDevice::CreateTilemap(cTileMap *TileMap) { - cTileMapRender* p = new cTileMapRender(TileMap); - TileMap->SetTilemapRender(p); - p->RestoreTilemapPool(); + for (auto type : cTileMap::RenderTypes) + { + cTileMapRender* p = new cTileMapRender(TileMap); + TileMap->SetTilemapRender(type, p); + p->RestoreTilemapPool(); + } + return 0; } int cInterfaceRenderDevice::DeleteTilemap(cTileMap *TileMap) { - cTileMapRender* p = TileMap->GetTilemapRender(); + for (auto type : cTileMap::RenderTypes) + { + cTileMapRender* p = TileMap->GetTilemapRender(type); - if (p) { - p->ClearTilemapPool(); - TileMap->SetTilemapRender(nullptr); - delete p; + if (p) { + p->ClearTilemapPool(); + TileMap->SetTilemapRender(type, nullptr); + delete p; + } } return true; @@ -41,6 +49,8 @@ cTileMapRender::cTileMapRender(cTileMap *pTileMap) for(int i=0;iGetTileNumber().y; y++) { for (int x = 0; x < tilemap->GetTileNumber().x; x++) { - sTile& Tile = tilemap->GetTile(x, y); - int& bumpTileID = Tile.bumpTileID; - bumpTileID = -1; + auto& Tile = GetRenderTile(x, y); + Tile.bumpTileID = -1; } } @@ -153,7 +162,7 @@ void cTileMapRender::PreDraw(cCamera* DrawNode) for(int y=0; y < tilemap->GetTileNumber().y; y++) for(int x=0; x < tilemap->GetTileNumber().x; x++) { - sTile &Tile = tilemap->GetTile(x, y); + sRenderTile &Tile = GetRenderTile(x, y); int &bumpTileID = Tile.bumpTileID; if(!Tile.GetAttribute(ATTRTILE_DRAWLOD)) { @@ -162,6 +171,10 @@ void cTileMapRender::PreDraw(cCamera* DrawNode) } Tile.ClearAttribute(ATTRTILE_DRAWLOD); + + if (tilemap->GetTile(x, y).GetAttribute(ATTRTILE_UPDATELOD)) { + Tile.SetAttribute(ATTRTILE_UPDATELOD); + } } if(update_stat) @@ -218,7 +231,7 @@ int cTileMapRender::bumpTileAlloc(int lod,int xpos,int ypos) int w = tilemap->GetTileSize().x >> bumpTexScale[lod]; int h = tilemap->GetTileSize().y >> bumpTexScale[lod]; cTilemapTexturePool* pool = FindFreeTexturePool(w, h); - sBumpTile* tile = new sBumpTile(tilemap, pool, lod, xpos, ypos); + sBumpTile* tile = new sBumpTile(tilemap, this, pool, lod, xpos, ypos); int i; for (i = 0; i < bumpTiles.size(); i++) { if (!bumpTiles[i]) { @@ -310,7 +323,6 @@ void cTileMapRender::DrawBump(cCamera* DrawNode,eBlendMode MatMode,TILEMAP_DRAW cCamera* pShadowMapCamera=DrawNode->FindCildCamera(ATTRCAMERA_SHADOWMAP); int reflection = DrawNode->GetAttribute(ATTRCAMERA_REFLECTION); cCamera* pNormalCamera=DrawNode->GetRoot(); - cTileMapRender* render=tilemap->GetTilemapRender(); bool use_shadow_map=false; //TODO remove this once D3D9 specifics are removed @@ -464,7 +476,7 @@ void cTileMapRender::DrawBump(cCamera* DrawNode,eBlendMode MatMode,TILEMAP_DRAW /**/ { // process visible tile - sTile &Tile = tilemap->GetTile(k, n); + sRenderTile &Tile = GetRenderTile(k, n); int &bumpTileID = Tile.bumpTileID; // calc LOD считается всегда по отгошению к прямой камере для @@ -477,8 +489,7 @@ void cTileMapRender::DrawBump(cCamera* DrawNode,eBlendMode MatMode,TILEMAP_DRAW vis_lod[k+n*dk]=iLod; // create/update render tile - if (render->bumpTileValid(bumpTileID) - && render->bumpTiles[bumpTileID]->LOD != iLod && !shadow) + if (bumpTileValid(bumpTileID) && bumpTiles[bumpTileID]->LOD != iLod && !shadow) { // LOD changed, free old tile and allocate new bumpTileFree(bumpTileID); @@ -520,7 +531,7 @@ void cTileMapRender::DrawBump(cCamera* DrawNode,eBlendMode MatMode,TILEMAP_DRAW for (n = 0; n < dn; n++) for (k = 0; k < dk; k++) { - sTile &Tile = tilemap->GetTile(k, n); + sRenderTile &Tile = GetRenderTile(k, n); int bumpTileID = Tile.bumpTileID; if(bumpTileID<0)continue; sBumpTile *bumpTile = bumpTiles[bumpTileID]; @@ -607,8 +618,8 @@ void cTileMapRender::DrawBump(cCamera* DrawNode,eBlendMode MatMode,TILEMAP_DRAW int nTiles = 0; VertexBuffer* lastVB = nullptr; #endif - VertexPoolManager* vtxPoolMan = render->GetVertexPool(); - IndexPoolManager* idxPoolMan = render->GetIndexPool(); + VertexPoolManager* vtxPoolMan = GetVertexPool(); + IndexPoolManager* idxPoolMan = GetIndexPool(); for (cTilemapTexturePool* curpool : bumpTexPools) { if (curpool->tileRenderList.empty()) { continue; diff --git a/Source/Render/tilemap/TileMapRender.h b/Source/Render/tilemap/TileMapRender.h index 1f36aa4b..177a5f2d 100644 --- a/Source/Render/tilemap/TileMapRender.h +++ b/Source/Render/tilemap/TileMapRender.h @@ -24,12 +24,26 @@ class cTileMapRender char* update_stat; bool update_in_frame; + struct sRenderTile final : public sAttribute + { + int bumpTileID = -1; + + inline int GetDraw() { return GetAttribute(ATTRTILE_DRAWLOD); } + inline int GetUpdate() { return GetAttribute(ATTRTILE_UPDATELOD); } + inline void SetDraw() { SetAttribute(ATTRTILE_DRAWLOD); } + + inline void ClearDraw() { ClearAttribute(ATTRTILE_DRAWLOD); } + inline void ClearUpdate() { ClearAttribute(ATTRTILE_UPDATELOD); } + }; + std::vector renderTiles; + void SaveUpdateStat(); VectDelta* delta_buffer; std::vector> index_buffer; cTilemapTexturePool* FindFreeTexturePool(int tex_width, int tex_height); + sRenderTile& GetRenderTile(int i, int j) { return renderTiles[i + j*tilemap->GetTileNumber().x]; } public: void IncUpdate(sBumpTile* pbump);