Hello.
I am making my third game BrickBreaker using Visual Studio 2010 and SFML 2.0.
At first I created a paddle and ball sprite along with a score heading string and score value string, and a score background slider. In short I just had total 5 draw calls and till then the game played very smooth.
Then I used vertex array to draw all the Bricks and the background. The texture used was the background texture, while the bricks were only colored, no texture used for them. I did exactly as it was in the tutorial, but after implementing this, my game speed dropped to like 3 FPS. If I remove drawing just the vertex array, speed returns back to normal, which means the background game logic is fine and don't have much issues.
Here is the code I used : Level class is the one responsible for populating the vertex array, while Display does all the drawing.
Level.h :
class Level : public Drawable, public Transformable
{
int video_width, video_height, brick_count;
int level;
Texture back_texture;
VertexArray m_vertices;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
// apply the transform
states.transform *= getTransform();
// apply the tileset texture
states.texture = &back_texture;
// draw the vertex array
target.draw(m_vertices, states);
}
public:
Level(void);
~Level(void);
void LevelCreate(std::list<Brick> Tile);
void Initialize(int a, int b);
void LevelSet(std::list<Brick>* Tile);
};
Level.cpp :
// ... Showing the main function -->
void Level::LevelCreate(std::list<Brick> Tile)
{
//Populating Background
sf::Vertex* quad = &m_vertices[0];
quad[0].position = sf::Vector2f(0, 0);
quad[1].position = sf::Vector2f(0.8 * video_width, 0);
quad[2].position = sf::Vector2f(0.8 * video_width, video_height);
quad[3].position = sf::Vector2f(0, video_height);
quad[0].texCoords = sf::Vector2f(0, 0);
quad[1].texCoords = sf::Vector2f(back_texture.getSize().x, 0);
quad[2].texCoords = sf::Vector2f(back_texture.getSize().x, back_texture.getSize().y);
quad[3].texCoords = sf::Vector2f(0, back_texture.getSize().y);
//Populating Bricks
int i = 1;
for (auto tile_no = Tile.begin(); tile_no != Tile.end(); tile_no++, i++)
{
sf::Vertex* quad = &m_vertices[i*4];
quad[0].position = sf::Vector2f(tile_no->GetDimension().x, tile_no->GetDimension().y);
quad[1].position = sf::Vector2f(tile_no->GetDimension().x + tile_no->GetSize().x, tile_no->GetDimension().y);
quad[2].position = sf::Vector2f(tile_no->GetDimension().x + tile_no->GetSize().x, tile_no->GetDimension().y + tile_no->GetSize().y);
quad[3].position = sf::Vector2f(tile_no->GetDimension().x, tile_no->GetDimension().y + tile_no->GetSize().y);
switch(tile_no->GetDurability())
{
case 1 : quad[0].color = quad[2].color = Color::Green;
break;
case 2 : quad[0].color = quad[2].color = Color::Blue;
break;
case 3 : quad[0].color = quad[2].color = Color::Red;
break;
case 4 : quad[0].color = Pcolor; quad[2].color = Pcolor2;
break;
}
}
//Removing previous held vertices.
for (; i <= brick_count; i++)
{
auto tile_no = Tile.begin();
sf::Vertex* quad = &m_vertices[i*4];
quad[0].position = sf::Vector2f(tile_no->GetDimension().x, tile_no->GetDimension().y);
quad[1].position = sf::Vector2f(tile_no->GetDimension().x + tile_no->GetSize().x, tile_no->GetDimension().y);
quad[2].position = sf::Vector2f(tile_no->GetDimension().x + tile_no->GetSize().x, tile_no->GetDimension().y + tile_no->GetSize().y);
quad[3].position = sf::Vector2f(tile_no->GetDimension().x, tile_no->GetDimension().y + tile_no->GetSize().y);
switch(tile_no->GetDurability())
{
case 1 : quad[0].color = quad[2].color = sf::Color::Green;
break;
case 2 : quad[0].color = quad[2].color = Color::Blue;
break;
case 3 : quad[0].color = quad[2].color = Color::Red;
break;
}
}
}
Actually I use a list for my Bricks. Once a brick is destroyed, it is thrown out of the list, but the vertex array still stores it, so basically I use my third for loop for the vertex array to store some other existing Brick in place of removed bricks. I tried removing the third for loop as well, no performance improvement, only a diff. logic where ghost bricks were shown even after they were destroyed, reason I mentioned above.
So I think there is no problem with the logic.
Another class Display uses an object of Level. It does all the Drawing :
void Display::DrawUpdate()
{
//Clearing Screen
BB_Win.clear();
//Drawing Screen
BB_Win.draw(Stage);//Vertex Array
Scor.Draw(BB_Win,Bal.BSpeed(),Life,ScoreValue);//Score Values, just 3 draw calls used here.
BB_Win.draw(Pad.Draw()); BB_Win.draw(Bal.Draw());// 2 draw calls for paddle and brick
//Displaying Screen
BB_Win.display();
}
I don't know why vertex array causes such a lag.. If I remove -- BB_Win.draw(Stage); -- command, I get all my performance back. this is my first time using Vertex array, all help appreciated. Do tell me if I need to provide any more information