void Scene::renderPass(unsigned int passId) { assert( passId>=0 && passId<getNumPasses() ); switch( passId ) { case 0: if( _panorama ) _panorama->render(); break; case 1: _stage->setPostRenderCallback( postRenderCallback, this ); _stage->render(); _stage->setPostRenderCallback( NULL, NULL ); if( _timeSpeedMultiplier > 1 ) { std::wstring text = wstrformat( Gameplay::iLanguage->getUnicodeString(376), int( _timeSpeedMultiplier ) ); Vector3f screenSize = Gameplay::iEngine->getScreenSize(); gui::Rect textRect( 0, 0, int( screenSize[0] ) ,32 ); Gameplay::iGui->renderUnicodeText( textRect, "instruction", Vector4f( 0,0,0,0.75f ), gui::atCenter, gui::atCenter, true, text.c_str() ); textRect.left -= 1, textRect.right -= 1, textRect.top -= 1, textRect.bottom -= 1; Gameplay::iGui->renderUnicodeText( textRect, "instruction", Vector4f( 1,1,0.25,1 ), gui::atCenter, gui::atCenter, true, text.c_str() ); } break; } }
unsigned int Scene::getPassClearFlag(unsigned int passId) { assert( passId>=0 && passId<getNumPasses() ); switch( passId ) { case 0: return engine::cmClearColor | engine::cmClearDepth | engine::cmClearStencil; case 1: return engine::cmClearDepth; } return 0; }
float Scene::getPassFarClip(unsigned int passId) { assert( passId>=0 && passId<getNumPasses() ); switch( passId ) { case 0: return _panoramaFarClip; case 1: return _stageFarClip; } return 1000.0f; }
void ProcessedShaderMaterial::dumpMaterialInfo() { for ( U32 i = 0; i < getNumPasses(); i++ ) { const ShaderRenderPassData *passData = _getRPD( i ); if ( passData == NULL ) continue; const GFXShader *shader = passData->shader; if ( shader == NULL ) Con::printf( " [%i] [NULL shader]", i ); else Con::printf( " [%i] %s", i, shader->describeSelf().c_str() ); } }
Action::ResultE DepthPeelingStage::renderEnter(Action *action) { RenderAction *a = dynamic_cast<RenderAction *>(action); a->disableDefaultPartition(); Int32 iVPWidth = a->getActivePartition()->getViewportWidth (); Int32 iVPHeight = a->getActivePartition()->getViewportHeight(); //Initial stage (fill depth buffer) this->beginPartitionGroup(a); { setupRenderScene(a, iVPWidth, iVPHeight, IS_INITIAL, DONTCARE); //Peel & Blend Stage Int32 numLayers = (getNumPasses() - 1) * 2; for (Int32 i=0; i < numLayers; ++i) { if (i % 2 == 0) { setupRenderScene(a, iVPWidth, iVPHeight, !IS_INITIAL, IS_PONG); setupPostProcess(a, !IS_FINAL, IS_PONG); } else { setupRenderScene(a, iVPWidth, iVPHeight, !IS_INITIAL, IS_PING); setupPostProcess(a, !IS_FINAL, IS_PING); } } //Final stage: draw quad to default framebuffer setupPostProcess(a, IS_FINAL, DONTCARE); } this->endPartitionGroup(a); return Action::Skip; }
void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) { if (pass == -1) { for (S32 i = 1; i < getNumPasses(); i++) { //skip foot shadows prerender(); beginRenderPass(i); renderAvatars(single_avatar, i); endRenderPass(i); } return; } if (mDrawFace.empty() && !single_avatar) { return; } LLVOAvatar *avatarp; if (single_avatar) { avatarp = single_avatar; } else { const LLFace *facep = mDrawFace[0]; if (!facep->getDrawable()) { return; } avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); } if (avatarp->isDead() || avatarp->mDrawable.isNull()) { return; } if (!single_avatar && !avatarp->isFullyLoaded()) { if (pass == 0 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0)) { // debug code to draw a sphere in place of avatar gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); gGL.setColorMask(true, true); LLVector3 pos = avatarp->getPositionAgent(); gGL.color4f(1.0f, 1.0f, 1.0f, 0.7f); gGL.pushMatrix(); gGL.translatef((F32)(pos.mV[VX]), (F32)(pos.mV[VY]), (F32)(pos.mV[VZ])); gGL.scalef(0.15f, 0.15f, 0.3f); gSphere.renderGGL(); gGL.popMatrix(); gGL.setColorMask(true, false); } // don't render please return; } BOOL impostor = avatarp->isImpostor() && !single_avatar; if (impostor && pass != 0) { //don't draw anything but the impostor for impostored avatars return; } if (pass == 0 && !impostor && LLPipeline::sUnderWaterRender) { //don't draw foot shadows under water return; } if (pass == 0) { if (!LLPipeline::sReflectionRender) { LLVOAvatar::sNumVisibleAvatars++; } if (impostor) { if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete()) { if (normal_channel > -1) { avatarp->mImpostor.bindTexture(2, normal_channel); } if (specular_channel > -1) { avatarp->mImpostor.bindTexture(1, specular_channel); } } avatarp->renderImpostor(LLColor4U(255,255,255,255), sDiffuseChannel); } return; } if (single_avatar && avatarp->mSpecialRenderMode >= 1) // 1=anim preview, 2=image preview, 3=morph view { gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f)); } if (pass == 1) { // render rigid meshes (eyeballs) first avatarp->renderRigid(); return; } if (pass == 3) { if (is_deferred_render) { renderDeferredRiggedSimple(avatarp); } else { renderRiggedSimple(avatarp); } return; } if (pass == 4) { if (is_deferred_render) { renderDeferredRiggedBump(avatarp); } else { renderRiggedFullbright(avatarp); } return; } if (pass == 5) { renderRiggedShinySimple(avatarp); return; } if (pass == 6) { renderRiggedFullbrightShiny(avatarp); return; } if (pass >= 7 && pass < 9) { LLGLEnable blend(GL_BLEND); gGL.setColorMask(true, true); gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); if (pass == 7) { renderRiggedAlpha(avatarp); return; } if (pass == 8) { renderRiggedFullbrightAlpha(avatarp); return; } } if (pass == 9) { LLGLEnable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); gGL.flush(); LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -1.0f); gGL.setSceneBlendType(LLRender::BT_ADD); LLGLDepthTest depth(GL_TRUE, GL_FALSE); gGL.setColorMask(false, true); renderRiggedGlow(avatarp); gGL.setColorMask(true, false); gGL.setSceneBlendType(LLRender::BT_ALPHA); return; } if (sShaderLevel > 0) { gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX]; } if (sShaderLevel >= SHADER_LEVEL_CLOTH) { LLMatrix4 rot_mat; LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); LLMatrix4 cfr(OGL_TO_CFR_ROTATION); rot_mat *= cfr; LLVector4 wind; wind.setVec(avatarp->mWindVec); wind.mV[VW] = 0; wind = wind * rot_mat; wind.mV[VW] = avatarp->mWindVec.mV[VW]; sVertexProgram->vertexAttrib4fv(LLViewerShaderMgr::AVATAR_WIND, wind.mV); F32 phase = -1.f * (avatarp->mRipplePhase); F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); LLVector4 sin_params(freq, freq, freq, phase); sVertexProgram->vertexAttrib4fv(LLViewerShaderMgr::AVATAR_SINWAVE, sin_params.mV); LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); gravity = gravity * rot_mat; sVertexProgram->vertexAttrib4fv(LLViewerShaderMgr::AVATAR_GRAVITY, gravity.mV); } if (!single_avatar || avatarp == single_avatar) { avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); } }
void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) { LLFastTimer t(FTM_RENDER_AVATARS); if (pass == -1) { for (S32 i = 1; i < getNumPasses(); i++) { //skip foot shadows prerender(); beginRenderPass(i); renderAvatars(single_avatar, i); endRenderPass(i); } return; } if (mDrawFace.empty() && !single_avatar) { return; } LLVOAvatar *avatarp; if (single_avatar) { avatarp = single_avatar; } else { const LLFace *facep = mDrawFace[0]; if (!facep->getDrawable()) { return; } avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); } if (avatarp->isDead() || avatarp->mDrawable.isNull()) { return; } if (!single_avatar && !avatarp->isFullyLoaded() ) { if (pass==0 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0)) { // debug code to draw a sphere in place of avatar gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); gGL.setColorMask(true, true); LLVector3 pos = avatarp->getPositionAgent(); gGL.color4f(1.0f, 1.0f, 1.0f, 0.7f); gGL.pushMatrix(); gGL.translatef((F32)(pos.mV[VX]), (F32)(pos.mV[VY]), (F32)(pos.mV[VZ])); gGL.scalef(0.15f, 0.15f, 0.3f); gSphere.renderGGL(); gGL.popMatrix(); gGL.setColorMask(true, false); } // don't render please return; } BOOL impostor = avatarp->isImpostor() && !single_avatar; if (impostor && pass != 0) { //don't draw anything but the impostor for impostored avatars return; } if (pass == 0 && !impostor && LLPipeline::sUnderWaterRender) { //don't draw foot shadows under water return; } if (pass == 0) { if (!LLPipeline::sReflectionRender) { LLVOAvatar::sNumVisibleAvatars++; } if (impostor) { if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete()) { if (normal_channel > -1) { avatarp->mImpostor.bindTexture(2, normal_channel); } if (specular_channel > -1) { avatarp->mImpostor.bindTexture(1, specular_channel); } } avatarp->renderImpostor(LLColor4U(255,255,255,255), sDiffuseChannel); } //else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS) && !LLPipeline::sRenderDeferred) //{ // avatarp->renderFootShadows(); //} return; } llassert(LLPipeline::sImpostorRender || !avatarp->isVisuallyMuted()); /*if (single_avatar && avatarp->mSpecialRenderMode >= 1) // 1=anim preview, 2=image preview, 3=morph view { gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f)); }*/ if (pass == 1) { // render rigid meshes (eyeballs) first avatarp->renderRigid(); return; } if (pass == 3) { if (is_deferred_render) { renderDeferredRiggedSimple(avatarp); } else { renderRiggedSimple(avatarp); if (LLPipeline::sRenderDeferred) { //render "simple" materials renderRigged(avatarp, RIGGED_MATERIAL); renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK); renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); renderRigged(avatarp, RIGGED_NORMMAP); renderRigged(avatarp, RIGGED_NORMMAP_MASK); renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE); renderRigged(avatarp, RIGGED_SPECMAP); renderRigged(avatarp, RIGGED_SPECMAP_MASK); renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); renderRigged(avatarp, RIGGED_NORMSPEC); renderRigged(avatarp, RIGGED_NORMSPEC_MASK); renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE); } } return; } if (pass == 4) { if (is_deferred_render) { renderDeferredRiggedBump(avatarp); } else { renderRiggedFullbright(avatarp); } return; } if (is_deferred_render && pass >= 5 && pass <= 21) { S32 p = pass-5; if (p != 1 && p != 5 && p != 9 && p != 13) { renderDeferredRiggedMaterial(avatarp, p); } return; } if (pass == 5) { renderRiggedShinySimple(avatarp); return; } if (pass == 6) { renderRiggedFullbrightShiny(avatarp); return; } if (pass >= 7 && pass < 13) { if (pass == 7) { renderRiggedAlpha(avatarp); if (LLPipeline::sRenderDeferred && !is_post_deferred_render) { //render transparent materials under water LLGLEnable blend(GL_BLEND); gGL.setColorMask(true, true); gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); renderRigged(avatarp, RIGGED_MATERIAL_ALPHA); renderRigged(avatarp, RIGGED_SPECMAP_BLEND); renderRigged(avatarp, RIGGED_NORMMAP_BLEND); renderRigged(avatarp, RIGGED_NORMSPEC_BLEND); gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.setColorMask(true, false); } return; } if (pass == 8) { renderRiggedFullbrightAlpha(avatarp); return; } if (LLPipeline::sRenderDeferred && is_post_deferred_render) { S32 p = 0; switch (pass) { case 9: p = 1; break; case 10: p = 5; break; case 11: p = 9; break; case 12: p = 13; break; } { LLGLEnable blend(GL_BLEND); renderDeferredRiggedMaterial(avatarp, p); } return; } else if (pass == 9) { renderRiggedGlow(avatarp); return; } } if (pass == 13) { renderRiggedGlow(avatarp); return; } if ((sShaderLevel >= SHADER_LEVEL_CLOTH)) { LLMatrix4 rot_mat; LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); LLMatrix4 cfr(OGL_TO_CFR_ROTATION.getF32ptr()); rot_mat *= cfr; LLVector4 wind; wind.setVec(avatarp->mWindVec); wind.mV[VW] = 0; wind = wind * rot_mat; wind.mV[VW] = avatarp->mWindVec.mV[VW]; sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV); F32 phase = -1.f * (avatarp->mRipplePhase); F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); LLVector4 sin_params(freq, freq, freq, phase); sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV); LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); gravity = gravity * rot_mat; sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV); } if( !single_avatar || (avatarp == single_avatar) ) { avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); } }
PostShaderStageDataTransitPtr PostShaderStage::setupStageData(Int32 iPixelWidth, Int32 iPixelHeight) { PostShaderStageDataTransitPtr returnValue = PostShaderStageData::createLocal(); if(returnValue == NULL) return returnValue; OSG::Thread::setCurrentLocalFlags(); // Scene Target FrameBufferObjectUnrecPtr pSceneFBO = FrameBufferObject::createLocal(); //Depth texture _pSceneDepthTex = TextureObjChunk::createLocal(); TextureEnvChunkUnrecPtr pSceneDepthTexEnv = TextureEnvChunk::createLocal(); ImageUnrecPtr pDepthImg = Image ::createLocal(); pDepthImg->set(Image::OSG_L_PF, iPixelWidth, iPixelHeight, 1, 1, 1, 0.0, NULL, Image::OSG_UINT8_IMAGEDATA, false); _pSceneDepthTex ->setImage (pDepthImg ); _pSceneDepthTex ->setMinFilter (GL_LINEAR ); _pSceneDepthTex ->setMagFilter (GL_LINEAR ); _pSceneDepthTex ->setWrapS (GL_CLAMP_TO_EDGE ); _pSceneDepthTex ->setWrapT (GL_CLAMP_TO_EDGE ); _pSceneDepthTex ->setInternalFormat(GL_DEPTH_COMPONENT); _pSceneDepthTex ->setExternalFormat(GL_DEPTH_COMPONENT); pSceneDepthTexEnv->setEnvMode (GL_REPLACE ); TextureBufferUnrecPtr pDepthBuffer = TextureBuffer::createLocal(); //pDepthBuffer->setInternalFormat(GL_DEPTH_COMPONENT24 ); pDepthBuffer->setTexture(_pSceneDepthTex); //Color Buffer _pSceneTex = TextureObjChunk::createLocal(); TextureEnvChunkUnrecPtr pSceneTexEnv = TextureEnvChunk::createLocal(); ImageUnrecPtr pImg = Image ::createLocal(); pImg->set(Image::OSG_RGB_PF, iPixelWidth, iPixelHeight, 1, 1, 1, 0.0, 0, Image::OSG_UINT8_IMAGEDATA, false); _pSceneTex ->setImage (pImg ); _pSceneTex ->setMinFilter (GL_LINEAR ); _pSceneTex ->setMagFilter (GL_LINEAR ); _pSceneTex ->setWrapS (GL_CLAMP_TO_EDGE ); _pSceneTex ->setWrapT (GL_CLAMP_TO_EDGE ); _pSceneTex ->setInternalFormat(getColorBufferFormat()); pSceneTexEnv->setEnvMode (GL_REPLACE ); TextureBufferUnrecPtr pSceneTexBuffer = TextureBuffer::createLocal(); pSceneTexBuffer->setTexture(_pSceneTex); pSceneFBO->setSize(iPixelWidth, iPixelHeight); pSceneFBO->setColorAttachment(pSceneTexBuffer, 0); pSceneFBO->setDepthAttachment(pDepthBuffer ); pSceneFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); setRenderTarget(pSceneFBO); // general mat chunk //Init all of the render passes _vPostProcessPasses.clear(); UInt32 NumPasses = getNumPasses(); for(UInt32 i =0; i != NumPasses ; ++i) { _vPostProcessPasses.push_back( RenderPassData::create( getVertexShaders(i), getFragmentShaders(i), (i == NumPasses-1), i, iPixelWidth, iPixelHeight, returnValue.get(), getPassSizes(i), _pSceneTex, _pSceneDepthTex, _vPostProcessPasses, pSceneFBO)); } OSG::Thread::resetCurrentLocalFlags(); Thread::getCurrentChangeList()->commitChanges(); return returnValue; }
DepthFirstStateAction::ResultE DepthFirstStateAction::traverseEnterLeave(void) { ResultE result = NewActionTypes::Continue; Int32 nodePass; // pass over current node UInt32 multiPasses; // requested passes over current node NodePtr pNode; StateRefCountStoreIt itStateRefCount; while((_nodeStack.empty() == false) && !(result & NewActionTypes::Quit)) { pNode = _nodeStack.back().getNode (); nodePass = _nodeStack.back().getPassCount (); itStateRefCount = _nodeStack.back().getStateRefCount(); if(itStateRefCount != _itActiveState) { #ifdef OSG_NEWACTION_STATISTICS getStatistics()->getElem(statStateRestores)->inc(); #endif /* OSG_NEWACTION_STATISTICS */ setState(itStateRefCount); // gained refs: active incRefCount(itStateRefCount); // lost refs: active decRefCount(_itActiveState); _itActiveState = itStateRefCount; } getChildrenList().setParentNode(pNode); if(nodePass > 0) { // positive pass -> enter node #ifdef OSG_NEWACTION_STATISTICS getStatistics()->getElem(statNodesEnter)->inc(); #endif /* OSG_NEWACTION_STATISTICS */ _stateClonedFlag = false; result = enterNode (pNode, static_cast<UInt32>(nodePass - 1)); multiPasses = getNumPasses( ); // only initial pass (nodePass == 1) can request multiPass. if((nodePass == 1) && (multiPasses > 1)) { // remove current node from stack _nodeStack.pop_back(); for(; multiPasses > 1; -- multiPasses) { // gained refs: addtional passs incRefCount(_itActiveState); _nodeStack.push_back( NodeStackEntry(pNode, _itActiveState, multiPasses)); } // readd current node - with negative pass -> leave _nodeStack.push_back( NodeStackEntry(pNode, _itActiveState, -nodePass)); } else { // change current node passCount to negative -> leave _nodeStack.back().setPassCount(-nodePass); } pushChildren(pNode, result); } else { // negative pass -> leave node #ifdef OSG_NEWACTION_STATISTICS getStatistics()->getElem(statNodesLeave)->inc(); #endif /* OSG_NEWACTION_STATISTICS */ _stateClonedFlag = true; result = leaveNode(pNode, static_cast<UInt32>(-nodePass - 1)); _nodeStack.pop_back(); // lost refs: current node decRefCount(_itActiveState); } } return result; }
DepthFirstStateAction::ResultE DepthFirstStateAction::traverseEnter(void) { ResultE result = NewActionTypes::Continue; NodePtr pNode; Int32 nodePass; // pass over current node UInt32 multiPasses; // requested passes over current node StateRefCountStoreIt itStateRefCount; // state for current node while((_nodeStack.empty() == false) && !(result & NewActionTypes::Quit)) { pNode = _nodeStack.back().getNode (); nodePass = _nodeStack.back().getPassCount (); itStateRefCount = _nodeStack.back().getStateRefCount(); #ifdef OSG_NEWACTION_STATISTICS getStatistics()->getElem(statNodesEnter)->inc(); #endif /* OSG_NEWACTION_STATISTICS */ if(itStateRefCount != _itActiveState) { #ifdef OSG_NEWACTION_STATISTICS getStatistics()->getElem(statStateRestores)->inc(); #endif /* OSG_NEWACTION_STATISTICS */ setState(itStateRefCount); // gained refs: active incRefCount(itStateRefCount); // lost refs: active decRefCount(_itActiveState); _itActiveState = itStateRefCount; } _stateClonedFlag = false; getChildrenList().setParentNode(pNode); result = enterNode (pNode, static_cast<UInt32>(nodePass - 1)); multiPasses = getNumPasses( ); _nodeStack.pop_back(); // only initial pass (nodePass == 1) can request multiPasses if((nodePass == 1) && (multiPasses > 1)) { for(; multiPasses > 1; --multiPasses) { // gained refs: additional pass incRefCount(_itActiveState); _nodeStack.push_back( NodeStackEntry(pNode, _itActiveState, multiPasses)); } } pushChildren(pNode, result); // lost refs: current node decRefCount(_itActiveState); } return result; }