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 "C4FoWRegion.h"
|
2016-01-01 01:28:05 +00:00
|
|
|
#include "C4DrawGL.h"
|
2014-10-11 21:13:10 +00:00
|
|
|
|
2016-01-02 01:23:44 +00:00
|
|
|
C4FoWRegion::C4FoWRegion(C4FoW *pFoW, C4Player *pPlayer)
|
|
|
|
: pFoW(pFoW)
|
|
|
|
, pPlayer(pPlayer)
|
|
|
|
#ifndef USE_CONSOLE
|
|
|
|
, hFrameBufDraw(0), hFrameBufRead(0), hVBO(0)
|
|
|
|
#endif
|
|
|
|
, Region(0,0,0,0), OldRegion(0,0,0,0)
|
|
|
|
, pSurface(new C4Surface), pBackSurface(new C4Surface)
|
|
|
|
{
|
|
|
|
ViewportRegion.left = ViewportRegion.right = ViewportRegion.top = ViewportRegion.bottom = 0.0f;
|
|
|
|
}
|
|
|
|
|
2014-10-11 21:13:10 +00:00
|
|
|
C4FoWRegion::~C4FoWRegion()
|
|
|
|
{
|
2015-12-28 17:31:24 +00:00
|
|
|
#ifndef USE_CONSOLE
|
|
|
|
if (hFrameBufDraw) {
|
|
|
|
glDeleteFramebuffersEXT(1, &hFrameBufDraw);
|
|
|
|
glDeleteFramebuffersEXT(1, &hFrameBufRead);
|
|
|
|
}
|
2016-01-02 01:23:44 +00:00
|
|
|
|
|
|
|
if (hVBO) {
|
|
|
|
glDeleteBuffers(1, &hVBO);
|
|
|
|
}
|
2015-12-28 17:31:24 +00:00
|
|
|
#endif
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool C4FoWRegion::BindFramebuf()
|
|
|
|
{
|
2015-06-17 19:30:56 +00:00
|
|
|
#ifndef USE_CONSOLE
|
2014-10-11 21:13:10 +00:00
|
|
|
// Flip texture
|
2015-12-28 17:34:57 +00:00
|
|
|
pSurface.swap(pBackSurface);
|
2014-10-11 21:13:10 +00:00
|
|
|
|
|
|
|
// Can simply reuse old texture?
|
2015-12-28 17:34:57 +00:00
|
|
|
if (pSurface->Wdt < Region.Wdt || (pSurface->Hgt / 2) < Region.Hgt)
|
2014-10-11 21:13:10 +00:00
|
|
|
{
|
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
|
|
|
// Determine texture size. Round up to next power of two in order to
|
2014-10-11 21:13:10 +00:00
|
|
|
// prevent rounding errors, as well as preventing lots of
|
|
|
|
// re-allocations when region size changes quickly (think zoom).
|
|
|
|
int iWdt = 1, iHgt = 1;
|
|
|
|
while (iWdt < Region.Wdt) iWdt *= 2;
|
|
|
|
while (iHgt < Region.Hgt) iHgt *= 2;
|
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
|
|
|
|
|
|
|
// Double the texture size. The second half of the texture
|
|
|
|
// will contain the light color information, while the
|
|
|
|
// first half contains the brightness and direction information
|
|
|
|
iHgt *= 2;
|
|
|
|
|
2016-01-06 04:22:12 +00:00
|
|
|
// Create the new surfaces
|
|
|
|
std::unique_ptr<C4Surface> pNewSurface(new C4Surface);
|
|
|
|
std::unique_ptr<C4Surface> pNewBackSurface(new C4Surface);
|
|
|
|
if (!pNewSurface->Create(iWdt, iHgt, false, 0, 0))
|
2014-10-11 21:13:10 +00:00
|
|
|
return false;
|
2016-01-06 04:22:12 +00:00
|
|
|
if (!pNewBackSurface->Create(iWdt, iHgt, false, 0, 0))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Copy over old content. This avoids flicker in already
|
|
|
|
// explored regions that might get temporarily dark and
|
|
|
|
// re-faded-in with the surface swap. New area in the surface
|
|
|
|
// is initialized with darkness (black).
|
|
|
|
pSurface->Lock();
|
|
|
|
pBackSurface->Lock();
|
|
|
|
pNewSurface->Lock();
|
|
|
|
pNewBackSurface->Lock();
|
|
|
|
|
|
|
|
// Take into account that the texture
|
|
|
|
// is split for normals/intensity and colors, and also that
|
|
|
|
// OpenGL textures are upside down.
|
|
|
|
for (int y = 0; y < iHgt / 2; ++y)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < iWdt; ++x)
|
|
|
|
{
|
|
|
|
if (y < pSurface->Hgt / 2 && x < pSurface->Wdt)
|
|
|
|
{
|
|
|
|
// Normals and intensity
|
2016-02-08 21:56:32 +00:00
|
|
|
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y - 1, pSurface->GetPixDw(x, pSurface->Hgt/2 - y - 1, false));
|
|
|
|
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y - 1, pBackSurface->GetPixDw(x, pBackSurface->Hgt/2 - y - 1, false));
|
2016-01-06 04:22:12 +00:00
|
|
|
|
|
|
|
// Color
|
2016-02-08 21:56:32 +00:00
|
|
|
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y + iHgt / 2 - 1, pSurface->GetPixDw(x, pSurface->Hgt/2 - y + pSurface->Hgt / 2 - 1, false));
|
|
|
|
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y + iHgt / 2 - 1, pBackSurface->GetPixDw(x, pBackSurface->Hgt/2 - y + pBackSurface->Hgt / 2 - 1, false));
|
2016-01-06 04:22:12 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Normals and intensity
|
2016-02-08 21:56:32 +00:00
|
|
|
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y - 1, 0x000000ff);
|
|
|
|
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y - 1, 0x000000ff);
|
2016-01-06 04:22:12 +00:00
|
|
|
|
|
|
|
// Color
|
2016-02-08 21:56:32 +00:00
|
|
|
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y + iHgt / 2 - 1, 0x000000ff);
|
|
|
|
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y + iHgt / 2 - 1, 0x000000ff);
|
2016-01-06 04:22:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pSurface = std::move(pNewSurface);
|
|
|
|
pBackSurface = std::move(pNewBackSurface);
|
|
|
|
|
|
|
|
pSurface->Unlock();
|
|
|
|
pBackSurface->Unlock();
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
|
2016-01-15 03:25:45 +00:00
|
|
|
// Cannot bind empty surface
|
|
|
|
if (!pSurface->iTexSize) return false;
|
|
|
|
|
2014-10-11 21:13:10 +00:00
|
|
|
// Generate frame buffer object
|
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
|
|
|
if (!hFrameBufDraw)
|
|
|
|
{
|
2014-10-11 21:13:10 +00:00
|
|
|
glGenFramebuffersEXT(1, &hFrameBufDraw);
|
|
|
|
glGenFramebuffersEXT(1, &hFrameBufRead);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bind current texture to frame buffer
|
|
|
|
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, hFrameBufDraw);
|
|
|
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, hFrameBufRead);
|
|
|
|
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT,
|
|
|
|
GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
|
2015-01-18 21:09:47 +00:00
|
|
|
pSurface->textures[0].texName, 0);
|
2015-12-28 17:34:57 +00:00
|
|
|
if (!pBackSurface->textures.empty())
|
2014-10-11 21:13:10 +00:00
|
|
|
glFramebufferTexture2DEXT(GL_READ_FRAMEBUFFER_EXT,
|
|
|
|
GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
|
2015-01-18 21:09:47 +00:00
|
|
|
pBackSurface->textures[0].texName, 0);
|
2014-10-11 21:13:10 +00:00
|
|
|
|
|
|
|
// Check status, unbind if something was amiss
|
|
|
|
GLenum status1 = glCheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER_EXT),
|
|
|
|
status2 = glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
|
|
|
|
if (status1 != GL_FRAMEBUFFER_COMPLETE_EXT ||
|
2015-12-25 00:24:47 +00:00
|
|
|
(pBackSurface && status2 != GL_FRAMEBUFFER_COMPLETE_EXT))
|
2014-10-11 21:13:10 +00:00
|
|
|
{
|
|
|
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
|
|
|
return false;
|
|
|
|
}
|
2015-06-17 19:30:56 +00:00
|
|
|
#endif
|
2014-10-11 21:13:10 +00:00
|
|
|
|
|
|
|
// Worked!
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-12-28 18:29:13 +00:00
|
|
|
int32_t C4FoWRegion::getSurfaceHeight() const
|
|
|
|
{
|
|
|
|
return pSurface->Hgt;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t C4FoWRegion::getSurfaceWidth() const
|
|
|
|
{
|
|
|
|
return pSurface->Wdt;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef USE_CONSOLE
|
|
|
|
GLuint C4FoWRegion::getSurfaceName() const
|
|
|
|
{
|
|
|
|
assert(!pSurface->textures.empty());
|
|
|
|
if (pSurface->textures.empty())
|
|
|
|
return 0;
|
|
|
|
return pSurface->textures[0].texName;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-01-07 16:29:48 +00:00
|
|
|
void C4FoWRegion::Update(C4Rect r, const FLOAT_RECT& vp)
|
2014-10-11 21:13:10 +00:00
|
|
|
{
|
|
|
|
// Set the new region
|
|
|
|
Region = r;
|
2015-01-07 16:29:48 +00:00
|
|
|
ViewportRegion = vp;
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
|
2016-01-15 13:53:00 +00:00
|
|
|
bool C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
|
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
|
|
|
// Update FoW at interesting location
|
2015-01-02 00:42:09 +00:00
|
|
|
pFoW->Update(Region, pPlayer);
|
2014-10-11 21:13:10 +00:00
|
|
|
|
|
|
|
// On screen? No need to set up frame buffer - simply shortcut
|
|
|
|
if (pOnScreen)
|
|
|
|
{
|
2016-01-01 01:28:05 +00:00
|
|
|
pFoW->Render(this, pOnScreen, pPlayer, pGL->GetProjectionMatrix());
|
2016-01-15 13:53:00 +00:00
|
|
|
return true;
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
|
2015-02-23 10:54:26 +00:00
|
|
|
// Set up shader. If this one doesn't work, we're really in trouble.
|
|
|
|
C4Shader *pShader = pFoW->GetFramebufShader();
|
|
|
|
assert(pShader);
|
2016-01-15 13:53:00 +00:00
|
|
|
if (!pShader) return false;
|
2015-02-23 10:54:26 +00:00
|
|
|
|
2014-10-11 21:13:10 +00:00
|
|
|
// Create & bind the frame buffer
|
|
|
|
pDraw->StorePrimaryClipper();
|
|
|
|
if(!BindFramebuf())
|
|
|
|
{
|
|
|
|
pDraw->RestorePrimaryClipper();
|
2016-01-15 13:53:00 +00:00
|
|
|
return false;
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
assert(pSurface && hFrameBufDraw);
|
|
|
|
if (!pSurface || !hFrameBufDraw)
|
2016-01-15 13:53:00 +00:00
|
|
|
return false;
|
2014-10-11 21:13:10 +00:00
|
|
|
|
|
|
|
// Set up a clean context
|
2015-12-28 18:29:13 +00:00
|
|
|
glViewport(0, 0, pSurface->Wdt, pSurface->Hgt);
|
2016-01-02 01:23:44 +00:00
|
|
|
const StdProjectionMatrix projectionMatrix = StdProjectionMatrix::Orthographic(0.0f, pSurface->Wdt, pSurface->Hgt, 0.0f);
|
2014-10-11 21:13:10 +00:00
|
|
|
|
|
|
|
// Clear texture contents
|
2015-12-28 18:29:13 +00:00
|
|
|
assert(pSurface->Hgt % 2 == 0);
|
|
|
|
glScissor(0, pSurface->Hgt / 2, pSurface->Wdt, pSurface->Hgt / 2);
|
2015-06-10 19:21:33 +00:00
|
|
|
glClearColor(0.0f, 0.5f / 1.5f, 0.5f / 1.5f, 0.0f);
|
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
|
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
|
|
|
// clear lower half of texture
|
2015-12-28 18:29:13 +00:00
|
|
|
glScissor(0, 0, pSurface->Wdt, pSurface->Hgt / 2);
|
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
|
|
|
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
2014-10-11 21:13:10 +00:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
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
|
|
|
glDisable(GL_SCISSOR_TEST);
|
2014-10-11 21:13:10 +00:00
|
|
|
|
2014-11-20 20:48:46 +00:00
|
|
|
// Render FoW to frame buffer object
|
|
|
|
glBlendFunc(GL_ONE, GL_ONE);
|
2016-01-01 01:28:05 +00:00
|
|
|
pFoW->Render(this, NULL, pPlayer, projectionMatrix);
|
2014-11-20 20:48:46 +00:00
|
|
|
|
2014-10-11 21:13:10 +00:00
|
|
|
// Copy over the old state
|
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
|
|
|
if (OldRegion.Wdt > 0)
|
|
|
|
{
|
2014-11-20 20:48:46 +00:00
|
|
|
|
|
|
|
// How much the borders have moved
|
2014-10-11 21:13:10 +00:00
|
|
|
int dx0 = Region.x - OldRegion.x,
|
|
|
|
dy0 = Region.y - OldRegion.y,
|
|
|
|
dx1 = Region.x + Region.Wdt - OldRegion.x - OldRegion.Wdt,
|
|
|
|
dy1 = Region.y + Region.Hgt - OldRegion.y - OldRegion.Hgt;
|
|
|
|
|
2014-11-20 20:48:46 +00:00
|
|
|
// Source and target rect coordinates (landscape coordinate system)
|
2015-11-15 12:53:01 +00:00
|
|
|
int sx0 = std::max(0, dx0), sy0 = std::max(0, dy0),
|
|
|
|
sx1 = OldRegion.Wdt - std::max(0, -dx1), sy1 = OldRegion.Hgt - std::max(0, -dy1),
|
|
|
|
tx0 = std::max(0, -dx0), ty0 = std::max(0, -dy0),
|
|
|
|
tx1 = Region.Wdt - std::max(0, dx1), ty1 = Region.Hgt - std::max(0, dy1);
|
2014-11-20 20:48:46 +00:00
|
|
|
|
|
|
|
// Quad coordinates
|
2016-01-02 01:23:44 +00:00
|
|
|
float vtxData[16];
|
|
|
|
float* squad = &vtxData[0];
|
|
|
|
float* tquad = &vtxData[8];
|
|
|
|
|
|
|
|
squad[0] = float(sx0);
|
|
|
|
squad[1] = float(sy0);
|
|
|
|
squad[2] = float(sx0);
|
|
|
|
squad[3] = float(sy1);
|
|
|
|
squad[4] = float(sx1);
|
|
|
|
squad[5] = float(sy0);
|
|
|
|
squad[6] = float(sx1);
|
|
|
|
squad[7] = float(sy1);
|
|
|
|
|
|
|
|
tquad[0] = float(tx0);
|
|
|
|
tquad[1] = float(ty0);
|
|
|
|
tquad[2] = float(tx0);
|
|
|
|
tquad[3] = float(ty1);
|
|
|
|
tquad[4] = float(tx1);
|
|
|
|
tquad[5] = float(ty0);
|
|
|
|
tquad[6] = float(tx1);
|
|
|
|
tquad[7] = float(ty1);
|
2014-11-20 20:48:46 +00:00
|
|
|
|
|
|
|
// Transform into texture coordinates
|
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
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
{
|
2015-12-28 18:29:13 +00:00
|
|
|
squad[i*2] = squad[i*2] / pBackSurface->Wdt;
|
|
|
|
squad[i*2+1] = 1.0 - squad[i*2+1] / pBackSurface->Hgt;
|
2014-11-20 20:48:46 +00:00
|
|
|
}
|
|
|
|
|
2016-01-02 01:23:44 +00:00
|
|
|
// Load coordinates into vertex buffer
|
|
|
|
if (hVBO == 0)
|
|
|
|
{
|
|
|
|
glGenBuffers(1, &hVBO);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, hVBO);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vtxData), vtxData, GL_STREAM_DRAW);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, hVBO);
|
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vtxData), vtxData);
|
|
|
|
}
|
|
|
|
|
2014-11-20 20:48:46 +00:00
|
|
|
// Copy using shader
|
|
|
|
C4ShaderCall Call(pShader);
|
|
|
|
Call.Start();
|
2016-01-03 03:11:41 +00:00
|
|
|
if (Call.AllocTexUnit(C4FoWFSU_Texture))
|
2015-12-28 18:29:13 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, pBackSurface->textures[0].texName);
|
2016-01-03 03:11:41 +00:00
|
|
|
Call.SetUniformMatrix4x4(C4FoWFSU_ProjectionMatrix, projectionMatrix);
|
2015-06-10 19:21:33 +00:00
|
|
|
glBlendFunc(GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR);
|
|
|
|
float normalBlend = 1.0f / 4.0f, // Normals change quickly
|
|
|
|
brightBlend = 1.0f / 16.0f; // Intensity more slowly
|
|
|
|
glBlendColor(0.0f,normalBlend,normalBlend,brightBlend);
|
2016-01-02 01:23:44 +00:00
|
|
|
|
2016-01-03 03:11:41 +00:00
|
|
|
glEnableVertexAttribArray(pShader->GetAttribute(C4FoWFSA_Position));
|
|
|
|
glEnableVertexAttribArray(pShader->GetAttribute(C4FoWFSA_TexCoord));
|
|
|
|
glVertexAttribPointer(pShader->GetAttribute(C4FoWFSA_Position), 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<const uint8_t*>(8 * sizeof(float)));
|
|
|
|
glVertexAttribPointer(pShader->GetAttribute(C4FoWFSA_TexCoord), 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<const uint8_t*>(0));
|
2016-01-02 01:23:44 +00:00
|
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
|
|
|
2016-01-03 03:11:41 +00:00
|
|
|
glDisableVertexAttribArray(pShader->GetAttribute(C4FoWFSA_Position));
|
|
|
|
glDisableVertexAttribArray(pShader->GetAttribute(C4FoWFSA_TexCoord));
|
2016-01-02 01:23:44 +00:00
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
|
2014-11-20 20:48:46 +00:00
|
|
|
Call.Finish();
|
2015-06-10 19:21:33 +00:00
|
|
|
}
|
2014-10-11 21:13:10 +00:00
|
|
|
|
|
|
|
// Done!
|
|
|
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
|
|
|
pDraw->RestorePrimaryClipper();
|
|
|
|
|
|
|
|
OldRegion = Region;
|
2015-06-17 19:30:56 +00:00
|
|
|
#endif
|
2016-01-15 13:53:00 +00:00
|
|
|
return true;
|
2014-10-11 21:13:10 +00:00
|
|
|
}
|
|
|
|
|
2014-12-26 15:16:09 +00:00
|
|
|
void C4FoWRegion::GetFragTransform(const C4Rect& clipRect, const C4Rect& outRect, float lightTransform[6]) const
|
2014-12-22 16:15:46 +00:00
|
|
|
{
|
|
|
|
const C4Rect& lightRect = getRegion();
|
2015-01-07 16:29:48 +00:00
|
|
|
const FLOAT_RECT& vpRect = ViewportRegion;
|
2014-12-26 15:16:09 +00:00
|
|
|
|
|
|
|
C4FragTransform trans;
|
|
|
|
// Clip offset
|
2015-01-07 11:05:21 +00:00
|
|
|
assert(outRect.Hgt >= clipRect.y + clipRect.Hgt);
|
|
|
|
trans.Translate(-clipRect.x, -(outRect.Hgt - clipRect.y - clipRect.Hgt));
|
2014-12-26 15:16:09 +00:00
|
|
|
// Clip normalization (0,0 -> 1,1)
|
|
|
|
trans.Scale(1.0f / clipRect.Wdt, 1.0f / clipRect.Hgt);
|
2015-01-07 16:29:48 +00:00
|
|
|
// Viewport/Landscape normalization
|
|
|
|
trans.Scale(vpRect.right - vpRect.left, vpRect.bottom - vpRect.top);
|
|
|
|
// Offset between viewport and light texture
|
|
|
|
trans.Translate(vpRect.left - lightRect.x, vpRect.top - lightRect.y);
|
2014-12-26 15:16:09 +00:00
|
|
|
// Light surface normalization
|
2015-12-28 18:29:13 +00:00
|
|
|
trans.Scale(1.0f / pSurface->Wdt, 1.0f / pSurface->Hgt);
|
2014-12-26 15:16:09 +00:00
|
|
|
// Light surface Y offset
|
2015-12-28 18:29:13 +00:00
|
|
|
trans.Translate(0.0f, 1.0f - (float)(lightRect.Hgt) / (float)pSurface->Hgt);
|
2014-12-26 15:16:09 +00:00
|
|
|
|
|
|
|
// Extract matrix
|
|
|
|
trans.Get2x3(lightTransform);
|
2014-12-22 16:15:46 +00:00
|
|
|
}
|