openclonk/src/landscape/fow/C4FoW.cpp

130 lines
2.9 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2014-2015, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
#include "C4Include.h"
#include "C4FoW.h"
#include <float.h>
C4FoW::C4FoW()
: pLights(NULL)
{
}
C4Shader *C4FoW::GetFramebufShader()
{
#ifndef USE_CONSOLE
// Not created yet?
if (!FramebufShader.Initialised())
{
// Create the frame buffer shader. The details are in C4FoWRegion, but
// this is about how to utilise old frame buffer data in the lights texture.
// Or put in other words: This shader is responsible for fading lights out.
FramebufShader.AddVertexDefaults();
FramebufShader.AddTexCoord("texCoord");
FramebufShader.AddFragmentSlice(-1, "uniform sampler2D tex;");
FramebufShader.AddFragmentSlice(0,
"gl_FragColor = vec4(texture2D(tex, texCoord.st).rgb, 3.0f/4.0f);");
const char *szUniforms[] = { "tex", NULL };
if (!FramebufShader.Init("framebuf", szUniforms)) {
FramebufShader.ClearSlices();
return NULL;
}
}
return &FramebufShader;
#else
return NULL;
#endif
}
void C4FoW::Add(C4Object *pObj)
{
#ifndef USE_CONSOLE
// No view range? Probably want to remove instead
if(!pObj->lightRange && !pObj->lightFadeoutRange)
{
Remove(pObj);
return;
}
// Look for matching light
C4FoWLight *pLight;
for (pLight = pLights; pLight; pLight = pLight->getNext())
if (pLight->getObj() == pObj)
break;
if (pLight)
{
// Update reach
pLight->SetReach(pObj->lightRange, pObj->lightFadeoutRange);
}
else
{
// Create new light otherwise
pLight = new C4FoWLight(pObj);
pLight->pNext = pLights;
pLights = pLight;
}
#endif
}
void C4FoW::Remove(C4Object *pObj)
{
#ifndef USE_CONSOLE
// Look for matching light
C4FoWLight *pPrev = NULL, *pLight;
for (pLight = pLights; pLight; pPrev = pLight, pLight = pLight->getNext())
if (pLight->getObj() == pObj)
break;
if (!pLight)
return;
// Remove
(pPrev ? pPrev->pNext : pLights) = pLight->getNext();
delete pLight;
#endif
}
void C4FoW::Invalidate(C4Rect r)
{
#ifndef USE_CONSOLE
for (C4FoWLight *pLight = pLights; pLight; pLight = pLight->getNext())
pLight->Invalidate(r);
#endif
}
void C4FoW::Update(C4Rect r, C4Player *pPlr)
{
#ifndef USE_CONSOLE
for (C4FoWLight *pLight = pLights; pLight; pLight = pLight->getNext())
if (pLight->IsVisibleForPlayer(pPlr))
pLight->Update(r);
#endif
}
void C4FoW::Render(C4FoWRegion *pRegion, const C4TargetFacet *pOnScreen, C4Player *pPlr)
{
#ifndef USE_CONSOLE
for (C4FoWLight *pLight = pLights; pLight; pLight = pLight->getNext())
if (pLight->IsVisibleForPlayer(pPlr))
pLight->Render(pRegion, pOnScreen);
#endif
}