Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML 2.X] Przyśpieszyć ładowanie tekstur

Ostatnio zmodyfikowano 2025-04-21 15:08
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
» 2025-04-20 10:48:44
Dobra, udało się chyba. I do tego plik ma 6MB! Dzięki Wielkie DejaVu :-)

C/C++
void save_textures_as_packet() {
   
   
std::vector < std::string > pathfiles;
   
for( auto & single: singleTextures ) {
       
pathfiles.push_back( single->name );
   
}
   
   
std::ofstream packet( "assets\\atex.assets", std::ios::binary );
   
   
uint32_t filesCount = pathfiles.size();
   
packet.write( reinterpret_cast < char * >( & filesCount ), sizeof( filesCount ) ); // 4 bajty
   
   
for( auto & path: pathfiles ) {
       
std::ifstream file( "assets\\" + path + ".png", std::ios::binary );
       
       
if( !file ) {
           
//std::cerr << "Nie można otworzyć pliku: " << path << "\n";
           
continue;
       
}
       
       
       
//string filename = std::filesystem::path(path).filename().string();
       
string filename = path;
       
cout << filename << "\n";
       
       
uint8_t nameLength = filename.size();
       
       
file.seekg( 0, std::ios::end );
       
uint32_t fileSize = file.tellg();
       
file.seekg( 0 );
       
       
std::vector < char > buffer( fileSize );
       
file.read( buffer.data(), fileSize );
       
       
// save the data
       
packet.write( reinterpret_cast < char * >( & nameLength ), sizeof( nameLength ) ); // 1 bajt
       
packet.write( filename.c_str(), nameLength ); // N bajtów
       
packet.write( reinterpret_cast < char * >( & fileSize ), sizeof( fileSize ) ); // 4 bajty
       
packet.write( buffer.data(), fileSize ); // X bajtów
       
   
}
   
   
packet.close();
}

void loadTexturesFromPacket() {
   
std::ifstream packet( "assets\\atex.assets", std::ios::binary );
   
if( !packet ) {
       
//std::cerr << "Nie można otworzyć pliku pakiet.bin\n";
       
return;
   
}
   
   
uint32_t fileCount;
   
packet.read( reinterpret_cast < char * >( & fileCount ), sizeof( fileCount ) );
   
   
std::vector < SingleTexture * > textures;
   
for( uint32_t i = 0; i < fileCount; ++i ) {
       
       
uint8_t nameLength;
       
packet.read( reinterpret_cast < char * >( & nameLength ), sizeof( nameLength ) );
       
       
std::string fileName( nameLength, '\0' );
       
packet.read( & fileName[ 0 ], nameLength );
       
//std::cout << "name: " << fileName << "\n";
       
uint32_t fileSize;
       
packet.read( reinterpret_cast < char * >( & fileSize ), sizeof( fileSize ) );
       
       
std::vector < char > buffer( fileSize );
       
packet.read( buffer.data(), fileSize );
       
       
sf::Image img = sf::Image();
       
if( !img.loadFromMemory( buffer.data(), buffer.size() ) ) {
           
std::cerr << "Nie udało się załadować obrazka: " << fileName << "(" << i << ")" << "\n";
           
continue; // pomiń ten plik
       
}
       
       
SingleTexture * t = new SingleTexture( fileName, img, 0, 0 );
       
textures.push_back( t );
   
}
   
   
   
packet.close();
   
   
std::cout << "wczytano " << textures.size() << " tekstur\n";
   
singleTextures = textures;
}
P-182265
tBane
Temat założony przez niniejszego użytkownika
» 2025-04-21 10:56:32
teraz jeszcze musze przerobić tak algorytm, by wczytywał zarówno pojedyncze tekstury jak i zbiory tekstur.

C/C++
void loadSingleTexture( string pathfile, float cx, float cy )
void loadTextureSets( string pathfile, int tile_width, int tile_height, float cx, float cy )
P-182266
tBane
Temat założony przez niniejszego użytkownika
» 2025-04-21 13:22:09
Napisałem usuwanie duplikatów za pomocy sprawdzanie pikseli w sf::Image tekstur i czas wzrósł do >5s (mam ponad 2500 tekstur). Jak szybciej sprawdzić czy tekstury są takie same ?

