tBane Temat założony przez niniejszego użytkownika |
[SFML 2.X] sf::Vertex oraz linie między różnymi kafelkami mapy » 2024-10-29 19:45:55 Witam. Chciałbym pomiędzy różniącymi się kafelkami wygenerować linie. Do tego celu stworzyłem funkcję generateMesh(). Napisałem funkcję ale coś nie działa czasem nie rysuje linii. Czy mógłby mi ktoś doradzić dlaczego to nie działa i gdzie robię błąd ? class Terrain : public sf::Drawable , public sf::Transformable { public: short width, height; sf::Vector2i coords; sf::VertexArray vertexes; sf::Texture tileset; sf::VertexArray outlines; std::vector < short > tiles; Terrain( short x, short y, short width, short height ) { coords.x = x; coords.y = y; this->width = width; this->height = height; tileset = sf::Texture(); tileset = * getTexture( "tiles/0_tileset" )->texture; vertexes.setPrimitiveType( sf::Triangles ); vertexes.resize( width * height * 6 ); tiles.resize( width * height ); short coord_x, coord_y; for( short y = 0; y < height; y++ ) for( short x = 0; x < width; x++ ) { sf::Vertex * triangles = & vertexes[( y * width + x ) * 6 ]; coord_x =( coords.x + x ); coord_y =( coords.y + y ); triangles[ 0 ].position = sf::Vector2f( coord_x * tileSide, coord_y * tileSide ); triangles[ 1 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide, coord_y * tileSide ); triangles[ 2 ].position = sf::Vector2f( coord_x * tileSide,( coord_y + 1 ) * tileSide ); triangles[ 3 ].position = sf::Vector2f( coord_x * tileSide,( coord_y + 1 ) * tileSide ); triangles[ 4 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide, coord_y * tileSide ); triangles[ 5 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide,( coord_y + 1 ) * tileSide ); edit( x, y, 0 ); } generateMesh(); } void edit( short x, short y, short value ) { if( x < 0 || x >= width || y < 0 || y >= height ) return; if( value > 4 || value < 0 ) return; tiles[ y * width + x ] = value; short global_x = coords.x + x; short global_y = coords.y + y; sf::Vertex * triangles = & vertexes[( y * width + x ) * 6 ]; short tu =( short( global_x * tileSide ) % 64 ) +( value * 64 ); short tv =( short( global_y * tileSide ) % 64 ); triangles[ 0 ].texCoords = sf::Vector2f( tu, tv ); triangles[ 1 ].texCoords = sf::Vector2f( tu + tileSide, tv ); triangles[ 2 ].texCoords = sf::Vector2f( tu, tv + tileSide ); triangles[ 3 ].texCoords = sf::Vector2f( tu, tv + tileSide ); triangles[ 4 ].texCoords = sf::Vector2f( tu + tileSide, tv ); triangles[ 5 ].texCoords = sf::Vector2f( tu + tileSide, tv + tileSide ); } void generateMesh() { outlines.clear(); outlines.setPrimitiveType( sf::Lines ); cout << "generate mesh\n"; int x, y; int coord_x, coord_y; for( int i = 0; i < tiles.size(); i++ ) { x = i % width; y = i / width; if( x > 0 && x < 15 && y > 0 && y < 15 ) { if( tiles[( y - 1 ) * width + x ] != tiles[ y * width + x ] ) { coord_x =( coords.x + x ); coord_y =( coords.y + y ); sf::Vertex line[ 2 ]; line[ 0 ].position = sf::Vector2f( coord_x * tileSide, coord_y * tileSide ); line[ 0 ].color = sf::Color::Black; line[ 1 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide, coord_y * tileSide ); line[ 1 ].color = sf::Color::Black; outlines.append( line[ 0 ] ); outlines.append( line[ 1 ] ); } if( tiles[( y + 1 ) * width + x ] != tiles[ y * width + x ] ) { coord_x =( coords.x + x ); coord_y =( coords.y + y ); sf::Vertex line[ 2 ]; line[ 0 ].position = sf::Vector2f( coord_x * tileSide,( coord_y + 1 ) * tileSide ); line[ 0 ].color = sf::Color::Black; line[ 1 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide,( coord_y + 1 ) * tileSide ); line[ 1 ].color = sf::Color::Black; outlines.append( line[ 0 ] ); outlines.append( line[ 1 ] ); } if( tiles[ y * width + x - 1 ] != tiles[ y * width + x ] ) { coord_x =( coords.x + x ); coord_y =( coords.y + y ); sf::Vertex line[ 2 ]; line[ 0 ].position = sf::Vector2f( coord_x * tileSide, coord_y * tileSide ); line[ 0 ].color = sf::Color::Black; line[ 1 ].position = sf::Vector2f( coord_x * tileSide,( coord_y + 1 ) * tileSide ); line[ 1 ].color = sf::Color::Black; outlines.append( line[ 0 ] ); outlines.append( line[ 1 ] ); } if( tiles[ y * width + x + 1 ] != tiles[ y * width + x ] ) { coord_x =( coords.x + x ); coord_y =( coords.y + y ); sf::Vertex line[ 2 ]; line[ 0 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide, coord_y * tileSide ); line[ 0 ].color = sf::Color::Black; line[ 1 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide,( coord_y + 1 ) * tileSide ); line[ 1 ].color = sf::Color::Black; outlines.append( line[ 0 ] ); outlines.append( line[ 1 ] ); } } } } private: virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const { states.transform *= getTransform(); states.texture = & tileset; target.draw( vertexes, states ); target.draw( outlines, states ); } };
Terrain * terrain = new Terrain( x * 16, y * 16, 16, 16 ); for( iny y = 0; y < 16; y++ ) for( int x = 0; x < 16; x++ ) terrain->edit( x, y, rand() % 3 );
terrain->generateMesh(); window->draw( * terrain );
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-10-29 20:28:20 Pogrubiłem te linie: void generateMesh() { outlines.clear(); outlines.setPrimitiveType( sf::Quads ); cout << "generate mesh\n"; int x, y; int coord_x, coord_y; float lineThickness = 4.0f; for( int i = 0; i < tiles.size(); i++ ) { x = i % width; y = i / width; if( x > 0 && x < 15 && y > 0 && y < 15 ) { coord_x =( coords.x + x ) * tileSide; coord_y =( coords.y + y ) * tileSide; if( tiles[( y - 1 ) * width + x ] != tiles[ y * width + x ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y + lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y + lineThickness / 2 ), sf::Color::Black ) ); } if( tiles[( y + 1 ) * width + x ] != tiles[ y * width + x ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y + tileSide - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y + tileSide - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y + tileSide + lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y + tileSide + lineThickness / 2 ), sf::Color::Black ) ); } if( tiles[ y * width +( x - 1 ) ] != tiles[ y * width + x ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x - lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x - lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); } if( tiles[ y * width +( x + 1 ) ] != tiles[ y * width + x ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide - lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide + lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide + lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide - lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); } } } }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-10-29 21:41:35 void generateBorders( Terrain * topTerrain, Terrain * bottomTerrain, Terrain * leftTerrain, Terrain * rightTerrain ) { outlines.clear(); outlines.setPrimitiveType( sf::Quads ); int x, y; int coord_x, coord_y; float lineThickness = 2.0f; for( int i = 0; i < tiles.size(); i++ ) { x = i % width; y = i / width; coord_x =( coords.x + i % width ) * tileSide; coord_y =( coords.y + i / width ) * tileSide; short tileValue; if( y == 0 ) { if( topTerrain != nullptr ) { tileValue = topTerrain->tiles[ 15 * width + x ]; } else { tileValue = tiles[ y * width + x ]; } } else { tileValue = tiles[( y - 1 ) * width + x ]; } if( tiles[ i ] != tileValue ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y + lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y + lineThickness / 2 ), sf::Color::Black ) ); } } }
|
|
pekfos |
» 2024-10-29 21:46:25 if( x > 0 && x < 15 && y > 0 && y < 15 ) Ten warunek nie pokrywa poprawnie przypadków brzegowych. Zapewniłeś tu że każda współrzędna +/-1 jest poprawna, ale przykładowo na górnej krawędzi y-1 jest błędne, podczas gdy x+-1 jest dalej poprawne. Powinieneś testować y > 0 w warunku który wymaga tego do poprawności i analogicznie pozostałe. Np if( y > 0 && tiles[( y - 1 ) * width + x ] != tiles[ y * width + x ] ) |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-10-29 21:54:31 Teraz potrzebowałbym jeszcze by na granicach mapy też to działało. void generateBorders( Terrain * topTerrain, Terrain * bottomTerrain, Terrain * leftTerrain, Terrain * rightTerrain ) { outlines.clear(); outlines.setPrimitiveType( sf::Quads ); int x, y; int coord_x, coord_y; float lineThickness = 4.0f; for( int i = 0; i < tiles.size(); i++ ) { x = i % width; y = i / width; coord_x =( coords.x + x ) * tileSide; coord_y =( coords.y + y ) * tileSide; if( y > 0 && y < 15 && x > 0 && x < 15 ) { if( tiles[ i ] != tiles[ i - width ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y + lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y + lineThickness / 2 ), sf::Color::Black ) ); } if( tiles[ i ] != tiles[ i + width ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y + tileSide - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y + tileSide - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y + tileSide + lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y + tileSide + lineThickness / 2 ), sf::Color::Black ) ); } if( tiles[ i ] != tiles[ i - 1 ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x - lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x - lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); } if( tiles[ i ] != tiles[ i + 1 ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide - lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide + lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide + lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide - lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); } } } }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-10-30 13:24:15 Jak na razie napisałem coś takiego ale generuje mi nie wiadomo skąd linie na granicach map: https://github.com/tBane1995/testvoid generateBorders() { Chunk * topChunk; Chunk * bottomChunk; Chunk * leftChunk; Chunk * rightChunk; Terrain * topTerrain; Terrain * bottomTerrain; Terrain * leftTerrain; Terrain * rightTerrain; int y, x; for( int i = 0; i < chunks.size(); i++ ) { y = i / width; x = i % width; topChunk = getChunk( x, y - 1 ); bottomChunk = getChunk( x, y + 1 ); leftChunk = getChunk( x - 1, y ); rightChunk = getChunk( x + 1, y ); ( topChunk != nullptr ) ? topTerrain = topChunk->terrain : topTerrain = nullptr; ( bottomChunk != nullptr ) ? bottomTerrain = bottomChunk->terrain : bottomTerrain = nullptr; ( leftChunk != nullptr ) ? leftTerrain = leftChunk->terrain : leftTerrain = nullptr; ( rightChunk != nullptr ) ? rightTerrain = rightChunk->terrain : rightTerrain = nullptr; chunks[ i ]->terrain->generateBorders( topTerrain, bottomTerrain, leftTerrain, rightTerrain ); } }
void generateBorders( Terrain * topTerrain, Terrain * bottomTerrain, Terrain * leftTerrain, Terrain * rightTerrain ) { outlines.clear(); outlines.setPrimitiveType( sf::Quads ); int x, y; int coord_x, coord_y; float lineThickness = 4.0f; for( int i = 0; i < tiles.size(); i++ ) { x = i % width; y = i / width; coord_x =( coords.x + x ) * tileSide; coord_y =( coords.y + y ) * tileSide; short tileValue; if( y == 0 ) { ( topTerrain != nullptr ) ? tileValue = topTerrain->tiles[ y * 15 + x ] : tileValue = - 1; } else tileValue = this->tiles[ i - width ]; if( this->tiles[ i ] != tileValue ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y + lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y + lineThickness / 2 ), sf::Color::Black ) ); } if( y > 0 && y < 15 && x > 0 && x < 15 ) { if( tiles[ i ] != tiles[ i + width ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y + tileSide - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y + tileSide - lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide, coord_y + tileSide + lineThickness / 2 ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x, coord_y + tileSide + lineThickness / 2 ), sf::Color::Black ) ); } if( tiles[ i ] != tiles[ i - 1 ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x - lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x - lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); } if( tiles[ i ] != tiles[ i + 1 ] ) { outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide - lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide + lineThickness / 2, coord_y ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide + lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); outlines.append( sf::Vertex( sf::Vector2f( coord_x + tileSide - lineThickness / 2, coord_y + tileSide ), sf::Color::Black ) ); } } } }
Zrobiłem testy i wyszło, że jest problem z przesyłanie terenów przez funkcję: chunks[ i ]->terrain->generateBorders( topTerrain, bottomTerrain, leftTerrain, rightTerrain );
coords 1 1 topTerrain is null bottomTerrain is null leftTerrain is null rightTerrain is null |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-10-30 16:23:00 problemem było, że chunki w liścia niekoniecznie muszą być uporządkowane : : void generateBorders() { Chunk * topChunk = nullptr; Chunk * bottomChunk = nullptr; Chunk * leftChunk = nullptr; Chunk * rightChunk = nullptr; Terrain * topTerrain = nullptr; Terrain * bottomTerrain = nullptr; Terrain * leftTerrain = nullptr; Terrain * rightTerrain = nullptr; short y, x; for( int i = 0; i < chunks.size(); i++ ) { y = chunks[ i ]->coords.y; x = chunks[ i ]->coords.x; ... } |
|
« 1 » |