diff --git a/binaries/data/mods/public/shaders/model_common.fs b/binaries/data/mods/public/shaders/model_common.fs
index e54a551426..25b8575864 100644
--- a/binaries/data/mods/public/shaders/model_common.fs
+++ b/binaries/data/mods/public/shaders/model_common.fs
@@ -1,3 +1,5 @@
+#version 110
+
uniform sampler2D baseTex;
uniform sampler2DShadow shadowTex;
uniform sampler2D losTex;
@@ -26,7 +28,7 @@ void main()
// Apply player-coloring based on texture alpha
#ifdef USE_OBJECTCOLOR
- color *= mix(objectColor, 1.0, tex.a);
+ color *= mix(objectColor, vec3(1.0, 1.0, 1.0), tex.a);
#endif
#ifdef USE_SHADOW
@@ -38,7 +40,7 @@ void main()
shadow2D(shadowTex, vec3(v_shadow.xy + shadowOffsets2.zw, v_shadow.z)).a
) * 0.25;
#else
- float shadow = shadow2D(shadowTex, v_shadow).a;
+ float shadow = shadow2D(shadowTex, v_shadow.xyz).a;
#endif
#else
float shadow = 1.0;
diff --git a/binaries/data/mods/public/shaders/model_common.vs b/binaries/data/mods/public/shaders/model_common.vs
index 56d58a81c4..74acc7e989 100644
--- a/binaries/data/mods/public/shaders/model_common.vs
+++ b/binaries/data/mods/public/shaders/model_common.vs
@@ -1,3 +1,5 @@
+#version 110
+
uniform vec3 sunDir;
uniform vec3 sunColor;
uniform vec2 losTransform;
@@ -9,20 +11,24 @@ varying vec2 v_tex;
varying vec4 v_shadow;
varying vec2 v_los;
+attribute vec3 a_vertex;
+attribute vec3 a_normal;
+attribute vec2 a_uv0;
+
void main()
{
#ifdef USE_INSTANCING
- vec4 position = instancingTransform * gl_Vertex;
- vec3 normal = instancingTransform * vec4(gl_Normal, 0.0);
+ vec4 position = instancingTransform * vec4(a_vertex, 1.0);
+ vec3 normal = (instancingTransform * vec4(a_normal, 0.0)).xyz;
#else
- vec4 position = gl_Vertex;
- vec3 normal = gl_Normal;
+ vec4 position = vec4(a_vertex, 1.0);
+ vec3 normal = a_normal;
#endif
gl_Position = gl_ModelViewProjectionMatrix * position;
v_lighting = max(0.0, dot(normal, -sunDir)) * sunColor;
- v_tex = gl_MultiTexCoord0.xy;
+ v_tex = a_uv0;
v_shadow = shadowTransform * position;
v_los = position.xz * losTransform.x + losTransform.y;
}
diff --git a/binaries/data/mods/public/shaders/model_common_glsl.xml b/binaries/data/mods/public/shaders/model_common_glsl.xml
index bfe49c675c..662d5c3dc8 100644
--- a/binaries/data/mods/public/shaders/model_common_glsl.xml
+++ b/binaries/data/mods/public/shaders/model_common_glsl.xml
@@ -5,6 +5,9 @@
+
+
+
diff --git a/binaries/data/mods/public/shaders/model_common_instancing_glsl.xml b/binaries/data/mods/public/shaders/model_common_instancing_glsl.xml
index 641ad2c213..a8ad6ba626 100644
--- a/binaries/data/mods/public/shaders/model_common_instancing_glsl.xml
+++ b/binaries/data/mods/public/shaders/model_common_instancing_glsl.xml
@@ -7,6 +7,9 @@
+
+
+
diff --git a/binaries/data/mods/public/shaders/program.rng b/binaries/data/mods/public/shaders/program.rng
index 30c43fcaf8..10f4bd8beb 100644
--- a/binaries/data/mods/public/shaders/program.rng
+++ b/binaries/data/mods/public/shaders/program.rng
@@ -48,7 +48,23 @@
-
+
+
+ gl_Vertex
+ gl_Normal
+ gl_Color
+ gl_SecondaryColor
+ gl_FogCoord
+ gl_MultiTexCoord0
+ gl_MultiTexCoord1
+ gl_MultiTexCoord2
+ gl_MultiTexCoord3
+ gl_MultiTexCoord4
+ gl_MultiTexCoord5
+ gl_MultiTexCoord6
+ gl_MultiTexCoord7
+
+
diff --git a/binaries/data/mods/public/shaders/water_high.fs b/binaries/data/mods/public/shaders/water_high.fs
index f6f2ad0fab..114f5a2c1b 100644
--- a/binaries/data/mods/public/shaders/water_high.fs
+++ b/binaries/data/mods/public/shaders/water_high.fs
@@ -1,3 +1,5 @@
+#version 110
+
uniform vec3 ambient;
uniform vec3 sunDir;
uniform vec3 sunColor;
diff --git a/binaries/data/mods/public/shaders/water_high.vs b/binaries/data/mods/public/shaders/water_high.vs
index f510c874cb..6e846028a1 100644
--- a/binaries/data/mods/public/shaders/water_high.vs
+++ b/binaries/data/mods/public/shaders/water_high.vs
@@ -1,3 +1,5 @@
+#version 110
+
uniform mat4 reflectionMatrix;
uniform mat4 refractionMatrix;
uniform mat4 losMatrix;
diff --git a/source/graphics/ShaderManager.cpp b/source/graphics/ShaderManager.cpp
index 13b88aaa2b..5368314edf 100644
--- a/source/graphics/ShaderManager.cpp
+++ b/source/graphics/ShaderManager.cpp
@@ -82,6 +82,29 @@ CShaderProgramPtr CShaderManager::LoadProgram(const char* name, const std::map& baseDefines, CShaderProgramPtr& program)
{
PROFILE2("loading shader");
@@ -120,17 +143,18 @@ bool CShaderManager::NewProgram(const char* name, const std::map& ba
// Define all the elements and attributes used in the XML file
#define EL(x) int el_##x = XeroFile.GetElementID(#x)
#define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
- EL(vertex);
- EL(fragment);
- EL(define);
- EL(uniform);
EL(attrib);
+ EL(define);
+ EL(fragment);
EL(stream);
- AT(type);
+ EL(uniform);
+ EL(vertex);
AT(file);
- AT(name);
- AT(value);
AT(loc);
+ AT(name);
+ AT(semantics);
+ AT(type);
+ AT(value);
#undef AT
#undef EL
@@ -142,6 +166,7 @@ bool CShaderManager::NewProgram(const char* name, const std::map& ba
std::map defines = baseDefines;
std::map vertexUniforms;
std::map fragmentUniforms;
+ std::map vertexAttribs;
int streamFlags = 0;
XERO_ITER_EL(Root, Child)
@@ -180,7 +205,8 @@ bool CShaderManager::NewProgram(const char* name, const std::map& ba
}
else if (Param.GetNodeName() == el_attrib)
{
- // TODO: add support for vertex attributes
+ int attribLoc = ParseAttribSemantics(Param.GetAttributes().GetNamedItem(at_semantics));
+ vertexAttribs[Param.GetAttributes().GetNamedItem(at_name)] = attribLoc;
}
}
}
@@ -199,7 +225,7 @@ bool CShaderManager::NewProgram(const char* name, const std::map& ba
}
if (isGLSL)
- program = CShaderProgramPtr(CShaderProgram::ConstructGLSL(vertexFile, fragmentFile, defines, streamFlags));
+ program = CShaderProgramPtr(CShaderProgram::ConstructGLSL(vertexFile, fragmentFile, defines, vertexAttribs, streamFlags));
else
program = CShaderProgramPtr(CShaderProgram::ConstructARB(vertexFile, fragmentFile, defines, vertexUniforms, fragmentUniforms, streamFlags));
diff --git a/source/graphics/ShaderProgram.cpp b/source/graphics/ShaderProgram.cpp
index 59d6c4618e..22f1ee34e0 100644
--- a/source/graphics/ShaderProgram.cpp
+++ b/source/graphics/ShaderProgram.cpp
@@ -121,6 +121,8 @@ public:
glEnable(GL_FRAGMENT_PROGRAM_ARB);
pglBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_VertexProgram);
pglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_FragmentProgram);
+
+ BindClientStates();
}
virtual void Unbind()
@@ -130,6 +132,8 @@ public:
pglBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0);
pglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
+ UnbindClientStates();
+
// TODO: should unbind textures, probably
}
@@ -229,10 +233,12 @@ class CShaderProgramGLSL : public CShaderProgram
public:
CShaderProgramGLSL(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const std::map& defines,
+ const std::map& vertexAttribs,
int streamflags) :
CShaderProgram(streamflags),
m_VertexFile(vertexFile), m_FragmentFile(fragmentFile),
- m_Defines(defines)
+ m_Defines(defines),
+ m_VertexAttribs(vertexAttribs)
{
m_Program = 0;
m_VertexShader = pglCreateShaderObjectARB(GL_VERTEX_SHADER);
@@ -292,6 +298,12 @@ public:
pglAttachObjectARB(m_Program, m_FragmentShader);
ogl_WarnIfError();
+ // Set up the attribute bindings explicitly, since apparently drivers
+ // don't always pick the most efficient bindings automatically,
+ // and also this lets us hardcode indexes into VertexPointer etc
+ for (std::map::iterator it = m_VertexAttribs.begin(); it != m_VertexAttribs.end(); ++it)
+ pglBindAttribLocationARB(m_Program, it->second, it->first.c_str());
+
pglLinkProgramARB(m_Program);
GLint ok = 0;
@@ -397,12 +409,18 @@ public:
virtual void Bind()
{
pglUseProgramObjectARB(m_Program);
+
+ for (std::map::iterator it = m_VertexAttribs.begin(); it != m_VertexAttribs.end(); ++it)
+ pglEnableVertexAttribArrayARB(it->second);
}
virtual void Unbind()
{
pglUseProgramObjectARB(0);
+ for (std::map::iterator it = m_VertexAttribs.begin(); it != m_VertexAttribs.end(); ++it)
+ pglDisableVertexAttribArrayARB(it->second);
+
// TODO: should unbind textures, probably
}
@@ -489,10 +507,32 @@ public:
}
}
+ // Map the various fixed-function Pointer functions onto generic vertex attributes
+ // (matching the attribute indexes from ShaderManager's ParseAttribSemantics):
+
+ virtual void VertexPointer(GLint size, GLenum type, GLsizei stride, void* pointer)
+ {
+ pglVertexAttribPointerARB(0, size, type, GL_FALSE, stride, pointer);
+ m_ValidStreams |= STREAM_POS;
+ }
+
+ virtual void NormalPointer(GLenum type, GLsizei stride, void* pointer)
+ {
+ pglVertexAttribPointerARB(2, 3, type, GL_FALSE, stride, pointer);
+ m_ValidStreams |= STREAM_NORMAL;
+ }
+
+ virtual void TexCoordPointer(GLenum texture, GLint size, GLenum type, GLsizei stride, void* pointer)
+ {
+ pglVertexAttribPointerARB(8 + texture - GL_TEXTURE0, size, type, GL_FALSE, stride, pointer);
+ m_ValidStreams |= STREAM_UV0 << (texture - GL_TEXTURE0);
+ }
+
private:
VfsPath m_VertexFile;
VfsPath m_FragmentFile;
std::map m_Defines;
+ std::map m_VertexAttribs;
GLhandleARB m_Program;
GLhandleARB m_VertexShader;
@@ -506,7 +546,7 @@ private:
CShaderProgram::CShaderProgram(int streamflags)
- : m_IsValid(false), m_StreamFlags(streamflags)
+ : m_IsValid(false), m_StreamFlags(streamflags), m_ValidStreams(0)
{
}
@@ -520,9 +560,10 @@ CShaderProgram::CShaderProgram(int streamflags)
/*static*/ CShaderProgram* CShaderProgram::ConstructGLSL(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const std::map& defines,
+ const std::map& vertexAttribs,
int streamflags)
{
- return new CShaderProgramGLSL(vertexFile, fragmentFile, defines, streamflags);
+ return new CShaderProgramGLSL(vertexFile, fragmentFile, defines, vertexAttribs, streamflags);
}
bool CShaderProgram::IsValid() const
@@ -600,6 +641,25 @@ void CShaderProgram::Uniform(uniform_id_t id, const CMatrix3D& v)
Uniform(GetUniformBinding(id), v);
}
+void CShaderProgram::VertexPointer(GLint size, GLenum type, GLsizei stride, void* pointer)
+{
+ glVertexPointer(size, type, stride, pointer);
+ m_ValidStreams |= STREAM_POS;
+}
+
+void CShaderProgram::NormalPointer(GLenum type, GLsizei stride, void* pointer)
+{
+ glNormalPointer(type, stride, pointer);
+ m_ValidStreams |= STREAM_NORMAL;
+}
+
+void CShaderProgram::TexCoordPointer(GLenum texture, GLint size, GLenum type, GLsizei stride, void* pointer)
+{
+ pglActiveTextureARB(texture);
+ glTexCoordPointer(size, type, stride, pointer);
+ m_ValidStreams |= STREAM_UV0 << (texture - GL_TEXTURE0);
+}
+
CStr CShaderProgram::Preprocess(CPreprocessor& preprocessor, const CStr& input)
{
size_t len = 0;
@@ -620,3 +680,56 @@ CStr CShaderProgram::Preprocess(CPreprocessor& preprocessor, const CStr& input)
return ret;
}
+void CShaderProgram::BindClientStates()
+{
+ ENSURE(m_StreamFlags == (m_StreamFlags & (STREAM_POS|STREAM_NORMAL|STREAM_COLOR|STREAM_UV0|STREAM_UV1)));
+
+ // Enable all the desired client states for non-GLSL rendering
+
+ if (m_StreamFlags & STREAM_POS) glEnableClientState(GL_VERTEX_ARRAY);
+ if (m_StreamFlags & STREAM_NORMAL) glEnableClientState(GL_NORMAL_ARRAY);
+ if (m_StreamFlags & STREAM_COLOR) glEnableClientState(GL_COLOR_ARRAY);
+
+ if (m_StreamFlags & STREAM_UV0)
+ {
+ pglClientActiveTextureARB(GL_TEXTURE0);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+
+ if (m_StreamFlags & STREAM_UV1)
+ {
+ pglClientActiveTextureARB(GL_TEXTURE1);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ pglClientActiveTextureARB(GL_TEXTURE0);
+ }
+
+ // Rendering code must subsequently call VertexPointer etc for all of the streams
+ // that were activated in this function, else AssertPointersBound will complain
+ // that some arrays were unspecified
+ m_ValidStreams = 0;
+}
+
+void CShaderProgram::UnbindClientStates()
+{
+ if (m_StreamFlags & STREAM_POS) glDisableClientState(GL_VERTEX_ARRAY);
+ if (m_StreamFlags & STREAM_NORMAL) glDisableClientState(GL_NORMAL_ARRAY);
+ if (m_StreamFlags & STREAM_COLOR) glDisableClientState(GL_COLOR_ARRAY);
+
+ if (m_StreamFlags & STREAM_UV0)
+ {
+ pglClientActiveTextureARB(GL_TEXTURE0);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+
+ if (m_StreamFlags & STREAM_UV1)
+ {
+ pglClientActiveTextureARB(GL_TEXTURE1);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ pglClientActiveTextureARB(GL_TEXTURE0);
+ }
+}
+
+void CShaderProgram::AssertPointersBound()
+{
+ ENSURE(m_ValidStreams == m_StreamFlags);
+}
\ No newline at end of file
diff --git a/source/graphics/ShaderProgram.h b/source/graphics/ShaderProgram.h
index 56e12af62f..7f0312e17c 100644
--- a/source/graphics/ShaderProgram.h
+++ b/source/graphics/ShaderProgram.h
@@ -75,6 +75,7 @@ public:
*/
static CShaderProgram* ConstructGLSL(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const std::map& defines,
+ const std::map& vertexAttribs,
int streamflags);
/**
@@ -173,6 +174,18 @@ public:
void Uniform(uniform_id_t id, float v0, float v1, float v2, float v3);
void Uniform(uniform_id_t id, const CMatrix3D& v);
+ // Vertex attribute pointers (equivalent to glVertexPointer etc):
+
+ virtual void VertexPointer(GLint size, GLenum type, GLsizei stride, void* pointer);
+ virtual void NormalPointer(GLenum type, GLsizei stride, void* pointer);
+ virtual void TexCoordPointer(GLenum texture, GLint size, GLenum type, GLsizei stride, void* pointer);
+
+ /**
+ * Checks that all the required vertex attributes have been set.
+ * Call this before calling glDrawArrays/glDrawElements etc to avoid potential crashes.
+ */
+ void AssertPointersBound();
+
protected:
CShaderProgram(int streamflags);
@@ -180,6 +193,11 @@ protected:
bool m_IsValid;
int m_StreamFlags;
+
+ // Non-GLSL client state handling:
+ void BindClientStates();
+ void UnbindClientStates();
+ int m_ValidStreams; // which streams have been specified via VertexPointer etc since the last Bind
};
typedef shared_ptr CShaderProgramPtr;
diff --git a/source/graphics/ShaderProgramFFP.cpp b/source/graphics/ShaderProgramFFP.cpp
index 0726adf486..7db732ebd0 100644
--- a/source/graphics/ShaderProgramFFP.cpp
+++ b/source/graphics/ShaderProgramFFP.cpp
@@ -247,11 +247,14 @@ public:
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
-
+
+ BindClientStates();
}
virtual void Unbind()
{
+ UnbindClientStates();
+
pglActiveTextureARB(GL_TEXTURE2);
glDisable(GL_TEXTURE_2D);
@@ -311,10 +314,14 @@ public:
pglActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ BindClientStates();
}
virtual void Unbind()
{
+ UnbindClientStates();
+
pglActiveTextureARB(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
@@ -361,10 +368,14 @@ public:
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
+
+ BindClientStates();
}
virtual void Unbind()
{
+ UnbindClientStates();
+
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
diff --git a/source/gui/GUIRenderer.cpp b/source/gui/GUIRenderer.cpp
index 068161a2a7..34b92334ea 100644
--- a/source/gui/GUIRenderer.cpp
+++ b/source/gui/GUIRenderer.cpp
@@ -340,21 +340,20 @@ void GUIRenderer::Draw(DrawCalls &Calls, float Z)
std::swap(TexCoords.bottom, TexCoords.top);
}
- glBegin(GL_QUADS);
+ std::vector data;
+#define ADD(u, v, x, y, z) STMT(data.push_back(u); data.push_back(v); data.push_back(x); data.push_back(y); data.push_back(z))
+ ADD(TexCoords.left, TexCoords.bottom, Verts.left, Verts.bottom, Z + cit->m_DeltaZ);
+ ADD(TexCoords.right, TexCoords.bottom, Verts.right, Verts.bottom, Z + cit->m_DeltaZ);
+ ADD(TexCoords.right, TexCoords.top, Verts.right, Verts.top, Z + cit->m_DeltaZ);
- glTexCoord2f(TexCoords.left, TexCoords.bottom);
- glVertex3f(Verts.left, Verts.bottom, Z + cit->m_DeltaZ);
+ ADD(TexCoords.right, TexCoords.top, Verts.right, Verts.top, Z + cit->m_DeltaZ);
+ ADD(TexCoords.left, TexCoords.top, Verts.left, Verts.top, Z + cit->m_DeltaZ);
+ ADD(TexCoords.left, TexCoords.bottom, Verts.left, Verts.bottom, Z + cit->m_DeltaZ);
+#undef ADD
- glTexCoord2f(TexCoords.right, TexCoords.bottom);
- glVertex3f(Verts.right, Verts.bottom, Z + cit->m_DeltaZ);
-
- glTexCoord2f(TexCoords.right, TexCoords.top);
- glVertex3f(Verts.right, Verts.top, Z + cit->m_DeltaZ);
-
- glTexCoord2f(TexCoords.left, TexCoords.top);
- glVertex3f(Verts.left, Verts.top, Z + cit->m_DeltaZ);
-
- glEnd();
+ shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 5*sizeof(float), &data[0]);
+ shader->VertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
cit->m_Shader->EndPass(0);
}
@@ -378,23 +377,33 @@ void GUIRenderer::Draw(DrawCalls &Calls, float Z)
if (Verts.bottom < Verts.top)
std::swap(Verts.bottom, Verts.top);
- glBegin(GL_QUADS);
- glVertex3f(Verts.left, Verts.bottom, Z + cit->m_DeltaZ);
- glVertex3f(Verts.right, Verts.bottom, Z + cit->m_DeltaZ);
- glVertex3f(Verts.right, Verts.top, Z + cit->m_DeltaZ);
- glVertex3f(Verts.left, Verts.top, Z + cit->m_DeltaZ);
- glEnd();
+ std::vector data;
+#define ADD(x, y, z) STMT(data.push_back(x); data.push_back(y); data.push_back(z))
+ ADD(Verts.left, Verts.bottom, Z + cit->m_DeltaZ);
+ ADD(Verts.right, Verts.bottom, Z + cit->m_DeltaZ);
+ ADD(Verts.right, Verts.top, Z + cit->m_DeltaZ);
+
+ ADD(Verts.right, Verts.top, Z + cit->m_DeltaZ);
+ ADD(Verts.left, Verts.top, Z + cit->m_DeltaZ);
+ ADD(Verts.left, Verts.bottom, Z + cit->m_DeltaZ);
+
+ shader->VertexPointer(3, GL_FLOAT, 3*sizeof(float), &data[0]);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
if (cit->m_BorderColor != CColor())
{
shader->Uniform("color", cit->m_BorderColor);
- glBegin(GL_LINE_LOOP);
- glVertex3f(Verts.left + 0.5f, Verts.top + 0.5f, Z + cit->m_DeltaZ);
- glVertex3f(Verts.right - 0.5f, Verts.top + 0.5f, Z + cit->m_DeltaZ);
- glVertex3f(Verts.right - 0.5f, Verts.bottom - 0.5f, Z + cit->m_DeltaZ);
- glVertex3f(Verts.left + 0.5f, Verts.bottom - 0.5f, Z + cit->m_DeltaZ);
- glEnd();
+
+ data.clear();
+ ADD(Verts.left + 0.5f, Verts.top + 0.5f, Z + cit->m_DeltaZ);
+ ADD(Verts.right - 0.5f, Verts.top + 0.5f, Z + cit->m_DeltaZ);
+ ADD(Verts.right - 0.5f, Verts.bottom - 0.5f, Z + cit->m_DeltaZ);
+ ADD(Verts.left + 0.5f, Verts.bottom - 0.5f, Z + cit->m_DeltaZ);
+
+ shader->VertexPointer(3, GL_FLOAT, 3*sizeof(float), &data[0]);
+ glDrawArrays(GL_LINE_LOOP, 0, 4);
}
+#undef ADD
cit->m_Shader->EndPass(0);
}
diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp
index ec987f3bf4..48ebf56bfd 100644
--- a/source/gui/MiniMap.cpp
+++ b/source/gui/MiniMap.cpp
@@ -184,6 +184,13 @@ void CMiniMap::FireWorldClickEvent(int button, int clicks)
UNUSED2(clicks);
}
+#if CONFIG2_GLES
+#warning TODO: implement minimap for GLES
+void CMiniMap::Draw()
+{
+}
+#else
+
// render view rect : John M. Mena
// This sets up and draws the rectangle on the mini-map
// which represents the view of the camera in the world.
@@ -436,6 +443,8 @@ void CMiniMap::Draw()
glEnable(GL_TEXTURE_2D);
}
+#endif // CONFIG2_GLES
+
void CMiniMap::CreateTextures()
{
Destroy();
@@ -449,14 +458,14 @@ void CMiniMap::CreateTextures()
u32* texData = new u32[m_TextureSize * m_TextureSize];
for (ssize_t i = 0; i < m_TextureSize * m_TextureSize; ++i)
texData[i] = 0xFF000000;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_TextureSize, m_TextureSize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, texData);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureSize, m_TextureSize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, texData);
delete[] texData;
m_TerrainData = new u32[(m_MapSize - 1) * (m_MapSize - 1)];
- 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);
+ 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);
// Rebuild and upload both of them
RebuildTerrainTexture();
diff --git a/source/lib/res/graphics/unifont.cpp b/source/lib/res/graphics/unifont.cpp
index 726b48f9f1..847d21becd 100644
--- a/source/lib/res/graphics/unifont.cpp
+++ b/source/lib/res/graphics/unifont.cpp
@@ -291,7 +291,11 @@ void glvwprintf(const wchar_t* fmt, va_list args)
unifont_render(buf, &advance);
// Move into position for subsequent prints
+#if CONFIG2_GLES
+#warning TODO: implement unifont for GLES
+#else
glTranslatef((float)advance, 0, 0);
+#endif
}
void unifont_render(const wchar_t* str, int* advance)
diff --git a/source/renderer/FixedFunctionModelRenderer.cpp b/source/renderer/FixedFunctionModelRenderer.cpp
index f653cf672f..5354d1519e 100644
--- a/source/renderer/FixedFunctionModelRenderer.cpp
+++ b/source/renderer/FixedFunctionModelRenderer.cpp
@@ -240,7 +240,7 @@ void FixedFunctionModelRenderer::EndPass(int streamflags)
// Prepare UV coordinates for this modeldef
-void FixedFunctionModelRenderer::PrepareModelDef(int streamflags, const CModelDefPtr& def)
+void FixedFunctionModelRenderer::PrepareModelDef(CShaderProgramPtr& UNUSED(shader), int streamflags, const CModelDefPtr& def)
{
m->ffmodeldef = (FFModelDef*)def->GetRenderData(m);
@@ -257,7 +257,7 @@ void FixedFunctionModelRenderer::PrepareModelDef(int streamflags, const CModelDe
// Render one model
-void FixedFunctionModelRenderer::RenderModel(int streamflags, CModel* model, void* data)
+void FixedFunctionModelRenderer::RenderModel(CShaderProgramPtr& UNUSED(shader), int streamflags, CModel* model, void* data)
{
CModelDefPtr mdldef = model->GetModelDef();
FFModel* ffmodel = (FFModel*)data;
diff --git a/source/renderer/FixedFunctionModelRenderer.h b/source/renderer/FixedFunctionModelRenderer.h
index 79acfdd64c..d9952c9aa6 100644
--- a/source/renderer/FixedFunctionModelRenderer.h
+++ b/source/renderer/FixedFunctionModelRenderer.h
@@ -44,8 +44,8 @@ public:
void BeginPass(int streamflags);
void EndPass(int streamflags);
- void PrepareModelDef(int streamflags, const CModelDefPtr& def);
- void RenderModel(int streamflags, CModel* model, void* data);
+ void PrepareModelDef(CShaderProgramPtr& shader, int streamflags, const CModelDefPtr& def);
+ void RenderModel(CShaderProgramPtr& shader, int streamflags, CModel* model, void* data);
private:
FixedFunctionModelRendererInternals* m;
diff --git a/source/renderer/HWLightingModelRenderer.cpp b/source/renderer/HWLightingModelRenderer.cpp
index bd3d1adb76..dc9aeab5c9 100644
--- a/source/renderer/HWLightingModelRenderer.cpp
+++ b/source/renderer/HWLightingModelRenderer.cpp
@@ -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
@@ -205,7 +205,7 @@ void ShaderModelRenderer::EndPass(int streamflags)
// Prepare UV coordinates for this modeldef
-void ShaderModelRenderer::PrepareModelDef(int streamflags, const CModelDefPtr& def)
+void ShaderModelRenderer::PrepareModelDef(CShaderProgramPtr& shader, int streamflags, const CModelDefPtr& def)
{
m->shadermodeldef = (ShaderModelDef*)def->GetRenderData(m);
@@ -216,13 +216,13 @@ void ShaderModelRenderer::PrepareModelDef(int streamflags, const CModelDefPtr& d
u8* base = m->shadermodeldef->m_Array.Bind();
GLsizei stride = (GLsizei)m->shadermodeldef->m_Array.GetStride();
- glTexCoordPointer(2, GL_FLOAT, stride, base + m->shadermodeldef->m_UV.offset);
+ shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, base + m->shadermodeldef->m_UV.offset);
}
}
// Render one model
-void ShaderModelRenderer::RenderModel(int streamflags, CModel* model, void* data)
+void ShaderModelRenderer::RenderModel(CShaderProgramPtr& shader, int streamflags, CModel* model, void* data)
{
CModelDefPtr mdldef = model->GetModelDef();
ShaderModel* shadermodel = (ShaderModel*)data;
@@ -233,10 +233,12 @@ void ShaderModelRenderer::RenderModel(int streamflags, CModel* model, void* data
u8* indexBase = m->shadermodeldef->m_IndexArray.Bind();
if (streamflags & STREAM_POS)
- glVertexPointer(3, GL_FLOAT, stride, base + shadermodel->m_Position.offset);
+ shader->VertexPointer(3, GL_FLOAT, stride, base + shadermodel->m_Position.offset);
if (streamflags & STREAM_NORMAL)
- glNormalPointer(GL_FLOAT, stride, base + shadermodel->m_Normal.offset);
+ shader->NormalPointer(GL_FLOAT, stride, base + shadermodel->m_Normal.offset);
+
+ shader->AssertPointersBound();
// render the lot
size_t numFaces = mdldef->GetNumFaces();
diff --git a/source/renderer/HWLightingModelRenderer.h b/source/renderer/HWLightingModelRenderer.h
index 7ea933ecfe..04f6a7da24 100644
--- a/source/renderer/HWLightingModelRenderer.h
+++ b/source/renderer/HWLightingModelRenderer.h
@@ -51,8 +51,8 @@ public:
void BeginPass(int streamflags);
void EndPass(int streamflags);
- void PrepareModelDef(int streamflags, const CModelDefPtr& def);
- void RenderModel(int streamflags, CModel* model, void* data);
+ void PrepareModelDef(CShaderProgramPtr& shader, int streamflags, const CModelDefPtr& def);
+ void RenderModel(CShaderProgramPtr& shader, int streamflags, CModel* model, void* data);
protected:
ShaderModelRendererInternals* m;
diff --git a/source/renderer/InstancingModelRenderer.cpp b/source/renderer/InstancingModelRenderer.cpp
index c667ac0e2f..945b7fcffb 100644
--- a/source/renderer/InstancingModelRenderer.cpp
+++ b/source/renderer/InstancingModelRenderer.cpp
@@ -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
@@ -99,9 +99,6 @@ IModelDef::IModelDef(const CModelDefPtr& mdef)
struct InstancingModelRendererInternals
{
- /// Currently used RenderModifier
- RenderModifierPtr modifier;
-
/// Previously prepared modeldef
IModelDef* imodeldef;
@@ -157,35 +154,17 @@ void InstancingModelRenderer::DestroyModelData(CModel* UNUSED(model), void* UNUS
void InstancingModelRenderer::BeginPass(int streamflags)
{
ENSURE(streamflags == (streamflags & (STREAM_POS|STREAM_NORMAL|STREAM_UV0)));
-
- if (streamflags & STREAM_POS)
- glEnableClientState(GL_VERTEX_ARRAY);
-
- if (streamflags & STREAM_NORMAL)
- glEnableClientState(GL_NORMAL_ARRAY);
-
- if (streamflags & STREAM_UV0)
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
// Cleanup rendering pass.
-void InstancingModelRenderer::EndPass(int streamflags)
+void InstancingModelRenderer::EndPass(int UNUSED(streamflags))
{
- if (streamflags & STREAM_POS)
- glDisableClientState(GL_VERTEX_ARRAY);
-
- if (streamflags & STREAM_NORMAL)
- glDisableClientState(GL_NORMAL_ARRAY);
-
- if (streamflags & STREAM_UV0)
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
CVertexBuffer::Unbind();
}
// Prepare UV coordinates for this modeldef
-void InstancingModelRenderer::PrepareModelDef(int streamflags, const CModelDefPtr& def)
+void InstancingModelRenderer::PrepareModelDef(CShaderProgramPtr& shader, int streamflags, const CModelDefPtr& def)
{
m->imodeldef = (IModelDef*)def->GetRenderData(m);
@@ -197,18 +176,20 @@ void InstancingModelRenderer::PrepareModelDef(int streamflags, const CModelDefPt
m->imodeldefIndexBase = m->imodeldef->m_IndexArray.Bind();
if (streamflags & STREAM_POS)
- glVertexPointer(3, GL_FLOAT, stride, base + m->imodeldef->m_Position.offset);
+ shader->VertexPointer(3, GL_FLOAT, stride, base + m->imodeldef->m_Position.offset);
if (streamflags & STREAM_NORMAL)
- glNormalPointer(GL_FLOAT, stride, base + m->imodeldef->m_Normal.offset);
+ shader->NormalPointer(GL_FLOAT, stride, base + m->imodeldef->m_Normal.offset);
if (streamflags & STREAM_UV0)
- glTexCoordPointer(2, GL_FLOAT, stride, base + m->imodeldef->m_UV.offset);
+ shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, base + m->imodeldef->m_UV.offset);
+
+ shader->AssertPointersBound();
}
// Render one model
-void InstancingModelRenderer::RenderModel(int UNUSED(streamflags), CModel* model, void* UNUSED(data))
+void InstancingModelRenderer::RenderModel(CShaderProgramPtr& UNUSED(shader), int UNUSED(streamflags), CModel* model, void* UNUSED(data))
{
CModelDefPtr mdldef = model->GetModelDef();
diff --git a/source/renderer/InstancingModelRenderer.h b/source/renderer/InstancingModelRenderer.h
index cbbaf78589..35c654b1a2 100644
--- a/source/renderer/InstancingModelRenderer.h
+++ b/source/renderer/InstancingModelRenderer.h
@@ -45,8 +45,8 @@ public:
void BeginPass(int streamflags);
void EndPass(int streamflags);
- void PrepareModelDef(int streamflags, const CModelDefPtr& def);
- void RenderModel(int streamflags, CModel* model, void* data);
+ void PrepareModelDef(CShaderProgramPtr& shader, int streamflags, const CModelDefPtr& def);
+ void RenderModel(CShaderProgramPtr& shader, int streamflags, CModel* model, void* data);
protected:
InstancingModelRendererInternals* m;
diff --git a/source/renderer/ModelRenderer.cpp b/source/renderer/ModelRenderer.cpp
index ac0acf8543..b2fb28d0ec 100644
--- a/source/renderer/ModelRenderer.cpp
+++ b/source/renderer/ModelRenderer.cpp
@@ -442,9 +442,11 @@ void BatchModelRendererInternals::RenderAllModels(
const RenderModifierPtr& modifier, int filterflags,
int pass, int streamflags)
{
+ CShaderProgramPtr shader = modifier->GetShader(pass);
+
for(BMRModelDefTracker* mdeftracker = submissions; mdeftracker; mdeftracker = mdeftracker->m_Next)
{
- vertexRenderer->PrepareModelDef(streamflags, mdeftracker->m_ModelDef.lock());
+ vertexRenderer->PrepareModelDef(shader, streamflags, mdeftracker->m_ModelDef.lock());
for(size_t idx = 0; idx < mdeftracker->m_Slots; ++idx)
{
@@ -462,7 +464,7 @@ void BatchModelRendererInternals::RenderAllModels(
continue;
modifier->PrepareModel(pass, model);
- vertexRenderer->RenderModel(streamflags, model, bmrdata->m_Data);
+ vertexRenderer->RenderModel(shader, streamflags, model, bmrdata->m_Data);
}
}
}
diff --git a/source/renderer/ModelVertexRenderer.h b/source/renderer/ModelVertexRenderer.h
index 428e4ca8b5..2cbb011448 100644
--- a/source/renderer/ModelVertexRenderer.h
+++ b/source/renderer/ModelVertexRenderer.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009 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
@@ -24,6 +24,7 @@
#define INCLUDED_MODELVERTEXRENDERER
#include "graphics/MeshManager.h"
+#include "graphics/ShaderProgram.h"
class CModel;
@@ -147,7 +148,7 @@ public:
* BeginPass.
* @param def The model definition.
*/
- virtual void PrepareModelDef(int streamflags, const CModelDefPtr& def) = 0;
+ virtual void PrepareModelDef(CShaderProgramPtr& shader, int streamflags, const CModelDefPtr& def) = 0;
/**
@@ -169,7 +170,7 @@ public:
* that use the same CModelDef object and the same texture must
* succeed.
*/
- virtual void RenderModel(int streamflags, CModel* model, void* data) = 0;
+ virtual void RenderModel(CShaderProgramPtr& shader, int streamflags, CModel* model, void* data) = 0;
};
diff --git a/source/renderer/OverlayRenderer.cpp b/source/renderer/OverlayRenderer.cpp
index 53d6b59ce2..2fd44d0dc5 100644
--- a/source/renderer/OverlayRenderer.cpp
+++ b/source/renderer/OverlayRenderer.cpp
@@ -256,21 +256,6 @@ void OverlayRenderer::RenderTexturedOverlayLines(CShaderProgramPtr shaderTexLine
{
int streamflags = shaderTexLine->GetStreamFlags();
- if (streamflags & STREAM_POS)
- glEnableClientState(GL_VERTEX_ARRAY);
-
- if (streamflags & STREAM_UV0)
- {
- pglClientActiveTextureARB(GL_TEXTURE0);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- }
-
- if (streamflags & STREAM_UV1)
- {
- pglClientActiveTextureARB(GL_TEXTURE1);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- }
-
for (size_t i = 0; i < m->texlines.size(); ++i)
{
SOverlayTexturedLine* line = m->texlines[i];
@@ -293,26 +278,21 @@ void OverlayRenderer::RenderTexturedOverlayLines(CShaderProgramPtr shaderTexLine
CTexturedLineRData::SVertex* vertexBase = reinterpret_cast(rdata->m_VB->m_Owner->Bind());
if (streamflags & STREAM_POS)
- glVertexPointer(3, GL_FLOAT, stride, &vertexBase->m_Position[0]);
+ shaderTexLine->VertexPointer(3, GL_FLOAT, stride, &vertexBase->m_Position[0]);
if (streamflags & STREAM_UV0)
- {
- pglClientActiveTextureARB(GL_TEXTURE0);
- glTexCoordPointer(2, GL_FLOAT, stride, &vertexBase->m_UVs[0]);
- }
+ shaderTexLine->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, &vertexBase->m_UVs[0]);
if (streamflags & STREAM_UV1)
- {
- pglClientActiveTextureARB(GL_TEXTURE1);
- glTexCoordPointer(2, GL_FLOAT, stride, &vertexBase->m_UVs[0]);
- }
+ shaderTexLine->TexCoordPointer(GL_TEXTURE1, 2, GL_FLOAT, stride, &vertexBase->m_UVs[0]);
u8* indexBase = rdata->m_VBIndices->m_Owner->Bind();
+
+ shaderTexLine->AssertPointersBound();
glDrawElements(GL_TRIANGLES, rdata->m_VBIndices->m_Count, GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*rdata->m_VBIndices->m_Index);
+
g_Renderer.GetStats().m_OverlayTris += rdata->m_VBIndices->m_Count/3;
-
}
-
}
void OverlayRenderer::RenderForegroundOverlays(const CCamera& viewCamera)
diff --git a/source/renderer/RenderModifiers.cpp b/source/renderer/RenderModifiers.cpp
index d3d6e3d412..d0b34746b9 100644
--- a/source/renderer/RenderModifiers.cpp
+++ b/source/renderer/RenderModifiers.cpp
@@ -47,6 +47,10 @@ void RenderModifier::PrepareModel(int UNUSED(pass), CModel* UNUSED(model))
{
}
+CShaderProgramPtr RenderModifier::GetShader(int UNUSED(pass))
+{
+ return CShaderProgramPtr();
+}
///////////////////////////////////////////////////////////////////////////////////////////////
// LitRenderModifier implementation
@@ -272,6 +276,11 @@ bool ShaderRenderModifier::EndPass(int pass)
return (pass >= m_Technique->GetNumPasses()-1);
}
+CShaderProgramPtr ShaderRenderModifier::GetShader(int pass)
+{
+ return m_Technique->GetShader(pass);
+}
+
void ShaderRenderModifier::PrepareTexture(int pass, CTexturePtr& texture)
{
CShaderProgramPtr shader = m_Technique->GetShader(pass);
diff --git a/source/renderer/RenderModifiers.h b/source/renderer/RenderModifiers.h
index eb911e50e6..9a184793f7 100644
--- a/source/renderer/RenderModifiers.h
+++ b/source/renderer/RenderModifiers.h
@@ -72,6 +72,11 @@ public:
*/
virtual bool EndPass(int pass) = 0;
+ /**
+ * Return the shader for the given pass, or a null pointer if none.
+ */
+ virtual CShaderProgramPtr GetShader(int pass);
+
/**
* PrepareTexture: Called before rendering models that use the given
* texture.
@@ -200,6 +205,7 @@ public:
// Implementation
int BeginPass(int pass);
bool EndPass(int pass);
+ CShaderProgramPtr GetShader(int pass);
void PrepareTexture(int pass, CTexturePtr& texture);
void PrepareModel(int pass, CModel* model);
diff --git a/source/renderer/TransparencyRenderer.cpp b/source/renderer/TransparencyRenderer.cpp
index 7c5c119336..1cdd37c139 100644
--- a/source/renderer/TransparencyRenderer.cpp
+++ b/source/renderer/TransparencyRenderer.cpp
@@ -330,7 +330,7 @@ void PolygonSortModelRenderer::EndPass(int streamflags)
// Prepare for rendering models using this CModelDef
-void PolygonSortModelRenderer::PrepareModelDef(int streamflags, const CModelDefPtr& def)
+void PolygonSortModelRenderer::PrepareModelDef(CShaderProgramPtr& UNUSED(shader), int streamflags, const CModelDefPtr& def)
{
if (streamflags & STREAM_UV0)
{
@@ -347,7 +347,7 @@ void PolygonSortModelRenderer::PrepareModelDef(int streamflags, const CModelDefP
// Render one model
-void PolygonSortModelRenderer::RenderModel(int streamflags, CModel* model, void* data)
+void PolygonSortModelRenderer::RenderModel(CShaderProgramPtr& UNUSED(shader), int streamflags, CModel* model, void* data)
{
CModelDefPtr mdef = model->GetModelDef();
PSModel* psmdl = (PSModel*)data;
@@ -529,6 +529,8 @@ void SortModelRenderer::Render(const RenderModifierPtr& modifier, int flags)
CModelDefPtr lastmdef;
CTexturePtr lasttex;
+ CShaderProgramPtr shader = modifier->GetShader(pass);
+
m->vertexRenderer->BeginPass(streamflags);
for(std::vector::iterator it = m->models.begin(); it != m->models.end(); ++it)
@@ -547,7 +549,7 @@ void SortModelRenderer::Render(const RenderModifierPtr& modifier, int flags)
// Prepare per-CModelDef data if changed
if (mdef != lastmdef)
{
- m->vertexRenderer->PrepareModelDef(streamflags, mdef);
+ m->vertexRenderer->PrepareModelDef(shader, streamflags, mdef);
lastmdef = mdef;
}
@@ -561,7 +563,7 @@ void SortModelRenderer::Render(const RenderModifierPtr& modifier, int flags)
modifier->PrepareModel(pass, mdl);
// Render the model
- m->vertexRenderer->RenderModel(streamflags, mdl, smdl->m_Data);
+ m->vertexRenderer->RenderModel(shader, streamflags, mdl, smdl->m_Data);
}
m->vertexRenderer->EndPass(streamflags);
diff --git a/source/renderer/TransparencyRenderer.h b/source/renderer/TransparencyRenderer.h
index ca308698f1..73d2fe2dd2 100644
--- a/source/renderer/TransparencyRenderer.h
+++ b/source/renderer/TransparencyRenderer.h
@@ -51,8 +51,8 @@ public:
void BeginPass(int streamflags);
void EndPass(int streamflags);
- void PrepareModelDef(int streamflags, const CModelDefPtr& def);
- void RenderModel(int streamflags, CModel* model, void* data);
+ void PrepareModelDef(CShaderProgramPtr& shader, int streamflags, const CModelDefPtr& def);
+ void RenderModel(CShaderProgramPtr& shader, int streamflags, CModel* model, void* data);
private:
PolygonSortModelRendererInternals* m;