// This file is distributed under a BSD license. See LICENSE.txt for details. #include "_types.hpp" #include "_start.hpp" #include "rtmanager.hpp" /****************************************************************************/ void RenderTargetManager_::GetRealResolution(const Target *tgt,sInt &xRes,sInt &yRes) const { xRes = tgt->XRes ? tgt->XRes : MasterVP.Window.XSize(); yRes = tgt->YRes ? tgt->YRes : MasterVP.Window.YSize(); } void RenderTargetManager_::ResizeInternal(Target *tgt,sInt xRes,sInt yRes) { sInt useXRes,useYRes; tgt->XRes = xRes; tgt->YRes = yRes; GetRealResolution(tgt,useXRes,useYRes); /*sInt texXRes = sMin(sMakePower2(useXRes),2048); sInt texYRes = sMin(sMakePower2(useYRes),2048);*/ sInt texXRes = useXRes; // "das war einfach" sInt texYRes = useYRes; sInt realX,realY; if(tgt->Handle != sINVALID) sSystem->GetTextureSize(tgt->Handle,realX,realY); else realX = realY = 0; // never ever make rendertargets smaller! (else you'll end up resizing a lot) texXRes = sMax(texXRes,realX); texYRes = sMax(texYRes,realY); // re-allocate texture if necessary if(texXRes > realX/*tgt->TexXRes*/ || texYRes > realY/*tgt->TexYRes*/) { if(tgt->Handle != sINVALID) sSystem->RemTexture(tgt->Handle); tgt->TexXRes = texXRes; tgt->TexYRes = texYRes; tgt->Handle = sSystem->AddTexture(tgt->TexXRes,tgt->TexYRes,sTF_A8R8G8B8,0); #if !sINTRO sDPrintF("RTManager: target %08x resized to %dx%d\n",tgt->Id,tgt->TexXRes,tgt->TexYRes); #endif } } RenderTargetManager_::RenderTargetManager_() { Targets.Init(); MasterVP.Init(); } RenderTargetManager_::~RenderTargetManager_() { for(sInt i=0;iRemTexture(Targets[i].Handle); Targets.Exit(); } void RenderTargetManager_::GetMasterViewport(sViewport &vp) { vp = MasterVP; } void RenderTargetManager_::SetMasterViewport(const sViewport &vp) { MasterVP = vp; if(MasterVP.RenderTarget != -1 && vp.Window.XSize() == 0) { sInt w,h; sSystem->GetTextureSize(MasterVP.RenderTarget,w,h); MasterVP.Window.Init(0,0,w,h); } // go through all fullscreen targets, resizing them if necessary for(sInt i=0;iXRes && !tgt->YRes) ResizeInternal(tgt,0,0); } } void RenderTargetManager_::Add(sU32 id,sInt xRes,sInt yRes) { sF32 us,vs; if(Get(id,us,vs) != sINVALID) // only add if not yet added return; Target *tgt = Targets.Add(); tgt->Id = id; tgt->TexXRes = 0; tgt->TexYRes = 0; tgt->Handle = sINVALID; ResizeInternal(tgt,xRes,yRes); } void RenderTargetManager_::Resize(sU32 id,sInt xRes,sInt yRes) { for(sInt i=0;iId == id) ResizeInternal(tgt,xRes,yRes); } } sInt RenderTargetManager_::Get(sU32 id,sF32 &uScale,sF32 &vScale) const { for(sInt i=0;iId == id) { sInt useXRes,useYRes; GetRealResolution(tgt,useXRes,useYRes); if(useXRes <= tgt->TexXRes && useYRes <= tgt->TexYRes) { uScale = 1.0f * useXRes / tgt->TexXRes; vScale = 1.0f * useYRes / tgt->TexYRes; } else uScale = vScale = 1.0f; return tgt->Handle; } } return sINVALID; } void RenderTargetManager_::SetAsTarget(sU32 id) const { for(sInt i=0;iId == id) { sViewport vp; vp.InitTex(tgt->Handle); vp.Window.x0 = 0; vp.Window.y0 = 0; GetRealResolution(tgt,vp.Window.x1,vp.Window.y1); if(vp.Window.x1 > tgt->TexXRes || vp.Window.y1 > tgt->TexYRes) vp.Window.Init(0,0,tgt->TexXRes,tgt->TexYRes); sSystem->SetViewport(vp); } } } void RenderTargetManager_::GrabToTarget(sU32 targetId,const sRect *window) const { if(!window) window = &MasterVP.Window; for(sInt i=0;iId == targetId && tgt->Handle != sINVALID) { sInt useXRes,useYRes; GetRealResolution(tgt,useXRes,useYRes); sBool stretch = useXRes > tgt->TexXRes || useYRes > tgt->TexYRes; sSystem->GrabScreen(MasterVP.RenderTarget,*window,tgt->Handle,stretch); break; } } } /****************************************************************************/ RenderTargetManager_ *RenderTargetManager = 0; /****************************************************************************/