improve map far view rendering
This commit is contained in:
parent
51b0822267
commit
aa1a10afbc
|
@ -64,7 +64,7 @@ void MapView::draw(const Rect& rect)
|
||||||
else if(m_viewRange == MID_VIEW)
|
else if(m_viewRange == MID_VIEW)
|
||||||
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems;
|
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems;
|
||||||
else if(m_viewRange == FAR_VIEW)
|
else if(m_viewRange == FAR_VIEW)
|
||||||
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems;
|
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls;
|
||||||
else // HUGE_VIEW
|
else // HUGE_VIEW
|
||||||
tileDrawFlags = Otc::DrawGround;
|
tileDrawFlags = Otc::DrawGround;
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ void MapView::draw(const Rect& rect)
|
||||||
Size tileStretchedSize = Size(m_tileSize * horizontalStretchFactor, m_tileSize * verticalStretchFactor);
|
Size tileStretchedSize = Size(m_tileSize * horizontalStretchFactor, m_tileSize * verticalStretchFactor);
|
||||||
|
|
||||||
// avoid drawing texts on map in far zoom outs
|
// avoid drawing texts on map in far zoom outs
|
||||||
if(tileStretchedSize.width() >= 24) {
|
if(m_viewRange == NEAR_VIEW) {
|
||||||
for(const CreaturePtr& creature : m_cachedFloorVisibleCreatures) {
|
for(const CreaturePtr& creature : m_cachedFloorVisibleCreatures) {
|
||||||
const TilePtr& tile = creature->getCurrentTile();
|
const TilePtr& tile = creature->getCurrentTile();
|
||||||
Position pos = tile->getPosition();
|
Position pos = tile->getPosition();
|
||||||
|
@ -154,10 +154,8 @@ void MapView::draw(const Rect& rect)
|
||||||
p += rect.topLeft();
|
p += rect.topLeft();
|
||||||
animatedText->draw(p, rect);
|
animatedText->draw(p, rect);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
// draw a arrow for position the center in non near views
|
||||||
// draw a arrow for position the center in non near views
|
|
||||||
if(m_viewRange != NEAR_VIEW) {
|
|
||||||
g_painter.setColor(Fw::red);
|
g_painter.setColor(Fw::red);
|
||||||
g_painter.drawFilledRect(Rect(rect.center(), 4, 4));
|
g_painter.drawFilledRect(Rect(rect.center(), 4, 4));
|
||||||
}
|
}
|
||||||
|
@ -200,26 +198,126 @@ void MapView::updateVisibleTilesCache(int start)
|
||||||
// cache visible tiles in draw order
|
// cache visible tiles in draw order
|
||||||
// draw from last floor (the lower) to first floor (the higher)
|
// draw from last floor (the lower) to first floor (the higher)
|
||||||
for(int iz = m_cachedLastVisibleFloor; iz >= m_cachedFirstVisibleFloor && !stop; --iz) {
|
for(int iz = m_cachedLastVisibleFloor; iz >= m_cachedFirstVisibleFloor && !stop; --iz) {
|
||||||
// draw tiles like linus pauling's rule order
|
//TODO: cleanup this code
|
||||||
const int numDiagonals = m_drawDimension.width() + m_drawDimension.height() - 1;
|
if(m_viewRange <= FAR_VIEW) {
|
||||||
for(int diagonal = 0; diagonal < numDiagonals && !stop; ++diagonal) {
|
// draw tiles like linus pauling's rule order
|
||||||
// loop through / diagonal tiles
|
const int numDiagonals = m_drawDimension.width() + m_drawDimension.height() - 1;
|
||||||
for(int ix = std::min(diagonal, m_drawDimension.width() - 1), iy = std::max(diagonal - m_drawDimension.width() + 1, 0); ix >= 0 && iy < m_drawDimension.height() && !stop; --ix, ++iy) {
|
for(int diagonal = 0; diagonal < numDiagonals && !stop; ++diagonal) {
|
||||||
// only start really looking tiles in the desired start
|
// loop through / diagonal tiles
|
||||||
if(count < start) {
|
for(int ix = std::min(diagonal, m_drawDimension.width() - 1), iy = std::max(diagonal - m_drawDimension.width() + 1, 0); ix >= 0 && iy < m_drawDimension.height() && !stop; --ix, ++iy) {
|
||||||
|
// only start really looking tiles in the desired start
|
||||||
|
if(count < start) {
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// avoid rendering too much tiles at once on far views
|
||||||
|
if(count - start + 1 > MAX_TILE_UPDATES && m_viewRange >= FAR_VIEW) {
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// position on current floor
|
||||||
|
//TODO: check position limits
|
||||||
|
Position tilePos = cameraPosition.translated(ix - m_virtualCenterOffset.x, iy - m_virtualCenterOffset.y);
|
||||||
|
// adjust tilePos to the wanted floor
|
||||||
|
tilePos.coveredUp(cameraPosition.z - iz);
|
||||||
|
if(const TilePtr& tile = g_map.getTile(tilePos)) {
|
||||||
|
// skip tiles that have nothing
|
||||||
|
if(tile->isEmpty())
|
||||||
|
continue;
|
||||||
|
// skip tiles that are completely behind another tile
|
||||||
|
if(g_map.isCompletelyCovered(tilePos, m_cachedLastVisibleFloor))
|
||||||
|
continue;
|
||||||
|
m_cachedVisibleTiles.push_back(tile);
|
||||||
|
}
|
||||||
count++;
|
count++;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
static std::vector<Point> points;
|
||||||
|
points.clear();
|
||||||
|
assert(m_drawDimension.width() % 2 == 0 && m_drawDimension.height() % 2 == 0);
|
||||||
|
Point quadTopLeft(m_drawDimension.width()/2 - 1, m_drawDimension.height()/2 - 1);
|
||||||
|
for(int step = 1; !(quadTopLeft.x < 0 && quadTopLeft.y < 0) && !stop; ++step) {
|
||||||
|
|
||||||
// avoid rendering too much tiles at once on far views
|
int quadWidth = std::min(2*step, m_drawDimension.width());
|
||||||
if(count - start + 1 > MAX_TILE_UPDATES && m_viewRange >= FAR_VIEW) {
|
int quadHeight = std::min(2*step, m_drawDimension.height());
|
||||||
stop = true;
|
int fillWidth = (quadTopLeft.x >= 0) ? quadWidth-1 : quadWidth;
|
||||||
break;
|
int fillHeight = (quadTopLeft.x >= 0) ? quadHeight-1 : quadHeight;
|
||||||
|
if(quadTopLeft.y >= 0) {
|
||||||
|
for(int qx=0;qx<fillWidth;++qx) {
|
||||||
|
// only start really looking tiles in the desired start
|
||||||
|
if(count < start) {
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// avoid rendering too much tiles at once on far views
|
||||||
|
if(count - start + 1 > MAX_TILE_UPDATES) {
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
points.push_back(Point(std::max(quadTopLeft.x, 0) + qx, quadTopLeft.y));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if(quadTopLeft.x >= 0) {
|
||||||
|
for(int qy=0;qy<fillHeight;++qy) {
|
||||||
|
// only start really looking tiles in the desired start
|
||||||
|
if(count < start) {
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// position on current floor
|
// avoid rendering too much tiles at once on far views
|
||||||
//TODO: check position limits
|
if(count - start + 1 > MAX_TILE_UPDATES) {
|
||||||
Position tilePos = cameraPosition.translated(ix - m_virtualCenterOffset.x, iy - m_virtualCenterOffset.y);
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
points.push_back(Point(quadTopLeft.x + quadWidth-1, std::max(quadTopLeft.y, 0) + qy));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(quadTopLeft.y >= 0) {
|
||||||
|
for(int qx=0;qx<fillWidth;++qx) {
|
||||||
|
// only start really looking tiles in the desired start
|
||||||
|
if(count < start) {
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// avoid rendering too much tiles at once on far views
|
||||||
|
if(count - start + 1 > MAX_TILE_UPDATES) {
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
points.push_back(Point(std::max(quadTopLeft.x, 0) + quadWidth-qx-1, quadTopLeft.y + quadHeight-1));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(quadTopLeft.x >= 0) {
|
||||||
|
for(int qy=0;qy<fillHeight;++qy) {
|
||||||
|
// only start really looking tiles in the desired start
|
||||||
|
if(count < start) {
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// avoid rendering too much tiles at once on far views
|
||||||
|
if(count - start + 1 > MAX_TILE_UPDATES) {
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
points.push_back(Point(quadTopLeft.x, std::max(quadTopLeft.y, 0) + quadHeight-qy-1));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
quadTopLeft -= Point(1,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const Point& point : points) {
|
||||||
|
Position tilePos = cameraPosition.translated(point.x - m_virtualCenterOffset.x, point.y - m_virtualCenterOffset.y);
|
||||||
// adjust tilePos to the wanted floor
|
// adjust tilePos to the wanted floor
|
||||||
tilePos.coveredUp(cameraPosition.z - iz);
|
tilePos.coveredUp(cameraPosition.z - iz);
|
||||||
if(const TilePtr& tile = g_map.getTile(tilePos)) {
|
if(const TilePtr& tile = g_map.getTile(tilePos)) {
|
||||||
|
@ -231,15 +329,8 @@ void MapView::updateVisibleTilesCache(int start)
|
||||||
continue;
|
continue;
|
||||||
m_cachedVisibleTiles.push_back(tile);
|
m_cachedVisibleTiles.push_back(tile);
|
||||||
}
|
}
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
for(int range=0; range <= m_drawDimension.width() || range <= m_drawDimension.height(); ++range) {
|
|
||||||
for(int ix=0;ix<=range;++ix) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stop) {
|
if(stop) {
|
||||||
|
@ -313,23 +404,18 @@ void MapView::setVisibleDimension(const Size& visibleDimension)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tileSize != m_tileSize) {
|
|
||||||
dump << "tile size =" << tileSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point virtualCenterOffset = (drawDimension/2 - Size(1,1)).toPoint();
|
Point virtualCenterOffset = (drawDimension/2 - Size(1,1)).toPoint();
|
||||||
|
|
||||||
ViewRange viewRange;
|
ViewRange viewRange;
|
||||||
if(visibleDimension.area() <= NEAR_VIEW_AREA)
|
if(tileSize >= 32 && visibleDimension.area() <= NEAR_VIEW_AREA)
|
||||||
viewRange = NEAR_VIEW;
|
viewRange = NEAR_VIEW;
|
||||||
else if(visibleDimension.area() <= MID_VIEW_AREA)
|
else if(tileSize >= 16 && visibleDimension.area() <= MID_VIEW_AREA)
|
||||||
viewRange = MID_VIEW;
|
viewRange = MID_VIEW;
|
||||||
else if(visibleDimension.area() <= FAR_VIEW_AREA)
|
else if(tileSize >= 8)
|
||||||
viewRange = FAR_VIEW;
|
viewRange = FAR_VIEW;
|
||||||
else
|
else
|
||||||
viewRange = HUGE_VIEW;
|
viewRange = HUGE_VIEW;
|
||||||
|
|
||||||
dump << visibleDimension;
|
|
||||||
if(m_viewRange != viewRange) {
|
if(m_viewRange != viewRange) {
|
||||||
if(viewRange == NEAR_VIEW) dump << "near view";
|
if(viewRange == NEAR_VIEW) dump << "near view";
|
||||||
else if(viewRange == MID_VIEW) dump << "mid view";
|
else if(viewRange == MID_VIEW) dump << "mid view";
|
||||||
|
|
|
@ -34,12 +34,11 @@ class MapView : public LuaObject
|
||||||
// 3840x2160 => 1080p optimized
|
// 3840x2160 => 1080p optimized
|
||||||
// 2560x1440 => 720p optimized
|
// 2560x1440 => 720p optimized
|
||||||
// 1728x972 => 480p optimized
|
// 1728x972 => 480p optimized
|
||||||
DEFAULT_FRAMBUFFER_WIDTH = 3840,
|
DEFAULT_FRAMBUFFER_WIDTH = 2560,
|
||||||
DEFAULT_FRAMBUFFER_HEIGHT = 2160,
|
DEFAULT_FRAMBUFFER_HEIGHT = 1440,
|
||||||
|
|
||||||
NEAR_VIEW_AREA = 48*48,
|
NEAR_VIEW_AREA = 32*32,
|
||||||
MID_VIEW_AREA = 96*96,
|
MID_VIEW_AREA = 64*64,
|
||||||
FAR_VIEW_AREA = 384*384,
|
|
||||||
MAX_TILE_UPDATES = NEAR_VIEW_AREA*7
|
MAX_TILE_UPDATES = NEAR_VIEW_AREA*7
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,11 @@ void UIMap::zoomOut()
|
||||||
m_mapRect.moveCenter(m_rect.center());
|
m_mapRect.moveCenter(m_rect.center());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UIMap::setCameraPosition(const Position& pos)
|
||||||
|
{
|
||||||
|
m_mapView->setCameraPosition(pos);
|
||||||
|
}
|
||||||
|
|
||||||
TilePtr UIMap::getTile(const Point& mousePos)
|
TilePtr UIMap::getTile(const Point& mousePos)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
|
|
||||||
void zoomIn();
|
void zoomIn();
|
||||||
void zoomOut();
|
void zoomOut();
|
||||||
|
void setCameraPosition(const Position& pos);
|
||||||
|
|
||||||
TilePtr getTile(const Point& mousePos);
|
TilePtr getTile(const Point& mousePos);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue