Simplify GLSL program files.

Move water shaders to new shader system.

This was SVN commit r10982.
This commit is contained in:
Ykkrosh 2012-01-29 12:04:39 +00:00
parent 19c6ae7b1e
commit 8324a8981d
11 changed files with 100 additions and 187 deletions

View File

@ -2,25 +2,11 @@
<program type="glsl">
<vertex file="model_common.vs">
<uniform name="sunDir" type="vec3"/>
<uniform name="sunColor" type="vec3"/>
<uniform name="losTransform" type="vec2"/>
<uniform name="shadowTransform" type="mat4"/>
<stream name="pos"/>
<stream name="normal"/>
<stream name="uv0"/>
</vertex>
<fragment file="model_common.fs">
<uniform name="baseTex" type="sampler2D"/>
<uniform name="shadowTex" type="sampler2DShadow"/>
<uniform name="losTex" type="sampler2D"/>
<uniform name="objectColor" type="vec3"/>
<uniform name="shadingColor" type="vec3"/>
<uniform name="ambient" type="vec3"/>
<uniform name="shadowOffsets1" type="vec4"/>
<uniform name="shadowOffsets2" type="vec4"/>
</fragment>
<fragment file="model_common.fs"/>
</program>

View File

@ -4,26 +4,11 @@
<define name="USE_INSTANCING" value="1"/>
<vertex file="model_common.vs">
<uniform name="sunDir" type="vec3"/>
<uniform name="sunColor" type="vec3"/>
<uniform name="losTransform" type="vec2"/>
<uniform name="shadowTransform" type="mat4"/>
<uniform name="instancingTransform" type="mat4"/>
<stream name="pos"/>
<stream name="normal"/>
<stream name="uv0"/>
</vertex>
<fragment file="model_common.fs">
<uniform name="baseTex" type="sampler2D"/>
<uniform name="shadowTex" type="sampler2DShadow"/>
<uniform name="losTex" type="sampler2D"/>
<uniform name="objectColor" type="vec3"/>
<uniform name="shadingColor" type="vec3"/>
<uniform name="ambient" type="vec3"/>
<uniform name="shadowOffsets1" type="vec4"/>
<uniform name="shadowOffsets2" type="vec4"/>
</fragment>
<fragment file="model_common.fs"/>
</program>

View File

@ -19,7 +19,7 @@
<attribute name="file"><text/></attribute>
<zeroOrMore>
<choice>
<ref name="uniformContentARB"/>
<ref name="uniformContent"/>
<element name="attrib">
<attribute name="name"><text/></attribute>
<attribute name="loc"><data type="integer"/></attribute>
@ -32,7 +32,7 @@
<element name="fragment">
<attribute name="file"><text/></attribute>
<zeroOrMore>
<ref name="uniformContentARB"/>
<ref name="uniformContent"/>
</zeroOrMore>
</element>
</group>
@ -46,7 +46,6 @@
<attribute name="file"><text/></attribute>
<zeroOrMore>
<choice>
<ref name="uniformContentGLSL"/>
<element name="attrib">
<attribute name="name"><text/></attribute>
<attribute name="loc"><data type="integer"/></attribute>
@ -58,9 +57,6 @@
<element name="fragment">
<attribute name="file"><text/></attribute>
<zeroOrMore>
<ref name="uniformContentGLSL"/>
</zeroOrMore>
</element>
</group>
@ -69,7 +65,7 @@
</start>
<define name="uniformContentARB">
<define name="uniformContent">
<element name="uniform">
<attribute name="name"><text/></attribute>
<attribute name="loc"><data type="integer"/></attribute>
@ -90,26 +86,6 @@
</element>
</define>
<define name="uniformContentGLSL">
<element name="uniform">
<attribute name="name"><text/></attribute>
<attribute name="type">
<choice>
<value>float</value>
<value>vec2</value>
<value>vec3</value>
<value>vec4</value>
<value>mat2</value>
<value>mat3</value>
<value>mat4</value>
<value>sampler2D</value>
<value>sampler2DShadow</value>
<value>samplerCube</value>
</choice>
</attribute>
</element>
</define>
<define name="streamContent">
<element name="stream">
<attribute name="name">

View File

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<Program>
<Shaders>
<Shader type="VERTEX_SHADER">shaders/water_high.vs</Shader>
<Shader type="FRAGMENT_SHADER">shaders/water_high.fs</Shader>
</Shaders>
</Program>
<?xml version="1.0" encoding="utf-8"?>
<program type="glsl">
<vertex file="water_high.vs"/>
<fragment file="water_high.fs"/>
</program>

View File

@ -91,10 +91,10 @@ GLuint CLOSTexture::GetTexture()
return m_Texture;
}
const float* CLOSTexture::GetTextureMatrix()
const CMatrix3D& CLOSTexture::GetTextureMatrix()
{
ENSURE(!m_Dirty);
return &m_TextureMatrix._11;
return m_TextureMatrix;
}
const float* CLOSTexture::GetMinimapTextureMatrix()

View File

@ -61,7 +61,7 @@ public:
* coordinates, in the form expected by glLoadMatrixf.
* This must only be called after BindTexture.
*/
const float* GetTextureMatrix();
const CMatrix3D& GetTextureMatrix();
/**
* Returns a matrix to map (0,0)-(1,1) texture coordinates onto LOS texture

View File

@ -82,21 +82,6 @@ CShaderProgramPtr CShaderManager::LoadProgram(const char* name, const std::map<C
return program;
}
static GLenum GetGLSLType(const CStr type)
{
if (type == "float") return GL_FLOAT;
if (type == "vec2") return GL_FLOAT_VEC2;
if (type == "vec3") return GL_FLOAT_VEC3;
if (type == "vec4") return GL_FLOAT_VEC4;
if (type == "mat2") return GL_FLOAT_MAT2;
if (type == "mat3") return GL_FLOAT_MAT3;
if (type == "mat4") return GL_FLOAT_MAT4;
if (type == "sampler2D") return GL_SAMPLER_2D;
if (type == "sampler2DShadow") return GL_SAMPLER_2D;
if (type == "samplerCube") return GL_SAMPLER_CUBE;
return 0;
}
bool CShaderManager::NewProgram(const char* name, const std::map<CStr, CStr>& baseDefines, CShaderProgramPtr& program)
{
PROFILE2("loading shader");
@ -155,9 +140,8 @@ bool CShaderManager::NewProgram(const char* name, const std::map<CStr, CStr>& ba
VfsPath vertexFile;
VfsPath fragmentFile;
std::map<CStr, CStr> defines = baseDefines;
std::map<CStr, int> arbVertexUniforms;
std::map<CStr, int> arbFragmentUniforms;
std::map<CStr, GLenum> glslUniforms;
std::map<CStr, int> vertexUniforms;
std::map<CStr, int> fragmentUniforms;
int streamFlags = 0;
XERO_ITER_EL(Root, Child)
@ -174,10 +158,7 @@ bool CShaderManager::NewProgram(const char* name, const std::map<CStr, CStr>& ba
{
if (Param.GetNodeName() == el_uniform)
{
if (isGLSL)
glslUniforms[Param.GetAttributes().GetNamedItem(at_name)] = GetGLSLType(Param.GetAttributes().GetNamedItem(at_type));
else
arbVertexUniforms[Param.GetAttributes().GetNamedItem(at_name)] = Param.GetAttributes().GetNamedItem(at_loc).ToInt();
vertexUniforms[Param.GetAttributes().GetNamedItem(at_name)] = Param.GetAttributes().GetNamedItem(at_loc).ToInt();
}
else if (Param.GetNodeName() == el_stream)
{
@ -211,19 +192,16 @@ bool CShaderManager::NewProgram(const char* name, const std::map<CStr, CStr>& ba
{
if (Param.GetNodeName() == el_uniform)
{
if (isGLSL)
glslUniforms[Param.GetAttributes().GetNamedItem(at_name)] = GetGLSLType(Param.GetAttributes().GetNamedItem(at_type));
else
arbFragmentUniforms[Param.GetAttributes().GetNamedItem(at_name)] = Param.GetAttributes().GetNamedItem(at_loc).ToInt();
fragmentUniforms[Param.GetAttributes().GetNamedItem(at_name)] = Param.GetAttributes().GetNamedItem(at_loc).ToInt();
}
}
}
}
if (isGLSL)
program = CShaderProgramPtr(CShaderProgram::ConstructGLSL(vertexFile, fragmentFile, defines, glslUniforms, streamFlags));
program = CShaderProgramPtr(CShaderProgram::ConstructGLSL(vertexFile, fragmentFile, defines, streamFlags));
else
program = CShaderProgramPtr(CShaderProgram::ConstructARB(vertexFile, fragmentFile, defines, arbVertexUniforms, arbFragmentUniforms, streamFlags));
program = CShaderProgramPtr(CShaderProgram::ConstructARB(vertexFile, fragmentFile, defines, vertexUniforms, fragmentUniforms, streamFlags));
program->Reload();

View File

@ -19,6 +19,7 @@
#include "ShaderProgram.h"
#include "graphics/TextureManager.h"
#include "lib/res/graphics/ogl_tex.h"
#include "maths/Matrix3D.h"
#include "maths/Vector3D.h"
@ -223,12 +224,10 @@ class CShaderProgramGLSL : public CShaderProgram
public:
CShaderProgramGLSL(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const std::map<CStr, CStr>& defines,
const std::map<CStr, GLenum>& uniformTypes,
int streamflags) :
CShaderProgram(streamflags),
m_VertexFile(vertexFile), m_FragmentFile(fragmentFile),
m_Defines(defines),
m_UniformTypes(uniformTypes)
m_Defines(defines)
{
m_Program = 0;
m_VertexShader = pglCreateShaderObjectARB(GL_VERTEX_SHADER);
@ -311,25 +310,31 @@ public:
ogl_WarnIfError();
m_UniformLocations.clear();
m_UniformTypes.clear();
m_Samplers.clear();
Bind();
for (std::map<CStr, GLenum>::iterator it = m_UniformTypes.begin(); it != m_UniformTypes.end(); ++it)
GLint numUniforms = 0;
pglGetProgramiv(m_Program, GL_ACTIVE_UNIFORMS, &numUniforms);
for (GLint i = 0; i < numUniforms; ++i)
{
int loc = pglGetUniformLocationARB(m_Program, it->first.c_str());
m_UniformLocations[it->first] = loc;
char name[256] = {0};
GLsizei nameLength = 0;
GLint size = 0;
GLenum type = 0;
pglGetActiveUniformARB(m_Program, i, ARRAY_SIZE(name), &nameLength, &size, &type, name);
if (loc != -1)
m_UniformLocations[name] = i;
m_UniformTypes[name] = type;
// Assign sampler uniforms to sequential texture units
if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_SHADOW || type == GL_SAMPLER_CUBE)
{
// Assign in-use sampler uniforms to sequential texture units
if (it->second == GL_SAMPLER_2D || it->second == GL_SAMPLER_CUBE)
{
int unit = (int)m_Samplers.size();
m_Samplers[it->first].first = (it->second == GL_SAMPLER_CUBE ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D);
m_Samplers[it->first].second = unit;
pglUniform1iARB(loc, unit); // link uniform to unit
}
int unit = (int)m_Samplers.size();
m_Samplers[name].first = (type == GL_SAMPLER_CUBE ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D);
m_Samplers[name].second = unit;
pglUniform1iARB(i, unit); // link uniform to unit
}
}
@ -501,10 +506,9 @@ CShaderProgram::CShaderProgram(int streamflags)
/*static*/ CShaderProgram* CShaderProgram::ConstructGLSL(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const std::map<CStr, CStr>& defines,
const std::map<CStr, GLenum>& uniformTypes,
int streamflags)
{
return new CShaderProgramGLSL(vertexFile, fragmentFile, defines, uniformTypes, streamflags);
return new CShaderProgramGLSL(vertexFile, fragmentFile, defines, streamflags);
}
bool CShaderProgram::IsValid() const
@ -517,6 +521,11 @@ int CShaderProgram::GetStreamFlags() const
return m_StreamFlags;
}
void CShaderProgram::BindTexture(texture_id_t id, CTexturePtr tex)
{
BindTexture(id, tex->GetHandle());
}
void CShaderProgram::Uniform(Binding id, int v)
{
Uniform(id, (float)v, (float)v, (float)v, (float)v);
@ -527,6 +536,11 @@ void CShaderProgram::Uniform(Binding id, float v)
Uniform(id, v, v, v, v);
}
void CShaderProgram::Uniform(Binding id, float v0, float v1)
{
Uniform(id, v0, v1, 0.0f, 0.0f);
}
void CShaderProgram::Uniform(Binding id, const CVector3D& v)
{
Uniform(id, v.X, v.Y, v.Z, 0.0f);
@ -547,6 +561,11 @@ void CShaderProgram::Uniform(uniform_id_t id, float v)
Uniform(GetUniformBinding(id), v, v, v, v);
}
void CShaderProgram::Uniform(uniform_id_t id, float v0, float v1)
{
Uniform(GetUniformBinding(id), v0, v1, 0.0f, 0.0f);
}
void CShaderProgram::Uniform(uniform_id_t id, const CVector3D& v)
{
Uniform(GetUniformBinding(id), v.X, v.Y, v.Z, 0.0f);

View File

@ -18,6 +18,7 @@
#ifndef INCLUDED_SHADERPROGRAM
#define INCLUDED_SHADERPROGRAM
#include "graphics/Texture.h"
#include "lib/ogl.h"
#include "lib/file/vfs/vfs_path.h"
#include "lib/res/handle.h"
@ -74,7 +75,6 @@ public:
*/
static CShaderProgram* ConstructGLSL(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const std::map<CStr, CStr>& defines,
const std::map<CStr, GLenum>& uniformTypes,
int streamflags);
/**
@ -143,6 +143,8 @@ public:
*/
virtual bool HasTexture(texture_id_t id) = 0;
void BindTexture(texture_id_t id, CTexturePtr tex);
virtual void BindTexture(texture_id_t id, Handle tex) = 0;
virtual void BindTexture(texture_id_t id, GLuint tex) = 0;
@ -157,11 +159,13 @@ public:
void Uniform(Binding id, int v);
void Uniform(Binding id, float v);
void Uniform(Binding id, float v0, float v1);
void Uniform(Binding id, const CVector3D& v);
void Uniform(Binding id, const CColor& v);
void Uniform(uniform_id_t id, int v);
void Uniform(uniform_id_t id, float v);
void Uniform(uniform_id_t id, float v0, float v1);
void Uniform(uniform_id_t id, const CVector3D& v);
void Uniform(uniform_id_t id, const CColor& v);
void Uniform(uniform_id_t id, float v0, float v1, float v2, float v3);

View File

@ -79,13 +79,20 @@ public:
// NOTE: in this function definition, 'col' and 'row' represent the column and row into the
// internal element matrix which is the transposed of the mathematical notation, so the first
// and second arguments here are actually the row and column into the mathematical notation.
float& operator()(int col,int row) {
float& operator()(int col, int row)
{
return _data[row*4+col];
}
const float& operator()(int col,int row) const {
const float& operator()(int col, int row) const
{
return _data[row*4+col];
}
float operator[](int idx) const
{
return _data[idx];
}
// matrix multiplication
CMatrix3D operator*(const CMatrix3D &matrix) const
{

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2011 Wildfire Games.
/* Copyright (C) 2012 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -84,7 +84,7 @@ struct TerrainRendererInternals
std::vector<CDecalRData*> filteredDecals;
/// Fancy water shader
Handle fancyWaterShader;
CShaderProgramPtr fancyWaterShader;
};
@ -95,15 +95,10 @@ TerrainRenderer::TerrainRenderer()
{
m = new TerrainRendererInternals();
m->phase = Phase_Submit;
m->fancyWaterShader = 0;
}
TerrainRenderer::~TerrainRenderer()
{
if( m->fancyWaterShader )
{
ogl_program_free( m->fancyWaterShader );
}
delete m;
}
@ -335,7 +330,7 @@ void TerrainRenderer::RenderTerrain(bool filtered)
streamflags |= STREAM_POSTOUV1;
glMatrixMode(GL_TEXTURE);
glLoadMatrixf(losTexture.GetTextureMatrix());
glLoadMatrixf(&losTexture.GetTextureMatrix()._11);
glMatrixMode(GL_MODELVIEW);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@ -611,17 +606,14 @@ bool TerrainRenderer::RenderFancyWater()
// If we're using fancy water, make sure its shader is loaded
if (!m->fancyWaterShader)
{
Handle h = ogl_program_load(g_VFS, L"shaders/water_high.xml");
if (h < 0)
std::map<CStr, CStr> defNull;
m->fancyWaterShader = g_Renderer.GetShaderManager().LoadProgram("water_high", defNull);
if (!m->fancyWaterShader)
{
LOGERROR(L"Failed to load water shader. Falling back to non-fancy water.\n");
g_Renderer.m_Options.m_FancyWater = false;
return false;
}
else
{
m->fancyWaterShader = h;
}
}
WaterManager* WaterMgr = g_Renderer.GetWaterManager();
@ -636,7 +628,9 @@ bool TerrainRenderer::RenderFancyWater()
double period = 1.6;
int curTex = (int)(time*60/period) % 60;
WaterMgr->m_NormalMap[curTex]->Bind();
m->fancyWaterShader->Bind();
m->fancyWaterShader->BindTexture("normalMap", WaterMgr->m_NormalMap[curTex]);
// Shift the texture coordinates by these amounts to make the water "flow"
float tx = -fmod(time, 81.0)/81.0;
@ -649,63 +643,30 @@ bool TerrainRenderer::RenderFancyWater()
const CCamera& camera = g_Renderer.GetViewCamera();
CVector3D camPos = camera.m_Orientation.GetTranslation();
// Bind reflection and refraction textures on texture units 1 and 2
pglActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, WaterMgr->m_ReflectionTexture);
pglActiveTextureARB(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, WaterMgr->m_RefractionTexture);
// Bind reflection and refraction textures
m->fancyWaterShader->BindTexture("reflectionMap", WaterMgr->m_ReflectionTexture);
m->fancyWaterShader->BindTexture("refractionMap", WaterMgr->m_RefractionTexture);
losTexture.BindTexture(3);
// Bind water shader and set arguments
ogl_program_use(m->fancyWaterShader);
GLint ambient = ogl_program_get_uniform_location(m->fancyWaterShader, "ambient");
GLint sunDir = ogl_program_get_uniform_location(m->fancyWaterShader, "sunDir");
GLint sunColor = ogl_program_get_uniform_location(m->fancyWaterShader, "sunColor");
GLint cameraPos = ogl_program_get_uniform_location(m->fancyWaterShader, "cameraPos");
GLint shininess = ogl_program_get_uniform_location(m->fancyWaterShader, "shininess");
GLint specularStrength = ogl_program_get_uniform_location(m->fancyWaterShader, "specularStrength");
GLint waviness = ogl_program_get_uniform_location(m->fancyWaterShader, "waviness");
GLint murkiness = ogl_program_get_uniform_location(m->fancyWaterShader, "murkiness");
GLint fullDepth = ogl_program_get_uniform_location(m->fancyWaterShader, "fullDepth");
GLint tint = ogl_program_get_uniform_location(m->fancyWaterShader, "tint");
GLint reflectionTint = ogl_program_get_uniform_location(m->fancyWaterShader, "reflectionTint");
GLint reflectionTintStrength = ogl_program_get_uniform_location(m->fancyWaterShader, "reflectionTintStrength");
GLint translation = ogl_program_get_uniform_location(m->fancyWaterShader, "translation");
GLint repeatScale = ogl_program_get_uniform_location(m->fancyWaterShader, "repeatScale");
GLint reflectionMatrix = ogl_program_get_uniform_location(m->fancyWaterShader, "reflectionMatrix");
GLint refractionMatrix = ogl_program_get_uniform_location(m->fancyWaterShader, "refractionMatrix");
GLint losMatrix = ogl_program_get_uniform_location(m->fancyWaterShader, "losMatrix");
GLint normalMap = ogl_program_get_uniform_location(m->fancyWaterShader, "normalMap");
GLint reflectionMap = ogl_program_get_uniform_location(m->fancyWaterShader, "reflectionMap");
GLint refractionMap = ogl_program_get_uniform_location(m->fancyWaterShader, "refractionMap");
GLint losMap = ogl_program_get_uniform_location(m->fancyWaterShader, "losMap");
m->fancyWaterShader->BindTexture("losMap", losTexture.GetTexture());
const CLightEnv& lightEnv = g_Renderer.GetLightEnv();
pglUniform3fvARB(ambient, 1, &lightEnv.m_TerrainAmbientColor.X);
pglUniform3fvARB(sunDir, 1, &lightEnv.GetSunDir().X);
pglUniform3fvARB(sunColor, 1, &lightEnv.m_SunColor.X);
pglUniform1fARB(shininess, WaterMgr->m_Shininess);
pglUniform1fARB(specularStrength, WaterMgr->m_SpecularStrength);
pglUniform1fARB(waviness, WaterMgr->m_Waviness);
pglUniform1fARB(murkiness, WaterMgr->m_Murkiness);
pglUniform1fARB(fullDepth, WaterMgr->m_WaterFullDepth);
pglUniform3fvARB(tint, 1, WaterMgr->m_WaterTint.FloatArray());
pglUniform1fARB(reflectionTintStrength, WaterMgr->m_ReflectionTintStrength);
pglUniform3fvARB(reflectionTint, 1, WaterMgr->m_ReflectionTint.FloatArray());
pglUniform2fARB(translation, tx, ty);
pglUniform1fARB(repeatScale, 1.0f / repeatPeriod);
pglUniformMatrix4fvARB(reflectionMatrix, 1, false, &WaterMgr->m_ReflectionMatrix._11);
pglUniformMatrix4fvARB(refractionMatrix, 1, false, &WaterMgr->m_RefractionMatrix._11);
pglUniformMatrix4fvARB(losMatrix, 1, false, losTexture.GetTextureMatrix());
pglUniform1iARB(normalMap, 0); // texture unit 0
pglUniform1iARB(reflectionMap, 1); // texture unit 1
pglUniform1iARB(refractionMap, 2); // texture unit 2
pglUniform1iARB(losMap, 3); // texture unit 3
pglUniform3fvARB(cameraPos, 1, &camPos.X);
m->fancyWaterShader->Uniform("ambient", lightEnv.m_TerrainAmbientColor);
m->fancyWaterShader->Uniform("sunDir", lightEnv.GetSunDir());
m->fancyWaterShader->Uniform("sunColor", lightEnv.m_SunColor.X);
m->fancyWaterShader->Uniform("shininess", WaterMgr->m_Shininess);
m->fancyWaterShader->Uniform("specularStrength", WaterMgr->m_SpecularStrength);
m->fancyWaterShader->Uniform("waviness", WaterMgr->m_Waviness);
m->fancyWaterShader->Uniform("murkiness", WaterMgr->m_Murkiness);
m->fancyWaterShader->Uniform("fullDepth", WaterMgr->m_WaterFullDepth);
m->fancyWaterShader->Uniform("tint", WaterMgr->m_WaterTint);
m->fancyWaterShader->Uniform("reflectionTintStrength", WaterMgr->m_ReflectionTintStrength);
m->fancyWaterShader->Uniform("reflectionTint", WaterMgr->m_ReflectionTint);
m->fancyWaterShader->Uniform("translation", tx, ty);
m->fancyWaterShader->Uniform("repeatScale", 1.0f / repeatPeriod);
m->fancyWaterShader->Uniform("reflectionMatrix", WaterMgr->m_ReflectionMatrix);
m->fancyWaterShader->Uniform("refractionMatrix", WaterMgr->m_RefractionMatrix);
m->fancyWaterShader->Uniform("losMatrix", losTexture.GetTextureMatrix());
m->fancyWaterShader->Uniform("cameraPos", camPos);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
@ -781,7 +742,7 @@ void TerrainRenderer::RenderSimpleWater()
// Multiply by LOS texture
losTexture.BindTexture(1);
const float *losMatrix = losTexture.GetTextureMatrix();
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);