Support more commands in shader technique XML files.

Always print GLSL shader logs, to help debugging.

This was SVN commit r11149.
This commit is contained in:
Ykkrosh 2012-02-25 15:38:38 +00:00
parent 7286fbaf90
commit 9b0a3830df
4 changed files with 108 additions and 36 deletions

View File

@ -238,6 +238,28 @@ bool CShaderManager::NewProgram(const char* name, const std::map<CStr, CStr>& ba
return true;
}
static GLenum ParseComparisonFunc(const CStr& str)
{
if (str == "never")
return GL_NEVER;
if (str == "always")
return GL_ALWAYS;
if (str == "less")
return GL_LESS;
if (str == "lequal")
return GL_LEQUAL;
if (str == "equal")
return GL_EQUAL;
if (str == "gequal")
return GL_GEQUAL;
if (str == "greater")
return GL_GREATER;
if (str == "notequal")
return GL_NOTEQUAL;
debug_warn("Invalid comparison func");
return GL_ALWAYS;
}
static GLenum ParseBlendFunc(const CStr& str)
{
if (str == "zero")
@ -270,6 +292,7 @@ static GLenum ParseBlendFunc(const CStr& str)
return GL_ONE_MINUS_CONSTANT_ALPHA;
if (str == "src_alpha_saturate")
return GL_SRC_ALPHA_SATURATE;
debug_warn("Invalid blend func");
return GL_ZERO;
}
@ -325,7 +348,9 @@ bool CShaderManager::NewEffect(const char* name, const std::map<CStr, CStr>& bas
CShaderProgramPtr program = LoadProgram(name+7, baseDefines);
if (!program)
return false;
tech->AddPass(CShaderPass(program));
CShaderPass pass;
pass.SetShader(program);
tech->AddPass(pass);
return true;
}
@ -339,13 +364,21 @@ bool CShaderManager::NewEffect(const char* name, const std::map<CStr, CStr>& bas
// 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(alpha);
EL(blend);
EL(define);
EL(depth);
EL(pass);
EL(require);
EL(blend);
AT(shaders);
AT(shader);
AT(src);
AT(dst);
AT(func);
AT(ref);
AT(shader);
AT(shaders);
AT(src);
AT(mask);
AT(name);
AT(value);
#undef AT
#undef EL
@ -405,19 +438,41 @@ bool CShaderManager::NewEffect(const char* name, const std::map<CStr, CStr>& bas
{
if (Child.GetNodeName() == el_pass)
{
CShaderProgramPtr shader = LoadProgram(Child.GetAttributes().GetNamedItem(at_shader).c_str(), baseDefines);
CShaderPass pass(shader);
std::map<CStr, CStr> defines = baseDefines;
CShaderPass pass;
XERO_ITER_EL(Child, Element)
{
if (Element.GetNodeName() == el_blend)
if (Element.GetNodeName() == el_define)
{
defines[Element.GetAttributes().GetNamedItem(at_name)] = Element.GetAttributes().GetNamedItem(at_value);
}
else if (Element.GetNodeName() == el_alpha)
{
GLenum func = ParseComparisonFunc(Element.GetAttributes().GetNamedItem(at_func));
float ref = Element.GetAttributes().GetNamedItem(at_ref).ToFloat();
pass.AlphaFunc(func, ref);
}
else if (Element.GetNodeName() == el_blend)
{
GLenum src = ParseBlendFunc(Element.GetAttributes().GetNamedItem(at_src));
GLenum dst = ParseBlendFunc(Element.GetAttributes().GetNamedItem(at_dst));
pass.BlendFunc(src, dst);
}
else if (Element.GetNodeName() == el_depth)
{
if (!Element.GetAttributes().GetNamedItem(at_func).empty())
pass.DepthFunc(ParseComparisonFunc(Element.GetAttributes().GetNamedItem(at_func)));
if (!Element.GetAttributes().GetNamedItem(at_mask).empty())
pass.DepthMask(Element.GetAttributes().GetNamedItem(at_mask) == "true" ? 1 : 0);
}
}
// Load the shader program after we've read all the possibly-relevant <define>s
pass.SetShader(LoadProgram(Child.GetAttributes().GetNamedItem(at_shader).c_str(), defines));
tech->AddPass(pass);
}
}

View File

@ -268,27 +268,31 @@ public:
GLint ok = 0;
pglGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
if (!ok)
GLint length = 0;
pglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
// Apparently sometimes GL_INFO_LOG_LENGTH is incorrectly reported as 0
// (http://code.google.com/p/android/issues/detail?id=9953)
if (!ok && length == 0)
length = 4096;
if (length > 1)
{
GLint length = 0;
pglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
// Apparently sometimes GL_INFO_LOG_LENGTH is incorrectly reported as 0
// (http://code.google.com/p/android/issues/detail?id=9953)
if (length == 0)
length = 4096;
char* infolog = new char[length];
pglGetShaderInfoLog(shader, length, NULL, infolog);
LOGERROR(L"Failed to compile shader '%ls':\n%hs", file.string().c_str(), infolog);
delete[] infolog;
return false;
if (ok)
LOGMESSAGE(L"Info when compiling shader '%ls':\n%hs", file.string().c_str(), infolog);
else
LOGERROR(L"Failed to compile shader '%ls':\n%hs", file.string().c_str(), infolog);
delete[] infolog;
}
ogl_WarnIfError();
return true;
return (ok ? true : false);
}
bool Link()
@ -311,24 +315,31 @@ public:
GLint ok = 0;
pglGetProgramiv(m_Program, GL_LINK_STATUS, &ok);
if (!ok)
GLint length = 0;
pglGetProgramiv(m_Program, GL_INFO_LOG_LENGTH, &length);
if (!ok && length == 0)
length = 4096;
if (length > 1)
{
GLint length = 0;
pglGetProgramiv(m_Program, GL_INFO_LOG_LENGTH, &length);
if (length == 0)
length = 4096;
char* infolog = new char[length];
pglGetProgramInfoLog(m_Program, length, NULL, infolog);
LOGERROR(L"Failed to link program '%ls'+'%ls':\n%hs", m_VertexFile.string().c_str(), m_FragmentFile.string().c_str(), infolog);
delete[] infolog;
return false;
if (ok)
LOGMESSAGE(L"Info when linking program '%ls'+'%ls':\n%hs", m_VertexFile.string().c_str(), m_FragmentFile.string().c_str(), infolog);
else
LOGERROR(L"Failed to link program '%ls'+'%ls':\n%hs", m_VertexFile.string().c_str(), m_FragmentFile.string().c_str(), infolog);
delete[] infolog;
}
ogl_WarnIfError();
if (!ok)
return false;
m_UniformLocations.clear();
m_UniformTypes.clear();
m_Samplers.clear();
@ -402,7 +413,9 @@ public:
// Ugly hack to replace desktop GLSL 1.10 with GLSL ES 1.00,
// and also to set default float precision for fragment shaders
vertexCode.Replace("#version 110\n", "#version 100\n");
fragmentCode.Replace("#version 110\n", "#version 100\nprecision highp float;\n");
vertexCode.Replace("#version 110\r\n", "#version 100\n");
fragmentCode.Replace("#version 110\n", "#version 100\nprecision mediump float;\n");
fragmentCode.Replace("#version 110\r\n", "#version 100\nprecision mediump float;\n");
#endif
if (!Compile(m_VertexShader, m_VertexFile, vertexCode))

View File

@ -19,8 +19,7 @@
#include "ShaderTechnique.h"
CShaderPass::CShaderPass(const CShaderProgramPtr& shader) :
m_Shader(shader),
CShaderPass::CShaderPass() :
m_HasAlpha(false), m_HasBlend(false), m_HasColorMask(false), m_HasDepthMask(false), m_HasDepthFunc(false)
{
}

View File

@ -26,7 +26,12 @@
class CShaderPass
{
public:
CShaderPass(const CShaderProgramPtr& shader);
CShaderPass();
/**
* Set the shader program used for rendering with this pass.
*/
void SetShader(const CShaderProgramPtr& shader) { m_Shader = shader; }
// Add various bits of GL state to the pass:
void AlphaFunc(GLenum func, GLclampf ref);
@ -36,7 +41,7 @@ public:
void DepthFunc(GLenum func);
/**
* Set all the GL state that was previously specified on this pass.
* Set up all the GL state that was previously specified on this pass.
*/
void Bind();