bool RenderObjectManager::render() {
	// Den Objekt-Status des Wurzelobjektes aktualisieren. Dadurch werden rekursiv alle Baumelemente aktualisiert.
	// Beim aktualisieren des Objekt-Status werden auch die Update-Rects gefunden, so dass feststeht, was neu gezeichnet
	// werden muss.
	if (!_rootPtr.isValid() || !_rootPtr->updateObjectState())
		return false;

	_frameStarted = false;

	// Die Render-Methode der Wurzel aufrufen. Dadurch wird das rekursive Rendern der Baumelemente angestoßen.

	_currQueue->clear();
	_rootPtr->preRender(_currQueue);

	_uta->clear();

	// Add rectangles of objects which don't exist in this frame any more
	for (RenderObjectQueue::iterator it = _prevQueue->begin(); it != _prevQueue->end(); ++it) {
		if (!_currQueue->exists(*it))
			_uta->addRect((*it)._bbox);
	}

	// Add rectangles of objects which are different from the previous frame
	for (RenderObjectQueue::iterator it = _currQueue->begin(); it != _currQueue->end(); ++it) {
		if (!_prevQueue->exists(*it))
			_uta->addRect((*it)._bbox);
	}

	RectangleList *updateRects = _uta->getRectangles();
	Common::Array<int> updateRectsMinZ;

	updateRectsMinZ.reserve(updateRects->size());

	// Calculate the minimum drawing Z value of each update rectangle
	// Solid bitmaps with a Z order less than the value calculated here would be overdrawn again and
	// so don't need to be drawn in the first place which speeds things up a bit.
	for (RectangleList::iterator rectIt = updateRects->begin(); rectIt != updateRects->end(); ++rectIt) {
		int minZ = 0;
		for (RenderObjectQueue::iterator it = _currQueue->reverse_begin(); it != _currQueue->end(); --it) {
			if ((*it)._renderObject->isVisible() && (*it)._renderObject->isSolid() &&
				(*it)._renderObject->getBbox().contains(*rectIt)) {
				minZ = (*it)._renderObject->getAbsoluteZ();
				break;
			}
		}
		updateRectsMinZ.push_back(minZ);
	}

	if (_rootPtr->render(updateRects, updateRectsMinZ)) {
		// Copy updated rectangles to the video screen
		Graphics::Surface *backSurface = Kernel::getInstance()->getGfx()->getSurface();
		for (RectangleList::iterator rectIt = updateRects->begin(); rectIt != updateRects->end(); ++rectIt) {
			const int x = (*rectIt).left;
			const int y = (*rectIt).top;
			const int width = (*rectIt).width();
			const int height = (*rectIt).height();
			g_system->copyRectToScreen(backSurface->getBasePtr(x, y), backSurface->pitch, x, y, width, height);
		}
	}

	delete updateRects;

	SWAP(_currQueue, _prevQueue);

	return true;
}