Чистый способ визуализации вещей - PullRequest
2 голосов
/ 10 февраля 2012

У меня действительно нет проблем с тем, как я сейчас рендеринг, но я не чувствую, что это очень хороший способ обработки рендеринга.Я использую SDL.

Это сводится к этому, у меня есть какой-то абстрактный класс

class Renderable

С двумя функциями.

virtual void update() = 0;
virtual void doRender(SDL_Surface* surface) = 0;

У меня есть еще одинкласс

class RenderManager

с 1 std::vector

std::vector<Renderable*> _world;

и 2 std::queue

std::queue<Renderable*> _addQueue;
std::queue<Renderable*> _delQueue;

В этих двух очередях хранятся средства рендеринга, которые необходимо добавить вследующий тик и те, которые нужно убрать.Выполнение всего за один снимок доставило мне проблемы, и теперь, когда я об этом думаю, это имеет смысл (по крайней мере, так, как я это сделал).

Renderables могут добавлять и удалять себя из RenderManager статически.

Вот более-менее функция, обрабатывающая все.

void renderAll() {
    std::vector<Renderable*>::iterator begin, end;
    begin = _world.begin();
    end = _world.end();

    for (;begin != end; ++begin) {
        (*begin)->update();
        (*begin)->doRender(_mainWindow); // _mainWindow is the screen of course
    }

    begin = world.begin();

    if (_delQueue.size() > 0) {
        for (unsigned int i = 0; i < _delQueue.size(); i++) {
            std::vector<Renderable*>::iterator del;
            del = std::find(begin, end, _delQueue.front());

            if (del != end) {
                delete *del;
                _world.erase(del);
            }
            _delQueue.pop();
        }
    }

    if (_addQueue.size() > 0) {
        for (unsigned int i = 0; i < _addQueue.size(); i++) {
            Renderable* front = _addQueue.front();

            // _placement is a property of Renderable calculated by RenderManager
            // where they can choose the level they want to be rendered on.
            _world.insert(begin + front->_placement, front);
            _addQueue.pop();
        }
    }
}

Я немного новичок в C ++, но, думаю, я знаю, как обойти это в среднем масштабе.Я даже новичок в SDL, но он кажется довольно простым и легким в освоении.Я обеспокоен, потому что у меня есть 3 большие петли вместе.Я попробовал один выстрел, но у меня были проблемы с изменением размера _world во время цикла, что вызвало огромное количество разрушений.Но я не утверждаю, что сделал все правильно!:)

Я думал, может быть, что-то с потоками?

РЕДАКТИРОВАТЬ:

Ах, извините за двусмысленность.Под «чище» я подразумеваю более эффективный.Кроме того, в моем подходе нет «проблем», я просто чувствую, что есть более эффективный способ.

1 Ответ

0 голосов
/ 17 февраля 2012

Во-первых, я бы сказал, не чинить то, что не сломано. У вас проблемы с производительностью? Если вы не добавляете и не удаляете «рендеринг» в огромных количествах в каждом кадре, я не вижу большой проблемы с тем, что у вас есть. Конечно, с точки зрения общего приложения это может быть неуклюжий дизайн, но вы еще не указали, для какого приложения это приложение, поэтому трудно, если не невозможно, судить.

Однако я могу догадаться и сказать, что, поскольку вы используете SDL, есть шанс, что вы разрабатываете игру. Лично я всегда рендерил игровые объекты, используя метод рендеринга для каждого активного объекта, и использую диспетчер объектов, чтобы переключаться между указателями на каждый объект каждый тик и вызывать этот метод рендеринга. Поскольку постоянное удаление элемента из середины вектора может вызвать замедление из-за внутреннего копирования памяти (векторы гарантируют непрерывную память), у вас может быть флаг в каждом объекте, который устанавливается, когда он должен быть удален, и периодически объект Диспетчер выполняет «сборку мусора», удаляя все объекты с этим флагом, установленным одновременно, тем самым уменьшая объем копирования, который необходимо выполнить. В то же время, перед тем, как происходит сборка мусора, менеджер просто игнорирует помеченный объект, не вызывая его метод рендеринга каждый тик - это как если бы он ушел. Это на самом деле не слишком отличается от того, что вы имеете здесь с вашей системой очередей, на самом деле, если игровые объекты являются производными от вашего «визуализируемого» класса, это может считаться тем же.

Кстати, есть ли причина, по которой вы запрашиваете размеры очереди, прежде чем получить доступ к их элементам? Если size () равен 0, циклы for не будут работать в любом случае.

...