diff options
Diffstat (limited to 'drivers/gles2/shader_gles2.cpp')
| -rw-r--r-- | drivers/gles2/shader_gles2.cpp | 193 |
1 files changed, 88 insertions, 105 deletions
diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp index 146575973f..84bd413abb 100644 --- a/drivers/gles2/shader_gles2.cpp +++ b/drivers/gles2/shader_gles2.cpp @@ -27,12 +27,12 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "shader_gles2.h" -#include "memory.h" -#include "print_string.h" -#include "string_builder.h" +#include "shader_gles2.h" +#include "core/os/memory.h" +#include "core/print_string.h" +#include "core/string_builder.h" #include "rasterizer_gles2.h" #include "rasterizer_storage_gles2.h" @@ -57,7 +57,7 @@ ShaderGLES2 *ShaderGLES2::active = NULL; -// #define DEBUG_SHADER +//#define DEBUG_SHADER #ifdef DEBUG_SHADER @@ -99,7 +99,7 @@ void ShaderGLES2::bind_uniforms() { const Map<uint32_t, CameraMatrix>::Element *C = uniform_cameras.front(); while (C) { - int idx = E->key(); + int idx = C->key(); int location = version->uniform_location[idx]; if (location < 0) { @@ -132,6 +132,11 @@ bool ShaderGLES2::bind() { ERR_FAIL_COND_V(!version, false); + if (!version->ok) { //broken, unable to bind (do not throw error, you saw it before already when it failed compilation). + glUseProgram(0); + return false; + } + glUseProgram(version->id); // find out uniform names and locations @@ -171,73 +176,30 @@ void ShaderGLES2::unbind() { active = NULL; } -static String _fix_error_code_line(const String &p_error, int p_code_start, int p_offset) { - - int last_find_pos = -1; - // NVIDIA - String error = p_error; - while ((last_find_pos = p_error.find("(", last_find_pos + 1)) != -1) { - - int end_pos = last_find_pos + 1; - - while (true) { - - if (p_error[end_pos] >= '0' && p_error[end_pos] <= '9') { - - end_pos++; - continue; - } else if (p_error[end_pos] == ')') { - break; - } else { - - end_pos = -1; - break; - } - } +static void _display_error_with_code(const String &p_error, const Vector<const char *> &p_code) { - if (end_pos == -1) - continue; + int line = 1; + String total_code; - String numstr = error.substr(last_find_pos + 1, (end_pos - last_find_pos) - 1); - String begin = error.substr(0, last_find_pos + 1); - String end = error.substr(end_pos, error.length()); - int num = numstr.to_int() + p_code_start - p_offset; - error = begin + itos(num) + end; + for (int i = 0; i < p_code.size(); i++) { + total_code += String(p_code[i]); } - // ATI - last_find_pos = -1; - while ((last_find_pos = p_error.find("ERROR: ", last_find_pos + 1)) != -1) { - - last_find_pos += 6; - int end_pos = last_find_pos + 1; + Vector<String> lines = String(total_code).split("\n"); - while (true) { + for (int j = 0; j < lines.size(); j++) { - if (p_error[end_pos] >= '0' && p_error[end_pos] <= '9') { + print_line(itos(line) + ": " + lines[j]); + line++; + } - end_pos++; - continue; - } else if (p_error[end_pos] == ':') { - break; - } else { + ERR_PRINTS(p_error); +} - end_pos = -1; - break; - } - } - continue; - if (end_pos == -1) - continue; +static String _mkid(const String &p_id) { - String numstr = error.substr(last_find_pos + 1, (end_pos - last_find_pos) - 1); - print_line("numstr: " + numstr); - String begin = error.substr(0, last_find_pos + 1); - String end = error.substr(end_pos, error.length()); - int num = numstr.to_int() + p_code_start - p_offset; - error = begin + itos(num) + end; - } - return error; + String id = "m_" + p_id; + return id.replace("__", "_dus_"); //doubleunderscore is reserverd in glsl } ShaderGLES2::Version *ShaderGLES2::get_current_version() { @@ -294,7 +256,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() { } } - // keep them around during the functino + // keep them around during the function CharString code_string; CharString code_string2; CharString code_globals; @@ -317,7 +279,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() { if (cc) { for (int i = 0; i < cc->custom_defines.size(); i++) { strings.push_back(cc->custom_defines.write[i]); - DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i])); + DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i].get_data())); } } @@ -376,9 +338,8 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() { String err_string = get_shader_name() + ": Vertex shader compilation failed:\n"; err_string += ilogmem; - err_string = _fix_error_code_line(err_string, vertex_code_start, define_line_ofs); - ERR_PRINTS(err_string); + _display_error_with_code(err_string, strings); Memory::free_static(ilogmem); glDeleteShader(v.vert_id); @@ -452,9 +413,8 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() { String err_string = get_shader_name() + ": Fragment shader compilation failed:\n"; err_string += ilogmem; - err_string = _fix_error_code_line(err_string, fragment_code_start, define_line_ofs); - ERR_PRINTS(err_string); + _display_error_with_code(err_string, strings); Memory::free_static(ilogmem); glDeleteShader(v.frag_id); @@ -504,9 +464,8 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() { String err_string = get_shader_name() + ": Program linking failed:\n"; err_string += ilogmem; - err_string = _fix_error_code_line(err_string, fragment_code_start, define_line_ofs); - ERR_PRINTS(err_string); + _display_error_with_code(err_string, strings); Memory::free_static(ilogmem); glDeleteShader(v.frag_id); @@ -527,22 +486,27 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() { for (int i = 0; i < texunit_pair_count; i++) { GLint loc = glGetUniformLocation(v.id, texunit_pairs[i].name); - if (loc >= 0) - glUniform1i(loc, texunit_pairs[i].index); + if (loc >= 0) { + if (texunit_pairs[i].index < 0) { + glUniform1i(loc, max_image_units + texunit_pairs[i].index); + } else { + glUniform1i(loc, texunit_pairs[i].index); + } + } } if (cc) { // uniforms for (int i = 0; i < cc->custom_uniforms.size(); i++) { - StringName native_uniform_name = "m_" + cc->custom_uniforms[i]; - GLint location = glGetUniformLocation(v.id, ((String)native_uniform_name).ascii().get_data()); + String native_uniform_name = _mkid(cc->custom_uniforms[i]); + GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data()); v.custom_uniform_locations[cc->custom_uniforms[i]] = location; } // textures for (int i = 0; i < cc->texture_uniforms.size(); i++) { - StringName native_uniform_name = "m_" + cc->texture_uniforms[i]; - GLint location = glGetUniformLocation(v.id, ((String)native_uniform_name).ascii().get_data()); + String native_uniform_name = _mkid(cc->texture_uniforms[i]); + GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data()); v.custom_uniform_locations[cc->texture_uniforms[i]] = location; } } @@ -643,6 +607,8 @@ void ShaderGLES2::setup( } } } + + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_image_units); } void ShaderGLES2::finish() { @@ -717,7 +683,7 @@ void ShaderGLES2::free_custom_shader(uint32_t p_code_id) { custom_code_map.erase(p_code_id); } -void ShaderGLES2::use_material(void *p_material, int p_num_predef_textures) { +void ShaderGLES2::use_material(void *p_material) { RasterizerStorageGLES2::Material *material = (RasterizerStorageGLES2::Material *)p_material; if (!material) { @@ -730,11 +696,6 @@ void ShaderGLES2::use_material(void *p_material, int p_num_predef_textures) { Version *v = version_map.getptr(conditional_version); - CustomCode *cc = NULL; - if (v) { - cc = custom_code_map.getptr(v->code_version); - } - // bind uniforms for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = material->shader->uniforms.front(); E; E = E->next()) { @@ -906,35 +867,61 @@ void ShaderGLES2::use_material(void *p_material, int p_num_predef_textures) { case ShaderLanguage::TYPE_MAT2: { Transform2D val = V->get(); - // TODO + if (value.second.size() < 4) { + value.second.resize(4); + } + + value.second.write[0].real = val.elements[0][0]; + value.second.write[1].real = val.elements[0][1]; + value.second.write[2].real = val.elements[1][0]; + value.second.write[3].real = val.elements[1][1]; } break; case ShaderLanguage::TYPE_MAT3: { Basis val = V->get(); - // TODO + if (value.second.size() < 9) { + value.second.resize(9); + } + + value.second.write[0].real = val.elements[0][0]; + value.second.write[1].real = val.elements[0][1]; + value.second.write[2].real = val.elements[0][2]; + value.second.write[3].real = val.elements[1][0]; + value.second.write[4].real = val.elements[1][1]; + value.second.write[5].real = val.elements[1][2]; + value.second.write[6].real = val.elements[2][0]; + value.second.write[7].real = val.elements[2][1]; + value.second.write[8].real = val.elements[2][2]; } break; case ShaderLanguage::TYPE_MAT4: { Transform val = V->get(); - // TODO - } break; - - case ShaderLanguage::TYPE_SAMPLER2D: { - - } break; - - case ShaderLanguage::TYPE_ISAMPLER2D: { - - } break; - - case ShaderLanguage::TYPE_USAMPLER2D: { + if (value.second.size() < 16) { + value.second.resize(16); + } + value.second.write[0].real = val.basis.elements[0][0]; + value.second.write[1].real = val.basis.elements[0][1]; + value.second.write[2].real = val.basis.elements[0][2]; + value.second.write[3].real = 0; + value.second.write[4].real = val.basis.elements[1][0]; + value.second.write[5].real = val.basis.elements[1][1]; + value.second.write[6].real = val.basis.elements[1][2]; + value.second.write[7].real = 0; + value.second.write[8].real = val.basis.elements[2][0]; + value.second.write[9].real = val.basis.elements[2][1]; + value.second.write[10].real = val.basis.elements[2][2]; + value.second.write[11].real = 0; + value.second.write[12].real = val.origin[0]; + value.second.write[13].real = val.origin[1]; + value.second.write[14].real = val.origin[2]; + value.second.write[15].real = 1; } break; - case ShaderLanguage::TYPE_SAMPLERCUBE: { + default: { } break; } @@ -996,7 +983,7 @@ void ShaderGLES2::use_material(void *p_material, int p_num_predef_textures) { value.second.resize(default_arg_size); - for (int i = 0; i < default_arg_size; i++) { + for (size_t i = 0; i < default_arg_size; i++) { if (is_float) { value.second.write[i].real = 0.0; } else { @@ -1006,8 +993,6 @@ void ShaderGLES2::use_material(void *p_material, int p_num_predef_textures) { } } - // GLint location = get_uniform_location(E->key()); - GLint location; if (v->custom_uniform_locations.has(E->key())) { location = v->custom_uniform_locations[E->key()]; @@ -1027,14 +1012,12 @@ void ShaderGLES2::use_material(void *p_material, int p_num_predef_textures) { int tc = material->textures.size(); Pair<StringName, RID> *textures = material->textures.ptrw(); - ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = material->shader->texture_hints.ptrw(); - for (int i = 0; i < tc; i++) { Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > value; value.first = ShaderLanguage::TYPE_INT; value.second.resize(1); - value.second.write[0].sint = p_num_predef_textures + i; + value.second.write[0].sint = i; // GLint location = get_uniform_location(textures[i].first); |