1
1
forked from 0ad/0ad

Water and waterfall shaders, materials and examples.

This was SVN commit r12643.
This commit is contained in:
myconid 2012-09-08 18:56:13 +00:00
parent 1fec7c382b
commit 779a33ee30
28 changed files with 681 additions and 8 deletions

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<actor version="1">
<castshadow/>
<group>
<variant frequency="100" name="Base">
<animations/>
<mesh>test/reservoir.dae</mesh>
<props>
<prop actor="temp/reservoir_water.xml" attachpoint="root"/>
</props>
<textures>
<texture file="structural/rome_struct.png" name="baseTex"/>
</textures>
</variant>
</group>
</actor>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<actor version="1">
<group>
<variant frequency="100" name="Base">
<animations/>
<mesh>test/reservoir-water.dae</mesh>
<props/>
<textures>
<texture file="structural/rome_struct.png" name="baseTex"/>
</textures>
</variant>
</group>
<material>player_water.xml</material>
</actor>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<actor version="1">
<group>
<variant frequency="100" name="water_plane">
<animations/>
<mesh>test/waterplane.dae</mesh>
<props/>
<textures>
<texture file="structural/rome_struct.png" name="baseTex"/>
</textures>
</variant>
</group>
<material>player_water.xml</material>
</actor>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<actor version="1">
<group>
<variant frequency="100" name="waterfall">
<animations/>
<mesh>test/waterfall.dae</mesh>
<props/>
<textures>
<texture file="temp/waterfall.png" name="baseTex"/>
</textures>
</variant>
</group>
<material>waterfall.xml</material>
</actor>

View File

@ -3,7 +3,7 @@
<shader effect="model_transparent"/>
<alpha_blending/>
<define name="USE_TRANSPARENT" value="1"/>
<renderquery name="time"/>
<renderquery name="sim_time"/>
<define name="USE_WIND" value="1"/>
<uniform name="windData" value="1.0 1.0"/>
</material>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<material>
<shader effect="model_water"/>
<renderquery name="water_tex"/>
<renderquery name="sky_cube"/>
<renderquery name="sim_time"/>
<uniform name="translation" value="0.05 -0.05"/>
<uniform name="shininess" value="32.0"/>
<uniform name="specularStrength" value="1.5"/>
<uniform name="waviness" value="0.5"/>
<uniform name="waterTint" value="0.2 0.3 0.2"/>
<uniform name="murkiness" value="0.6"/>
<uniform name="reflectionTint" value="0.3 0.4 0.3"/>
<uniform name="reflectionTintStrength" value="0.1"/>
</material>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<material>
<shader effect="model"/>
<renderquery name="time"/>
<renderquery name="sim_time"/>
<define name="USE_WIND" value="1"/>
<uniform name="windData" value="1.0 1.0"/>
</material>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<material>
<shader effect="model_waterfall"/>
<alpha_blending/>
<renderquery name="sim_time"/>
<uniform name="translation" value="0.0 -0.4"/>
<uniform name="specularPower" value="16.0"/>
<uniform name="specularColor" value="1.0 1.0 1.0"/>
</material>

Binary file not shown.

BIN
binaries/data/mods/public/art/meshes/test/reservoir.dae (Stored with Git LFS) Normal file

Binary file not shown.

BIN
binaries/data/mods/public/art/meshes/test/waterfall.dae (Stored with Git LFS) Normal file

Binary file not shown.

