DejaVu |
» 2025-03-20 15:28:17 Masz 10 tekstur. Trzymaj 10 tekstur w RAM. Musisz połączyć te 10 tekstur z konkretną maską -> generuj teksturę jaka wynika z kombinacji tekstury + maski. Zapisz sobie ją w dictionary i reużywaj.
Innymi słowy: te tekstury, które musisz wygenerować, to wygeneruj, ale nie generuj wszystkich możliwości, bo 99% tekstur i tak nie zostałoby użyte. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-03-20 15:46:55 Nie wiem w jaki sposób mógłbym przetwarzać tak tekstury jak radzisz.
Jedynym w miarę sensownym rozwiązaniem wydaje mi się generowanie tekstury dla każdego tilesa, ale to jest zasobożerne :-/ |
|
DejaVu |
» 2025-03-20 15:52:03 Generalnie sam wlazłeś w pokrzywy chcąc mieć 'głównego' tilesa, łączonego z 'innym' tilesem. Chcesz, aby coś ładniej wyglądało? masz konsekwencje w postaci zwiększonych obliczeń CPU lub GPU lub użycia RAM. Efekt będzie fajny jak zaimplementujesz rozwiązanie, ale do tego czasu to masz konkretny problem do rozwiązania. Najlepiej by było zapewne, abyś zrobił klasę, która ma metodę: sf::Texture TextureManager::GetCombinedTexture( int texture1, int texture2, unsigned mask ) { }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-03-20 16:24:13 Czyli znowu się wszystko sprowadza do tego, że dla każdego tilesa trzeba osobną teksturę przypisać a to spowolni znacznie działanie programu :-/
Ogólnie to mam trzy metody na to jak rozwiązać ten problem ale każda z nich ma jakiś minus
pierwsza to taka, że każdy kafelek ma sf::Sprite.. (zasobożerność, słaba prędkość) drugi pomysł to taki, że każdy kafelek ma sf::VertexArray i unikalną teksturę (zasobożerność, średnia prędkość), trzeci pomysł to taki że każdy kafelek jest zdefiniowany jako sf::VertexArray i odnosi się do głównej tekstury ale ta ma olbrzymi rozmiar :-?
// edit 64*102400 = 6553600 sqrt(6553600) = 2560. Tekstura się zmieści :-) |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-03-20 19:03:50 Algorytm do generowania wszystkich kombinacji 10 bazowych kafelków z 16 maskami w teksturze o rozmiarach 2816x2816 zamieszczam poniżej. :-) void generateTileSet() { sf::Image masks[ 16 ]; for( int i = 0; i < 16; i++ ) { masks[ i ].create( 64, 64 ); if( !masks[ i ].loadFromFile( "assets/tiles/basic2/" + std::to_string( i ) + ".png" ) ) std::cout << "błąd wczytywania maski: " << i << "\n"; } std::cout << "Wczytano maski\n"; std::vector < SingleTexture * > tiles = getSingleTextures( "tiles/tile_" ); std::cout << "Tiles: " << tiles.size() << "\n"; unsigned int newWidth = 2816; unsigned int newHeight = 2816; unsigned int tilesPerRow = newWidth / 64; sf::Image tile_set_image; tile_set_image.create( newWidth, newHeight, sf::Color::Transparent ); sf::Image first_tile, second_tile, mask, result_tile; first_tile.create( 64, 64 ); second_tile.create( 64, 64 ); mask.create( 64, 64 ); result_tile.create( 64, 64 ); unsigned int tileIndex = 0; for( short tile_1_id = 0; tile_1_id < 11; tile_1_id++ ) { first_tile = tiles[ tile_1_id ]->texture->copyToImage(); for( short tile_2_id = 0; tile_2_id < 11; tile_2_id++ ) { second_tile = tiles[ tile_2_id ]->texture->copyToImage(); for( short mask_id = 0; mask_id < 16; mask_id++ ) { mask = masks[ mask_id ]; for( unsigned int y = 0; y < 64; y++ ) { for( unsigned int x = 0; x < 64; x++ ) { sf::Color pixel = mask.getPixel( x, y ); if( pixel.r == 237 && pixel.g == 28 && pixel.b == 36 ) { result_tile.setPixel( x, y, first_tile.getPixel( x, y ) ); } else if( pixel.r == 127 && pixel.g == 127 && pixel.b == 127 ) { result_tile.setPixel( x, y, second_tile.getPixel( x, y ) ); } else { result_tile.setPixel( x, y, pixel ); } } } unsigned int newX =( tileIndex % tilesPerRow ) * 64; unsigned int newY =( tileIndex / tilesPerRow ) * 64; if( newY >= newHeight ) { std::cerr << "Za dużo kafelków! Przekracza rozmiar 2816x2816." << std::endl; return; } tile_set_image.copy( result_tile, newX, newY ); tileIndex++; } } } tile_set_image.saveToFile( "assets/tiles/tile_set_final.png" ); }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-03-21 17:39:18 Wiele kafelków się powtarza. Spróbuję wyeliminować powtórzenia. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-03-21 20:02:25 Udało się. Wyeliminowałem powtórzenia w tilesecie void generateTileSet() { sf::Image masks[ 16 ]; for( int i = 0; i < 16; i++ ) { masks[ i ].create( 64, 64 ); if( !masks[ i ].loadFromFile( "assets/tiles/basic2/" + std::to_string( i ) + ".png" ) ) { std::cout << "Błąd wczytywania maski: " << i << "\n"; return; } } std::cout << "Wczytano maski\n"; std::vector < SingleTexture * > tiles = getSingleTextures( "tiles/tile_" ); std::cout << "Tiles: " << tiles.size() << "\n"; unsigned int N = tiles.size(); unsigned int M = 14; unsigned int totalTiles =( N *( N - 1 ) / 2 ) * M; unsigned int tileSize = 64; unsigned int tilesPerRow = std::ceil( std::sqrt( totalTiles ) ); unsigned int rows =( totalTiles + tilesPerRow - 1 ) / tilesPerRow; sf::Image tile_set_image; tile_set_image.create( tilesPerRow * tileSize, rows * tileSize, sf::Color::Transparent ); sf::Image first_tile, second_tile, mask, result_tile; first_tile.create( tileSize, tileSize ); second_tile.create( tileSize, tileSize ); result_tile.create( tileSize, tileSize ); unsigned int tileIndex = 0; for( short tile_id = 0; tile_id < N; tile_id++ ) { unsigned int newX =( tileIndex % tilesPerRow ) * tileSize; unsigned int newY =( tileIndex / tilesPerRow ) * tileSize; tile_set_image.copy( tiles[ tile_id ]->texture->copyToImage(), newX, newY ); tileIndex++; } for( short tile_1_id = 0; tile_1_id < N; tile_1_id++ ) { for( short tile_2_id = tile_1_id + 1; tile_2_id < N; tile_2_id++ ) { first_tile = tiles[ tile_1_id ]->texture->copyToImage(); second_tile = tiles[ tile_2_id ]->texture->copyToImage(); for( short mask_id = 1; mask_id < 15; mask_id++ ) { mask = masks[ mask_id ]; for( unsigned int y = 0; y < tileSize; y++ ) { for( unsigned int x = 0; x < tileSize; x++ ) { sf::Color pixel = mask.getPixel( x, y ); if( pixel.r == 237 && pixel.g == 28 && pixel.b == 36 ) { result_tile.setPixel( x, y, first_tile.getPixel( x, y ) ); } else if( pixel.r == 127 && pixel.g == 127 && pixel.b == 127 ) { result_tile.setPixel( x, y, second_tile.getPixel( x, y ) ); } else { result_tile.setPixel( x, y, pixel ); } } } unsigned int newX =( tileIndex % tilesPerRow ) * tileSize; unsigned int newY =( tileIndex / tilesPerRow ) * tileSize; if( newY >= rows * tileSize ) { std::cerr << "Za dużo kafelków! Przekracza rozmiar tekstury.\n"; return; } tile_set_image.copy( result_tile, newX, newY ); tileIndex++; } } } tile_set_image.saveToFile( "assets/tiles/tile_set_final.png" ); std::cout << "Zapisano tile_set_final.png\n"; }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-03-21 22:26:20 Chyba są rozmieszczone regularnie te kafelki z wstępnych obliczeń. Jutro będę próbował umieśćić je w palecie i zobaczymy czy ten autotiling to dobre rozwiązanie. left-top | top | right-top 11 13 12 25 27 26 39 41 40 53 55 54
11+0 11+2 11+1 11+14 11+16 11+15 11+28 11+30 11+29 11+42 11+44 11+43 |
|
1 « 2 » |