void Screen::update() { _ticks = _vm->_system->getMillis(); updatePalette(); if (_fullRefresh) { // NOTE When playing a fullscreen/doubled Smacker video usually a full screen refresh is needed _vm->_system->copyRectToScreen((const byte*)_backScreen->getPixels(), _backScreen->pitch, 0, 0, 640, 480); _fullRefresh = false; return; } _microTiles->clear(); for (RenderQueue::iterator it = _renderQueue->begin(); it != _renderQueue->end(); ++it) { RenderItem &renderItem = (*it); renderItem._refresh = true; for (RenderQueue::iterator jt = _prevRenderQueue->begin(); jt != _prevRenderQueue->end(); ++jt) { RenderItem &prevRenderItem = (*jt); if (prevRenderItem == renderItem) { prevRenderItem._refresh = false; renderItem._refresh = false; } } } for (RenderQueue::iterator jt = _prevRenderQueue->begin(); jt != _prevRenderQueue->end(); ++jt) { RenderItem &prevRenderItem = (*jt); if (prevRenderItem._refresh) _microTiles->addRect(Common::Rect(prevRenderItem._destX, prevRenderItem._destY, prevRenderItem._destX + prevRenderItem._width, prevRenderItem._destY + prevRenderItem._height)); } for (RenderQueue::iterator it = _renderQueue->begin(); it != _renderQueue->end(); ++it) { RenderItem &renderItem = (*it); if (renderItem._refresh) _microTiles->addRect(Common::Rect(renderItem._destX, renderItem._destY, renderItem._destX + renderItem._width, renderItem._destY + renderItem._height)); renderItem._refresh = true; } RectangleList *updateRects = _microTiles->getRectangles(); for (RenderQueue::iterator it = _renderQueue->begin(); it != _renderQueue->end(); ++it) { RenderItem &renderItem = (*it); for (RectangleList::iterator ri = updateRects->begin(); ri != updateRects->end(); ++ri) blitRenderItem(renderItem, *ri); } SWAP(_renderQueue, _prevRenderQueue); _renderQueue->clear(); for (RectangleList::iterator ri = updateRects->begin(); ri != updateRects->end(); ++ri) { Common::Rect &r = *ri; _vm->_system->copyRectToScreen((const byte*)_backScreen->getBasePtr(r.left, r.top), _backScreen->pitch, r.left, r.top, r.width(), r.height()); } delete updateRects; }
void clearRegionInFrameBuffer (const RectangleList& list, const float scaleFactor) { glClearColor (0, 0, 0, 0); glEnable (GL_SCISSOR_TEST); const GLuint previousFrameBufferTarget = OpenGLFrameBuffer::getCurrentFrameBufferTarget(); cachedImageFrameBuffer.makeCurrentRenderingTarget(); const int imageH = cachedImageFrameBuffer.getHeight(); for (const Rectangle<int>* i = list.begin(), * const e = list.end(); i != e; ++i) { const Rectangle<int> r ((i->toFloat() * scaleFactor).getSmallestIntegerContainer()); glScissor (r.getX(), imageH - r.getBottom(), r.getWidth(), r.getHeight()); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } glDisable (GL_SCISSOR_TEST); context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, previousFrameBufferTarget); JUCE_CHECK_OPENGL_ERROR }
void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, const AffineTransform& transform) { const int w = sourceImage.getWidth(); const int h = sourceImage.getHeight(); writeClip(); out << "gsave "; writeTransform (transform.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset) .scaled (1.0f, -1.0f)); RectangleList<int> imageClip; sourceImage.createSolidAreaMask (imageClip, 0.5f); out << "newpath "; int itemsOnLine = 0; for (const Rectangle<int>* i = imageClip.begin(), * const e = imageClip.end(); i != e; ++i) { if (++itemsOnLine == 6) { out << '\n'; itemsOnLine = 0; } out << i->getX() << ' ' << i->getY() << ' ' << i->getWidth() << ' ' << i->getHeight() << " pr "; } out << " clip newpath\n"; out << w << ' ' << h << " scale\n"; out << w << ' ' << h << " 8 [" << w << " 0 0 -" << h << ' ' << (int) 0 << ' ' << h << " ]\n"; writeImage (sourceImage, 0, 0, w, h); out << "false 3 colorimage grestore\n"; needToClip = true; }
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; }
void Graphics::fillRectList (const RectangleList<int>& rects) const { for (const Rectangle<int>* r = rects.begin(), * const e = rects.end(); r != e; ++r) context.fillRect (*r, false); }
void fillRectList (const RectangleList<float>& list) { for (const Rectangle<float>* r = list.begin(), * const e = list.end(); r != e; ++r) fillRect (*r); }