1
0
forked from 0ad/0ad

Moves simple water from fixed pipeline to shader pipelines (ARB/GLSL).

Commented By: Stan
Reported By: Freagarach
Tested By: Freagarach, Stan
Differential Revision: https://code.wildfiregames.com/D3059
This was SVN commit r24129.
This commit is contained in:
Vladislav Belov 2020-11-04 22:25:08 +00:00
parent e98fce58a6
commit ad965e167d
10 changed files with 151 additions and 65 deletions

View File

@ -0,0 +1,17 @@
!!ARBfp1.0
PARAM color = program.local[2];
ATTRIB v_coords = fragment.texcoord[0];
ATTRIB v_losCoords = fragment.texcoord[1];
TEMP diffuse;
TEX diffuse, v_coords, texture[0], 2D;
MUL diffuse, diffuse, color;
TEMP los;
TEX los, v_losCoords, texture[1], 2D;
MUL diffuse, diffuse, los.a;
MOV result.color, diffuse;
END

View File

@ -0,0 +1,38 @@
!!ARBvp1.0
ATTRIB position = vertex.position;
PARAM transform[4] = { program.local[0..3] };
PARAM losMatrix[4] = { program.local[4..7] };
PARAM time = program.local[8];
OUTPUT v_coords = result.texcoord[0];
OUTPUT v_losCoords = result.texcoord[1];
DP4 result.position.x, transform[0], position;
DP4 result.position.y, transform[1], position;
DP4 result.position.z, transform[2], position;
DP4 result.position.w, transform[3], position;
TEMP tx;
MUL tx, time, -0.01235; // 1.0 / 81.0
FRC tx, tx;
TEMP tz;
MUL tz, time, -0.02941; // 1.0 / 34.0
FRC tz, tz;
TEMP offset;
MOV offset.x, tx;
MOV offset.z, tz;
TEMP coords;
// Divide by period 16 and add offset.
MAD coords, position, 0.0625, offset;
ADD coords, coords, offset;
MOV v_coords, coords.xzxz;
TEMP losCoords;
DP4 losCoords.x, losMatrix[0], position;
DP4 losCoords.y, losMatrix[1], position;
MOV v_losCoords, losCoords.xyxy;
END

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<program type="arb">
<vertex file="arb/water_simple.vp">
<stream name="pos"/>
<uniform name="transform" loc="0" type="mat4"/>
<uniform name="losMatrix" loc="4" type="mat4"/>
<uniform name="time" loc="8" type="float"/>
</vertex>
<fragment file="arb/water_simple.fp">
<uniform name="baseTex" loc="0" type="sampler2D"/>
<uniform name="losMap" loc="1" type="sampler2D"/>
<uniform name="color" loc="2" type="vec4"/>
</fragment>
</program>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require shaders="arb"/>
<pass shader="arb/water_simple"/>
</technique>
<technique>
<require shaders="glsl"/>
<pass shader="glsl/water_simple"/>
</technique>
</effect>

View File

@ -22,7 +22,6 @@ uniform vec3 fogColor;
uniform vec2 fogParams;
uniform vec2 screenSize;
uniform float time;
varying float moddedTime;
varying vec3 worldPos;
@ -354,7 +353,7 @@ void main()
#if USE_FOG
color = get_fog(color);
#endif
float alpha = refrColor.a;
float losMod = texture2D(losMap, losCoords.st).a;
losMod = losMod < 0.03 ? 0.0 : losMod;

View File

@ -0,0 +1,15 @@
#version 110
uniform sampler2D baseTex;
uniform sampler2D losMap;
uniform vec3 color;
varying vec2 v_coords;
varying vec2 v_losCoords;
void main()
{
float losMod = texture2D(losMap, v_losCoords.st).a;
losMod = losMod < 0.03 ? 0.0 : losMod;
gl_FragColor = vec4(texture2D(baseTex, v_coords).rgb * color * losMod, 1.0);
}

View File

