changed shadereffect texture image unit counter and map to be non-static, get max texture units from max combined TIUs instead of max fragment shader TIUs, added the current MVP matrix as an argument to the vertex shader transform function, reduced code duplication in ShaderEffect::sendImage and sendCanvas

This commit is contained in:
Alexander Szpakowski
2012-12-21 05:03:50 -04:00
parent 0611234067
commit 5252ed28cd
4 changed files with 61 additions and 54 deletions
+32 -43
View File
@@ -19,7 +19,6 @@
**/ **/
#include "ShaderEffect.h" #include "ShaderEffect.h"
#include "GLee.h"
#include "Graphics.h" #include "Graphics.h"
namespace namespace
@@ -51,36 +50,34 @@ namespace opengl
ShaderEffect *ShaderEffect::current = NULL; ShaderEffect *ShaderEffect::current = NULL;
std::map<std::string, GLint> ShaderEffect::_texture_unit_pool;
GLint ShaderEffect::_current_texture_unit = 0;
GLint ShaderEffect::_max_texture_units = 0;
GLint ShaderEffect::getTextureUnit(const std::string &name)
{
std::map<std::string, GLint>::const_iterator it = _texture_unit_pool.find(name);
if (it != _texture_unit_pool.end())
return it->second;
if (++_current_texture_unit >= _max_texture_units)
throw love::Exception("No more texture units available");
_texture_unit_pool[name] = _current_texture_unit;
return _current_texture_unit;
}
ShaderEffect::ShaderEffect(const std::string &vertcode, const std::string &fragcode) ShaderEffect::ShaderEffect(const std::string &vertcode, const std::string &fragcode)
: _program(0) : _program(0)
, _vertcode(vertcode) , _vertcode(vertcode)
, _fragcode(fragcode) , _fragcode(fragcode)
, _current_texture_unit(0)
{ {
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &_max_texture_units); glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &_max_texture_units);
loadVolatile(); loadVolatile();
} }
GLint ShaderEffect::getTextureUnit(const std::string &name)
{
std::map<std::string, GLint>::const_iterator it = _texture_unit_pool.find(name);
if (it != _texture_unit_pool.end())
return it->second;
if (++_current_texture_unit >= _max_texture_units)
throw love::Exception("No more texture units available");
_texture_unit_pool[name] = _current_texture_unit;
return _current_texture_unit;
}
GLuint ShaderEffect::createShader(GLenum type, const std::string &code) GLuint ShaderEffect::createShader(GLenum type, const std::string &code)
{ {
const char *shadertypename = NULL; const char *shadertypename = NULL;
switch (type) switch (type)
{ {
case GL_VERTEX_SHADER: case GL_VERTEX_SHADER:
@@ -138,7 +135,7 @@ void ShaderEffect::createProgram(const std::vector<GLuint> &shaders)
glLinkProgram(_program); glLinkProgram(_program);
for (it = shaders.begin(); it != shaders.end(); ++it) for (it = shaders.begin(); it != shaders.end(); ++it)
glDetachShader(_program, *it); glDetachShader(_program, *it); // we can freely detach shaders after linking
GLint link_ok; GLint link_ok;
glGetProgramiv(_program, GL_LINK_STATUS, &link_ok); glGetProgramiv(_program, GL_LINK_STATUS, &link_ok);
@@ -162,7 +159,7 @@ bool ShaderEffect::loadVolatile()
shaders.push_back(createShader(GL_FRAGMENT_SHADER, _fragcode)); shaders.push_back(createShader(GL_FRAGMENT_SHADER, _fragcode));
if (shaders.size() == 0) if (shaders.size() == 0)
throw love::Exception("Cannot create ShaderEffect: no source code!"); throw love::Exception("Cannot create shader effect: no source code!");
try try
{ {
@@ -305,40 +302,32 @@ void ShaderEffect::sendMatrix(const std::string &name, int size, const GLfloat *
checkSetUniformError(); checkSetUniformError();
} }
void ShaderEffect::sendImage(const std::string &name, const Image &image) void ShaderEffect::sendTexture(const std::string &name, GLuint texture)
{ {
GLint texture_unit = getTextureUnit(name);
TemporaryAttacher attacher(this); TemporaryAttacher attacher(this);
GLint location = getUniformLocation(name); GLint location = getUniformLocation(name);
GLint texture_unit = getTextureUnit(name);
glActiveTexture(GL_TEXTURE0 + texture_unit); glActiveTexture(GL_TEXTURE0 + texture_unit);
bindTexture(image.getTextureName(), true); // guarantee it gets bound bindTexture(texture, true); // guarantee it gets bound
glUniform1i(location, texture_unit); glUniform1i(location, texture_unit);
// reset texture unit // reset texture unit
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
// throw error if needed // throw error if needed
checkSetUniformError(); checkSetUniformError();
} }
void ShaderEffect::sendImage(const std::string &name, const Image &image)
{
sendTexture(name, image.getTextureName());
}
void ShaderEffect::sendCanvas(const std::string &name, const Canvas &canvas) void ShaderEffect::sendCanvas(const std::string &name, const Canvas &canvas)
{ {
GLint texture_unit = getTextureUnit(name); sendTexture(name, canvas.getTextureName());
TemporaryAttacher attacher(this);
GLint location = getUniformLocation(name);
glActiveTexture(GL_TEXTURE0 + texture_unit);
bindTexture(canvas.getTextureName(), true); // guarantee it gets bound
glUniform1i(location, texture_unit);
// reset texture unit
glActiveTexture(GL_TEXTURE0);
// throw error if needed
checkSetUniformError();
} }
GLint ShaderEffect::getUniformLocation(const std::string &name) GLint ShaderEffect::getUniformLocation(const std::string &name)
+6 -4
View File
@@ -72,10 +72,12 @@ private:
std::map<std::string, GLint> _uniforms; std::map<std::string, GLint> _uniforms;
// texture unit pool for setting images // texture unit pool for setting images
static std::map<std::string, GLint> _texture_unit_pool; std::map<std::string, GLint> _texture_unit_pool;
static GLint _current_texture_unit; GLint _current_texture_unit;
static GLint _max_texture_units; GLint _max_texture_units;
static GLint getTextureUnit(const std::string &name); GLint getTextureUnit(const std::string &name);
void sendTexture(const std::string &name, GLuint texture);
}; };
} // opengl } // opengl
+7 -3
View File
@@ -1299,7 +1299,7 @@ uniform sampler2D _tex0_;]],
void main() { void main() {
gl_TexCoord[0] = gl_MultiTexCoord0; gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color; gl_FrontColor = gl_Color;
gl_Position = transform(gl_Vertex); gl_Position = transform(gl_ModelViewProjectionMatrix, gl_Vertex);
}]], }]],
} }
@@ -1349,7 +1349,7 @@ void main() {
fragcode = table.concat{GLSL_FRAG.HEADER, "\n", fragcode, GLSL_FRAG.FOOTER} fragcode = table.concat{GLSL_FRAG.HEADER, "\n", fragcode, GLSL_FRAG.FOOTER}
end end
return vertcode, fragcode return vertcode, fragcode
end end
function love.graphics._transformGLSLErrorMessages(message) function love.graphics._transformGLSLErrorMessages(message)
@@ -1366,7 +1366,11 @@ void main() {
linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$") linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$")
end end
if linenumber and what and message then if linenumber and what and message then
linenumber = linenumber - GLSL_HEADER_LINE_COUNT local headerlinecount = GLSL_FRAG.HEADER_LINE_COUNT
if shadertype == "vertex" then
headerlinecount = GLSL_VERT.HEADER_LINE_COUNT
end
linenumber = linenumber - headerlinecount
lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber, what, message) lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber, what, message)
end end
end end
+16 -4
View File
@@ -6285,7 +6285,9 @@ const unsigned char graphics_lua[] =
0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x67, 0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x67,
0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a,
0x09, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x61, 0x09, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x61,
0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x67, 0x6c, 0x5f, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x29, 0x3b, 0x0a, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x67, 0x6c, 0x5f, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65,
0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2c,
0x20, 0x67, 0x6c, 0x5f, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x29, 0x3b, 0x0a,
0x7d, 0x5d, 0x5d, 0x2c, 0x0a, 0x7d, 0x5d, 0x5d, 0x2c, 0x0a,
0x09, 0x7d, 0x0a, 0x09, 0x7d, 0x0a,
0x09, 0x0a, 0x09, 0x0a,
@@ -6376,7 +6378,7 @@ const unsigned char graphics_lua[] =
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a,
0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c,
0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x0a, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61,
0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x47, 0x4c, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x47, 0x4c,
@@ -6425,9 +6427,19 @@ const unsigned char graphics_lua[] =
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x6e, 0x64, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x6c, 0x69,
0x6e, 0x65, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x46, 0x52, 0x41,
0x47, 0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e,
0x54, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x20,
0x3d, 0x3d, 0x20, 0x22, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x09, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x20, 0x3d, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x2e, 0x48, 0x45, 0x41,
0x44, 0x45, 0x52, 0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x6c, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x6c,
0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x48, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72,
0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x5b, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2b, 0x31, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x5b, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2b, 0x31,
0x5d, 0x20, 0x3d, 0x20, 0x28, 0x22, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x25, 0x64, 0x3a, 0x20, 0x25, 0x73, 0x3a, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x22, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x25, 0x64, 0x3a, 0x20, 0x25, 0x73, 0x3a,
0x20, 0x25, 0x73, 0x22, 0x29, 0x3a, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x20, 0x25, 0x73, 0x22, 0x29, 0x3a, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x6e,