From da6140a8cc177ccc37c3d076a14cb5b5fba7dfdf Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 14 Jul 2015 21:00:12 +0100 Subject: [PATCH] Changes to GLSL input handling that further assist in efforts to port from Cg to GLSL --- panda/src/glstuff/glShaderContext_src.cxx | 159 ++++++++++++++-------- panda/src/glstuff/glShaderContext_src.h | 2 +- 2 files changed, 107 insertions(+), 54 deletions(-) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 2fd3c25577..f0fcf509d8 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -51,59 +51,51 @@ TypeHandle CLP(ShaderContext)::_type_handle; // actually picked up and the appropriate ShaderMatSpec pushed onto _mat_spec. //////////////////////////////////////////////////////////////////// bool CLP(ShaderContext):: -parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *objShader) { +parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_type, GLint param_size, Shader *objShader) { Shader::ShaderArgInfo p; p._id = arg_id; p._cat = GLCAT; string basename(arg_id._name); + // Split it at the underscores. vector_string pieces; tokenize(basename, pieces, "_"); - if (pieces[0] == "mstrans") { - pieces[0] = "trans"; - pieces.push_back("to"); - pieces.push_back("model"); - } - if (pieces[0] == "wstrans") { - pieces[0] = "trans"; - pieces.push_back("to"); - pieces.push_back("world"); - } - if (pieces[0] == "vstrans") { - pieces[0] = "trans"; - pieces.push_back("to"); - pieces.push_back("view"); - } - if (pieces[0] == "cstrans") { - pieces[0] = "trans"; - pieces.push_back("to"); - pieces.push_back("clip"); - } - if (pieces[0] == "mspos") { - pieces[0] = "row3"; - pieces.push_back("to"); - pieces.push_back("model"); - } - if (pieces[0] == "wspos") { - pieces[0] = "row3"; - pieces.push_back("to"); - pieces.push_back("world"); - } - if (pieces[0] == "vspos") { - pieces[0] = "row3"; - pieces.push_back("to"); - pieces.push_back("view"); - } - if (pieces[0] == "cspos") { - pieces[0] = "row3"; - pieces.push_back("to"); - pieces.push_back("clip"); + if (pieces.size() == 0 || pieces[0].size() < 3) { + return false; } - if ((pieces[0] == "mat") || (pieces[0] == "inv") || - (pieces[0] == "tps") || (pieces[0] == "itp")) { + // mstrans, wstrans, vstrans, cstrans, mspos, wspos, vspos, cspos + if (strcmp(pieces[0].c_str() + 1, "strans") == 0 || + strcmp(pieces[0].c_str() + 1, "spos") == 0) { + pieces.push_back("to"); + + switch (pieces[0][0]) { + case 'm': + pieces.push_back("model"); + break; + case 'w': + pieces.push_back("world"); + break; + case 'v': + pieces.push_back("view"); + break; + case 'c': + pieces.push_back("clip"); + break; + default: + return false; + } + if (strcmp(pieces[0].c_str() + 1, "strans") == 0) { + pieces[0] = "trans"; + } else { + pieces[0] = "row3"; + } + // mat_modelproj et al + } else if (pieces[0].size() == 3 && + (pieces[0] == "mat" || pieces[0] == "inv" || + pieces[0] == "tps" || pieces[0] == "itp")) { if (!objShader->cp_errchk_parameter_words(p, 2)) { return false; } @@ -156,16 +148,58 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *objSha pieces.push_back(""); // Decide whether this is a matrix or vector. - if (pieces[0] == "trans") bind._piece = Shader::SMP_whole; - else if (pieces[0] == "tpose") bind._piece = Shader::SMP_transpose; - else if (pieces[0] == "row0") bind._piece = Shader::SMP_row0; - else if (pieces[0] == "row1") bind._piece = Shader::SMP_row1; - else if (pieces[0] == "row2") bind._piece = Shader::SMP_row2; - else if (pieces[0] == "row3") bind._piece = Shader::SMP_row3; - else if (pieces[0] == "col0") bind._piece = Shader::SMP_col0; - else if (pieces[0] == "col1") bind._piece = Shader::SMP_col1; - else if (pieces[0] == "col2") bind._piece = Shader::SMP_col2; - else if (pieces[0] == "col3") bind._piece = Shader::SMP_col3; + if (param_type == GL_FLOAT_MAT4) { + if (pieces[0] == "trans") bind._piece = Shader::SMP_whole; + else if (pieces[0] == "tpose") bind._piece = Shader::SMP_transpose; + else { + GLCAT.error() << basename << " should be vec4, not mat3\n"; + return false; + } + } else if (param_type == GL_FLOAT_MAT3) { + if (pieces[0] == "trans") bind._piece = Shader::SMP_upper3x3; + else if (pieces[0] == "tpose") bind._piece = Shader::SMP_transpose3x3; + else { + GLCAT.error() << basename << " should be vec4, not mat3\n"; + return false; + } + } else if (param_type == GL_FLOAT_VEC4) { + if (pieces[0] == "trans") bind._piece = Shader::SMP_col0; + else if (pieces[0] == "tpose") bind._piece = Shader::SMP_row0; + else if (pieces[0] == "row0") bind._piece = Shader::SMP_row0; + else if (pieces[0] == "row1") bind._piece = Shader::SMP_row1; + else if (pieces[0] == "row2") bind._piece = Shader::SMP_row2; + else if (pieces[0] == "row3") bind._piece = Shader::SMP_row3; + else if (pieces[0] == "col0") bind._piece = Shader::SMP_col0; + else if (pieces[0] == "col1") bind._piece = Shader::SMP_col1; + else if (pieces[0] == "col2") bind._piece = Shader::SMP_col2; + else if (pieces[0] == "col3") bind._piece = Shader::SMP_col3; + else { + GLCAT.error() << basename << " should be mat4, not vec4\n"; + return false; + } + } else if (pieces[0] == "row3") { + // We'll permit this too, simply because we can support it. + switch (param_type) { + case GL_FLOAT: + bind._piece = Shader::SMP_row3x1; + break; + case GL_FLOAT_VEC2: + bind._piece = Shader::SMP_row3x2; + break; + case GL_FLOAT_VEC3: + bind._piece = Shader::SMP_row3x3; + break; + default: + GLCAT.error() << basename << " should be vec4\n"; + return false; + } + } else if (pieces[0] == "trans" || pieces[0] == "tpose") { + GLCAT.error() << basename << " should be mat4 or mat3\n"; + return false; + } else { + GLCAT.error() << basename << " should be vec4\n"; + return false; + } if (!objShader->cp_parse_coord_sys(p, pieces, next, bind, true)) { return false; @@ -194,6 +228,25 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *objSha objShader->cp_optimize_mat_spec(bind); objShader->_mat_spec.push_back(bind); + + if (param_size > 1) { + // We support arrays of rows and arrays of columns, so we can + // run the GLSL shaders that cgc spits out. + if (bind._piece == Shader::SMP_row0 || bind._piece == Shader::SMP_col0) { + if (param_size > 4) { + GLCAT.warning() << basename << "[" << param_size << "] is too large, only the first four elements will be defined\n"; + param_size = 4; + } + for (int i = 1; i < param_size; ++i) { + bind._id._seqno += 1; + bind._piece = (Shader::ShaderMatPiece)((int)bind._piece + 1); + objShader->_mat_spec.push_back(bind); + } + } else { + GLCAT.warning() << basename << "[" << param_size << "] should not be an array, only the first element will be defined\n"; + } + } + return true; } return false; @@ -963,7 +1016,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { } else { // Tries to parse shorthand notations like mspos_XXX and trans_model_to_clip_of_XXX - if (parse_and_set_short_hand_shader_vars(arg_id, _shader)) { + if (parse_and_set_short_hand_shader_vars(arg_id, param_type, param_size, _shader)) { return; } } diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index fd4b56def4..9147bcf1b1 100644 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -98,7 +98,7 @@ private: void glsl_report_program_errors(GLuint program, bool fatal); bool glsl_compile_shader(Shader::ShaderType type); bool glsl_compile_and_link(); - bool parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *s); + bool parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_type, GLint param_size, Shader *s); void release_resources(); public: