Call this manually to update mipmaps when appropriate
| 1447 | |
| 1448 | //Call this manually to update mipmaps when appropriate |
| 1449 | void Tr2TextureAtlas::UpdateMipMaps( Tr2RenderContext& renderContext ) |
| 1450 | { |
| 1451 | CCP_STATS_ZONE( __FUNCTION__ ); |
| 1452 | |
| 1453 | if( !m_hasMipMaps || m_dirtyMipRegions.empty() ) |
| 1454 | { |
| 1455 | return; |
| 1456 | } |
| 1457 | if( m_format != Tr2RenderContextEnum::PIXEL_FORMAT_B8G8R8A8_UNORM ) |
| 1458 | { |
| 1459 | CCP_LOGERR( "Texture format not supported for mipmapped atlases: %08x [%d]", int( m_format ), int( m_format ) ); |
| 1460 | m_dirtyMipRegions.clear(); |
| 1461 | return; |
| 1462 | } |
| 1463 | |
| 1464 | if( !m_texture.IsValid() ) |
| 1465 | { |
| 1466 | m_dirtyMipRegions.clear(); |
| 1467 | return; |
| 1468 | } |
| 1469 | |
| 1470 | // Get a copy of the first mip level into system memory |
| 1471 | uint32_t sourcePitch; |
| 1472 | const void* sourceData; |
| 1473 | if( FAILED( m_texture.MapForReading( Tr2TextureSubresource( 0 ), sourceData, sourcePitch, renderContext ) ) ) |
| 1474 | { |
| 1475 | CCP_LOGERR( "Tr2TextureAtlas::UpdateMipMaps: Failed to read texture" ); |
| 1476 | return; |
| 1477 | } |
| 1478 | std::vector<unsigned char> buffer0( m_texture.GetMipSize( 0 ) ); |
| 1479 | const unsigned char* row = reinterpret_cast<const unsigned char*>( sourceData ); |
| 1480 | auto destRow = buffer0.begin(); |
| 1481 | for( unsigned i = 0; i < m_texture.GetHeight(); ++i ) |
| 1482 | { |
| 1483 | std::copy( row, row + m_texture.GetWidth() * 4, destRow ); |
| 1484 | destRow += m_texture.GetWidth() * 4; |
| 1485 | row += sourcePitch; |
| 1486 | } |
| 1487 | m_texture.UnmapForReading( renderContext ); |
| 1488 | sourcePitch = m_texture.GetWidth() * 4; |
| 1489 | |
| 1490 | uint32_t destPitch = sourcePitch / 2; |
| 1491 | |
| 1492 | std::vector<unsigned char>* prevMip = &buffer0; |
| 1493 | std::vector<unsigned char> buffer1( m_texture.GetMipSize( 1 ) ); |
| 1494 | std::vector<unsigned char>* nextMip = &buffer1; |
| 1495 | |
| 1496 | for( unsigned i = 1; i < m_mipLevels; ++i ) |
| 1497 | { |
| 1498 | // Construct next mip level data for dirty regions using previous mip level copy in system memory |
| 1499 | // and update rectangles in the texture |
| 1500 | bool updated = false; |
| 1501 | for( auto it = m_dirtyMipRegions.begin(); it != m_dirtyMipRegions.end(); ++it ) |
| 1502 | { |
| 1503 | const Tr2Rect source = { it->left >> ( i - 1 ), it->top >> ( i - 1 ), it->right >> ( i - 1 ), it->bottom >> ( i - 1 ) }; |
| 1504 | Tr2Rect dest = { it->left >> i, it->top >> i, it->right >> i, it->bottom >> i }; |
| 1505 | const int height = dest.bottom - dest.top; |
| 1506 | const int width = dest.right - dest.left; |
nothing calls this directly
no test coverage detected