Initial support for GLSL generic vertex attributes in shader API, for GLES compatibility.

Specify GLSL version in shader files, for better error detection.

This was SVN commit r11040.
This commit is contained in:
Ykkrosh 2012-02-09 17:55:25 +00:00
parent 1f5b8f1c9a
commit a3f168b887
27 changed files with 337 additions and 130 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -5,6 +5,9 @@
<stream name="pos"/>
<stream name="normal"/>
<stream name="uv0"/>
<attrib name="a_vertex" semantics="gl_Vertex"/>
<attrib name="a_normal" semantics="gl_Normal"/>
<attrib name="a_uv0" semantics="gl_MultiTexCoord0"/>
</vertex>
<fragment file="model_common.fs"/>

View File

@ -7,6 +7,9 @@
<stream name="pos"/>
<stream name="normal"/>
<stream name="uv0"/>
<attrib name="a_vertex" semantics="gl_Vertex"/>
<attrib name="a_normal" semantics="gl_Normal"/>
<attrib name="a_uv0" semantics="gl_MultiTexCoord0"/>
</vertex>
<fragment file="model_common.fs"/>

View File

@ -48,7 +48,23 @@
<choice>
<element name="attrib">
<attribute name="name"><text/></attribute>
<attribute name="loc"><data type="integer"/></attribute>
<attribute name="semantics">
<choice>
<value>gl_Vertex</value>
<value>gl_Normal</value>
<value>gl_Color</value>
<value>gl_SecondaryColor</value>
<value>gl_FogCoord</value>
<value>gl_MultiTexCoord0</value>
<value>gl_MultiTexCoord1</value>
<value>gl_MultiTexCoord2</value>
<value>gl_MultiTexCoord3</value>
<value>gl_MultiTexCoord4</value>
<value>gl_MultiTexCoord5</value>
<value>gl_MultiTexCoord6</value>
<value>gl_MultiTexCoord7</value>
</choice>
</attribute>
</element>
<ref name="streamContent"/>
</choice>

View File

@ -1,3 +1,5 @@
#version 110
uniform vec3 ambient;
uniform vec3 sunDir;
uniform vec3 sunColor;

View File

@ -1,3 +1,5 @@
#version 110
uniform mat4 reflectionMatrix;
uniform mat4 refractionMatrix;
uniform mat4 losMatrix;

View File

@ -82,6 +82,29 @@ CShaderProgramPtr CShaderManager::LoadProgram(const char* name, const std::map<C
return program;
}
static GLenum ParseAttribSemantics(const CStr& str)
{
// Map known semantics onto the attribute locations documented by NVIDIA
if (str == "gl_Vertex") return 0;
if (str == "gl_Normal") return 2;
if (str == "gl_Color") return 3;
if (str == "gl_SecondaryColor") return 4;
if (str == "gl_FogCoord") return 5;
if (str == "gl_MultiTexCoord0") return 8;
if (str == "gl_MultiTexCoord1") return 9;
if (str == "gl_MultiTexCoord2") return 10;
if (str == "gl_MultiTexCoord3") return 11;
if (str == "gl_MultiTexCoord4") return 12;
if (str == "gl_MultiTexCoord5") return 13;
if (str == "gl_MultiTexCoord6") return 14;
if (str == "gl_MultiTexCoord7") return 15;
// TODO: support user-defined semantics somehow
debug_warn("Invalid attribute semantics");
return 0;
}
bool CShaderManager::NewProgram(const char* name, const std::map<CStr, CStr>& baseDefines, CShaderProgramPtr& program)
{
PROFILE2("loading shader");
@ -120,17 +143,18 @@ bool CShaderManager::NewProgram(const char* name, const std::map<CStr, CStr>& 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<CStr, CStr>& ba
std::map<CStr, CStr> defines = baseDefines;
std::map<CStr, int> vertexUniforms;
std::map<CStr, int> fragmentUniforms;
std::map<CStr, int> vertexAttribs;
int streamFlags = 0;
XERO_ITER_EL(Root, Child)
@ -180,7 +205,8 @@ bool CShaderManager::NewProgram(const char* name, const std::map<CStr, CStr>& 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<CStr, CStr>& 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));

View File

@ -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<CStr, CStr>& defines,
const std::map<CStr, int>& 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<CStr, int>::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<CStr, int>::iterator it = m_VertexAttribs.begin(); it != m_VertexAttribs.end(); ++it)
pglEnableVertexAttribArrayARB(it->second);
}
virtual void Unbind()
{
pglUseProgramObjectARB(0);
for (std::map<CStr, int>::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<CStr, CStr> m_Defines;
std::map<CStr, int> 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<CStr, CStr>& defines,
const std::map<CStr, int>& 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);
}

View File

@ -75,6 +75,7 @@ public:
*/
static CShaderProgram* ConstructGLSL(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const std::map<CStr, CStr>& defines,
const std::map<CStr, int>& 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<CShaderProgram> CShaderProgramPtr;

View File

@ -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);

View File

@ -340,21 +340,20 @@ void GUIRenderer::Draw(DrawCalls &Calls, float Z)
std::swap(TexCoords.bottom, TexCoords.top);
}
glBegin(GL_QUADS);
std::vector<float> 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<float> 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);
}

View File

@ -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();

View File

@ -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)

View File

@ -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;

View File

@ -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;

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
@ -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();

View File

@ -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;

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
@ -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();

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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;
};

View File

@ -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<CTexturedLineRData::SVertex*>(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)

View File

@ -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);

View File

@ -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);

View File

@ -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<SModel*>::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);

View File

@ -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;