Workflow::OutputBuffer* AudioClipWorkflow::getOutput( ClipWorkflow::GetMode mode, qint64 ) { QMutexLocker lock( m_renderLock ); if ( m_lastReturnedBuffer != NULL ) { m_availableBuffers.enqueue( m_lastReturnedBuffer ); m_lastReturnedBuffer = NULL; } if ( getNbComputedBuffers() == 0 ) return NULL; if ( shouldRender() == false ) return NULL; if ( mode == ClipWorkflow::Get ) vlmcCritical() << "A sound buffer should never be asked with 'Get' mode"; Workflow::AudioSample *buff = m_computedBuffers.dequeue(); if ( m_previousPts == -1 ) { buff->ptsDiff = 0; m_previousPts = buff->pts; } else { buff->ptsDiff = buff->pts - m_previousPts; m_previousPts = buff->pts; } postGetOutput(); m_lastReturnedBuffer = buff; return buff; }
Workflow::OutputBuffer* VideoClipWorkflow::getOutput( ClipWorkflow::GetMode mode, qint64 currentFrame ) { QMutexLocker lock( m_renderLock ); if ( m_lastReturnedBuffer != NULL ) { m_availableBuffers.enqueue( m_lastReturnedBuffer ); m_lastReturnedBuffer = NULL; } if ( shouldRender() == false ) return NULL; if ( getNbComputedBuffers() == 0 ) m_renderWaitCond->wait( m_renderLock ); //Recheck again, as the WaitCondition may have been awaken when stopping. if ( getNbComputedBuffers() == 0 ) return NULL; Workflow::Frame *buff = NULL; if ( mode == ClipWorkflow::Pop ) { buff = m_computedBuffers.dequeue(); m_lastReturnedBuffer = buff; } else buff = m_computedBuffers.head(); quint32 *newFrame = applyFilters( buff, currentFrame, currentFrame * 1000.0 / clip()->getMedia()->fps() ); if ( newFrame != NULL ) buff->setBuffer( newFrame ); postGetOutput(); return buff; }
Workflow::OutputBuffer* VideoClipWorkflow::getOutput( ClipWorkflow::GetMode mode, qint64 currentFrame ) { QMutexLocker lock( m_renderLock ); if ( m_lastReturnedBuffer != NULL ) { m_availableBuffers.enqueue( m_lastReturnedBuffer ); m_lastReturnedBuffer = NULL; } if ( shouldRender() == false ) return NULL; if ( getNbComputedBuffers() == 0 ) { if ( m_renderWaitCond->wait( m_renderLock, 50 ) == false ) { vlmcWarning() << "Clip workflow" << m_clipHelper->uuid() << "Timed out while waiting for a frame"; errorEncountered(); return NULL; } if ( shouldRender() == false ) return NULL; } Workflow::Frame *buff = NULL; if ( mode == ClipWorkflow::Pop ) { buff = m_computedBuffers.dequeue(); m_lastReturnedBuffer = buff; } else buff = m_computedBuffers.head(); quint32 *newFrame = applyFilters( buff, currentFrame, currentFrame * 1000.0 / clip()->getMedia()->source()->fps() ); if ( newFrame != NULL ) buff->setBuffer( newFrame ); postGetOutput(); return buff; }
void HelpItemManager::renderMessages(const ClientGame *game, F32 yPos, F32 alpha) const { if(!shouldRender(game)) return; #ifdef TNL_DEBUG // This bit is for displaying our help messages one-by-one so we can see how they look on-screen, cycle with CTRL+H if(mTestingTimer.getCurrent() > 0) { FontManager::pushFontContext(HelpItemContext); doRenderMessages(game, mInputCodeManager, (HelpItem)(mTestingCtr % HelpItemCount), yPos, Colors::red, alpha); FontManager::popFontContext(); return; } #endif if(!mEnabled) return; FontManager::pushFontContext(HelpItemContext); for(S32 i = 0; i < mHelpItems.size(); i++) // Iterate over each message being displayed { // Height of the message in pixels, including the gap before the next message (even if there isn't one) F32 height = F32(getLinesInHelpItem(i) * (FontSize + FontGap)) + InterMsgGap; // Offset makes lower items slide up as upper items are rolled up -- when we're not fading, offset // is 0; when we are, offset directs doRenderMessages to render with the top of the message higher // than normal. That, combined with scissors clipping, results in the rolling-up effect. F32 offset = height * (mHelpFading[i] ? 1 - mHelpTimer[i].getFraction() : 0); DisplayMode displayMode = game->getSettings()->getSetting<DisplayMode>(IniKey::WindowMode); scissorsManager.enable(mHelpFading[i], displayMode, 0, yPos - FontSize, (F32)DisplayManager::getScreenInfo()->getGameCanvasWidth(), height); doRenderMessages(game, mInputCodeManager, mHelpItems[i], yPos - offset, Colors::HelpItemRenderColor, alpha); yPos += height - offset; scissorsManager.disable(); } FontManager::popFontContext(); }
void ParticleRenderSystem::processEntities( const vector<Entity*>& p_entities ) { ClientStateSystem* stateSystem = static_cast<ClientStateSystem*>(m_world->getSystem(SystemType::ClientStateSystem)); /* if (stateSystem->getCurrentState() == GameStates::INGAME) { timeInGame += m_world->getDelta(); if (timeInGame < 2.0f) return; } */ clearRenderQues(); drawnPS = 0; calcCameraPlanes(); // get camera pos, for sorting AglVector3 cameraPos( 0.0f, 0.0f, 0.0f ); auto entitymanager = m_world->getEntityManager(); Entity* cam = entitymanager->getFirstEntityByComponentType(ComponentType::TAG_MainCamera); if (cam) { Transform* camTransform = static_cast<Transform*>( cam->getComponent( ComponentType::Transform ) ); if (camTransform) cameraPos = camTransform->getTranslation(); } // all particle systems for( unsigned int i = 0; i<p_entities.size(); i++ ) { Transform* transform = static_cast<Transform*>( p_entities[i]->getComponent( ComponentType::Transform ) ); MeshOffsetTransform* offset = static_cast<MeshOffsetTransform*>( p_entities[i]->getComponent( ComponentType::MeshOffsetTransform ) ); ParticleSystemsComponent* particlesComp = static_cast<ParticleSystemsComponent*>( p_entities[i]->getComponent( ComponentType::ParticleSystemsComponent ) ); if( particlesComp->getParticleSystemCnt() > 0 ) { for( unsigned int i=0; i<particlesComp->getParticleSystemsPtr()->size(); i++ ) { ParticleSystemAndTexture* psAndTex = particlesComp->getParticleSystemAndTexturePtr(i); if( psAndTex != NULL ) { if (shouldRender(psAndTex)) { drawnPS++; AglParticleSystemHeader header = psAndTex->particleSystem.getHeader(); AglMatrix transMat = transform->getMatrix(); Transform* newTrans = new Transform(transform->getMatrix()); // Offset Agl-loaded meshes by their offset matrix if( offset != NULL ) { transMat = offset->offset.inverse() * transMat; } newTrans->setMatrix(transMat); if( header.spawnSpace == AglParticleSystemHeader::AglSpace_LOCAL && header.particleSpace == AglParticleSystemHeader::AglSpace_GLOBAL) { particlesComp->setSpawn( transMat, i ); } PsRenderInfo info( psAndTex, newTrans->getInstanceVertex()); insertToRenderQue( info ); delete newTrans; } } } } particlesComp->updateParticleSystems( m_world->getDelta(), cameraPos); } if (drawnPS > maxDrawnPS) maxDrawnPS = drawnPS; }
bool ProjectedShadow::_updateDecal( const SceneRenderState *state ) { PROFILE_SCOPE( ProjectedShadow_UpdateDecal ); if ( !LIGHTMGR ) return false; // Get the position of the decal first. const Box3F &objBox = mParentObject->getObjBox(); const Point3F boxCenter = objBox.getCenter(); Point3F decalPos = boxCenter; const MatrixF &renderTransform = mParentObject->getRenderTransform(); { // Set up the decal position. // We use the object space box center // multiplied by the render transform // of the object to ensure we benefit // from interpolation. MatrixF t( renderTransform ); t.setColumn(2,Point3F::UnitZ); t.mulP( decalPos ); } if ( mDecalInstance ) { mDecalInstance->mPosition = decalPos; if ( !shouldRender( state ) ) return false; } // Get the sunlight for the shadow projection. // We want the LightManager to return NULL if it can't // get the "real" sun, so we specify false for the useDefault parameter. LightInfo *lights[4] = {0}; LightQuery query; query.init( mParentObject->getWorldSphere() ); query.getLights( lights, 4 ); Point3F pos = renderTransform.getPosition(); Point3F lightDir( 0, 0, 0 ); Point3F tmp( 0, 0, 0 ); F32 weight = 0; F32 range = 0; U32 lightCount = 0; F32 dist = 0; F32 fade = 0; for ( U32 i = 0; i < 4; i++ ) { // If we got a NULL light, // we're at the end of the list. if ( !lights[i] ) break; if ( !lights[i]->getCastShadows() ) continue; if ( lights[i]->getType() != LightInfo::Point ) tmp = lights[i]->getDirection(); else tmp = pos - lights[i]->getPosition(); range = lights[i]->getRange().x; dist = ( (tmp.lenSquared()) / ((range * range) * 0.5f)); weight = mClampF( 1.0f - ( tmp.lenSquared() / (range * range)), 0.00001f, 1.0f ); if ( lights[i]->getType() == LightInfo::Vector ) fade = getMax( fade, 1.0f ); else fade = getMax( fade, mClampF( 1.0f - dist, 0.00001f, 1.0f ) ); lightDir += tmp * weight; lightCount++; } lightDir.normalize(); // No light... no shadow. if ( !lights[0] ) return false; // Has the light direction // changed since last update? bool lightDirChanged = !mLastLightDir.equal( lightDir ); // Has the parent object moved // or scaled since the last update? bool hasMoved = !mLastObjectPosition.equal( mParentObject->getRenderPosition() ); bool hasScaled = !mLastObjectScale.equal( mParentObject->getScale() ); // Set the last light direction // to the current light direction. mLastLightDir = lightDir; mLastObjectPosition = mParentObject->getRenderPosition(); mLastObjectScale = mParentObject->getScale(); // Temps used to generate // tangent vector for DecalInstance below. VectorF right( 0, 0, 0 ); VectorF fwd( 0, 0, 0 ); VectorF tmpFwd( 0, 0, 0 ); U32 idx = lightDir.getLeastComponentIndex(); tmpFwd[idx] = 1.0f; right = mCross( tmpFwd, lightDir ); fwd = mCross( lightDir, right ); right = mCross( fwd, lightDir ); right.normalize(); // Set up the world to light space // matrix, along with proper position // and rotation to be used as the world // matrix for the render to texture later on. static MatrixF sRotMat(EulerF( 0.0f, -(M_PI_F/2.0f), 0.0f)); mWorldToLight.identity(); MathUtils::getMatrixFromForwardVector( lightDir, &mWorldToLight ); mWorldToLight.setPosition( ( pos + boxCenter ) - ( ( (mRadius * smDepthAdjust) + 0.001f ) * lightDir ) ); mWorldToLight.mul( sRotMat ); mWorldToLight.inverse(); // Get the shapebase datablock if we have one. ShapeBaseData *data = NULL; if ( mShapeBase ) data = static_cast<ShapeBaseData*>( mShapeBase->getDataBlock() ); // We use the object box's extents multiplied // by the object's scale divided by 2 for the radius // because the object's worldsphere radius is not // rotationally invariant. mRadius = (objBox.getExtents() * mParentObject->getScale()).len() * 0.5f; if ( data ) mRadius *= data->shadowSphereAdjust; // Create the decal if we don't have one yet. if ( !mDecalInstance ) mDecalInstance = gDecalManager->addDecal( decalPos, lightDir, right, mDecalData, 1.0f, 0, PermanentDecal | ClipDecal | CustomDecal ); if ( !mDecalInstance ) return false; mDecalInstance->mVisibility = fade; // Setup decal parameters. mDecalInstance->mSize = mRadius * 2.0f; mDecalInstance->mNormal = -lightDir; mDecalInstance->mTangent = -right; mDecalInstance->mRotAroundNormal = 0; mDecalInstance->mPosition = decalPos; mDecalInstance->mDataBlock = mDecalData; // If the position of the world // space box center is the same // as the decal's position, and // the light direction has not // changed, we don't need to clip. bool shouldClip = lightDirChanged || hasMoved || hasScaled; // Now, check and see if the object is visible. const Frustum &frust = state->getCullingFrustum(); if ( frust.isCulled( SphereF( mDecalInstance->mPosition, mDecalInstance->mSize * mDecalInstance->mSize ) ) && !shouldClip ) return false; F32 shadowLen = 10.0f; if ( data ) shadowLen = data->shadowProjectionDistance; const Point3F &boxExtents = objBox.getExtents(); mShadowLength = shadowLen * mParentObject->getScale().z; // Set up clip depth, and box half // offset for decal clipping. Point2F clipParams( mShadowLength, (boxExtents.x + boxExtents.y) * 0.25f ); bool render = false; bool clipSucceeded = true; // Clip! if ( shouldClip ) { clipSucceeded = gDecalManager->clipDecal( mDecalInstance, NULL, &clipParams ); } // If the clip failed, // we'll return false in // order to keep from // unnecessarily rendering // into the texture. If // there was no reason to clip // on this update, we'll assume we // should update the texture. render = clipSucceeded; // Tell the DecalManager we've changed this decal. gDecalManager->notifyDecalModified( mDecalInstance ); return render; }