smooth LOS
This was SVN commit r12304.
This commit is contained in:
parent
4b119b9bd1
commit
648e68e49c
@ -62,12 +62,15 @@ force_s3tc_enable = true
|
||||
renderpath = default
|
||||
|
||||
;;;;; EXPERIMENTAL ;;;;;
|
||||
; Prefer GLSL shaders over ARB shaders (not recommended). REQUIRES gentangents=true
|
||||
; Prefer GLSL shaders over ARB shaders (not recommended). REQUIRES gentangents=true.
|
||||
preferglsl = false
|
||||
|
||||
; Generate tangents for normal and parallax mapping. REQUIRES preferglsl=true. Incompatible with gpuskinning.
|
||||
gentangents = false
|
||||
|
||||
; Use smooth LOS interpolation; REQUIRES preferglsl=true.
|
||||
smoothlos = false
|
||||
|
||||
; Quality level of shader effects (set to 0 for lowest)
|
||||
materialmgr.quality = 9.0
|
||||
|
||||
|
9
binaries/data/mods/public/shaders/effects/los_interp.xml
Normal file
9
binaries/data/mods/public/shaders/effects/los_interp.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<effect>
|
||||
|
||||
<technique>
|
||||
<require shaders="glsl"/>
|
||||
<pass shader="glsl/los_interp"/>
|
||||
</technique>
|
||||
|
||||
</effect>
|
17
binaries/data/mods/public/shaders/glsl/los_interp.fs
Normal file
17
binaries/data/mods/public/shaders/glsl/los_interp.fs
Normal file
@ -0,0 +1,17 @@
|
||||
#version 110
|
||||
|
||||
varying vec2 v_tex;
|
||||
|
||||
uniform sampler2D losTex1, losTex2;
|
||||
|
||||
uniform vec3 delta;
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
float los2 = texture2D(losTex1, v_tex).a;
|
||||
float los1 = texture2D(losTex2, v_tex).a;
|
||||
|
||||
gl_FragColor.a = mix(los1, los2, clamp(delta.r, 0.0, 1.0));
|
||||
}
|
||||
|
19
binaries/data/mods/public/shaders/glsl/los_interp.vs
Normal file
19
binaries/data/mods/public/shaders/glsl/los_interp.vs
Normal file
@ -0,0 +1,19 @@
|
||||
#version 110
|
||||
|
||||
uniform mat4 transform;
|
||||
uniform vec2 losTransform;
|
||||
|
||||
varying vec2 v_tex;
|
||||
|
||||
attribute vec3 a_vertex;
|
||||
attribute vec2 a_uv0;
|
||||
|
||||
|
||||
varying vec2 v_los;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = gl_Vertex;
|
||||
|
||||
v_tex = vec2(gl_MultiTexCoord0);
|
||||
}
|
13
binaries/data/mods/public/shaders/glsl/los_interp.xml
Normal file
13
binaries/data/mods/public/shaders/glsl/los_interp.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<program type="glsl">
|
||||
|
||||
<vertex file="glsl/los_interp.vs">
|
||||
<stream name="pos"/>
|
||||
<stream name="uv0"/>
|
||||
<attrib name="a_vertex" semantics="gl_Vertex"/>
|
||||
<attrib name="a_uv0" semantics="gl_MultiTexCoord0"/>
|
||||
</vertex>
|
||||
|
||||
<fragment file="glsl/los_interp.fs"/>
|
||||
|
||||
</program>
|
@ -19,11 +19,14 @@
|
||||
|
||||
#include "LOSTexture.h"
|
||||
|
||||
#include "graphics/ShaderManager.h"
|
||||
#include "graphics/Terrain.h"
|
||||
#include "lib/bits.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "renderer/TimeManager.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpRangeManager.h"
|
||||
#include "simulation2/components/ICmpTerrain.h"
|
||||
@ -48,8 +51,23 @@ The blurred bitmap is then uploaded into a GL texture for use by the renderer.
|
||||
static const size_t g_BlurSize = 7;
|
||||
|
||||
CLOSTexture::CLOSTexture(CSimulation2& simulation) :
|
||||
m_Simulation(simulation), m_Dirty(true), m_Texture(0), m_MapSize(0), m_TextureSize(0)
|
||||
m_Simulation(simulation), m_Dirty(true), m_Texture(0), m_smoothFbo(0), m_MapSize(0), m_TextureSize(0), whichTex(true)
|
||||
{
|
||||
if (g_Renderer.m_Options.m_SmoothLOS)
|
||||
{
|
||||
m_smoothShader = g_Renderer.GetShaderManager().LoadEffect("los_interp");
|
||||
CShaderProgramPtr shader = m_smoothShader->GetShader();
|
||||
|
||||
if (m_smoothShader && shader)
|
||||
{
|
||||
pglGenFramebuffersEXT(1, &m_smoothFbo);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(L"Failed to load SmoothLOS shader, disabling.");
|
||||
g_Renderer.m_Options.m_SmoothLOS = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLOSTexture::~CLOSTexture()
|
||||
@ -61,6 +79,11 @@ CLOSTexture::~CLOSTexture()
|
||||
void CLOSTexture::DeleteTexture()
|
||||
{
|
||||
glDeleteTextures(1, &m_Texture);
|
||||
if (g_Renderer.m_Options.m_SmoothLOS)
|
||||
{
|
||||
glDeleteTextures(1, &m_TextureSmooth1);
|
||||
glDeleteTextures(1, &m_TextureSmooth2);
|
||||
}
|
||||
m_Texture = 0;
|
||||
}
|
||||
|
||||
@ -80,6 +103,71 @@ void CLOSTexture::BindTexture(int unit)
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
}
|
||||
|
||||
GLuint CLOSTexture::GetTextureSmooth()
|
||||
{
|
||||
if (!g_Renderer.m_Options.m_SmoothLOS)
|
||||
return GetTexture();
|
||||
else
|
||||
return whichTex ? m_TextureSmooth1 : m_TextureSmooth2;
|
||||
}
|
||||
|
||||
void CLOSTexture::InterpolateLOS()
|
||||
{
|
||||
if (!g_Renderer.m_Options.m_SmoothLOS)
|
||||
return;
|
||||
|
||||
if (m_Dirty)
|
||||
{
|
||||
RecomputeTexture(0);
|
||||
m_Dirty = false;
|
||||
}
|
||||
|
||||
GLint originalFBO;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originalFBO);
|
||||
|
||||
pglBindFramebufferEXT(GL_FRAMEBUFFER, m_smoothFbo);
|
||||
pglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
whichTex ? m_TextureSmooth2 : m_TextureSmooth1, 0);
|
||||
|
||||
GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
LOGWARNING(L"LOS framebuffer object incomplete: 0x%04X", status);
|
||||
}
|
||||
|
||||
m_smoothShader->BeginPass();
|
||||
CShaderProgramPtr shader = m_smoothShader->GetShader();
|
||||
|
||||
shader->Bind();
|
||||
|
||||
shader->BindTexture("losTex1", m_Texture);
|
||||
shader->BindTexture("losTex2", whichTex ? m_TextureSmooth1 : m_TextureSmooth2);
|
||||
|
||||
shader->Uniform("delta", (float)g_Renderer.GetTimeManager().GetFrameDelta() * 4.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
glViewport(0, 0, m_TextureSize, m_TextureSize);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
glTexCoord2f(1.0, 1.0); glVertex2f(1,1);
|
||||
glTexCoord2f(0.0, 1.0); glVertex2f(-1,1);
|
||||
glTexCoord2f(0.0, 0.0); glVertex2f(-1,-1);
|
||||
glTexCoord2f(1.0, 0.0); glVertex2f(1,-1);
|
||||
glEnd();
|
||||
|
||||
glPopAttrib();
|
||||
shader->Unbind();
|
||||
m_smoothShader->EndPass();
|
||||
|
||||
pglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
|
||||
pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, originalFBO);
|
||||
|
||||
whichTex = !whichTex;
|
||||
}
|
||||
|
||||
|
||||
GLuint CLOSTexture::GetTexture()
|
||||
{
|
||||
if (m_Dirty)
|
||||
@ -114,20 +202,41 @@ void CLOSTexture::ConstructTexture(int unit)
|
||||
m_TextureSize = (GLsizei)round_up_to_pow2((size_t)m_MapSize + g_BlurSize - 1);
|
||||
|
||||
glGenTextures(1, &m_Texture);
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
|
||||
// Initialise texture with SoD colour, for the areas we don't
|
||||
// overwrite with glTexSubImage2D later
|
||||
u8* texData = new u8[m_TextureSize * m_TextureSize];
|
||||
memset(texData, 0x00, m_TextureSize * m_TextureSize);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_TextureSize, m_TextureSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texData);
|
||||
delete[] texData;
|
||||
u8* texData = new u8[m_TextureSize * m_TextureSize * 4];
|
||||
memset(texData, 0x00, m_TextureSize * m_TextureSize * 4);
|
||||
|
||||
if (g_Renderer.m_Options.m_SmoothLOS)
|
||||
{
|
||||
glGenTextures(1, &m_TextureSmooth1);
|
||||
glGenTextures(1, &m_TextureSmooth2);
|
||||
|
||||
g_Renderer.BindTexture(unit, m_TextureSmooth1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureSize, m_TextureSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texData);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
g_Renderer.BindTexture(unit, m_TextureSmooth2);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureSize, m_TextureSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texData);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_TextureSize, m_TextureSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texData);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
delete[] texData;
|
||||
|
||||
{
|
||||
// Texture matrix: We want to map
|
||||
// world pos (0, y, 0) (i.e. first vertex)
|
||||
@ -166,8 +275,12 @@ void CLOSTexture::RecomputeTexture(int unit)
|
||||
DeleteTexture();
|
||||
}
|
||||
|
||||
bool recreated = false;
|
||||
if (!m_Texture)
|
||||
{
|
||||
ConstructTexture(unit);
|
||||
recreated = true;
|
||||
}
|
||||
|
||||
PROFILE("recompute LOS texture");
|
||||
|
||||
@ -182,6 +295,14 @@ void CLOSTexture::RecomputeTexture(int unit)
|
||||
|
||||
GenerateBitmap(los, &losData[0], m_MapSize, m_MapSize);
|
||||
|
||||
if (g_Renderer.m_Options.m_SmoothLOS && recreated)
|
||||
{
|
||||
g_Renderer.BindTexture(unit, m_TextureSmooth1);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_MapSize + g_BlurSize - 1, m_MapSize + g_BlurSize - 1, GL_ALPHA, GL_UNSIGNED_BYTE, &losData[0]);
|
||||
g_Renderer.BindTexture(unit, m_TextureSmooth2);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_MapSize + g_BlurSize - 1, m_MapSize + g_BlurSize - 1, GL_ALPHA, GL_UNSIGNED_BYTE, &losData[0]);
|
||||
}
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_MapSize + g_BlurSize - 1, m_MapSize + g_BlurSize - 1, GL_ALPHA, GL_UNSIGNED_BYTE, &losData[0]);
|
||||
}
|
||||
|
@ -20,6 +20,9 @@
|
||||
#include "maths/Matrix3D.h"
|
||||
#include "simulation2/components/ICmpRangeManager.h"
|
||||
|
||||
#include "graphics/ShaderManager.h"
|
||||
|
||||
|
||||
class CSimulation2;
|
||||
|
||||
/**
|
||||
@ -56,6 +59,9 @@ public:
|
||||
*/
|
||||
GLuint GetTexture();
|
||||
|
||||
void InterpolateLOS();
|
||||
GLuint GetTextureSmooth();
|
||||
|
||||
/**
|
||||
* Returns a matrix to map (x,y,z) world coordinates onto (u,v) LOS texture
|
||||
* coordinates, in the form expected by glLoadMatrixf.
|
||||
@ -83,6 +89,12 @@ private:
|
||||
bool m_Dirty;
|
||||
|
||||
GLuint m_Texture;
|
||||
GLuint m_TextureSmooth1, m_TextureSmooth2;
|
||||
|
||||
bool whichTex;
|
||||
|
||||
GLuint m_smoothFbo;
|
||||
CShaderTechniquePtr m_smoothShader;
|
||||
|
||||
ssize_t m_MapSize; // vertexes per side
|
||||
GLsizei m_TextureSize; // texels per side
|
||||
|
@ -95,7 +95,7 @@ void ShaderRenderModifier::BeginPass(const CShaderProgramPtr& shader)
|
||||
if (shader->GetTextureBinding("losTex").Active())
|
||||
{
|
||||
CLOSTexture& los = g_Renderer.GetScene().GetLOSTexture();
|
||||
shader->BindTexture("losTex", los.GetTexture());
|
||||
shader->BindTexture("losTex", los.GetTextureSmooth());
|
||||
// Don't bother sending the whole matrix, we just need two floats (scale and translation)
|
||||
shader->Uniform("losTransform", los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "graphics/Camera.h"
|
||||
#include "graphics/GameView.h"
|
||||
#include "graphics/LightEnv.h"
|
||||
#include "graphics/LOSTexture.h"
|
||||
#include "graphics/MaterialManager.h"
|
||||
#include "graphics/Model.h"
|
||||
#include "graphics/ModelDef.h"
|
||||
@ -435,12 +436,14 @@ CRenderer::CRenderer()
|
||||
m_Options.m_ForceAlphaTest = false;
|
||||
m_Options.m_GPUSkinning = false;
|
||||
m_Options.m_GenTangents = false;
|
||||
m_Options.m_SmoothLOS = false;
|
||||
|
||||
// TODO: be more consistent in use of the config system
|
||||
CFG_GET_USER_VAL("preferglsl", Bool, m_Options.m_PreferGLSL);
|
||||
CFG_GET_USER_VAL("forcealphatest", Bool, m_Options.m_ForceAlphaTest);
|
||||
CFG_GET_USER_VAL("gpuskinning", Bool, m_Options.m_GPUSkinning);
|
||||
CFG_GET_USER_VAL("gentangents", Bool, m_Options.m_GenTangents);
|
||||
CFG_GET_USER_VAL("smoothlos", Bool, m_Options.m_SmoothLOS);
|
||||
|
||||
#if CONFIG2_GLES
|
||||
// Override config option since GLES only supports GLSL
|
||||
@ -1359,6 +1362,8 @@ void CRenderer::RenderSubmissions()
|
||||
{
|
||||
PROFILE3("render submissions");
|
||||
|
||||
GetScene().GetLOSTexture().InterpolateLOS();
|
||||
|
||||
CShaderDefines context = m->globalContext;
|
||||
|
||||
ogl_WarnIfError();
|
||||
|
@ -132,6 +132,7 @@ public:
|
||||
bool m_GPUSkinning;
|
||||
bool m_Silhouettes;
|
||||
bool m_GenTangents;
|
||||
bool m_SmoothLOS;
|
||||
} m_Options;
|
||||
|
||||
struct Caps {
|
||||
|
@ -477,7 +477,7 @@ void TerrainRenderer::PrepareShader(const CShaderProgramPtr& shader, ShadowMap*
|
||||
shader->Uniform("sunColor", lightEnv.m_SunColor);
|
||||
|
||||
CLOSTexture& los = g_Renderer.GetScene().GetLOSTexture();
|
||||
shader->BindTexture("losTex", los.GetTexture());
|
||||
shader->BindTexture("losTex", los.GetTextureSmooth());
|
||||
shader->Uniform("losTransform", los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f);
|
||||
|
||||
shader->Uniform("ambient", lightEnv.m_TerrainAmbientColor);
|
||||
@ -709,7 +709,7 @@ bool TerrainRenderer::RenderFancyWater()
|
||||
m->fancyWaterShader->BindTexture("reflectionMap", WaterMgr->m_ReflectionTexture);
|
||||
m->fancyWaterShader->BindTexture("refractionMap", WaterMgr->m_RefractionTexture);
|
||||
|
||||
m->fancyWaterShader->BindTexture("losMap", losTexture.GetTexture());
|
||||
m->fancyWaterShader->BindTexture("losMap", losTexture.GetTextureSmooth());
|
||||
|
||||
const CLightEnv& lightEnv = g_Renderer.GetLightEnv();
|
||||
m->fancyWaterShader->Uniform("ambient", lightEnv.m_TerrainAmbientColor);
|
||||
|
@ -617,7 +617,13 @@ void CCmpVisualActor::UpdateVisibility()
|
||||
else
|
||||
{
|
||||
CmpPtr<ICmpRangeManager> cmpRangeManager(GetSimContext(), SYSTEM_ENTITY);
|
||||
m_Visibility = cmpRangeManager->GetLosVisibility(GetEntityId(), GetSimContext().GetCurrentDisplayedPlayer());
|
||||
// Uncomment the following lines to prevent the models from popping into existence
|
||||
// near the LOS boundary. Is rather resource intensive.
|
||||
//if (cmpVision->GetRetainInFog())
|
||||
// m_Visibility = ICmpRangeManager::VIS_VISIBLE;
|
||||
//else
|
||||
m_Visibility = cmpRangeManager->GetLosVisibility(GetEntityId(),
|
||||
GetSimContext().GetCurrentDisplayedPlayer());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user