Esempio n. 1
0
            void Jungle::render()
            {
                video::IVideoDriver * driver = SceneManager->getVideoDriver();

                ICameraSceneNode* cam = SceneManager->getActiveCamera();
                driver->setTransform(video::ETS_VIEW, cam->getViewMatrix());
                driver->setTransform(video::ETS_PROJECTION, cam->getProjectionMatrix());
                driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);

                core::vector3df camPos = SceneManager->getActiveCamera()->getAbsolutePosition();
                f32 far = SceneManager->getActiveCamera()->getFarValue();
                camPos.Y = 0;

                //start rendering
                for(u8 x = 0 ; x < WORLD_SIZE; x ++)
                {
                    for(u8 y = 0 ; y < WORLD_SIZE; y ++)
                    {
                        f32 dist = camPos.getDistanceFrom(
                                        core::vector3df(chunks[x][y].X + 16,
                                                        chunks[x][y].Y + 16,
                                                        chunks[x][y].Z + 16));
                        if(dist > far)
                            continue;
                        //v_chunks[x][y].render(driver);
                        driver->setMaterial(Material);
                        chunks[x][y].renderBark(driver);
                        driver->setMaterial(MaterialLeaf);
                        chunks[x][y].renderLeaf(driver);
                    }
                }
            }
