示例#1
0
void BaseRenderOSystem::drawFromTicket(RenderTicket *renderTicket) {
	renderTicket->_wantsDraw = true;
	// A new item always has _drawNum == 0
	if (renderTicket->_drawNum == 0) {
		// In-order
		if (_renderQueue.empty() || _drawNum > (_renderQueue.back())->_drawNum) {
			renderTicket->_drawNum = _drawNum++;
			_renderQueue.push_back(renderTicket);
			addDirtyRect(renderTicket->_dstRect);
			++_lastAddedTicket;
		} else {
			// Before something
			RenderQueueIterator pos;
			for (pos = _renderQueue.begin(); pos != _renderQueue.end(); pos++) {
				if ((*pos)->_drawNum >= _drawNum) {
					break;
				}
			}
			_renderQueue.insert(pos, renderTicket);
			renderTicket->_drawNum = _drawNum++;
			// Increment the following tickets, so they still are in line
			RenderQueueIterator it;
			for (it = pos; it != _renderQueue.end(); ++it) {
				(*it)->_drawNum++;
				(*it)->_wantsDraw = false;
			}
			addDirtyRect(renderTicket->_dstRect);
			_lastAddedTicket = pos;
		}
	} else {
		// Was drawn last round, still in the same order
		if (_drawNum == renderTicket->_drawNum) {
			_drawNum++;
			++_lastAddedTicket;
		} else {
			// Remove the ticket from the list
			RenderQueueIterator it = _renderQueue.begin();
			while (it != _renderQueue.end()) {
				if ((*it) == renderTicket) {
					it = _renderQueue.erase(it);
					break;
				} else {
					++it;
				}
			}
			if (it != _renderQueue.end()) {
				// Decreement the following tickets.
				for (; it != _renderQueue.end(); ++it) {
					(*it)->_drawNum--;
				}
			}
			// Is not in order, so readd it as if it was a new ticket
			renderTicket->_drawNum = 0;
			drawFromTicket(renderTicket);
		}
	}
}
void BaseRenderOSystem::drawFromQueuedTicket(const RenderQueueIterator &ticket) {
	RenderTicket *renderTicket = *ticket;
	assert(!renderTicket->_wantsDraw);
	renderTicket->_wantsDraw = true;

	++_lastFrameIter;
	// Not in the same order?
	if (*_lastFrameIter != renderTicket) {
		--_lastFrameIter;
		// Remove the ticket from the list
		assert(*_lastFrameIter != renderTicket);
		_renderQueue.erase(ticket);
		// Is not in order, so readd it as if it was a new ticket
		drawFromTicket(renderTicket);
	}
}
void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform) { 

	if (_disableDirtyRects) {
		RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform);
		ticket->_wantsDraw = true;
		_renderQueue.push_back(ticket);
		drawFromSurface(ticket);
		return;
	}

	// Skip rects that are completely outside the screen:
	if ((dstRect->left < 0 && dstRect->right < 0) || (dstRect->top < 0 && dstRect->bottom < 0)) {
		return;
	}

	if (owner) { // Fade-tickets are owner-less
		RenderTicket compare(owner, nullptr, srcRect, dstRect, transform);
		RenderQueueIterator it = _lastFrameIter;
		++it;
		// Avoid calling end() and operator* every time, when potentially going through
		// LOTS of tickets.
		RenderQueueIterator endIterator = _renderQueue.end();
		RenderTicket *compareTicket = nullptr;
		for (; it != endIterator; ++it) {
			compareTicket = *it;
			if (*(compareTicket) == compare && compareTicket->_isValid) {
				if (_disableDirtyRects) {
					drawFromSurface(compareTicket);
				} else {
					drawFromQueuedTicket(it);
				}
				return;
			}
		}
	}
	RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform);
	if (!_disableDirtyRects) {
		drawFromTicket(ticket);
	} else {
		ticket->_wantsDraw = true;
		_renderQueue.push_back(ticket);
		drawFromSurface(ticket);
	}
}
示例#4
0
void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform) { 

	if (_tempDisableDirtyRects || _disableDirtyRects) {
		RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform);
		ticket->_transform._rgbaMod = _colorMod;
		ticket->_wantsDraw = true;
		_renderQueue.push_back(ticket);
		_previousTicket = ticket;
		drawFromSurface(ticket);
		return;
	}

	// Start searching from the beginning for the first and second items (since it's empty the first time around
	// then keep incrementing the start-position, to avoid comparing against already used tickets.
	if (_drawNum == 0 || _drawNum == 1) {
		_lastAddedTicket = _renderQueue.begin();
	}

	// Skip rects that are completely outside the screen:
	if ((dstRect->left < 0 && dstRect->right < 0) || (dstRect->top < 0 && dstRect->bottom < 0)) {
		return;
	}

	if (owner) { // Fade-tickets are owner-less
		RenderTicket compare(owner, nullptr, srcRect, dstRect, transform);
		compare._batchNum = _batchNum;
		if (_spriteBatch) {
			_batchNum++;
		}
		RenderQueueIterator it;
		// Avoid calling end() and operator* every time, when potentially going through
		// LOTS of tickets.
		RenderQueueIterator endIterator = _renderQueue.end();
		RenderTicket *compareTicket = nullptr;
		for (it = _lastAddedTicket; it != endIterator; ++it) {
			compareTicket = *it;
			if (*(compareTicket) == compare && compareTicket->_isValid) {
				compareTicket->_transform._rgbaMod = transform._rgbaMod; 
				if (_disableDirtyRects) {
					drawFromSurface(compareTicket);
				} else {
					drawFromTicket(compareTicket);
					_previousTicket = compareTicket;
				}
				if (_renderQueue.size() > DIRTY_RECT_LIMIT) {
					drawTickets();
					_tempDisableDirtyRects = 3;
				}
				return;
			}
		}
	}
	RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform);
	if (!_disableDirtyRects) {
		drawFromTicket(ticket);
		_previousTicket = ticket;
	} else {
		ticket->_wantsDraw = true;
		_renderQueue.push_back(ticket);
		_previousTicket = ticket;
		drawFromSurface(ticket);
	}
}