2015-02-16 17:36:18 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2014-10-11 21:13:10 +00:00
|
|
|
|
|
|
|
#include "C4Include.h"
|
|
|
|
#include "C4FoW.h"
|
|
|
|
|
|
|
|
#include <float.h>
|
|
|
|
|
|
|
|
|
|
|
|
C4FoW::C4FoW()
|
|
|
|
: pLights(NULL)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-11-20 20:48:46 +00:00
|
|
|
C4Shader *C4FoW::GetFramebufShader()
|
|
|
|
{
|
2015-06-17 19:30:56 +00:00
|
|
|
#ifndef USE_CONSOLE
|
2014-11-20 20:48:46 +00:00
|
|
|
// Not created yet?
|
|
|
|
if (!FramebufShader.Initialised())
|
|
|
|
{
|
2015-01-15 11:30:29 +00:00
|
|
|
// 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.
|
2016-01-03 03:11:41 +00:00
|
|
|
const char* FramebufVertexShader =
|
|
|
|
"attribute vec2 oc_Position;\n"
|
|
|
|
"attribute vec2 oc_TexCoord;\n"
|
|
|
|
"varying vec2 texcoord;\n"
|
|
|
|
"uniform mat4 projectionMatrix;\n"
|
|
|
|
"\n"
|
|
|
|
"slice(position)\n"
|
|
|
|
"{\n"
|
|
|
|
" gl_Position = projectionMatrix * vec4(oc_Position, 0.0, 1.0);\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"slice(texcoord)\n"
|
|
|
|
"{\n"
|
|
|
|
" texcoord = oc_TexCoord;\n"
|
|
|
|
"}";
|
|
|
|
|
|
|
|
const char* FramebufFragmentShader =
|
|
|
|
"varying vec2 texcoord;\n"
|
|
|
|
"uniform sampler2D tex;\n"
|
|
|
|
"\n"
|
|
|
|
"slice(color)\n"
|
|
|
|
"{\n"
|
|
|
|
" gl_FragColor = texture2D(tex, texcoord);\n"
|
|
|
|
"}";
|
|
|
|
|
|
|
|
FramebufShader.AddVertexSlices("built-in FoW framebuf shader", FramebufVertexShader);
|
|
|
|
FramebufShader.AddFragmentSlices("built-in FoW framebuf shader", FramebufFragmentShader);
|
|
|
|
|
|
|
|
const char *szUniforms[C4FoWFSU_Count + 1];
|
|
|
|
szUniforms[C4FoWFSU_ProjectionMatrix] = "projectionMatrix";
|
|
|
|
szUniforms[C4FoWFSU_Texture] = "tex";
|
|
|
|
szUniforms[C4FoWFSU_Count] = NULL;
|
|
|
|
|
|
|
|
const char *szAttributes[C4FoWFSA_Count + 1];
|
|
|
|
szAttributes[C4FoWFSA_Position] = "oc_Position";
|
|
|
|
szAttributes[C4FoWFSA_TexCoord] = "oc_TexCoord";
|
|
|
|
szAttributes[C4FoWFSA_Count] = NULL;
|
|
|
|
|
|
|
|
if (!FramebufShader.Init("framebuf", szUniforms, szAttributes)) {
|
2014-11-20 20:48:46 +00:00
|
|
|
FramebufShader.ClearSlices();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &FramebufShader;
|
2015-06-17 19:30:56 +00:00
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
2014-11-20 20:48:46 +00:00
|
|
|
}
|
|
|
|
|
2016-01-01 01:28:05 +00:00
|
|
|
C4Shader *C4FoW::GetRenderShader()
|
|
|
|
{
|
|
|
|
#ifndef USE_CONSOLE
|
|
|
|
// Not created yet?
|
|
|
|
if (!RenderShader.Initialised())
|
|
|
|
{
|
|
|
|
// Create the render shader. Fairly simple pass-through.
|
2016-01-03 03:11:41 +00:00
|
|
|
const char* RenderVertexShader =
|
|
|
|
"attribute vec2 oc_Position;\n"
|
|
|
|
"attribute vec4 oc_Color;\n"
|
|
|
|
"varying vec4 vtxColor;\n"
|
|
|
|
"uniform mat4 projectionMatrix;\n"
|
|
|
|
"uniform vec2 vertexOffset;\n"
|
|
|
|
"\n"
|
|
|
|
"slice(position)\n"
|
|
|
|
"{\n"
|
|
|
|
" gl_Position = projectionMatrix * vec4(oc_Position + vertexOffset, 0.0, 1.0);\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"slice(color)\n"
|
|
|
|
"{\n"
|
|
|
|
" vtxColor = oc_Color;\n"
|
|
|
|
"}";
|
|
|
|
|
|
|
|
const char* RenderFragmentShader =
|
|
|
|
"varying vec4 vtxColor;\n"
|
|
|
|
"\n"
|
|
|
|
"slice(color)\n"
|
|
|
|
"{\n"
|
|
|
|
" gl_FragColor = vtxColor;\n"
|
|
|
|
"}";
|
|
|
|
|
|
|
|
RenderShader.AddVertexSlices("built-in FoW render shader", RenderVertexShader);
|
|
|
|
RenderShader.AddFragmentSlices("built-in FoW render shader", RenderFragmentShader);
|
|
|
|
|
|
|
|
const char* szUniforms[C4FoWRSU_Count + 1];
|
|
|
|
szUniforms[C4FoWRSU_ProjectionMatrix] = "projectionMatrix";
|
|
|
|
szUniforms[C4FoWRSU_VertexOffset] = "vertexOffset";
|
|
|
|
szUniforms[C4FoWRSU_Count] = NULL;
|
|
|
|
|
|
|
|
const char* szAttributes[C4FoWRSA_Count + 1];
|
|
|
|
szAttributes[C4FoWRSA_Position] = "oc_Position";
|
|
|
|
szAttributes[C4FoWRSA_Color] = "oc_Color";
|
|
|
|
szAttributes[C4FoWRSA_Count] = NULL;
|
|
|
|
|
|
|
|
if (!RenderShader.Init("fowRender", szUniforms, szAttributes)) {
|
2016-01-01 01:28:05 +00:00
|
|
|
RenderShader.ClearSlices();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return &RenderShader;
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-10-11 21:13:10 +00:00
|
|
|
void C4FoW::Add(C4Object *pObj)
|
|
|
|
{
|
2015-06-17 19:30:56 +00:00
|
|
|
#ifndef USE_CONSOLE
|
2014-10-11 21:13:10 +00:00
|
|
|
// No view range? Probably want to remove instead
|
2015-01-02 00:06:00 +00:00
|
|
|
if(!pObj->lightRange && !pObj->lightFadeoutRange)
|
2014-10-11 21:13:10 +00:00
|
|
|
{
|
|
|
|
Remove(pObj);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Look for matching light
|
|
|
|
C4FoWLight *pLight;
|
|
|
|
for (pLight = pLights; pLight; pLight = pLight->getNext())
|
|
|
|
if (pLight->getObj() == pObj)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (pLight)
|
|
|
|
{
|
|
|
|
|
Colored lights
The color of object lights can now be changed. This includes the following changes:
- added light test scenario, based on DarkCastle, with some lights,
- new functions SetLightColor() and GetLightColor() with C4Script documentation,
- third drawing pass for rendering the light color, the drawing passes are now referenced by enum,
- the blending of light from multiple colored light sources works correctly with alpha blending,
- light color value affects the intensity of the light,
- alpha blending of the light depends on color value and lightness. This means that brighter (= more value) and lighter (= more whiteish) light will be preferred in blending over other lights,
- the object light color is rendered to the lower half of the fow light texture now,
- the shader accesses the brightness/direction information and color information correctly,
The patch was created from the following commits:
dab898a SetLightColor()
f57286e Color texture experiment
d0702f5 Dynamic color
fa14cdf Light test scenario
f99203d Alternate lights
474bade Bugfixes
3113698 Brightness handled better
516fb21 GetLightColor
1d91ec9 Improvements
3cfbf6c Documentation
95ec185 Improvements: Light Shader
a63bffc Scope of alpha
20c7ca0 Improvement: C4FoWLight
17d9123 Undo code style
d79411b Cleaner code
(cherry picked from commit 36dec610e36860b88417e91ce727250673bc2ec2)
Conflicts:
src/landscape/fow/C4FoWRegion.cpp, merged
2015-06-28 18:58:53 +00:00
|
|
|
// Update reach and light color
|
2015-01-02 00:06:00 +00:00
|
|
|
pLight->SetReach(pObj->lightRange, pObj->lightFadeoutRange);
|
Colored lights
The color of object lights can now be changed. This includes the following changes:
- added light test scenario, based on DarkCastle, with some lights,
- new functions SetLightColor() and GetLightColor() with C4Script documentation,
- third drawing pass for rendering the light color, the drawing passes are now referenced by enum,
- the blending of light from multiple colored light sources works correctly with alpha blending,
- light color value affects the intensity of the light,
- alpha blending of the light depends on color value and lightness. This means that brighter (= more value) and lighter (= more whiteish) light will be preferred in blending over other lights,
- the object light color is rendered to the lower half of the fow light texture now,
- the shader accesses the brightness/direction information and color information correctly,
The patch was created from the following commits:
dab898a SetLightColor()
f57286e Color texture experiment
d0702f5 Dynamic color
fa14cdf Light test scenario
f99203d Alternate lights
474bade Bugfixes
3113698 Brightness handled better
516fb21 GetLightColor
1d91ec9 Improvements
3cfbf6c Documentation
95ec185 Improvements: Light Shader
a63bffc Scope of alpha
20c7ca0 Improvement: C4FoWLight
17d9123 Undo code style
d79411b Cleaner code
(cherry picked from commit 36dec610e36860b88417e91ce727250673bc2ec2)
Conflicts:
src/landscape/fow/C4FoWRegion.cpp, merged
2015-06-28 18:58:53 +00:00
|
|
|
pLight->SetColor(pObj->lightColor);
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Create new light otherwise
|
|
|
|
pLight = new C4FoWLight(pObj);
|
|
|
|
pLight->pNext = pLights;
|
|
|
|
pLights = pLight;
|
|
|
|
}
|
2015-06-17 19:30:56 +00:00
|
|
|
#endif
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void C4FoW::Remove(C4Object *pObj)
|
|
|
|
{
|
2015-06-17 19:30:56 +00:00
|
|
|
#ifndef USE_CONSOLE
|
2014-10-11 21:13:10 +00:00
|
|
|
// 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
|
2014-12-28 11:28:25 +00:00
|
|
|
(pPrev ? pPrev->pNext : pLights) = pLight->getNext();
|
2014-10-11 21:13:10 +00:00
|
|
|
delete pLight;
|
2015-06-17 19:30:56 +00:00
|
|
|
#endif
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void C4FoW::Invalidate(C4Rect r)
|
|
|
|
{
|
2015-06-17 19:30:56 +00:00
|
|
|
#ifndef USE_CONSOLE
|
2014-10-11 21:13:10 +00:00
|
|
|
for (C4FoWLight *pLight = pLights; pLight; pLight = pLight->getNext())
|
|
|
|
pLight->Invalidate(r);
|
2015-06-17 19:30:56 +00:00
|
|
|
#endif
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
|
2015-01-02 00:42:09 +00:00
|
|
|
void C4FoW::Update(C4Rect r, C4Player *pPlr)
|
2014-10-11 21:13:10 +00:00
|
|
|
{
|
2015-06-17 19:30:56 +00:00
|
|
|
#ifndef USE_CONSOLE
|
2014-10-11 21:13:10 +00:00
|
|
|
for (C4FoWLight *pLight = pLights; pLight; pLight = pLight->getNext())
|
2015-01-02 00:42:09 +00:00
|
|
|
if (pLight->IsVisibleForPlayer(pPlr))
|
|
|
|
pLight->Update(r);
|
2015-06-17 19:30:56 +00:00
|
|
|
#endif
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
|
2016-01-01 01:28:05 +00:00
|
|
|
void C4FoW::Render(C4FoWRegion *pRegion, const C4TargetFacet *pOnScreen, C4Player *pPlr, const StdProjectionMatrix& projectionMatrix)
|
2014-10-11 21:13:10 +00:00
|
|
|
{
|
2015-06-17 19:30:56 +00:00
|
|
|
#ifndef USE_CONSOLE
|
2016-01-01 01:28:05 +00:00
|
|
|
// Set up shader. If this one doesn't work, we're really in trouble.
|
|
|
|
C4Shader *pShader = GetRenderShader();
|
|
|
|
assert(pShader);
|
|
|
|
if (!pShader) return;
|
|
|
|
|
|
|
|
C4ShaderCall Call(pShader);
|
|
|
|
Call.Start();
|
2016-01-03 03:11:41 +00:00
|
|
|
Call.SetUniformMatrix4x4(C4FoWRSU_ProjectionMatrix, projectionMatrix);
|
2016-01-01 01:28:05 +00:00
|
|
|
|
2014-10-11 21:13:10 +00:00
|
|
|
for (C4FoWLight *pLight = pLights; pLight; pLight = pLight->getNext())
|
2015-01-02 00:42:09 +00:00
|
|
|
if (pLight->IsVisibleForPlayer(pPlr))
|
2016-01-02 05:18:15 +00:00
|
|
|
pLight->Render(pRegion, pOnScreen, Call);
|
2016-01-01 01:28:05 +00:00
|
|
|
|
|
|
|
Call.Finish();
|
2015-06-17 19:30:56 +00:00
|
|
|
#endif
|
2014-11-17 14:35:50 +00:00
|
|
|
}
|