예제 #1
0
void MultimediaRenderer::Imp::start()
{
	//Retrieve some useful infos
	double stretchTo = m_renderSettings.m_timeStretchTo;
	double stretchFrom = m_renderSettings.m_timeStretchFrom;

	double timeStretchFactor = stretchFrom / stretchTo;
	bool fieldRendering = m_renderSettings.m_fieldPrevalence != TRenderSettings::NoField;

	std::wstring modeStr;
	switch (m_multimediaMode) {
	case COLUMNS:
		modeStr = L"_col";
		break;
	case LAYERS:
		modeStr = L"_lay";
		break;
	default:
		assert(0);
	}

	//Build the post processing fxs tree
	std::vector<TFxP> postFxs(m_framesToRender.size());

	std::set<double>::iterator jt;
	int j;
	for (j = 0, jt = m_framesToRender.begin(); jt != m_framesToRender.end(); ++j, ++jt)
		postFxs[j] = buildPostSceneFx(m_scene, *jt, m_renderSettings.m_shrinkX, false); // Adds camera and camera dpi transforms

	//For each node to be rendered
	int i, count = m_fxsToRender.getFxCount();
	for (i = 0; i < count; ++i) {
		//In case the process has been canceled, return
		if (m_canceled)
			return;

		//Then, build the scene fx for each frame to be rendered
		std::vector<std::pair<double, TFxPair>> pairsToBeRendered;

		//NOTE: The above pairs should not be directly added to a previously declared movierenderer,
		//since an output level would be created even before knowing if any cell to be rendered is
		//actually available.
		const BSFX_Transforms_Enum transforms =   // Do NOT add camera and
			BSFX_Transforms_Enum(BSFX_COLUMN_TR); // camera dpi transforms

		int j;
		for (j = 0, jt = m_framesToRender.begin(); jt != m_framesToRender.end(); ++j, ++jt) {
			TFxPair fx;

			if (m_renderSettings.m_stereoscopic)
				m_scene->shiftCameraX(-m_renderSettings.m_stereoscopicShift / 2);

			fx.m_frameA = buildSceneFx(m_scene, *jt, 0, m_fxsToRender.getFx(i),
									   transforms);

			if (m_renderSettings.m_stereoscopic) {
				m_scene->shiftCameraX(m_renderSettings.m_stereoscopicShift);
				fx.m_frameB = buildSceneFx(m_scene, *jt, 0, m_fxsToRender.getFx(i),
										   transforms);
				m_scene->shiftCameraX(-m_renderSettings.m_stereoscopicShift / 2);
			} else if (fieldRendering)
				fx.m_frameB = buildSceneFx(m_scene, *jt + 0.5 * timeStretchFactor, 0,
										   m_fxsToRender.getFx(i), transforms);
			else
				fx.m_frameB = TRasterFxP();

			//Substitute with the post-process...
			if (fx.m_frameA)
				fx.m_frameA = addPostProcessing(fx.m_frameA, postFxs[j]);
			if (fx.m_frameB)
				fx.m_frameB = addPostProcessing(fx.m_frameB, postFxs[j]);

			if (fx.m_frameA) //Could be 0, if the corresponding cell is void / not rendered
				pairsToBeRendered.push_back(std::pair<double, TFxPair>(*jt, fx));
		}

		if (pairsToBeRendered.size() == 0)
			continue; //Could be, if no cell for this column was in the frame range.

		//Build the output name
		TColumnFx *colFx = searchColumn(m_fxsToRender.getFx(i));
		TFx *currFx = m_fxsToRender.getFx(i);
		assert(colFx);
		if (!colFx)
			continue;

		int columnIndex = colFx->getColumnIndex();
		std::wstring columnName(colFx->getColumnName());
		std::wstring columnId(colFx->getColumnId());
		std::wstring fxName(currFx->getName());
		std::wstring fxNameNoSpaces(::removeSpaces(fxName));
		std::wstring fxId(currFx->getFxId());

		std::wstring fpName = m_fp.getWideName() +
						 L"_" + columnName + (columnId == columnName ? L"" : L"(" + columnId + L")") +
						 (fxId.empty() ? L"" : L"_" + fxName + (fxId == fxNameNoSpaces ? L"" : L"(" + fxId + L")"));
		TFilePath movieFp(m_fp.withName(fpName));

		//Initialize a MovieRenderer with our infos
		MovieRenderer movieRenderer(m_scene, movieFp, m_threadCount, false);
		movieRenderer.setRenderSettings(m_renderSettings);
		movieRenderer.setDpi(m_xDpi, m_yDpi);
		movieRenderer.enablePrecomputing(m_precomputingEnabled);
		movieRenderer.addListener(this);

		for (unsigned int j = 0; j < pairsToBeRendered.size(); ++j) {
			std::pair<double, TFxPair> &currentPair = pairsToBeRendered[j];
			movieRenderer.addFrame(currentPair.first, currentPair.second);
		}

		//Finally, start rendering currently initialized MovieRenderer.
		m_currentFx = i;
		m_currentFrame = m_framesToRender.begin();
		m_currentTRenderer = movieRenderer.getTRenderer();

		movieRenderer.start();

		//I don't recall Toonz currently supports different, simultaneous rendering processes.
		//However, one rendering process is supposed to be exhausting the machine's resources
		//on its own - so, we'll just set up an idle (but GUI-reactive) loop here.
		//It will quit looping whenever the "onSequenceCompleted" notification gets called.
		m_eventLoop.exec();

		//---------------------- Loops here --------------------------
	}

	//Lastly, inform everyone that rendering stopped
	onRenderCompleted();
}
예제 #2
0
void RenderCommand::rasterRender(bool isPreview)
{
	ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();

	if (isPreview) {
		//Let the PreviewFxManager own the rest. Just pass him the current output node.
		PreviewFxManager::instance()->showNewPreview((TFx *)scene->getXsheet()->getFxDag()->getCurrentOutputFx());
		return;
	}

	string ext = m_fp.getType();

#ifdef WIN32
	if (ext == "avi" && !isPreview) {
		TPropertyGroup *props = scene->getProperties()->getOutputProperties()->getFileFormatProperties(ext);
		string codecName = props->getProperty(0)->getValueAsString();
		TDimension res = scene->getCurrentCamera()->getRes();
		if (!AviCodecRestrictions::canWriteMovie(toWideString(codecName), res)) {
			QString msg(QObject::tr("The resolution of the output camera does not fit with the options chosen for the output file format."));
			MsgBox(WARNING, msg);
			return;
		}
	}
#endif;

	//Extract output properties
	TOutputProperties *prop = isPreview ? scene->getProperties()->getPreviewProperties() : scene->getProperties()->getOutputProperties();

	//Build thread count
	/*-- Dedicated CPUs のコンボボックス (Single, Half, All) --*/
	int index = prop->getThreadIndex();

	const int procCount = TSystem::getProcessorCount();
	const int threadCounts[3] = {1, procCount / 2, procCount};

	int threadCount = threadCounts[index];

	/*-- MovieRendererを作る。Previewの場合はファイルパスは空 --*/
	MovieRenderer movieRenderer(scene, isPreview ? TFilePath() : m_fp, threadCount, isPreview);

	TRenderSettings rs = prop->getRenderSettings();

	//Build raster granularity size
	index = prop->getMaxTileSizeIndex();

	const int maxTileSizes[4] = {
		(std::numeric_limits<int>::max)(),
		TOutputProperties::LargeVal,
		TOutputProperties::MediumVal,
		TOutputProperties::SmallVal};
	rs.m_maxTileSize = maxTileSizes[index];

//Build

#ifdef BRAVODEMO
	rs.m_mark = loadBravo(scene->getCurrentCamera()->getRes());
#endif
	/*-- RenderSettingsをセット --*/
	movieRenderer.setRenderSettings(rs);
	/*-- カメラDPIの取得、セット --*/
	TPointD cameraDpi = isPreview ? scene->getCurrentPreviewCamera()->getDpi() : scene->getCurrentCamera()->getDpi();
	movieRenderer.setDpi(cameraDpi.x, cameraDpi.y);
	movieRenderer.enablePrecomputing(true);

	/*-- プログレス ダイアログの作成 --*/
	RenderListener *listener =
		new RenderListener(movieRenderer.getTRenderer(), m_fp, ((m_numFrames - 1) / m_step) + 1, isPreview);
	QObject::connect(listener, SIGNAL(canceled()), &movieRenderer, SLOT(onCanceled()));
	movieRenderer.addListener(listener);

	bool fieldRendering = rs.m_fieldPrevalence != TRenderSettings::NoField;

	/*-- buildSceneFxの進行状況を表示するプログレスバー --*/
	QProgressBar *buildSceneProgressBar = new QProgressBar(TApp::instance()->getMainWindow());
	buildSceneProgressBar->setAttribute(Qt::WA_DeleteOnClose);
	buildSceneProgressBar->setWindowFlags(Qt::SubWindow | Qt::Dialog | Qt::WindowStaysOnTopHint);
	buildSceneProgressBar->setMinimum(0);
	buildSceneProgressBar->setMaximum(m_numFrames - 1);
	buildSceneProgressBar->setValue(0);
	buildSceneProgressBar->move(600, 500);
	buildSceneProgressBar->setWindowTitle("Building Schematic...");
	buildSceneProgressBar->show();

	for (int i = 0; i < m_numFrames; ++i, m_r += m_stepd) {
		buildSceneProgressBar->setValue(i);

		if (rs.m_stereoscopic)
			scene->shiftCameraX(-rs.m_stereoscopicShift / 2);
		TFxPair fx;
		fx.m_frameA = buildSceneFx(scene, m_r, rs.m_shrinkX, isPreview);

		if (fieldRendering && !isPreview)
			fx.m_frameB = buildSceneFx(scene, m_r + 0.5 / m_timeStretchFactor, rs.m_shrinkX, isPreview);
		else if (rs.m_stereoscopic) {
			scene->shiftCameraX(rs.m_stereoscopicShift);
			fx.m_frameB = buildSceneFx(scene, m_r + 0.5 / m_timeStretchFactor, rs.m_shrinkX, isPreview);
			scene->shiftCameraX(-rs.m_stereoscopicShift / 2);
		} else
			fx.m_frameB = TRasterFxP();
		/*-- movieRendererにフレーム毎のFxを登録 --*/
		movieRenderer.addFrame(m_r, fx);
	}
	/*-- プログレスバーを閉じる --*/
	buildSceneProgressBar->close();

	//resetViewer(); //TODO cancella le immagini dell'eventuale render precedente
	//FileViewerPopupPool::instance()->getCurrent()->onClose();

	movieRenderer.start();
}