Make water specular more visible and fixes a few cases where it would actually hardly appear when it should.

Adds the ability to access an element in a dropdown box by typing the
first letters (Refs #1532).

This was SVN commit r13556.
This commit is contained in:
wraitii 2013-07-14 12:17:07 +00:00
parent 408c30e061
commit 595c964d77
5 changed files with 84 additions and 21 deletions

View File

@ -111,6 +111,10 @@ void main()
float wavyFactor = waviness * 0.125;
l = -sunDir;
v = normalize(cameraPos - worldPos);
h = normalize(l + v);
// always done cause this is also used, even when not using normals, by the refraction.
vec3 ww = texture2D(normalMap, (gl_TexCoord[0].st) * mix(2.0,0.8,waviness/10.0) +gl_TexCoord[0].zw).xzy;
@ -125,20 +129,15 @@ void main()
#else
n = normalize(ww - vec3(0.5, 0.5, 0.5));
#endif
ndoth = dot( mix(vec3(0.0,1.0,0.0),n,clamp(wavyFactor * v.y * 8.0,0.05,1.0)) ,h);
n = mix(vec3(0.0,1.0,0.0),n,wavyFactor);
#else
n = vec3(0.0,1.0,0.0);
#endif
l = -sunDir;
v = normalize(cameraPos - worldPos);
h = normalize(l + v);
ndotl = (dot(n, l) + 1.0)/2.0;
ndoth = dot(n, h);
ndotv = dot(n, v);
#if USE_REAL_DEPTH
// Don't change these two. They should match the values in the config (TODO: dec uniforms).
float zNear = 2.0;
@ -205,8 +204,8 @@ void main()
refrColor = (0.5 + 0.5*ndotl) * mix(color,mix(refColor,refColor*tint,colorExtinction),luminance*luminance);
#else
refrCoords = clamp( (0.5*gl_TexCoord[2].xy - n.xz * distoFactor) / gl_TexCoord[2].w + 0.5,0.0,1.0); // Unbias texture coords
// fake it. It won't look as good but it will give a similar result.
float perceivedDepth = waterDepth / v.y;
// cleverly get the perceived depth based on camera tilting (if horizontal, it's likely we will have more water to look at).
float perceivedDepth = waterDepth / (v.y*v.y);
vec3 refColor = texture2D(refractionMap, refrCoords).rgb;
float luminance = (1.0 - clamp((perceivedDepth/mix(300.0,1.0, pow(murkiness,0.2) )), 0.0, 1.0));
float colorExtinction = clamp(perceivedDepth*murkiness/5.0,0.0,1.0);
@ -215,11 +214,11 @@ void main()
#else
float alphaCoeff = 0.0;
#if USE_REAL_DEPTH
float luminance = clamp((waterDepth2/mix(300.0,1.0, pow(murkiness,0.2) )), 0.0, 1.0);
float luminance = clamp((waterDepth2/mix(150.0,2.0, pow(murkiness,0.2) )), 0.0, 1.0);
alphaCoeff = mix(mix(0.0,3.0 - (tint.r + tint.g + tint.b),clamp(waterDepth2*murkiness/5.0,0.0,1.0)),1.0,luminance*luminance);
#else
float luminance = clamp(((waterDepth / v.y)/mix(300.0,1.0, pow(murkiness,0.2) )), 0.0, 1.0);
alphaCoeff = mix(mix(0.0,3.0 - (tint.r + tint.g + tint.b),clamp((waterDepth / v.y)*murkiness/5.0,0.0,1.0)),1.0,luminance*luminance);
float luminance = clamp(((waterDepth / v.y)/mix(150.0,2.0, pow(murkiness,0.2) )), 0.0, 1.0);
alphaCoeff = mix(mix(0.0,3.0 - (tint.r + tint.g + tint.b),clamp(perceivedDepth*murkiness/5.0,0.0,1.0)),1.0,luminance*luminance);
#endif
refrColor = color;
#endif
@ -230,14 +229,14 @@ void main()
#endif
#if USE_REFLECTION
reflCoords = clamp( (0.5*gl_TexCoord[1].xy + 10.0*n.xz) / gl_TexCoord[1].w + 0.5,0.0,1.0); // Unbias texture coords
reflCoords = clamp( (0.5*gl_TexCoord[1].xy + distoFactor*1.5*n.xz) / gl_TexCoord[1].w + 0.5,0.0,1.0); // Unbias texture coords
reflColor = mix(texture2D(reflectionMap, reflCoords).rgb, sunColor * reflectionTint, reflectionTintStrength);
#else
// TODO: implement some sort of skybox rendering.
reflColor = mix( (sunColor + vec3(0.565,0.843,0.961))/1.85, reflectionTint, reflectionTintStrength);
#endif
specular = pow(ndoth, shininess) * sunColor * specularStrength;
specular = pow(ndoth, mix(50.0,450.0, v.y*2.0)) * sunColor * 1.5;
losMod = texture2D(losMap, gl_TexCoord[3].st).a;
losMod = losMod < 0.03 ? 0.0 : losMod;
@ -247,15 +246,15 @@ void main()
float shadow = get_shadow(vec4(v_shadow.xy - 8.0*waviness*n.xz, v_shadow.zw));
float fresShadow = mix(fresnel, fresnel*shadow, 0.05 + (murkiness * 0.15));
#if USE_FOAM
colour = mix(refrColor*(shadow/5.0 + 0.8) + fresnel*shadow*specular, reflColor + fresnel*shadow*specular, fresShadow) + max(ndotl,0.4)*(finalFoam)*(shadow/2.0 + 0.5);
colour = mix(refrColor*(shadow/5.0 + 0.8), reflColor, fresShadow) + max(ndotl,0.4)*(finalFoam)*(shadow/2.0 + 0.5);
#else
colour = mix(refrColor*(shadow/5.0 + 0.8) + fresnel*shadow*specular, reflColor + fresnel*shadow*specular, fresShadow);
colour = mix(refrColor*(shadow/5.0 + 0.8), reflColor, fresShadow);
#endif
#else
#if USE_FOAM
colour = mix(refrColor + fresnel*specular, reflColor + fresnel*specular, fresnel) + max(ndotl,0.4)*(finalFoam);
colour = mix(refrColor, reflColor, fresnel) + max(ndotl,0.4)*(finalFoam);
#else
colour = mix(refrColor + fresnel*specular, reflColor + fresnel*specular, fresnel);
colour = mix(refrColor, reflColor, fresnel);
#endif
#endif
@ -267,6 +266,12 @@ void main()
#endif
#endif
#if USE_SHADOWS && USE_SHADOW
colour += shadow*specular;
#else
colour += specular;
#endif
gl_FragColor.rgb = get_fog(colour) * losMod;
#if USE_REAL_DEPTH

View File

@ -25,6 +25,7 @@ CDropDown
#include "lib/external_libraries/libsdl.h"
#include "lib/ogl.h"
#include "lib/timer.h"
#include "soundmanager/ISoundManager.h"
@ -186,7 +187,7 @@ void CDropDown::HandleMessage(SGUIMessage &Message)
GUI<int>::GetSetting(this, "selected", m_ElementHighlight);
// Start at the position of the selected item, if possible.
GetScrollBar(0).SetPos( m_ItemsYPositions.empty() ? 0 : m_ItemsYPositions[m_ElementHighlight] );
GetScrollBar(0).SetPos( m_ItemsYPositions.empty() ? 0 : m_ItemsYPositions[m_ElementHighlight] - 60);
CStrW soundPath;
if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_opened", soundPath) == PSRETURN_OK && !soundPath.empty())
@ -277,6 +278,54 @@ InReaction CDropDown::ManuallyHandleEvent(const SDL_Event_* ev)
break;
default:
// If we have imputed a character try to get the closest element to it.
// TODO: not too nice and doesn't deal with dashes.
if (m_Open && ((szChar >= SDLK_a && szChar <= SDLK_z) || szChar == SDLK_SPACE
|| (szChar >= SDLK_0 && szChar <= SDLK_9) || (szChar >= SDLK_KP0 && szChar <= SDLK_KP9)))
{
// arbitrary 1 second limit to add to string or start fresh.
// maximal amount of characters is 100, which imo is far more than enough.
if (timer_Time() - m_TimeOfLastInput > 1.0 || m_InputBuffer.length() >= 100)
m_InputBuffer = szChar;
else
m_InputBuffer += szChar;
m_TimeOfLastInput = timer_Time();
CGUIList *pList;
GUI<CGUIList>::GetSettingPointer(this, "list", pList);
// let's look for the closest element
// basically it's alphabetic order and "as many letters as we can get".
int closest = -1;
int bestIndex = -1;
int difference = 1250;
for (int i=0; i<(int)pList->m_Items.size(); ++i)
{
int indexOfDifference = 0;
int diff = 0;
for (size_t j=0; j < m_InputBuffer.length(); ++j)
{
diff = abs(pList->m_Items[i].GetOriginalString().LowerCase()[j] - (int)m_InputBuffer[j]);
if (diff == 0)
indexOfDifference = j+1;
else
break;
}
if (indexOfDifference > bestIndex || (indexOfDifference >= bestIndex && diff < difference))
{
bestIndex = indexOfDifference;
closest = i;
difference = diff;
}
}
// let's select the closest element. There should basically always be one.
if (closest != -1)
{
GUI<int>::SetSetting(this, "selected", closest);
update_highlight = true;
GetScrollBar(0).SetPos(m_ItemsYPositions[closest] - 60);
}
}
break;
}

