Internally compose and pass an array of shader source codes to OpenGL, instead of relying on #line to make sure the line number is correct for shader error messages (resolves issue #882)

This commit is contained in:
Alex Szpakowski
2014-05-03 21:43:20 -03:00
parent 9972153696
commit 4bc96f1bf6
7 changed files with 158 additions and 78 deletions
+27 -12
View File
@@ -66,21 +66,25 @@ Shader *Shader::current = nullptr;
GLint Shader::maxTexUnits = 0;
std::vector<int> Shader::textureCounters;
Shader::Shader(const ShaderSources &sources)
: shaderSources(sources)
, program(0)
Shader::Shader(const std::vector<std::string> &vertcode, const std::vector<std::string> &pixelcode)
: program(0)
, builtinUniforms()
, vertexAttributes()
, lastCanvas((Canvas *) -1)
, lastViewport()
{
if (shaderSources.empty())
if (vertcode.empty() && pixelcode.empty())
throw love::Exception("Cannot create shader: no source code!");
shaderSources[TYPE_VERTEX] = vertcode;
shaderSources[TYPE_PIXEL] = pixelcode;
if (maxTexUnits <= 0)
{
GLint maxtexunits;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtexunits);
// TU 0 is never used for stored Shader images.
maxTexUnits = std::max(maxtexunits - 1, 0);
}
@@ -106,7 +110,7 @@ Shader::~Shader()
unloadVolatile();
}
GLuint Shader::compileCode(ShaderType type, const std::string &code)
GLuint Shader::compileCode(ShaderType type, const std::vector<std::string> &code)
{
GLenum glshadertype;
const char *typestr;
@@ -142,9 +146,18 @@ GLuint Shader::compileCode(ShaderType type, const std::string &code)
throw love::Exception("Cannot create %s shader object.", typestr);
}
const char *src = code.c_str();
size_t srclen = code.length();
glShaderSource(shaderid, 1, (const GLchar **)&src, (GLint *)&srclen);
std::vector<const GLchar *> codelist;
std::vector<GLint> lengthlist;
for (size_t i = 0; i < code.size(); i++)
{
codelist.push_back((const GLchar *) code[i].c_str());
lengthlist.push_back((GLint) code[i].length());
}
// The code parameter is a list of source code "files." We can hand them
// all to OpenGL at once using glShaderSource.
glShaderSource(shaderid, codelist.size(), &codelist[0], &lengthlist[0]);
glCompileShader(shaderid);
@@ -276,10 +289,12 @@ bool Shader::loadVolatile()
std::vector<GLuint> shaderids;
ShaderSources::const_iterator source;
for (source = shaderSources.begin(); source != shaderSources.end(); ++source)
for (int i = 0; i < (int) TYPE_MAX_ENUM; i++)
{
GLuint shaderid = compileCode(source->first, source->second);
if (shaderSources[i].empty())
continue;
GLuint shaderid = compileCode((ShaderType) i, shaderSources[i]);
shaderids.push_back(shaderid);
}
@@ -288,7 +303,7 @@ bool Shader::loadVolatile()
createProgram(shaderids);
// Retreive all active uniform variables in this shader from OpenGL.
// Get all active uniform variables in this shader from OpenGL.
mapActiveUniforms();
for (int i = 0; i < int(OpenGL::ATTRIB_MAX_ENUM); i++)