=============== ImageFromFile Finds or loads the given image, always returning a valid image pointer. Loading of the image may be deferred for dynamic loading. ============== */
| 1514 | ============== |
| 1515 | */ |
| 1516 | idImage *idImageManager::ImageFromFile( const char *_name, textureFilter_t filter, bool allowDownSize, |
| 1517 | textureRepeat_t repeat, textureDepth_t depth, cubeFiles_t cubeMap ) { |
| 1518 | idStr name; |
| 1519 | idImage *image; |
| 1520 | int hash; |
| 1521 | |
| 1522 | if ( !_name || !_name[0] || idStr::Icmp( _name, "default" ) == 0 || idStr::Icmp( _name, "_default" ) == 0 ) { |
| 1523 | declManager->MediaPrint( "DEFAULTED\n" ); |
| 1524 | return globalImages->defaultImage; |
| 1525 | } |
| 1526 | |
| 1527 | // strip any .tga file extensions from anywhere in the _name, including image program parameters |
| 1528 | name = _name; |
| 1529 | name.Replace( ".tga", "" ); |
| 1530 | name.BackSlashesToSlashes(); |
| 1531 | |
| 1532 | // |
| 1533 | // see if the image is already loaded, unless we |
| 1534 | // are in a reloadImages call |
| 1535 | // |
| 1536 | hash = name.FileNameHash(); |
| 1537 | for ( image = imageHashTable[hash]; image; image = image->hashNext ) { |
| 1538 | if ( name.Icmp( image->imgName ) == 0 ) { |
| 1539 | // the built in's, like _white and _flat always match the other options |
| 1540 | if ( name[0] == '_' ) { |
| 1541 | return image; |
| 1542 | } |
| 1543 | if ( image->cubeFiles != cubeMap ) { |
| 1544 | common->Error( "Image '%s' has been referenced with conflicting cube map states", _name ); |
| 1545 | } |
| 1546 | |
| 1547 | if ( image->filter != filter || image->repeat != repeat ) { |
| 1548 | // we might want to have the system reset these parameters on every bind and |
| 1549 | // share the image data |
| 1550 | continue; |
| 1551 | } |
| 1552 | |
| 1553 | if ( image->allowDownSize == allowDownSize && image->depth == depth ) { |
| 1554 | // note that it is used this level load |
| 1555 | image->levelLoadReferenced = true; |
| 1556 | if ( image->partialImage != NULL ) { |
| 1557 | image->partialImage->levelLoadReferenced = true; |
| 1558 | } |
| 1559 | return image; |
| 1560 | } |
| 1561 | |
| 1562 | // the same image is being requested, but with a different allowDownSize or depth |
| 1563 | // so pick the highest of the two and reload the old image with those parameters |
| 1564 | if ( !image->allowDownSize ) { |
| 1565 | allowDownSize = false; |
| 1566 | } |
| 1567 | if ( image->depth > depth ) { |
| 1568 | depth = image->depth; |
| 1569 | } |
| 1570 | if ( image->allowDownSize == allowDownSize && image->depth == depth ) { |
| 1571 | // the already created one is already the highest quality |
| 1572 | image->levelLoadReferenced = true; |
| 1573 | if ( image->partialImage != NULL ) { |
no test coverage detected