Esempio n. 2
0
void effectHandler::update(irr::video::ITexture* outputTarget)
{
	if(shadowsUnsupported || smgr->getActiveCamera() == 0)
		return;
	
	if(!ShadowNodeArray.empty() && !LightList.empty())
	{
		driver->setRenderTarget(ScreenQuad.rt[0], true, true, AmbientColour);

		ICameraSceneNode* activeCam = smgr->getActiveCamera();
		activeCam->OnAnimate(device->getTimer()->getTime());
		activeCam->OnRegisterSceneNode();
		activeCam->render();

		const u32 LightListSize = LightList.size();
		for(u32 l = 0;l < LightListSize;++l)
		{
			// Set max distance constant for depth shader.
			depthMC->FarLink = LightList[l].getFarValue();

			driver->setTransform(ETS_VIEW, LightList[l].getViewMatrix());
			driver->setTransform(ETS_PROJECTION, LightList[l].getProjectionMatrix());
			
			driver->setRenderTarget(ShadowMapTex, true, true, SColor(0xffffffff));
			
			const u32 ShadowNodeArraySize = ShadowNodeArray.size();
			for(u32 i = 0;i < ShadowNodeArraySize;++i)
			{
				if(ShadowNodeArray[i].shadowMode == ESM_RECEIVE)
					continue;

				BufferMaterialList.set_used(0);

				const u32 CurrentMaterialCount = ShadowNodeArray[i].node->getMaterialCount();
				for(u32 m = 0;m < CurrentMaterialCount;++m)
				{
					BufferMaterialList.push_back(ShadowNodeArray[i].node->getMaterial(m).MaterialType);
					ShadowNodeArray[i].node->getMaterial(m).MaterialType =
						ShadowNodeArray[i].node->getMaterial(m).MaterialType == Effects[EET_MRWIGGLE]
						? (E_MATERIAL_TYPE)DepthWiggle : (E_MATERIAL_TYPE)Depth;
				}

				ShadowNodeArray[i].node->OnAnimate(device->getTimer()->getTime());
				ShadowNodeArray[i].node->render();

				const u32 BufferMaterialListSize = BufferMaterialList.size();
				for(u32 m = 0;m < BufferMaterialListSize;++m)
					ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)BufferMaterialList[m];
			}
		
			driver->setTransform(ETS_VIEW, activeCam->getViewMatrix());
			driver->setTransform(ETS_PROJECTION, activeCam->getProjectionMatrix());

			shadowMC->LightColour = LightList[l].getLightColor();
			shadowMC->LightLink = LightList[l].getPosition();
			shadowMC->FarLink = LightList[l].getFarValue();
			shadowMC->ViewLink = LightList[l].getViewMatrix();
			shadowMC->ProjLink = LightList[l].getProjectionMatrix();
			
			driver->setRenderTarget(ScreenQuad.rt[1], true, true, SColor(0xffffffff));

			for(u32 i = 0;i < ShadowNodeArraySize;++i)
			{
				const u32 CurrentMaterialCount = ShadowNodeArray[i].node->getMaterialCount();

				BufferMaterialList.reallocate(CurrentMaterialCount);
				BufferTextureList.reallocate(CurrentMaterialCount);
				core::array<bool> BilinearBuffer(CurrentMaterialCount);
				BufferMaterialList.set_used(0);
				BufferTextureList.set_used(0);
				BilinearBuffer.set_used(0);
				
				for(u32 m = 0;m < CurrentMaterialCount;++m)
				{
					BufferMaterialList.push_back(ShadowNodeArray[i].node->getMaterial(m).MaterialType);
					BufferTextureList.push_back(ShadowNodeArray[i].node->getMaterial(m).getTexture(0));
					BilinearBuffer.push_back(ShadowNodeArray[i].node->getMaterial(m).TextureLayer[0].BilinearFilter);
				
					ShadowNodeArray[i].node->getMaterial(m).MaterialType = 
						(ShadowNodeArray[i].shadowMode == ESM_CAST) ? (E_MATERIAL_TYPE)WhiteWash
						: (E_MATERIAL_TYPE)Solid[ShadowNodeArray[i].filterType];

					ShadowNodeArray[i].node->getMaterial(m).setTexture(0, ShadowMapTex);
					ShadowNodeArray[i].node->getMaterial(m).TextureLayer[0].BilinearFilter = false;
				}

				ShadowNodeArray[i].node->OnAnimate(device->getTimer()->getTime());
				ShadowNodeArray[i].node->render();

				for(u32 m = 0;m < CurrentMaterialCount;++m)
				{
					ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)BufferMaterialList[m];
					ShadowNodeArray[i].node->getMaterial(m).setTexture(0, BufferTextureList[m]);
					ShadowNodeArray[i].node->getMaterial(m).TextureLayer[0].BilinearFilter = BilinearBuffer[m];
				}
			}

			driver->setRenderTarget(ScreenQuad.rt[0], false, false, SColor(0x0));
			ScreenQuad.getMaterial().setTexture(0, ScreenQuad.rt[1]);
			ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)Simple;
			
			ScreenQuad.render(driver);
		}
	}
	else
	{
		driver->setRenderTarget(ScreenQuad.rt[0], true, true, SColor(0xffffffff));
	}
	
	driver->setRenderTarget(ScreenQuad.rt[1], true, true, ClearColour);
	smgr->drawAll();

	const u32 PostProcessingRoutinesSize = PostProcessingRoutines.size();

	driver->setRenderTarget(PostProcessingRoutinesSize 
		? ScreenRTT : outputTarget, true, true, SColor(0x0));

	ScreenQuad.getMaterial().setTexture(0, ScreenQuad.rt[1]);
	ScreenQuad.getMaterial().setTexture(1, ScreenQuad.rt[0]);

	ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)LightModulate;
	ScreenQuad.render(driver);
	
	if(PostProcessingRoutinesSize)
	{
		bool Alter = 0;
		ScreenQuad.getMaterial().setTexture(1, ScreenRTT);
		ScreenQuad.getMaterial().setTexture(2, DepthRTT);
		for(u32 i = 0;i < PostProcessingRoutinesSize;++i)
		{
			ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)PostProcessingRoutines[i];

			Alter = !Alter;
			ScreenQuad.getMaterial().setTexture(0, i == 0 ? ScreenRTT : ScreenQuad.rt[int(!Alter)]);
			driver->setRenderTarget(i >= PostProcessingRoutinesSize - 1 ?
				outputTarget : ScreenQuad.rt[int(Alter)], true, true, ClearColour);
			ScreenQuad.render(driver);
		}
	}

	// Perform depth pass after rendering, to ensure animations stay up to date.
	if(DepthPass)
	{
		driver->setRenderTarget(DepthRTT, true, true, SColor(0xffffffff));

		// Set max distance constant for depth shader.
		depthMC->FarLink = smgr->getActiveCamera()->getFarValue();

		for(u32 i = 0;i < DepthPassArray.size();++i)
		{
			BufferMaterialList.set_used(0);

			for(u32 g = 0;g < DepthPassArray[i]->getMaterialCount();++g)
				BufferMaterialList.push_back(DepthPassArray[i]->getMaterial(g).MaterialType);

			DepthPassArray[i]->setMaterialType((E_MATERIAL_TYPE)Depth);
			DepthPassArray[i]->OnAnimate(device->getTimer()->getTime());
			DepthPassArray[i]->render();

			for(u32 g = 0;g < DepthPassArray[i]->getMaterialCount();++g)
				DepthPassArray[i]->getMaterial(g).MaterialType = (E_MATERIAL_TYPE)BufferMaterialList[g];
		}
	}
}
void CImpostorSceneNode::renderNode(SNodeLink& Imp)
{
	ISceneNode* n = Imp.Node;

	updatePosAndVector(Imp);

	// remember old viewport and render target
	core::rect<s32> oldView = SceneManager->getVideoDriver()->getViewPort();

	if (!oldView.isRectCollided(Imp.NewPos))
		return;

	ICameraSceneNode* cam = SceneManager->getActiveCamera();
	cam->updateAbsolutePosition();

	core::vector3df camP = cam->getAbsolutePosition();
	f32 distance = camP.getDistanceFrom(n->getTransformedBoundingBox().getCenter());

	// project into screen

	core::vector3df pUL = SceneManager->getSceneCollisionManager()->getRayFromScreenCoordinates(Imp.NewPos.UpperLeftCorner, cam).getVector();
	pUL.setLength(distance);
	core::vector3df pLR = SceneManager->getSceneCollisionManager()->getRayFromScreenCoordinates(Imp.NewPos.LowerRightCorner, cam).getVector();
	pLR.setLength(distance);
	core::vector3df pUR = SceneManager->getSceneCollisionManager()->getRayFromScreenCoordinates(core::position2di(Imp.NewPos.LowerRightCorner.X, Imp.NewPos.UpperLeftCorner.Y), cam).getVector();
	pUR.setLength(distance);
	core::vector3df pLL = SceneManager->getSceneCollisionManager()->getRayFromScreenCoordinates(core::position2di(Imp.NewPos.UpperLeftCorner.X, Imp.NewPos.LowerRightCorner.Y), cam).getVector();
	pLL.setLength(distance);

	Imp.BilPos1 = camP + pUL;
	Imp.BilPos2 = camP + pLR;
	Imp.BilPos3 = camP + pUR;
	Imp.BilPos4 = camP + pLL;

	// translate and scale, but don't rotate
	core::matrix4 invMat = n->getAbsoluteTransformation();
	invMat.makeInverse();
	Imp.BilPos1 *= invMat.getScale();
	invMat.translateVect(Imp.BilPos1);
	Imp.BilPos2 *= invMat.getScale();
	invMat.translateVect(Imp.BilPos2);
	Imp.BilPos3 *= invMat.getScale();
	invMat.translateVect(Imp.BilPos3);
	Imp.BilPos4 *= invMat.getScale();
	invMat.translateVect(Imp.BilPos4);

	Imp.ScreenPos = Imp.NewPos;
	Imp.RotVec = Imp.NewVec;
	video::ITexture* rt = 0; // SceneManager->getVideoDriver()->getRenderTarget();

	// set up the camera and viewport for rendering
	ISceneManager* oldManager = n->getSceneManager();

	// set up the camera
	ICameraSceneNode* cam2= LocalManager->getActiveCamera();

	cam2->setPosition(cam->getAbsolutePosition());

	core::vector3df v = n->getTransformedBoundingBox().getCenter();
	cam2->setUpVector(cam->getUpVector());
	cam2->setTarget(cam->getTarget());
	cam2->updateAbsolutePosition();

	f32 scaleW = f32(oldView.getWidth()) / f32(Imp.ScreenPos.getWidth());
	f32 scaleH = f32(oldView.getHeight()) / f32(Imp.ScreenPos.getHeight());

	//f32 transW = f32(Impostors[i].ScreenPos.getWidth()/2) / (f32(oldView.getWidth()) - f32(Impostors[i].ScreenPos.getCenter().X));
	//f32 transH = f32(Impostors[i].ScreenPos.getHeight()/2) / (f32(oldView.getHeight()) - f32(Impostors[i].ScreenPos.getCenter().X));

	f32 transW = (f32(oldView.getCenter().X) - f32(Imp.ScreenPos.getCenter().X)) / f32(Imp.ScreenPos.getWidth());
	f32 transH = (f32(oldView.getCenter().Y) -  f32(Imp.ScreenPos.getCenter().Y)) / f32(Imp.ScreenPos.getHeight());

	core::matrix4 proj(cam->getProjectionMatrix());
	core::matrix4 zoom, trans;

	Imp.Time = Timer->getRealTime();

	zoom.setScale(core::vector3df(scaleW, scaleH, 1.0));
	trans.setTranslation(core::vector3df(transW*2,-transH*2,0.0));


	proj = zoom * proj;
#if defined(GENERATE_METHOD_1)
	proj = trans * proj;
#endif




	// set the correct render target and viewport
	setTarget(Imp);

	// draw the scene
	cam2->setProjectionMatrix(proj);
	E_CULLING_TYPE culltype = EAC_FRUSTUM_BOX;
	n->setAutomaticCulling(EAC_OFF);
	//cam2->render();
//	n->setSceneManager(LocalManager);
	n->OnRegisterSceneNode();
	LocalManager->drawAll();

	n->setAutomaticCulling(culltype);

	//s32 numberzzz = LocalManager->getParameters()->getAttributeAsInt("culled");

	// copy work buffer back
	s32 slot = Buffers[Imp.BufferID].SlotSize;
	//SceneManager->getGUIEnvironment()->getBuiltInFont()->draw(L"HI THERE!", core::rect<s32>(0, 0, slot, slot), video::SColor(), true, true);
	SceneManager->getVideoDriver()->setRenderTarget(Buffers[ Imp.BufferID].Texture, false, true);
	//SceneManager->getVideoDriver()->setRenderTarget(0);



	//LocalManager->getVideoDriver()->setViewPort( core::rect<s32>(0,0,TextureWidth,TextureWidth) );

	s32 d = TextureWidth / slot;
	s32 x = (Imp.SlotID % d) * slot;
	s32 y = (Imp.SlotID / d) * slot;

	//LocalManager->getVideoDriver()->setViewPort( core::rect<s32>(0,0,TextureWidth,TextureWidth) );
/*
	SceneManager->getVideoDriver()->draw2DRectangle(
		video::SColor(127,0,0,0),
		core::rect<s32>(x,y,x+slot,y+slot));
	SceneManager->getVideoDriver()->draw2DRectangle(
		video::SColor(100,0,0,0),
		core::rect<s32>(x,y,x+slot,y+slot));
	SceneManager->getVideoDriver()->draw2DRectangle(
		video::SColor(100,0,0,0),
		core::rect<s32>(x,y,x+slot,y+slot));
*/
	//SceneManager->getVideoDriver()->setTransform

	core::rect<s32> clipRect(x,y, x+slot,y+slot);

	video::SMaterial m;
	m.MaterialTypeParam =video::pack_texureBlendFunc(video::EBF_ONE, video::EBF_ONE_MINUS_DST_ALPHA, video::EMFN_MODULATE_1X);
	m.MaterialType = video::EMT_ONETEXTURE_BLEND;
	m.Lighting=false;
	m.ZBuffer = false;
	m.ZWriteEnable = false;
	m.TextureLayer[0].TextureWrapU = video::ETC_CLAMP;
	m.setTexture(0, WorkTexture);

	video::S3DVertex Vertices[6];

	Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 0.0f, YDirection);
	Vertices[1] = video::S3DVertex(-1.0f,  1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 0.0f, 0.0f);
	Vertices[2] = video::S3DVertex( 1.0f,  1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 1.0f, 0.0f);
	Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 1.0f, YDirection);
	Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 0.0f, YDirection);
	Vertices[5] = video::S3DVertex( 1.0f,  1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 1.0f, 0.0f);

	const u16 i1[] = {0,1,2,3,4,5};
	const u16 i2[] = {0,2,1,3,5,4};
	const u16* indices = i1;

	core::matrix4 matrix, matrix2;
	if (YDirection == -1.0f)
	{
		matrix2.setScale(core::vector3df(1.0f,-1.0f,1.0f));
		indices = i2;
	}
	LocalManager->getVideoDriver()->setViewPort( clipRect );
	LocalManager->getVideoDriver()->setMaterial(m);
	SceneManager->getVideoDriver()->setTransform(video::ETS_WORLD, matrix);
	SceneManager->getVideoDriver()->setTransform(video::ETS_PROJECTION, matrix2);
	SceneManager->getVideoDriver()->setTransform(video::ETS_VIEW, matrix);
	SceneManager->getVideoDriver()->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
	LocalManager->getVideoDriver()->setViewPort(core::rect<s32>(0,0,TextureWidth, TextureWidth));

	//SceneManager->getVideoDriver()->draw2DImage(
	//	WorkTexture,
	//	core::position2di(x,y),
	//	core::rect<s32>(0,0,slot, slot),
	//	&clipRect,
	//	video::SColor(255,255,255,255),true);

	if (DebugDataVisible & EDS_IMPOSTOR_INFO && DebugFont)
	{
		core::stringw text;
		video::SColor col(255,255,0,0);
		core::rect<s32> clip(x, y, x+slot, 0);
		s32 third = s32(f32(slot)*0.5f);

		text=L"Buf: "; text+=Imp.BufferID;
		clip.UpperLeftCorner.Y = y+third;
		clip.LowerRightCorner.Y = y+ third*2;
		DebugFont->draw(text.c_str(), clip, col, true, true, &clip);

		text=L"Region: "; text+=Imp.SlotID;
		clip.UpperLeftCorner.Y = y+third*2;
		clip.LowerRightCorner.Y = y+slot;
		DebugFont->draw(text.c_str(), clip, col, true, true, &clip);
	}


	//core::rect<s32> blaView = SceneManager->getVideoDriver()->getViewPort();

	//SceneManager->getVideoDriver()->setTransform(video::ETS_WORLD, n->getAbsoluteTransformation());
	//SceneManager->getVideoDriver()->draw3DBox(n->getBoundingBox());

	// restore states
	SceneManager->getVideoDriver()->setRenderTarget(0, false, false);
	LocalManager->getVideoDriver()->setViewPort(oldView);