View File

@ -127,6 +127,14 @@ protected:
// it is set to "selected", but then when moving the mouse it will
// change.
int m_ElementHighlight;
// Stores any text entered by the user for quick access to an element
// (ie if you type "acro" it will take you to acropolis).
std::string m_InputBuffer;
// used to know if we want to restart anew or add to m_inputbuffer.
double m_TimeOfLastInput;
};
#endif

View File

@ -652,7 +652,7 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, ShadowMap*
WaterMgr->updateQuality();
// If we're using fancy water, make sure its shader is loaded
if (!m->fancyWaterShader || (WaterMgr->m_NeedsReloading && !g_AtlasGameLoop->running))
if (!m->fancyWaterShader || WaterMgr->m_NeedsReloading)
{
if(WaterMgr->m_WaterNormal)
defines.Add("USE_NORMALS","1");

View File

@ -378,7 +378,8 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
{
for (int yy = -4; yy <= 4; yy += 2)
{
normal += normals[(j+yy)*mapSize + (i+xx)];
if (j+yy < mapSize && i+xx < mapSize && i+xx >= 0 && j+yy >= 0)
normal += normals[(j+yy)*mapSize + (i+xx)];
if (terrain->GetVertexGroundLevel(i+xx,j+yy) < heightmap[j*mapSize + i]*HEIGHT_SCALE)
waterRaise += heightmap[j*mapSize + i]*HEIGHT_SCALE - terrain->GetVertexGroundLevel(i+xx,j+yy);
}