improve map far view rendering

This commit is contained in:
Eduardo Bart 2012-01-31 18:50:35 -02:00
parent 51b0822267
commit aa1a10afbc
4 changed files with 132 additions and 41 deletions

View File

@ -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,6 +198,8 @@ 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) {
//TODO: cleanup this code
if(m_viewRange <= FAR_VIEW) {
// draw tiles like linus pauling's rule order // draw tiles like linus pauling's rule order
const int numDiagonals = m_drawDimension.width() + m_drawDimension.height() - 1; const int numDiagonals = m_drawDimension.width() + m_drawDimension.height() - 1;
for(int diagonal = 0; diagonal < numDiagonals && !stop; ++diagonal) { for(int diagonal = 0; diagonal < numDiagonals && !stop; ++diagonal) {
@ -234,12 +234,103 @@ void MapView::updateVisibleTilesCache(int start)
count++; count++;
} }
} }
/* } else {
for(int range=0; range <= m_drawDimension.width() || range <= m_drawDimension.height(); ++range) { static std::vector<Point> points;
for(int ix=0;ix<=range;++ix) { 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) {
int quadWidth = std::min(2*step, m_drawDimension.width());
int quadHeight = std::min(2*step, m_drawDimension.height());
int fillWidth = (quadTopLeft.x >= 0) ? quadWidth-1 : quadWidth;
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;
}
// 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 + 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
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);
}
}
} }
}*/
} }
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";

View File

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

View File

@ -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)
{ {
/* /*

View File

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