void renderScene(void) { static int i = 0; glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0,0.0,1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); setWindow(-1+dx,1+dx,-1+dy,1+dy); setViewport(0,100,0,100); renderPointList(); setWindow(0,1,0,1); setViewport(100,200,0,100); renderLogicDiagram(0.1,0.7); setWindow(0.0,4.0,0.0,4.0); setViewport(200,300,0,100); renderClip(); glColor3f(0.0,0.0,1.0); setWindow(-1,1,-1,1); setViewport(300,400,0,100); renderArc1(0.4,0.4); setViewport(400,500,0,100); renderArc2(0.4,0.4); setViewport(500,600,0,100); renderArc3(0.4,0.4,0.8); setWindow(-5.0,5.0,-5.0,5.0); setViewport(0,100,100,200); ElectrostaticField(2.0,2.0,1.0); setWindow(-5.0,5.0,-5.0,5.0); setViewport(0,100,200,300); Smith(); setWindow(-0.5,0.5,-0.5,0.5); Layout(50,50,10,10); glFlush(); }
Workflow::OutputBuffer* TrackWorkflow::getOutput( qint64 currentFrame, qint64 subFrame, bool paused ) { QReadLocker lock( m_clipsLock ); QMap<qint64, ClipWorkflow*>::iterator it = m_clips.begin(); QMap<qint64, ClipWorkflow*>::iterator end = m_clips.end(); bool needRepositioning; Workflow::OutputBuffer *ret = NULL; Workflow::Frame *frames[EffectsEngine::MaxFramesForMixer]; quint32 frameId = 0; bool renderOneFrame = false; if ( m_lastFrame == -1 ) m_lastFrame = currentFrame; { QMutexLocker lock2( m_renderOneFrameMutex ); if ( m_renderOneFrame == true ) { m_renderOneFrame = false; renderOneFrame = true; } } { // This is a bit hackish : when we want to pop a frame in renderOneFrame mode, // we also set the position to avoid the stream to be missynchronized. // this frame setting will most likely toggle the next condition as true // If this condition is true, the clipworkflow will flush all its buffer // as we need to resynchronize after a setTime, so this condition has to remain // false. Easy ain't it? if ( paused == true && subFrame != m_lastFrame && renderOneFrame == false) needRepositioning = true; else needRepositioning = ( abs( subFrame - m_lastFrame ) > 1 ) ? true : false; } memset( frames, 0, sizeof(*frames) * EffectsEngine::MaxFramesForMixer ); while ( it != end ) { qint64 start = it.key(); ClipWorkflow* cw = it.value(); //Is the clip supposed to render now? if ( start <= currentFrame && currentFrame <= start + cw->getClipHelper()->length() ) { ret = renderClip( cw, currentFrame, start, needRepositioning, renderOneFrame, paused ); if ( m_trackType == Workflow::VideoTrack ) { frames[frameId] = static_cast<Workflow::Frame*>( ret ); ++frameId; } } //Is it about to be rendered? else if ( start > currentFrame && start - currentFrame < TrackWorkflow::nbFrameBeforePreload ) preloadClip( cw ); //Is it supposed to be stopped? else stopClipWorkflow( cw ); ++it; } //Handle mixers: if ( m_trackType == Workflow::VideoTrack ) { EffectHelper* mixer = getMixer( currentFrame ); if ( mixer != NULL && frames[0] != NULL ) //There's no point using the mixer if there's no frame rendered. { //FIXME: We don't handle mixer3 yet. mixer->effectInstance()->process( currentFrame * 1000.0 / m_fps, frames[0]->buffer(), frames[1] != NULL ? frames[1]->buffer() : MainWorkflow::getInstance()->blackOutput()->buffer(), NULL, m_mixerBuffer->buffer() ); m_mixerBuffer->ptsDiff = frames[0]->ptsDiff; ret = m_mixerBuffer; } else //If there's no mixer, just use the first frame, ignore the rest. It will be cleaned by the responsible ClipWorkflow. ret = frames[0]; //Now handle filters : quint32 *newFrame = applyFilters( ret != NULL ? static_cast<const Workflow::Frame*>( ret ) : MainWorkflow::getInstance()->blackOutput(), currentFrame, currentFrame * 1000.0 / m_fps ); if ( newFrame != NULL ) { if ( ret != NULL ) static_cast<Workflow::Frame*>( ret )->setBuffer( newFrame ); else //Use the m_mixerBuffer as the frame to return. Ugly but avoid another attribute. { m_mixerBuffer->setBuffer( newFrame ); ret = m_mixerBuffer; } } } m_lastFrame = subFrame; return ret; }