1
Graphics / Re: Storing sprites in a container for better performance
« on: July 05, 2017, 03:41:11 pm »
Thanks for answers guys, I appreciate it.
My project indeed is intented to be a real game, actualy it's Endless Online clone (that doesn't sound serious and even shouldn't sound like that). I have just started with map rendering and didn't really get any good performance (27% CPU usage while drawing a map of 6 layers). I didn't implement any of suggested methods yet and now probably I will. Here's my current code, feel free to comment it - would be great to get some hints on that. Anyway, I've been working on such rendering like 2 years ago and the best performance was while I used vertex arrays. By the way, the map is isometric.
My project indeed is intented to be a real game, actualy it's Endless Online clone (that doesn't sound serious and even shouldn't sound like that). I have just started with map rendering and didn't really get any good performance (27% CPU usage while drawing a map of 6 layers). I didn't implement any of suggested methods yet and now probably I will. Here's my current code, feel free to comment it - would be great to get some hints on that. Anyway, I've been working on such rendering like 2 years ago and the best performance was while I used vertex arrays. By the way, the map is isometric.
void Map::Draw()
{
S &s = S::GetInstance();
int width = s.emf->width;
int height = s.emf->height;
int gfx_id[5] = { 3, 4, 5, 6, 6 };
int g_xoff[5] = { 0, 0, 0, 0, 0 };
int g_yoff[5] = { 0, 0, 0, 0, 0 };
int min_x = s.character.x - 26 >= 0? s.character.x - 26 : 0;
int min_y = s.character.y - 26 >= 0? s.character.y - 26 : 0;
int max_x = s.character.x + 26 < width? s.character.x + 26 : width;
int max_y = s.character.y + 26 < height? s.character.y + 26 : height;
int cursor_closest_dist = 1000;
int cursor_closest_dist_x = 0;
int cursor_closest_dist_y = 0;
int cursor_closest_dist_draw_x = 0;
int cursor_closest_dist_draw_y = 0;
shared_ptr<sf::Texture> tex = s.gfx_loader.LoadTexture(gfx_id[0], s.emf->fill_tile);
sf::Sprite spr_fill(*tex);
for(int y = min_y; y < max_y; ++y)
{
for(int x = min_x; x < max_x; ++x)
{
int graphic_id = s.emf->fill_tile;
if(graphic_id != 0)
{
int player_x = s.character.x * 64 - s.character.x * 32 - s.character.y * 32;
int player_y = s.character.y * 32 + s.character.x * 16 - s.character.y * 16;
int screen_x = 640 / 2 - 32 - player_x;
int screen_y = 480 / 2 - 480 / 4 + 16 - player_y;
int xoff = x * 64;
int yoff = y * 32;
xoff -= x * 32;
yoff += x * 16;
xoff -= y * 32;
yoff -= y * 16;
//shared_ptr<sf::Texture> tex = s.gfx_loader.LoadTexture(gfx_id[0], graphic_id);
//sf::Sprite spr(*tex);
spr_fill.setPosition(screen_x + xoff + g_xoff[0], screen_y + yoff + g_yoff[0]);
s.window.draw(spr_fill);
if(x == s.character.x && y == s.character.y)
{
tex = s.gfx_loader.LoadTexture(3, 0);
//spr.setTexture(*tex);
//s.window.draw(spr);
}
sf::Vector2i pos = sf::Mouse::getPosition(s.window);
int distance = path_length(screen_x + xoff + 32, screen_y + yoff + 16, pos.x, pos.y);
if(distance < cursor_closest_dist)
{
cursor_closest_dist = distance;
cursor_closest_dist_x = x;
cursor_closest_dist_y = y;
cursor_closest_dist_draw_x = screen_x + xoff;
cursor_closest_dist_draw_y = screen_y + yoff;
}
}
}
}
if(cursor_closest_dist_x != 0)
{
shared_ptr<sf::Texture> tex = s.gfx_loader.LoadTexture(2, 24);
sf::Sprite spr(*tex, sf::IntRect(0, 0, 64, 32));
spr.setPosition(cursor_closest_dist_draw_x, cursor_closest_dist_draw_y);
s.window.draw(spr);
}
for(int y = min_y; y < max_y; ++y)
{
for(int x = min_x; x < max_x; ++x)
{
for(int l = 0; l < 5; ++l)
{
int graphic_id = s.emf->GetGraphicID(l, x, y);
if(graphic_id != 0)
{
int player_x = s.character.x * 64 - s.character.x * 32 - s.character.y * 32;
int player_y = s.character.y * 32 + s.character.x * 16 - s.character.y * 16;
int screen_x = 640 / 2 - 32 - player_x;
int screen_y = 480 / 2 - 480 / 4 + 16 - player_y;
int xoff = x * 64;
int yoff = y * 32;
xoff -= x * 32;
yoff += x * 16;
xoff -= y * 32;
yoff -= y * 16;
shared_ptr<sf::Texture> tex = s.gfx_loader.LoadTexture(gfx_id[l], graphic_id);
if(l == 1) // objects
{
g_xoff[l] = 32 - tex->getSize().x / 2;
g_yoff[l] = 0 - (tex->getSize().y - 32);
}
else if(l == 3) // wall down
{
g_xoff[l] = -16 + tex->getSize().x / 2;
g_yoff[l] = -tex->getSize().y + 32;
}
else if(l == 4) // wall right
{
g_xoff[l] = 16 + tex->getSize().x / 2;
g_yoff[l] = -tex->getSize().y + 32;
}
sf::Sprite spr(*tex);
spr.setPosition(screen_x + xoff + g_xoff[l], screen_y + yoff + g_yoff[l]);
s.window.draw(spr);
if(l == 0 && x == s.character.x && y == s.character.y)
{
tex = s.gfx_loader.LoadTexture(3, 0);
spr.setTexture(*tex);
spr.setPosition(screen_x + xoff, screen_y + yoff);
s.window.draw(spr);
}
if(l == 0 && cursor_closest_dist_x != 0 && x == cursor_closest_dist_x && y == cursor_closest_dist_y)
{
tex = s.gfx_loader.LoadTexture(2, 24);
spr = sf::Sprite(*tex, sf::IntRect(0, 0, 64, 32));
spr.setPosition(cursor_closest_dist_draw_x, cursor_closest_dist_draw_y);
s.window.draw(spr);
}
}
}
}
}
}
{
S &s = S::GetInstance();
int width = s.emf->width;
int height = s.emf->height;
int gfx_id[5] = { 3, 4, 5, 6, 6 };
int g_xoff[5] = { 0, 0, 0, 0, 0 };
int g_yoff[5] = { 0, 0, 0, 0, 0 };
int min_x = s.character.x - 26 >= 0? s.character.x - 26 : 0;
int min_y = s.character.y - 26 >= 0? s.character.y - 26 : 0;
int max_x = s.character.x + 26 < width? s.character.x + 26 : width;
int max_y = s.character.y + 26 < height? s.character.y + 26 : height;
int cursor_closest_dist = 1000;
int cursor_closest_dist_x = 0;
int cursor_closest_dist_y = 0;
int cursor_closest_dist_draw_x = 0;
int cursor_closest_dist_draw_y = 0;
shared_ptr<sf::Texture> tex = s.gfx_loader.LoadTexture(gfx_id[0], s.emf->fill_tile);
sf::Sprite spr_fill(*tex);
for(int y = min_y; y < max_y; ++y)
{
for(int x = min_x; x < max_x; ++x)
{
int graphic_id = s.emf->fill_tile;
if(graphic_id != 0)
{
int player_x = s.character.x * 64 - s.character.x * 32 - s.character.y * 32;
int player_y = s.character.y * 32 + s.character.x * 16 - s.character.y * 16;
int screen_x = 640 / 2 - 32 - player_x;
int screen_y = 480 / 2 - 480 / 4 + 16 - player_y;
int xoff = x * 64;
int yoff = y * 32;
xoff -= x * 32;
yoff += x * 16;
xoff -= y * 32;
yoff -= y * 16;
//shared_ptr<sf::Texture> tex = s.gfx_loader.LoadTexture(gfx_id[0], graphic_id);
//sf::Sprite spr(*tex);
spr_fill.setPosition(screen_x + xoff + g_xoff[0], screen_y + yoff + g_yoff[0]);
s.window.draw(spr_fill);
if(x == s.character.x && y == s.character.y)
{
tex = s.gfx_loader.LoadTexture(3, 0);
//spr.setTexture(*tex);
//s.window.draw(spr);
}
sf::Vector2i pos = sf::Mouse::getPosition(s.window);
int distance = path_length(screen_x + xoff + 32, screen_y + yoff + 16, pos.x, pos.y);
if(distance < cursor_closest_dist)
{
cursor_closest_dist = distance;
cursor_closest_dist_x = x;
cursor_closest_dist_y = y;
cursor_closest_dist_draw_x = screen_x + xoff;
cursor_closest_dist_draw_y = screen_y + yoff;
}
}
}
}
if(cursor_closest_dist_x != 0)
{
shared_ptr<sf::Texture> tex = s.gfx_loader.LoadTexture(2, 24);
sf::Sprite spr(*tex, sf::IntRect(0, 0, 64, 32));
spr.setPosition(cursor_closest_dist_draw_x, cursor_closest_dist_draw_y);
s.window.draw(spr);
}
for(int y = min_y; y < max_y; ++y)
{
for(int x = min_x; x < max_x; ++x)
{
for(int l = 0; l < 5; ++l)
{
int graphic_id = s.emf->GetGraphicID(l, x, y);
if(graphic_id != 0)
{
int player_x = s.character.x * 64 - s.character.x * 32 - s.character.y * 32;
int player_y = s.character.y * 32 + s.character.x * 16 - s.character.y * 16;
int screen_x = 640 / 2 - 32 - player_x;
int screen_y = 480 / 2 - 480 / 4 + 16 - player_y;
int xoff = x * 64;
int yoff = y * 32;
xoff -= x * 32;
yoff += x * 16;
xoff -= y * 32;
yoff -= y * 16;
shared_ptr<sf::Texture> tex = s.gfx_loader.LoadTexture(gfx_id[l], graphic_id);
if(l == 1) // objects
{
g_xoff[l] = 32 - tex->getSize().x / 2;
g_yoff[l] = 0 - (tex->getSize().y - 32);
}
else if(l == 3) // wall down
{
g_xoff[l] = -16 + tex->getSize().x / 2;
g_yoff[l] = -tex->getSize().y + 32;
}
else if(l == 4) // wall right
{
g_xoff[l] = 16 + tex->getSize().x / 2;
g_yoff[l] = -tex->getSize().y + 32;
}
sf::Sprite spr(*tex);
spr.setPosition(screen_x + xoff + g_xoff[l], screen_y + yoff + g_yoff[l]);
s.window.draw(spr);
if(l == 0 && x == s.character.x && y == s.character.y)
{
tex = s.gfx_loader.LoadTexture(3, 0);
spr.setTexture(*tex);
spr.setPosition(screen_x + xoff, screen_y + yoff);
s.window.draw(spr);
}
if(l == 0 && cursor_closest_dist_x != 0 && x == cursor_closest_dist_x && y == cursor_closest_dist_y)
{
tex = s.gfx_loader.LoadTexture(2, 24);
spr = sf::Sprite(*tex, sf::IntRect(0, 0, 64, 32));
spr.setPosition(cursor_closest_dist_draw_x, cursor_closest_dist_draw_y);
s.window.draw(spr);
}
}
}
}
}
}