//	n->setSceneManager(oldManager);
}
void EffectHandler::update(const irr::u32 time, const bool screenSpaceOnly,irr::video::ITexture* outputTarget,irr::scene::ISceneNode* node,irr::core::array<scene::IMeshBuffer*>* buffers)
{
    if(outputTarget)
    {
        if(outputTarget->getSize()!= ScreenRTT->getSize())
        {
            setScreenRenderTargetResolution(outputTarget->getSize());
        }
    }
    if (shadowsUnsupported || smgr->getActiveCamera() == 0)
        return;

    if (!ShadowNodeArray.empty() && !LightList.empty())
    {
        driver->setRenderTarget(ScreenQuad.rt[0], true, true, AmbientColour);

        ICameraSceneNode* activeCam = smgr->getActiveCamera();
        activeCam->OnAnimate(device->getTimer()->getTime());
        activeCam->OnRegisterSceneNode();
        activeCam->render();

        const u32 ShadowNodeArraySize = ShadowNodeArray.size();
        const u32 LightListSize = LightList.size();
        for (u32 l = 0; l < LightListSize; ++l)
        {
            // Set max distance constant for depth shader.
            depthMC->FarLink = LightList[l].getFarValue();

            driver->setTransform(ETS_VIEW, LightList[l].getViewMatrix());
            driver->setTransform(ETS_PROJECTION, LightList[l].getProjectionMatrix());

            ITexture* currentShadowMapTexture = getShadowMapTexture(LightList[l].getShadowMapResolution());
            driver->setRenderTarget(currentShadowMapTexture, true, true, SColor(0xffffffff));

            for (u32 i = 0; i < ShadowNodeArraySize; ++i)
            {
                if (ShadowNodeArray[i].shadowMode == ESM_RECEIVE || ShadowNodeArray[i].shadowMode == ESM_EXCLUDE)
                    continue;

                const u32 CurrentMaterialCount = ShadowNodeArray[i].node->getMaterialCount();
                core::array<irr::s32> BufferMaterialList(CurrentMaterialCount);
                BufferMaterialList.set_used(0);

                for (u32 m = 0; m < CurrentMaterialCount; ++m)
                {
                    BufferMaterialList.push_back(ShadowNodeArray[i].node->getMaterial(m).MaterialType);
                    ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)
                            (BufferMaterialList[m] == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF ? DepthT : Depth);
                }

                ShadowNodeArray[i].node->OnAnimate(device->getTimer()->getTime());
                ShadowNodeArray[i].node->render();

                const u32 BufferMaterialListSize = BufferMaterialList.size();
                for (u32 m = 0; m < BufferMaterialListSize; ++m)
                    ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)BufferMaterialList[m];
            }

            // Blur the shadow map texture if we're using VSM filtering.
            if (useVSM)
            {
                ITexture* currentSecondaryShadowMap = getShadowMapTexture(LightList[l].getShadowMapResolution(), true);

                driver->setRenderTarget(currentSecondaryShadowMap, true, true, SColor(0xffffffff));
                ScreenQuad.getMaterial().setTexture(0, currentShadowMapTexture);
                ScreenQuad.getMaterial().setTexture(0, currentShadowMapTexture);
                ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)VSMBlurH;
                ScreenQuad.getMaterial().TextureLayer[0].TextureWrapU=1;
                ScreenQuad.getMaterial().TextureLayer[0].BilinearFilter=0;
                //ScreenQuad.getMaterial().TextureLayer[1].BilinearFilter=false;

                ScreenQuad.render(driver);

                driver->setRenderTarget(currentShadowMapTexture, true, true, SColor(0xffffffff));
                ScreenQuad.getMaterial().setTexture(0, currentSecondaryShadowMap);
                ScreenQuad.getMaterial().setTexture(0, currentSecondaryShadowMap);
                ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)VSMBlurV;
                ScreenQuad.getMaterial().TextureLayer[0].BilinearFilter=0;
                //ScreenQuad.getMaterial().TextureLayer[1].BilinearFilter=false;

                ScreenQuad.render(driver);
            }

            driver->setRenderTarget(ScreenQuad.rt[1], true, true, SColor(0,0,0,0));

            driver->setTransform(ETS_VIEW, activeCam->getViewMatrix());
            driver->setTransform(ETS_PROJECTION, activeCam->getProjectionMatrix());

            shadowMC->LightColour = LightList[l].getLightColor();
            shadowMC->LightLink = LightList[l].getPosition();
            shadowMC->FarLink = LightList[l].getFarValue();
            shadowMC->ViewLink = LightList[l].getViewMatrix();
            shadowMC->ProjLink = LightList[l].getProjectionMatrix();
            shadowMC->MapRes = (f32)LightList[l].getShadowMapResolution();

            for (u32 i = 0; i < ShadowNodeArraySize; ++i)
            {
                if (ShadowNodeArray[i].shadowMode == ESM_CAST || ShadowNodeArray[i].shadowMode == ESM_EXCLUDE)
                    continue;

                const u32 CurrentMaterialCount = ShadowNodeArray[i].node->getMaterialCount();
                core::array<irr::s32> BufferMaterialList(CurrentMaterialCount);
                core::array<irr::video::ITexture*> BufferTextureList(CurrentMaterialCount);

                core::array<u8> clampModesUList(CurrentMaterialCount);
                core::array<u8> clampModesVList(CurrentMaterialCount);



                for (u32 m = 0; m < CurrentMaterialCount; ++m)
                {
                    BufferMaterialList.push_back(ShadowNodeArray[i].node->getMaterial(m).MaterialType);
                    BufferTextureList.push_back(ShadowNodeArray[i].node->getMaterial(m).getTexture(0));

                    if (screenSpaceOnly)
                    {
                        if(LightList[l].isSpot())
                            ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)ShadowSSS[ShadowNodeArray[i].filterType];
                        else
                            ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)ShadowSS[ShadowNodeArray[i].filterType];
                    }

                    else
                        ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)Shadow[ShadowNodeArray[i].filterType];
                    ShadowNodeArray[i].node->getMaterial(m).setTexture(0, currentShadowMapTexture);

                    clampModesUList.push_back(ShadowNodeArray[i].node->getMaterial(m).TextureLayer[0].TextureWrapU);
                    clampModesVList.push_back(ShadowNodeArray[i].node->getMaterial(m).TextureLayer[0].TextureWrapV);
                    //ShadowNodeArray[i].node->getMaterial(m).TextureLayer[0].TextureWrapU=video::ETC_CLAMP;
                    //ShadowNodeArray[i].node->getMaterial(m).TextureLayer[0].TextureWrapV=video::ETC_CLAMP;
                }

                //Render all project shadow maps
                if (!node)
                {
                    ShadowNodeArray[i].node->OnAnimate(device->getTimer()->getTime());
                    ShadowNodeArray[i].node->render();
                }
                else
                {
                    //render projected shadows on specific buffers of a single shAdow map
                    if (ShadowNodeArray[i].node==node)
                    {
                        ShadowNodeArray[i].node->OnAnimate(device->getTimer()->getTime());

                        driver->setTransform(video::ETS_WORLD, node->getAbsoluteTransformation());
                        irr::core::array<scene::IMeshBuffer*>bufferlist=*buffers;

                        for (int buf=0; buf<bufferlist.size(); buf++)
                        {
                            driver->setMaterial(ShadowNodeArray[i].node->getMaterial(buf));
                            driver->drawMeshBuffer(bufferlist[buf]);
                        }
                    }
                }

                for (u32 m = 0; m < CurrentMaterialCount; ++m)
                {
                    ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)BufferMaterialList[m];
                    ShadowNodeArray[i].node->getMaterial(m).setTexture(0, BufferTextureList[m]);

                    ShadowNodeArray[i].node->getMaterial(m).TextureLayer[0].TextureWrapU=clampModesUList[m];
                    ShadowNodeArray[i].node->getMaterial(m).TextureLayer[0].TextureWrapV=clampModesVList[m];
                }
            }

            driver->setRenderTarget(ScreenQuad.rt[0], false, false, SColor(0,0,0,0));
            ScreenQuad.getMaterial().setTexture(0, ScreenQuad.rt[1]);
            ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)Simple;
            ScreenQuad.getMaterial().ColorMask=0xffffffff;
            ScreenQuad.render(driver);
        }
        /*
                // Render all the excluded and casting-only nodes.
                for (u32 i = 0;i < ShadowNodeArraySize;++i)
                {
                    if (ShadowNodeArray[i].shadowMode != ESM_CAST && ShadowNodeArray[i].shadowMode != ESM_EXCLUDE)
                        continue;

                    const u32 CurrentMaterialCount = ShadowNodeArray[i].node->getMaterialCount();
                    core::array<irr::s32> BufferMaterialList(CurrentMaterialCount);
                    BufferMaterialList.set_used(0);

                    for (u32 m = 0;m < CurrentMaterialCount;++m)
                    {
                        BufferMaterialList.push_back(ShadowNodeArray[i].node->getMaterial(m).MaterialType);

                        switch (BufferMaterialList[m])
                        {
                        case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
                            ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWashTRef;
                            break;
                        case EMT_TRANSPARENT_ADD_COLOR:
                            ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWashTAdd;
                            break;
                        case EMT_TRANSPARENT_ALPHA_CHANNEL:
                            ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWashTAlpha;
                            break;
                        default:
                            ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWash;
                            break;
                        }
                    }

                    ShadowNodeArray[i].node->OnAnimate(device->getTimer()->getTime());
                    ShadowNodeArray[i].node->render();

                    for (u32 m = 0;m < CurrentMaterialCount;++m)
                        ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)BufferMaterialList[m];
                }*/
    }
    else
    {
        driver->setRenderTarget(ScreenQuad.rt[0], true, true, SColor(0xffffffff));
    }
    if (!screenSpaceOnly)
    {
        driver->setRenderTarget(ScreenQuad.rt[1], true, true, SColor(0xffffffff));

        core::list<scene::ISceneNode*>::ConstIterator it = smgr->getRootSceneNode()->getChildren().begin();
        while (it!=smgr->getRootSceneNode()->getChildren().end())
        {
            scene::ISceneNode* node = *it;
            node->OnAnimate(time);
            node->render();
            it++;

        }
    }

    const u32 PostProcessingRoutinesSize = PostProcessingRoutines.size();

    if (!screenSpaceOnly)
    {
        driver->setRenderTarget(outputTarget, true, true, SColor(0x0));


        ScreenQuad.getMaterial().setTexture(0, ScreenQuad.rt[1]);
        ScreenQuad.getMaterial().setTexture(1, ScreenQuad.rt[0]);

        ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)LightModulate;

        ScreenQuad.render(driver);
    }

    if (outputTarget)
    {

        driver->setRenderTarget(ScreenRTT , true, true, SColor(0,255,0,255));
        ScreenQuad.getMaterial().setTexture(0, ScreenQuad.rt[0]);
        ScreenQuad.getMaterial().setTexture(1, ScreenQuad.rt[0]);
        ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)VSMBlurH;
        ScreenQuad.getMaterial().TextureLayer[0].TextureWrapU=1;
        ScreenQuad.getMaterial().TextureLayer[0].TextureWrapV=1;
        ScreenQuad.getMaterial().TextureLayer[0].BilinearFilter=true;
        ScreenQuad.getMaterial().TextureLayer[1].BilinearFilter=false;


        //ScreenQuad.getMaterial().setFlag(video::EMF_BILINEAR_FILTER,false);
        ScreenQuad.render(driver);

        driver->setRenderTarget(ScreenQuad.rt[0], true, true, SColor(0,255,0,255))  ;
        ScreenQuad.getMaterial().setTexture(0, ScreenRTT );
        ScreenQuad.getMaterial().setTexture(1, ScreenRTT );
        ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)VSMBlurV;
        ScreenQuad.getMaterial().TextureLayer[0].TextureWrapU=1;
        ScreenQuad.getMaterial().TextureLayer[0].TextureWrapV=1;
        ScreenQuad.getMaterial().TextureLayer[0].BilinearFilter=true;
        ScreenQuad.getMaterial().TextureLayer[1].BilinearFilter=false;

        ScreenQuad.render(driver);


        //ScreenQuad.getMaterial().setFlag(video::EMF_BILINEAR_FILTER,false);
        ScreenQuad.render(driver);

        driver->setRenderTarget(outputTarget, true, true, SColor(0,255,0,255))  ;
        ScreenQuad.getMaterial().setTexture(0, ScreenQuad.rt[0] );
        ScreenQuad.getMaterial().setTexture(1, ScreenQuad.rt[0] );
        ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)VSMBlurH;
        ScreenQuad.getMaterial().TextureLayer[0].TextureWrapU=1;
        ScreenQuad.getMaterial().TextureLayer[0].TextureWrapV=1;
        ScreenQuad.getMaterial().TextureLayer[0].BilinearFilter=true;
        ScreenQuad.getMaterial().TextureLayer[1].BilinearFilter=true;

        ScreenQuad.render(driver);




    }

}
Esempio n. 5
0
void EffectHandler::update(irr::video::ITexture* outputTarget)
{
	if(shadowsUnsupported || smgr->getActiveCamera() == 0)
		return;
	
	if(!ShadowNodeArray.empty() && !LightList.empty())
	{
		driver->setRenderTarget(ScreenQuad.rt[0], true, true, AmbientColour);

		ICameraSceneNode* activeCam = smgr->getActiveCamera();
		activeCam->OnAnimate(device->getTimer()->getTime());
		activeCam->OnRegisterSceneNode();
		activeCam->render();

		const u32 ShadowNodeArraySize = ShadowNodeArray.size();
		const u32 LightListSize = LightList.size();
		for(u32 l = 0;l < LightListSize;++l)
		{
			// Set max distance constant for depth shader.
			depthMC->FarLink = LightList[l].getFarValue();

			driver->setTransform(ETS_VIEW, LightList[l].getViewMatrix());
			driver->setTransform(ETS_PROJECTION, LightList[l].getProjectionMatrix());
			
			ITexture* currentShadowMapTexture = getShadowMapTexture(LightList[l].getShadowMapResolution());
			driver->setRenderTarget(currentShadowMapTexture, true, true, SColor(0xffffffff));
			
			for(u32 i = 0;i < ShadowNodeArraySize;++i)
			{
				if(ShadowNodeArray[i].shadowMode == ESM_RECEIVE || ShadowNodeArray[i].shadowMode == ESM_EXCLUDE)
					continue;

				const u32 CurrentMaterialCount = ShadowNodeArray[i].node->getMaterialCount();
				core::array<irr::s32> BufferMaterialList(CurrentMaterialCount);
				BufferMaterialList.set_used(0);

				for(u32 m = 0;m < CurrentMaterialCount;++m)
				{
					BufferMaterialList.push_back(ShadowNodeArray[i].node->getMaterial(m).MaterialType);
					ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)
						(BufferMaterialList[m] == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF ? DepthT : Depth);
				}

				ShadowNodeArray[i].node->OnAnimate(device->getTimer()->getTime());
				ShadowNodeArray[i].node->render();

				const u32 BufferMaterialListSize = BufferMaterialList.size();
				for(u32 m = 0;m < BufferMaterialListSize;++m)
					ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)BufferMaterialList[m];
			}

			// Blur the shadow map texture if we're using VSM filtering.
			if(useVSM)
			{
				ITexture* currentSecondaryShadowMap = getShadowMapTexture(LightList[l].getShadowMapResolution(), true);

				driver->setRenderTarget(currentSecondaryShadowMap, true, true, SColor(0xffffffff));
				ScreenQuad.getMaterial().setTexture(0, currentShadowMapTexture);
				ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)VSMBlurH;
				
				ScreenQuad.render(driver);

				driver->setRenderTarget(currentShadowMapTexture, true, true, SColor(0xffffffff));
				ScreenQuad.getMaterial().setTexture(0, currentSecondaryShadowMap);
				ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)VSMBlurV;
				
				ScreenQuad.render(driver);
			}

			driver->setRenderTarget(ScreenQuad.rt[1], true, true, SColor(0xffffffff));
		
			driver->setTransform(ETS_VIEW, activeCam->getViewMatrix());
			driver->setTransform(ETS_PROJECTION, activeCam->getProjectionMatrix());

			shadowMC->LightColour = LightList[l].getLightColor();
			shadowMC->LightLink = LightList[l].getPosition();
			shadowMC->FarLink = LightList[l].getFarValue();
			shadowMC->ViewLink = LightList[l].getViewMatrix();
			shadowMC->ProjLink = LightList[l].getProjectionMatrix();
			shadowMC->MapRes = (f32)LightList[l].getShadowMapResolution();

			for(u32 i = 0;i < ShadowNodeArraySize;++i)
			{
				if(ShadowNodeArray[i].shadowMode == ESM_CAST || ShadowNodeArray[i].shadowMode == ESM_EXCLUDE)
						continue;

				const u32 CurrentMaterialCount = ShadowNodeArray[i].node->getMaterialCount();
				core::array<irr::s32> BufferMaterialList(CurrentMaterialCount);
				core::array<irr::video::ITexture*> BufferTextureList(CurrentMaterialCount);
				
				for(u32 m = 0;m < CurrentMaterialCount;++m)
				{
					BufferMaterialList.push_back(ShadowNodeArray[i].node->getMaterial(m).MaterialType);
					BufferTextureList.push_back(ShadowNodeArray[i].node->getMaterial(m).getTexture(0));
				
					ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)Shadow[ShadowNodeArray[i].filterType];
					ShadowNodeArray[i].node->getMaterial(m).setTexture(0, currentShadowMapTexture);
				}

				ShadowNodeArray[i].node->OnAnimate(device->getTimer()->getTime());
				ShadowNodeArray[i].node->render();

				for(u32 m = 0;m < CurrentMaterialCount;++m)
				{
					ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)BufferMaterialList[m];
					ShadowNodeArray[i].node->getMaterial(m).setTexture(0, BufferTextureList[m]);
				}
			}

			driver->setRenderTarget(ScreenQuad.rt[0], false, false, SColor(0x0));
			ScreenQuad.getMaterial().setTexture(0, ScreenQuad.rt[1]);
			ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)Simple;
			
			ScreenQuad.render(driver);
		}

		// Render all the excluded and casting-only nodes.
		for(u32 i = 0;i < ShadowNodeArraySize;++i)
		{
			if(ShadowNodeArray[i].shadowMode != ESM_CAST && ShadowNodeArray[i].shadowMode != ESM_EXCLUDE)
					continue;

			const u32 CurrentMaterialCount = ShadowNodeArray[i].node->getMaterialCount();
			core::array<irr::s32> BufferMaterialList(CurrentMaterialCount);
			BufferMaterialList.set_used(0);
			
			for(u32 m = 0;m < CurrentMaterialCount;++m)
			{
				BufferMaterialList.push_back(ShadowNodeArray[i].node->getMaterial(m).MaterialType);
			
				switch(BufferMaterialList[m])
				{
					case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
						ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWashTRef;
						break;
					case EMT_TRANSPARENT_ADD_COLOR:
						ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWashTAdd;
						break;
					case EMT_TRANSPARENT_ALPHA_CHANNEL:
						ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWashTAlpha;
						break;
					default:
						ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWash;
						break;
				}
			}

			ShadowNodeArray[i].node->OnAnimate(device->getTimer()->getTime());
			ShadowNodeArray[i].node->render();

			for(u32 m = 0;m < CurrentMaterialCount;++m)
				ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)BufferMaterialList[m];
		}
	}
	else
	{
		driver->setRenderTarget(ScreenQuad.rt[0], true, true, SColor(0xffffffff));
	}
	
	driver->setRenderTarget(ScreenQuad.rt[1], true, true, ClearColour);
	smgr->drawAll();

	const u32 PostProcessingRoutinesSize = PostProcessingRoutines.size();

	driver->setRenderTarget(PostProcessingRoutinesSize 
		? ScreenRTT : outputTarget, true, true, SColor(0x0));

	ScreenQuad.getMaterial().setTexture(0, ScreenQuad.rt[1]);
	ScreenQuad.getMaterial().setTexture(1, ScreenQuad.rt[0]);

	ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)LightModulate;
	ScreenQuad.render(driver);

	// Perform depth pass after rendering, to ensure animations stay up to date.
	if(DepthPass)
	{
		driver->setRenderTarget(DepthRTT, true, true, SColor(0xffffffff));

		// Set max distance constant for depth shader.
		depthMC->FarLink = smgr->getActiveCamera()->getFarValue();

		for(u32 i = 0;i < DepthPassArray.size();++i)
		{
			core::array<irr::s32> BufferMaterialList(DepthPassArray[i]->getMaterialCount());
			BufferMaterialList.set_used(0);

			for(u32 g = 0;g < DepthPassArray[i]->getMaterialCount();++g)
				BufferMaterialList.push_back(DepthPassArray[i]->getMaterial(g).MaterialType);

			DepthPassArray[i]->setMaterialType((E_MATERIAL_TYPE)Depth);
			DepthPassArray[i]->OnAnimate(device->getTimer()->getTime());
			DepthPassArray[i]->render();

			for(u32 g = 0;g < DepthPassArray[i]->getMaterialCount();++g)
				DepthPassArray[i]->getMaterial(g).MaterialType = (E_MATERIAL_TYPE)BufferMaterialList[g];
		}

		driver->setRenderTarget(0, false, false);
	}
	
	if(PostProcessingRoutinesSize)
	{
		bool Alter = false;
		ScreenQuad.getMaterial().setTexture(1, ScreenRTT);
		ScreenQuad.getMaterial().setTexture(2, DepthRTT);
		for(u32 i = 0;i < PostProcessingRoutinesSize;++i)
		{
			ScreenQuad.getMaterial().MaterialType = (E_MATERIAL_TYPE)PostProcessingRoutines[i].materialType;

			Alter = !Alter;
			ScreenQuad.getMaterial().setTexture(0, i == 0 ? ScreenRTT : ScreenQuad.rt[int(!Alter)]);
			driver->setRenderTarget(i >= PostProcessingRoutinesSize - 1 ?
				outputTarget : ScreenQuad.rt[int(Alter)], true, true, ClearColour);

			if(PostProcessingRoutines[i].renderCallback) PostProcessingRoutines[i].renderCallback->OnPreRender(this);
			ScreenQuad.render(driver);
			if(PostProcessingRoutines[i].renderCallback) PostProcessingRoutines[i].renderCallback->OnPostRender(this);
		}
	}
}