@ -0,0 +1,22 @@
#version 110
attribute vec3 a_vertex;
uniform mat4 transform;
uniform mat4 losMatrix;
uniform float time;
varying vec2 v_coords;
varying vec2 v_losCoords;
void main()
{
// Shift the texture coordinates by these amounts to make the water "flow"
float tx = -mod(time, 81.0) / 81.0;
float tz = -mod(time, 34.0) / 34.0;
float repeatPeriod = 16.0;
v_coords = a_vertex.xz / repeatPeriod + vec2(tx, tz);
v_losCoords = (losMatrix * vec4(a_vertex, 1.0)).rg;
gl_Position = transform * vec4(a_vertex, 1.0);
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<program type="glsl">
<vertex file="glsl/water_simple.vs">
<stream name="pos"/>
<attrib name="a_vertex" semantics="gl_Vertex"/>
</vertex>
<fragment file="glsl/water_simple.fs"/>
</program>

View File

@ -150,6 +150,7 @@ X(time)
X(tint)
X(transform)
X(translation)
X(water_simple)
X(waterEffectsTex)
X(waterTex)
X(waveTex)

View File

@ -881,57 +881,18 @@ void TerrainRenderer::RenderSimpleWater(int cullGroup)
double period = 1.6f;
int curTex = (int)(time*60/period) % 60;
WaterMgr->m_WaterTexture[curTex]->Bind();
CShaderTechniquePtr waterSimpleTech =
g_Renderer.GetShaderManager().LoadEffect(str_water_simple);
waterSimpleTech->BeginPass();
CShaderProgramPtr waterSimpleShader = waterSimpleTech->GetShader();
// Shift the texture coordinates by these amounts to make the water "flow"
float tx = -fmod(time, 81.0)/81.0;
float ty = -fmod(time, 34.0)/34.0;
float repeatPeriod = 16.0f;
// Perform the shifting by using texture coordinate generation
GLfloat texgenS0[4] = { 1/repeatPeriod, 0, 0, tx };
GLfloat texgenT0[4] = { 0, 0, 1/repeatPeriod, ty };
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, texgenS0);
glTexGenfv(GL_T, GL_OBJECT_PLANE, texgenT0);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
// Set up texture environment to multiply vertex RGB by texture RGB.
GLfloat waterColor[4] = { WaterMgr->m_WaterColor.r, WaterMgr->m_WaterColor.g, WaterMgr->m_WaterColor.b, 1.0f };
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, waterColor);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
// Multiply by LOS texture
losTexture.BindTexture(1);
CMatrix3D losMatrix = losTexture.GetTextureMatrix();
GLfloat texgenS1[4] = { losMatrix[0], losMatrix[4], losMatrix[8], losMatrix[12] };
GLfloat texgenT1[4] = { losMatrix[1], losMatrix[5], losMatrix[9], losMatrix[13] };
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, texgenS1);
glTexGenfv(GL_T, GL_OBJECT_PLANE, texgenT1);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA);
CShaderProgramPtr dummyShader = GetDummyShader();
dummyShader->Bind();
dummyShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
dummyShader->Uniform(str_color, CColor(0.0f, 0.0f, 0.0f, 1.0f));
waterSimpleShader->Bind();
waterSimpleShader->BindTexture(str_baseTex, WaterMgr->m_WaterTexture[curTex]);
waterSimpleShader->BindTexture(str_losMap, losTexture.GetTextureSmooth());
waterSimpleShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
waterSimpleShader->Uniform(str_losMatrix, losTexture.GetTextureMatrix());
waterSimpleShader->Uniform(str_time, static_cast<float>(time));
waterSimpleShader->Uniform(str_color, WaterMgr->m_WaterColor);
glEnableClientState(GL_VERTEX_ARRAY);
@ -939,27 +900,18 @@ void TerrainRenderer::RenderSimpleWater(int cullGroup)
for (size_t i = 0; i < visiblePatches.size(); ++i)
{
CPatchRData* data = visiblePatches[i];
data->RenderWater(dummyShader, false, true);
data->RenderWater(waterSimpleShader, false, true);
}
glDisableClientState(GL_VERTEX_ARRAY);
dummyShader->Unbind();
waterSimpleShader->Unbind();
g_Renderer.BindTexture(1, 0);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
pglActiveTextureARB(GL_TEXTURE0_ARB);
// Clean up the texture matrix and blend mode
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_TEXTURE_2D);
waterSimpleTech->EndPass();
#endif
}