//! Initialize the frame buffer objects. void initFBOs() { invariant(); Q_ASSERT_X(useFBO(), Q_FUNC_INFO, "We're not using FBO"); if (NULL == backBuffer) { Q_ASSERT_X(NULL == frontBuffer, Q_FUNC_INFO, "frontBuffer is not null even though backBuffer is"); // If non-power-of-two textures are supported, // FBOs must have power of two size large enough to fit the viewport. const QSize bufferSize = nonPowerOfTwoTexturesSupported ? StelUtils::smallestPowerOfTwoSizeGreaterOrEqualTo(viewportSize) : viewportSize; // We want a depth and stencil buffer attached to our FBO if possible. const QGLFramebufferObject::Attachment attachment = QGLFramebufferObject::CombinedDepthStencil; backBuffer = new QGLFramebufferObject(bufferSize, attachment); frontBuffer = new QGLFramebufferObject(bufferSize, attachment); Q_ASSERT_X(backBuffer->isValid() && frontBuffer->isValid(), Q_FUNC_INFO, "Framebuffer objects failed to initialize"); } invariant(); }
QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize, const QGLFramebufferObjectFormat &requestFormat, bool strictSize) { QGLFramebufferObject *chosen = 0; QGLFramebufferObject *candidate = 0; for (int i = 0; !chosen && i < m_fbos.size(); ++i) { QGLFramebufferObject *fbo = m_fbos.at(i); if (strictSize) { if (fbo->size() == requestSize && fbo->format() == requestFormat) { chosen = fbo; break; } else { continue; } } if (fbo->format() == requestFormat) { // choose the fbo with a matching format and the closest size if (!candidate || areaDiff(requestSize, candidate) > areaDiff(requestSize, fbo)) candidate = fbo; } if (candidate) { m_fbos.removeOne(candidate); const QSize fboSize = candidate->size(); QSize sz = fboSize; if (sz.width() < requestSize.width()) sz.setWidth(qMax(requestSize.width(), qRound(sz.width() * 1.5))); if (sz.height() < requestSize.height()) sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5))); // wasting too much space? if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4) sz = requestSize; if (sz != fboSize) { delete candidate; candidate = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(sz), requestFormat); } chosen = candidate; } } if (!chosen) { if (strictSize) chosen = new QGLFramebufferObject(requestSize, requestFormat); else chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat); } if (!chosen->isValid()) { delete chosen; chosen = 0; } return chosen; }