From 5252ed28cd21092b37ab4416844556fb12192349 Mon Sep 17 00:00:00 2001 From: Alexander Szpakowski Date: Fri, 21 Dec 2012 05:03:50 -0400 Subject: [PATCH] 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 --- src/modules/graphics/opengl/ShaderEffect.cpp | 75 +++++++++----------- src/modules/graphics/opengl/ShaderEffect.h | 10 +-- src/scripts/graphics.lua | 10 ++- src/scripts/graphics.lua.h | 20 ++++-- 4 files changed, 61 insertions(+), 54 deletions(-) diff --git a/src/modules/graphics/opengl/ShaderEffect.cpp b/src/modules/graphics/opengl/ShaderEffect.cpp index 10d91c7cf..b17b6fead 100644 --- a/src/modules/graphics/opengl/ShaderEffect.cpp +++ b/src/modules/graphics/opengl/ShaderEffect.cpp @@ -19,7 +19,6 @@ **/ #include "ShaderEffect.h" -#include "GLee.h" #include "Graphics.h" namespace @@ -51,36 +50,34 @@ namespace opengl ShaderEffect *ShaderEffect::current = NULL; -std::map 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::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) : _program(0) , _vertcode(vertcode) , _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(); } +GLint ShaderEffect::getTextureUnit(const std::string &name) +{ + std::map::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) { const char *shadertypename = NULL; + switch (type) { case GL_VERTEX_SHADER: @@ -138,7 +135,7 @@ void ShaderEffect::createProgram(const std::vector &shaders) glLinkProgram(_program); for (it = shaders.begin(); it != shaders.end(); ++it) - glDetachShader(_program, *it); + glDetachShader(_program, *it); // we can freely detach shaders after linking GLint link_ok; glGetProgramiv(_program, GL_LINK_STATUS, &link_ok); @@ -162,7 +159,7 @@ bool ShaderEffect::loadVolatile() shaders.push_back(createShader(GL_FRAGMENT_SHADER, _fragcode)); if (shaders.size() == 0) - throw love::Exception("Cannot create ShaderEffect: no source code!"); + throw love::Exception("Cannot create shader effect: no source code!"); try { @@ -305,40 +302,32 @@ void ShaderEffect::sendMatrix(const std::string &name, int size, const GLfloat * 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); GLint location = getUniformLocation(name); - + + GLint texture_unit = getTextureUnit(name); + glActiveTexture(GL_TEXTURE0 + texture_unit); - bindTexture(image.getTextureName(), true); // guarantee it gets bound + bindTexture(texture, true); // guarantee it gets bound glUniform1i(location, texture_unit); - + // reset texture unit glActiveTexture(GL_TEXTURE0); - + // throw error if needed 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) { - GLint texture_unit = getTextureUnit(name); - - 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(); + sendTexture(name, canvas.getTextureName()); } GLint ShaderEffect::getUniformLocation(const std::string &name) diff --git a/src/modules/graphics/opengl/ShaderEffect.h b/src/modules/graphics/opengl/ShaderEffect.h index b3bbf2dab..c270f48f2 100644 --- a/src/modules/graphics/opengl/ShaderEffect.h +++ b/src/modules/graphics/opengl/ShaderEffect.h @@ -72,10 +72,12 @@ private: std::map _uniforms; // texture unit pool for setting images - static std::map _texture_unit_pool; - static GLint _current_texture_unit; - static GLint _max_texture_units; - static GLint getTextureUnit(const std::string &name); + std::map _texture_unit_pool; + GLint _current_texture_unit; + GLint _max_texture_units; + GLint getTextureUnit(const std::string &name); + + void sendTexture(const std::string &name, GLuint texture); }; } // opengl diff --git a/src/scripts/graphics.lua b/src/scripts/graphics.lua index 0cefc4d77..f81b2da8a 100644 --- a/src/scripts/graphics.lua +++ b/src/scripts/graphics.lua @@ -1299,7 +1299,7 @@ uniform sampler2D _tex0_;]], void main() { gl_TexCoord[0] = gl_MultiTexCoord0; 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} end - return vertcode, fragcode + return vertcode, fragcode end function love.graphics._transformGLSLErrorMessages(message) @@ -1366,7 +1366,11 @@ void main() { linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$") end 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) end end diff --git a/src/scripts/graphics.lua.h b/src/scripts/graphics.lua.h index 654c5df91..580db6280 100644 --- a/src/scripts/graphics.lua.h +++ b/src/scripts/graphics.lua.h @@ -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, 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, - 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, 0x09, 0x7d, 0x0a, 0x09, 0x0a, @@ -6376,7 +6378,7 @@ const unsigned char graphics_lua[] = 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x0a, 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, 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, @@ -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, 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, + 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, - 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x48, - 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x0a, + 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 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, 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,