BIN
binaries/data/mods/public/art/meshes/test/waterplane.dae (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
binaries/data/mods/public/maps/scenarios/reservoir.xml (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require shaders="glsl"/>
<sort_by_distance/>
<pass shader="glsl/model_water">
<define name="USE_TRANSPARENT" value="1"/>
<define name="USE_SPECULAR" value="1"/>
<define name="USE_NORMAL_MAP" value="1"/>
<define name="USE_INSTANCING" value="1"/>
<define name="REQUIRE_ALPHA_GEQUAL" value="0.05"/>
<blend src="src_alpha" dst="one_minus_src_alpha"/>
<depth func="less" mask="true"/>
</pass>
</technique>
</effect>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require shaders="glsl"/>
<sort_by_distance/>
<pass shader="glsl/model_waterfall">
<define name="USE_TRANSPARENT" value="1"/>
<define name="USE_INSTANCING" value="1"/>
<blend src="src_alpha" dst="one_minus_src_alpha"/>
<depth func="less" mask="false"/>
</pass>
</technique>
</effect>

View File

@ -18,7 +18,7 @@ uniform mat4 instancingTransform;
#endif
#if USE_WIND
uniform vec4 time;
uniform vec4 sim_time;
uniform vec4 windData;
#endif
@ -115,9 +115,9 @@ void main()
vec4 cosVec;
// these determine the speed of the wind's "cosine" waves.
cosVec.x = time.x * modelPos[0] + position.x;
cosVec.y = time.x * modelPos[2] / 3 + instancingTransform[3][0];
cosVec.z = time.x * abswind / 4 + position.z;
cosVec.x = sim_time.x * modelPos[0] + position.x;
cosVec.y = sim_time.x * modelPos[2] / 3 + instancingTransform[3][0];
cosVec.z = sim_time.x * abswind / 4 + position.z;
// calculate "cosines" in parallel, using a smoothed triangle wave
cosVec = fakeCos(cosVec);

View File

@ -0,0 +1,151 @@
#version 120
uniform sampler2D baseTex;
uniform sampler2D losTex;
uniform sampler2D aoTex;
uniform sampler2D normTex;
uniform sampler2D specTex;
uniform sampler2D waterTex;
uniform samplerCube skyCube;
#if USE_SHADOW
#if USE_SHADOW_SAMPLER
uniform sampler2DShadow shadowTex;
#if USE_SHADOW_PCF
uniform vec4 shadowScale;
#endif
#else
uniform sampler2D shadowTex;
#endif
#endif
#if USE_OBJECTCOLOR
uniform vec3 objectColor;
#else
#if USE_PLAYERCOLOR
uniform vec3 playerColor;
#endif
#endif
uniform vec3 shadingColor;
uniform vec3 ambient;
uniform vec3 sunColor;
uniform vec3 sunDir;
uniform vec3 cameraPos;
uniform float shininess;
uniform float specularStrength;
uniform float waviness;
uniform vec3 waterTint;
uniform float murkiness;
uniform vec3 reflectionTint;
uniform float reflectionTintStrength;
float waterDepth = 4.0;
float fullDepth = 5.0; // Depth at which to use full murkiness (shallower water will be clearer)
varying vec4 worldPos;
varying vec4 v_tex;
varying vec4 v_shadow;
varying vec2 v_los;
float get_shadow(vec4 coords)
{
#if USE_SHADOW && !DISABLE_RECEIVE_SHADOWS
#if USE_SHADOW_SAMPLER
#if USE_SHADOW_PCF
vec2 offset = fract(coords.xy - 0.5);
vec4 size = vec4(offset + 1.0, 2.0 - offset);
vec4 weight = (vec4(2.0 - 1.0 / size.xy, 1.0 / size.zw - 1.0) + (coords.xy - offset).xyxy) * shadowScale.zwzw;
return (1.0/9.0)*dot(size.zxzx*size.wwyy,
vec4(shadow2D(shadowTex, vec3(weight.zw, coords.z)).r,
shadow2D(shadowTex, vec3(weight.xw, coords.z)).r,
shadow2D(shadowTex, vec3(weight.zy, coords.z)).r,
shadow2D(shadowTex, vec3(weight.xy, coords.z)).r));
#else
return shadow2D(shadowTex, coords.xyz).r;
#endif
#else
if (coords.z >= 1.0)
return 1.0;
return (coords.z <= texture2D(shadowTex, coords.xy).x ? 1.0 : 0.0);
#endif
#else
return 1.0;
#endif
}
void main()
{
vec3 n, l, h, v; // Normal, light vector, half-vector and view vector (vector to eye)
float ndotl, ndoth, ndotv;
float fresnel;
float t; // Temporary variable
vec2 reflCoords, refrCoords;
vec3 reflColor, refrColor, specular;
float losMod;
vec4 wtex = textureGrad(waterTex, vec3(fract(v_tex.xy), v_tex.z), dFdx(v_tex.xy), dFdy(v_tex.xy));
n = normalize(wtex.xzy - vec3(0.5, 0.5, 0.5));
l = -sunDir;
v = normalize(cameraPos - worldPos.xyz);
h = normalize(l + v);
ndotl = dot(n, l);
ndoth = dot(n, h);
ndotv = dot(n, v);
fresnel = pow(1.0 - ndotv, 0.8); // A rather random Fresnel approximation
//refrCoords = (0.5*gl_TexCoord[2].xy - 0.8*waviness*n.xz) / gl_TexCoord[2].w + 0.5; // Unbias texture coords
//reflCoords = (0.5*gl_TexCoord[1].xy + waviness*n.xz) / gl_TexCoord[1].w + 0.5; // Unbias texture coords
//vec3 dir = normalize(v + vec3(waviness*n.x, 0.0, waviness*n.z));
vec3 eye = reflect(v, n);
vec3 tex = textureCube(skyCube, eye).rgb;
reflColor = mix(tex, sunColor * reflectionTint,
reflectionTintStrength);
//waterDepth = 4.0 + 2.0 * dot(abs(v_tex.zw - 0.5), vec2(0.5));
waterDepth = 4.0;
//refrColor = (0.5 + 0.5*ndotl) * mix(texture2D(refractionMap, refrCoords).rgb, sunColor * tint,
refrColor = (0.5 + 0.5*ndotl) * mix(vec3(0.3), sunColor * waterTint,
murkiness * clamp(waterDepth / fullDepth, 0.0, 1.0)); // Murkiness and tint at this pixel (tweaked based on lighting and depth)
specular = pow(max(0.0, ndoth), shininess) * sunColor * specularStrength;
losMod = texture2D(losTex, v_los).a;
//losMod = texture2D(losMap, gl_TexCoord[3].st).a;
#if USE_SHADOW
float shadow = get_shadow(vec4(v_shadow.xy - 8*waviness*n.xz, v_shadow.zw));
float fresShadow = mix(fresnel, fresnel*shadow, dot(sunColor, vec3(0.16666)));
#else
float fresShadow = fresnel;
#endif
vec3 colour = mix(refrColor + 0.3*specular, reflColor + specular, fresShadow);
gl_FragColor.rgb = colour * losMod;
//gl_FragColor.rgb = mix(refrColor + 0.3*specular, reflColor + specular, fresnel) * losMod;
// Make alpha vary based on both depth (so it blends with the shore) and view angle (make it
// become opaque faster at lower view angles so we can't look "underneath" the water plane)
t = 18.0 * max(0.0, 0.7 - v.y);
gl_FragColor.a = 0.15 * waterDepth * (1.2 + t + fresnel);
}

View File

@ -0,0 +1,74 @@
#if USE_GPU_SKINNING
// Skinning requires GLSL 1.30 for ivec4 vertex attributes
#version 130
#else
#version 120
#endif
uniform mat4 transform;
uniform vec3 cameraPos;
uniform vec3 sunDir;
uniform vec3 sunColor;
uniform vec2 losTransform;
uniform mat4 shadowTransform;
uniform mat4 instancingTransform;
uniform float sim_time;
uniform vec2 translation;
#if USE_SHADOW_SAMPLER && USE_SHADOW_PCF
uniform vec4 shadowScale;
#endif
attribute vec3 a_vertex;
attribute vec3 a_normal;
#if USE_INSTANCING
attribute vec4 a_tangent;
#endif
attribute vec2 a_uv0;
attribute vec2 a_uv1;
#if USE_GPU_SKINNING
const int MAX_INFLUENCES = 4;
const int MAX_BONES = 64;
uniform mat4 skinBlendMatrices[MAX_BONES];
attribute ivec4 a_skinJoints;
attribute vec4 a_skinWeights;
#endif
varying vec4 worldPos;
varying vec4 v_tex;
varying vec4 v_shadow;
varying vec2 v_los;
vec4 fakeCos(vec4 x)
{
vec4 tri = abs(fract(x + 0.5) * 2.0 - 1.0);
return tri * tri *(3.0 - 2.0 * tri);
}
void main()
{
worldPos = instancingTransform * vec4(a_vertex, 1.0);
v_tex.xy = (a_uv0 + worldPos.xz) / 5.0 + sim_time * translation;
v_tex.zw = a_uv0;
#if USE_SHADOW
v_shadow = shadowTransform * worldPos;
#if USE_SHADOW_SAMPLER && USE_SHADOW_PCF
v_shadow.xy *= shadowScale.xy;
#endif
#endif
v_los = worldPos.xz * losTransform.x + losTransform.y;
gl_Position = transform * worldPos;
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<program type="glsl">
<vertex file="glsl/model_water.vs">
<stream name="pos"/>
<stream name="normal"/>
<stream name="uv0"/>
<stream name="uv1" if="USE_AO"/>
<attrib name="a_vertex" semantics="gl_Vertex"/>
<attrib name="a_normal" semantics="gl_Normal"/>
<attrib name="a_uv0" semantics="gl_MultiTexCoord0"/>
<attrib name="a_uv1" semantics="gl_MultiTexCoord1" if="USE_AO"/>
<attrib name="a_skinJoints" semantics="CustomAttribute0" if="USE_GPU_SKINNING"/>
<attrib name="a_skinWeights" semantics="CustomAttribute1" if="USE_GPU_SKINNING"/>
<attrib name="a_tangent" semantics="CustomAttribute2" if="USE_INSTANCING"/>
</vertex>
<fragment file="glsl/model_water.fs"/>
</program>

View File

@ -0,0 +1,82 @@
#version 120
uniform sampler2D baseTex;
uniform sampler2D losTex;
#if USE_SHADOW
#if USE_SHADOW_SAMPLER
uniform sampler2DShadow shadowTex;
#if USE_SHADOW_PCF
uniform vec4 shadowScale;
#endif
#else
uniform sampler2D shadowTex;
#endif
#endif
uniform vec3 shadingColor;
uniform vec3 ambient;
uniform vec3 sunColor;
uniform vec3 sunDir;
uniform vec3 cameraPos;
uniform float specularPower;
uniform vec3 specularColor;
varying vec4 v_tex;
varying vec4 v_shadow;
varying vec2 v_los;
varying vec3 v_half;
varying vec3 v_normal;
varying vec3 v_lighting;
float get_shadow()
{
#if USE_SHADOW && !DISABLE_RECEIVE_SHADOWS
#if USE_SHADOW_SAMPLER
#if USE_SHADOW_PCF
vec2 offset = fract(v_shadow.xy - 0.5);
vec4 size = vec4(offset + 1.0, 2.0 - offset);
vec4 weight = (vec4(2.0 - 1.0 / size.xy, 1.0 / size.zw - 1.0) + (v_shadow.xy - offset).xyxy) * shadowScale.zwzw;
return (1.0/9.0)*dot(size.zxzx*size.wwyy,
vec4(shadow2D(shadowTex, vec3(weight.zw, v_shadow.z)).r,
shadow2D(shadowTex, vec3(weight.xw, v_shadow.z)).r,
shadow2D(shadowTex, vec3(weight.zy, v_shadow.z)).r,
shadow2D(shadowTex, vec3(weight.xy, v_shadow.z)).r));
#else
return shadow2D(shadowTex, v_shadow.xyz).r;
#endif
#else
if (v_shadow.z >= 1.0)
return 1.0;
return (v_shadow.z <= texture2D(shadowTex, v_shadow.xy).x ? 1.0 : 0.0);
#endif
#else
return 1.0;
#endif
}
void main()
{
vec4 texdiffuse = textureGrad(baseTex, vec3(fract(v_tex.xy), v_tex.z), dFdx(v_tex.xy), dFdy(v_tex.xy));
vec3 specular = sunColor * specularColor * pow(max(0.0, dot(normalize(v_normal), v_half)), specularPower);
vec3 color = (texdiffuse.rgb * v_lighting + specular) * get_shadow();
color += texdiffuse.rgb * ambient;
#if !IGNORE_LOS
float los = texture2D(losTex, v_los).a;
los = los < 0.03 ? 0.0 : los;
color *= los;
#endif
gl_FragColor.rgb = color;
gl_FragColor.a = texdiffuse.a;
}

View File

@ -0,0 +1,64 @@
#if USE_GPU_SKINNING
// Skinning requires GLSL 1.30 for ivec4 vertex attributes
#version 130
#else
#version 120
#endif
uniform mat4 transform;
uniform vec3 cameraPos;
uniform vec3 sunDir;
uniform vec3 sunColor;
uniform vec2 losTransform;
uniform mat4 shadowTransform;
uniform mat4 instancingTransform;
uniform float sim_time;
uniform vec2 translation;
#if USE_SHADOW_SAMPLER && USE_SHADOW_PCF
uniform vec4 shadowScale;
#endif
attribute vec3 a_vertex;
attribute vec3 a_normal;
attribute vec2 a_uv0;
varying vec4 worldPos;
varying vec4 v_tex;
varying vec4 v_shadow;
varying vec2 v_los;
varying vec3 v_half;
varying vec3 v_normal;
varying vec3 v_lighting;
void main()
{
worldPos = instancingTransform * vec4(a_vertex, 1.0);
v_tex.xy = a_uv0 + sim_time * translation;
#if USE_SHADOW
v_shadow = shadowTransform * worldPos;
#if USE_SHADOW_SAMPLER && USE_SHADOW_PCF
v_shadow.xy *= shadowScale.xy;
#endif
#endif
v_los = worldPos.xz * losTransform.x + losTransform.y;
vec3 eyeVec = cameraPos.xyz - worldPos.xyz;
vec3 sunVec = -sunDir;
v_half = normalize(sunVec + normalize(eyeVec));
mat3 normalMatrix = mat3(instancingTransform[0].xyz, instancingTransform[1].xyz, instancingTransform[2].xyz);
v_normal = normalMatrix * a_normal;
v_lighting = max(0.0, dot(v_normal, -sunDir)) * sunColor;
gl_Position = transform * worldPos;
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<program type="glsl">
<vertex file="glsl/model_waterfall.vs">
<stream name="pos"/>
<stream name="normal"/>
<stream name="uv0"/>
<stream name="uv1" if="USE_AO"/>
<attrib name="a_vertex" semantics="gl_Vertex"/>
<attrib name="a_normal" semantics="gl_Normal"/>
<attrib name="a_uv0" semantics="gl_MultiTexCoord0"/>
<attrib name="a_uv1" semantics="gl_MultiTexCoord1" if="USE_AO"/>
<attrib name="a_skinJoints" semantics="CustomAttribute0" if="USE_GPU_SKINNING"/>
<attrib name="a_skinWeights" semantics="CustomAttribute1" if="USE_GPU_SKINNING"/>
<attrib name="a_tangent" semantics="CustomAttribute2" if="USE_INSTANCING"/>
</vertex>
<fragment file="glsl/model_waterfall.fs"/>
</program>

View File

@ -236,10 +236,18 @@ void CShaderUniforms::BindUniforms(const CShaderProgramPtr& shader) const
void CShaderRenderQueries::Add(const char* name)
{
if (name == std::string("time"))
if (name == CStr("sim_time"))
{
m_Items.push_back(std::make_pair(RQUERY_TIME, CStrIntern(name)));
}
else if (name == CStr("water_tex"))
{
m_Items.push_back(std::make_pair(RQUERY_WATER_TEX, CStrIntern(name)));
}
else if (name == CStr("sky_cube"))
{
m_Items.push_back(std::make_pair(RQUERY_SKY_CUBE, CStrIntern(name)));
}
}
size_t CShaderRenderQueries::GetSize()

View File

@ -170,7 +170,9 @@ public:
// Add here the types of queries we can make in the renderer
enum RENDER_QUERIES
{
RQUERY_TIME
RQUERY_TIME,
RQUERY_WATER_TEX,
RQUERY_SKY_CUBE
};
/**

View File

@ -37,6 +37,8 @@
#include "renderer/ModelVertexRenderer.h"
#include "renderer/Renderer.h"
#include "renderer/RenderModifiers.h"
#include "renderer/SkyManager.h"
#include "renderer/WaterManager.h"
#include <boost/weak_ptr.hpp>
@ -705,6 +707,19 @@ void ShaderModelRenderer::Render(const RenderModifierPtr& modifier, const CShade
shader->Uniform(binding, time, 0,0,0);
}
}
else if (rq.first == RQUERY_WATER_TEX)
{
WaterManager* WaterMgr = g_Renderer.GetWaterManager();
double time = WaterMgr->m_WaterTexTimer;
double period = 1.6;
int curTex = (int)(time*60/period) % 60;
shader->BindTexture("waterTex", WaterMgr->m_NormalMap[curTex]);
}
else if (rq.first == RQUERY_SKY_CUBE)
{
shader->BindTexture("skyCube", g_Renderer.GetSkyManager()->GetSkyCube());
}
}
modifier->PrepareModel(shader, model);

View File

@ -67,6 +67,8 @@ SkyManager::SkyManager()
m_SkySet = L"";
m_HorizonHeight = -150.0f;
m_SkyCubeMap = 0;
}
@ -84,6 +86,77 @@ void SkyManager::LoadSkyTextures()
texture->Prefetch();
m_SkyTexture[i] = texture;
}
glGenTextures(1, &m_SkyCubeMap);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_SkyCubeMap);
int types[] = {
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
};
const wchar_t* images[numTextures+1] = {
L"front",
L"back",
L"right",
L"left",
L"top",
L"top"
};
for (size_t i = 0; i < numTextures+1; ++i)
{
VfsPath path = VfsPath("art/textures/skies") / m_SkySet / (Path::String(images[i])+L".dds");
shared_ptr<u8> file;
size_t fileSize;
g_VFS->LoadFile(path, file, fileSize);
Tex tex;
tex_decode(file, fileSize, &tex);
tex_transform_to(&tex, (tex.flags | TEX_BOTTOM_UP | TEX_ALPHA) & ~(TEX_DXT | TEX_MIPMAPS));
u8* data = tex_get_data(&tex);
if (types[i] == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y || types[i] == GL_TEXTURE_CUBE_MAP_POSITIVE_Y)
{
std::vector<u8> rotated(tex.dataSize);
for (size_t y = 0; y < tex.h; ++y)
{
for (size_t x = 0; x < tex.w; ++x)
{
size_t invx = y, invy = tex.w-x-1;
rotated[(y*tex.w + x) * 4 + 0] = data[(invy*tex.w + invx) * 4 + 0];
rotated[(y*tex.w + x) * 4 + 1] = data[(invy*tex.w + invx) * 4 + 1];
rotated[(y*tex.w + x) * 4 + 2] = data[(invy*tex.w + invx) * 4 + 2];
rotated[(y*tex.w + x) * 4 + 3] = data[(invy*tex.w + invx) * 4 + 3];
}
}
glTexImage2D(types[i], 0, GL_RGB, tex.w, tex.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, &rotated[0]);
}
else
{
glTexImage2D(types[i], 0, GL_RGB, tex.w, tex.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
tex_free(&tex);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
}
@ -93,6 +166,13 @@ void SkyManager::SetSkySet( const CStrW& newSet )
{
if(newSet == m_SkySet)
return;
if (m_SkyCubeMap)
{
glDeleteTextures(1, &m_SkyCubeMap);
m_SkyCubeMap = 0;
}
m_SkySet = newSet;
LoadSkyTextures();

View File

@ -47,6 +47,10 @@ public:
inline const CStrW& GetSkySet() const {
return m_SkySet;
}
GLuint GetSkyCube() {
return m_SkyCubeMap;
}
/**
* GetSkySet(): Set the sky set name, potentially loading the textures.
@ -78,6 +82,8 @@ private:
// Sky textures
CTexturePtr m_SkyTexture[numTextures];
GLuint m_SkyCubeMap;
// Array of image names (defined in SkyManager.cpp), in the order of the IMG_ id's
static const wchar_t* s_imageNames[numTextures];