I've got a problem while rendering a 2D map which is drawn using vertex arrays; first let me explain my idea:
I want to draw objects on the map. They have irregular size and are stored in separate graphic files. I need to load them by ID (ID is loaded from a map file).
I also want to have them all in one texture, so I will call the draw function only once.
Until now, my game was creating a virtual image and putting them all in it. It was also storing an information about each object size and possition on the "big texture".
The problem is that when I added more objects there were too many of them and the texture was too big (it gives me SFML error).
My question is: is there any other way to manage graphics like that? I don't want to call draw() too often :S
The only idea that comes to my mind is to create just another texture and put the rest of the objects there. Here's a code I wrote a while ago. It doesn't work but I hope it will show you what I mean...
void SpriteSheet::mergeImages(GFXLoader::Directory &dir)
{
sf::Vector2f totalTextureSize;
sf::Vector2f currentPossition;
for(auto &img: dir.img)
{
unsigned int w = img.second.getSize().x;
unsigned int h = img.second.getSize().y;
if(currentPossition.x + w < sf::Texture::getMaximumSize())
{
currentPossition.x += w;
if(totalTextureSize.x < currentPossition.x) totalTextureSize.x = currentPossition.x;
}
else
{
currentPossition.x = 0;
currentPossition.y += h;
if(totalTextureSize.y < currentPossition.y) totalTextureSize.y = currentPossition.y;
}
if(totalTextureSize.y < h) totalTextureSize.y = h;
}
unsigned int img_w = totalTextureSize.x > sf::Texture::getMaximumSize()?
sf::Texture::getMaximumSize() : totalTextureSize.x;
unsigned int img_h = totalTextureSize.y > sf::Texture::getMaximumSize()?
sf::Texture::getMaximumSize() : totalTextureSize.y;
sf::Image bigImage;
bigImage.create(img_w, img_h, sf::Color(0, 0, 0));
unsigned int textureCount = 0;
unsigned int maxHeight = 0;
unsigned int sprId = 0;
sf::Vector2f remaining;
remaining.x = totalTextureSize.x;
remaining.y = totalTextureSize.y;
currentPossition.x = 0;
currentPossition.y = 0;
for(auto &img: dir.img)
{
unsigned int w = img.second.getSize().x;
unsigned int h = img.second.getSize().y;
SpriteInfo sprInfo;
sprInfo.textureId = textureCount;
if(h > maxHeight) maxHeight = h;
if(currentPossition.x + w < sf::Texture::getMaximumSize())
{
bigImage.copy(img.second, currentPossition.x, currentPossition.x, sf::IntRect(0, 0, w, h));
sprInfo.rect = sf::IntRect(currentPossition.x, currentPossition.x, w, h);
sprites[sprId] = sprInfo;
currentPossition.x += w;
sprId++;
}
else if(currentPossition.y + h < sf::Texture::getMaximumSize())
{
currentPossition.x = 0;
currentPossition.y += maxHeight;
remaining.y -= maxHeight;
bigImage.copy(img.second, currentPossition.x, currentPossition.y, sf::IntRect(0, 0, w, h));
sprInfo.rect = sf::IntRect(currentPossition.x, currentPossition.y, w, h);
sprites[sprId] = sprInfo;
sprId++;
}
else
{
images.push_back(bigImage);
sf::Texture tex;
tex.loadFromImage(images[images.size() - 1]);
textures.push_back(tex);
currentPossition.x = 0;
currentPossition.y = 0;
if(remaining.y > 0)
{
img_w = totalTextureSize.x > sf::Texture::getMaximumSize()?
sf::Texture::getMaximumSize() : totalTextureSize.x;
img_h = remaining.y > sf::Texture::getMaximumSize()?
sf::Texture::getMaximumSize() : remaining.y;
bigImage.create(img_w, img_h, sf::Color(0, 0, 0));
textureCount++;
}
}
}
}