Попозже оформлю покрасивее.
До некоторого времени я загружал одинаковые картинки для каждого объекта свою, впрочем, вы наверное так-же делаете
Но столкнулся я с проблемой:
Имеется сложный тайлсет размерами w=768 h=128, весит 6.13 Kb
Для создания глобальной карты мне потребуется ровно 10.000 таких картинок.
61300 Kb приблизительно 61.3 Mb, серьёзно?
В общем, программа у меня жрала 2 Gb ОЗУ, точнее сколько смогла, столько и взяла, и не включилась.
И тут я понял что нужна какая-то оптимизация.
Самый простой велосипед, который удалось придумать, это библиотека изображений.
Основной принцип:
Одна картинка может рисоваться 10.000 раз вместо того чтобы 10.000 картинок рисовать по 1 разу.
От пустой болтовни к коду:
1. Класс Image содержащий в себе sf::Image, sf::Texture, sf::Sprite и различные параметры и методы картинки, такой вы и сами сможете сделать.
2. Класс ссылка на картинку
Я его назвал LImage (L – сокращение от анг. библиотечная)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#pragma once #include "stdafx.h" #include "Image.h" class LImage { public: Image* img; sf::Vector2f pos; public: LImage(void); ~LImage(void); bool setImage(Image* image); void draw(sf::RenderWindow *window); sf::Vector2f getPosition(); void setPosition(float x, float y); }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#include "LImage.h" LImage::LImage(void) { img = NULL; pos.x = 0; pos.y = 0; } LImage::~LImage(void) { } bool LImage::setImage(Image* image) { if(image == NULL) return false; img = image; return true; } void LImage::draw(sf::RenderWindow *window) { img->setPosition(pos.x, pos.y); img->draw(window); } sf::Vector2f LImage::getPosition() { return pos; } void LImage::setPosition(float x, float y) { pos.x = x; pos.y = y; } |
3. Класс LibImg – библиотека изображений
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#pragma once #include "stdafx.h" #include "Tilemovi.h" class LibImg { public: std::vector<Image*> vecImage; std::vector<Tileset*> vecTileset; std::vector<Tilemovi*> vecTilemovi; std::vector<Image*> vecImage2; std::vector<Tileset*> vecTileset2; std::vector<Tilemovi*> vecTilemovi2; public: LibImg(void); ~LibImg(void); }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include "LibImg.h" LibImg::LibImg(void) { vecImage.reserve(0); vecTileset.reserve(0); vecTilemovi.reserve(0); vecImage2.reserve(0); vecTileset2.reserve(0); vecTilemovi2.reserve(0); } LibImg::~LibImg(void) { } |
Небольшая задумка на будущее: в первой тройке векторов хранятся картинки которые имеют одинаковый набор параметров, и меняют только координаты или какие-то другие простые параметры.
Во второй тройке хранятся другие такие же картинки, для того чтобы можно было проводить с ними сложные операции по изменению размеров цвета и т.д..
4. main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include "stdafx.h" #include "LibImg.h" #include "LImage.h" int main() { LibImg* libImg = new LibImg(); Image* image = new Image("image01.png"); libImg->vecImage.push_back(image); std::vector<LImage*> vecLImage; for(int i=0;i<10;i++) { LImage* lImage = new LImage(); lImage->setImage(image); lImage->setPosition(16 + i*32, 16); vecLImage.push_back(lImage); } sf::RenderWindow window(sf::VideoMode(1200, 700), "kychka-pc.ru/legozaur"); float time = 0; sf::Clock clock; while (window.isOpen()) { time = clock.getElapsedTime().asSeconds(); clock.restart(); sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); } window.clear(sf::Color(255, 255, 255)); for(std::vector<LImage*>::iterator it = vecLImage.begin(); it != vecLImage.end(); it++) (*it)->draw(&window); window.display(); } return 0; } |
Проверка:
Тестирование производилось на 10000 картинках по 32*32px
Результаты:
в 1 случае через 10000 Image
во 2 случае через LibImg и 10000 LImageВроде ощутимо, вы так не считаете?
В общем то всё.