C/C++
if( type == 1 ) {
   
   
uint16_t tile_width, tile_height, cx, cy;
   
   
packet.read( reinterpret_cast < char * >( & tile_width ), sizeof( tile_width ) );
   
packet.read( reinterpret_cast < char * >( & tile_height ), sizeof( tile_height ) );
   
packet.read( reinterpret_cast < char * >( & cx ), sizeof( cx ) );
   
packet.read( reinterpret_cast < char * >( & cy ), sizeof( cy ) );
   
   
uint32_t fileSize;
   
packet.read( reinterpret_cast < char * >( & fileSize ), sizeof( fileSize ) );
   
   
std::vector < char > buffer( fileSize );
   
packet.read( buffer.data(), fileSize );
   
   
sf::Image img = sf::Image();
   
if( !img.loadFromMemory( buffer.data(), buffer.size() ) ) {
       
std::cerr << "Nie udało się załadować obrazka: " << "assets\\" + fileName + ".png" << "(" << i << ")" << "\n";
       
continue; // pomiń ten plik
   
}
   
   
short image_width = img.getSize().x;
   
short image_height = img.getSize().y;
   
   
//cout << image_width << "x" << image_height << "\n";
   
   
int counter = 0;
   
   
for( short y = 0; y < image_height; y += tile_height )
   
for( short x = 0; x < image_width; x += tile_width ) {
       
       
// create tile - fragment of texture
       
sf::Image tile;
       
tile.create( tile_width, tile_height );
       
tile.copy( img, 0, 0, sf::IntRect( x, y, tile_width, tile_height ) );
       
       
bool isEmpty = true;
       
for( short yy = 0; yy < tile_height && isEmpty; yy++ ) {
           
for( short xx = 0; xx < tile_width; xx++ ) {
               
if( tile.getPixel( xx, yy ) != sf::Color::Transparent ) {
                   
isEmpty = false;
                   
break;
               
}
            }
        }
       
       
if( isEmpty )
           
 continue;
       
       
       
// searching - exist doubles or no
       
bool existed = false;
       
       
for( short i = 0; i < textures.size(); i++ ) {
           
sf::Image img = textures[ i ]->texture->copyToImage();
           
           
if( areImagesEqual( tile, img ) ) {
               
existed = true;
               
//cout << "exits now\n";
               
break;
           
}
        }
       
       
// if no exist then add
       
if( existed == false ) {
           
           
SingleTexture * new_texture = new SingleTexture( fileName + "_" + to_string( counter ), tile, cx, cy );
           
//cout << "created texture: " << pathfile + "_" + to_string(counter) << "\n";
           
textures.push_back( new_texture );
           
           
counter += 1;
           
       
}
       
    }
   
   
//std::cout << "wczytano set: " << fileName << "\n";
}
P-182267
tBane
Temat założony przez niniejszego użytkownika
» 2025-04-21 14:53:22
Zmieniłem kolejność zapisywania tekstur i czas ładowania spadł z >6s do <1s. Solved :-)

C/C++
std::ofstream packet( "assets\\atex.assets", std::ios::binary );
packet.write( reinterpret_cast < char * >( & textures_count ), sizeof( textures_count ) );

for( auto & ter: terrains_textures_to_save ) {
   
save_texture( packet, ter->name, ter->cx, ter->cy );
}

for( auto & set: sets_to_save ) {
   
save_set( packet, set->name, set->width, set->height, set->cx, set->cy );
}

for( auto & anim: animations_to_save ) {
   
save_animation( packet, anim->name, anim->width, anim->height, anim->cx, anim->cy );
}

for( auto & tex: textures_to_save ) {
   
save_texture( packet, tex->name, tex->cx, tex->cy );
}

packet.close();
P-182268
1 « 2 »
Poprzednia strona Strona 2 z 2