diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 1263339604..ee69ed5fba 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -1265,10 +1265,17 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, case Shader::SMO_model_to_view: { return &(get_external_transform()->get_mat()); } + case Shader::SMO_model_to_apiview: { + return &(get_internal_transform()->get_mat()); + } case Shader::SMO_view_to_model: { t = get_external_transform()->get_inverse()->get_mat(); return &t; } + case Shader::SMO_apiview_to_model: { + t = get_internal_transform()->get_inverse()->get_mat(); + return &t; + } case Shader::SMO_apiview_to_view: { return &(_inv_cs_transform->get_mat()); } @@ -1301,6 +1308,12 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, t = _cs_transform->get_mat() * _projection_mat->get_mat(); return &t; } + case Shader::SMO_apiclip_to_apiview: { + return &(_projection_mat_inv->get_mat()); + } + case Shader::SMO_apiview_to_apiclip: { + return &(_projection_mat->get_mat()); + } case Shader::SMO_view_x_to_view: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4::ident_mat()); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 37dff91eea..7f5718cd4b 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -304,7 +304,7 @@ int CLP(GraphicsStateGuardian)::get_driver_shader_version_minor() { return _gl_s //////////////////////////////////////////////////////////////////// CLP(GraphicsStateGuardian):: CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) : - GraphicsStateGuardian(CS_yup_right, engine, pipe) + GraphicsStateGuardian(gl_coordinate_system, engine, pipe) { _error_count = 0; @@ -2847,7 +2847,8 @@ calc_projection_mat(const Lens *lens) { // choice in the modelview matrix. LMatrix4 result = - LMatrix4::convert_mat(CS_yup_right, lens->get_coordinate_system()) * + LMatrix4::convert_mat(_internal_coordinate_system, + lens->get_coordinate_system()) * lens->get_projection_mat(_current_stereo_channel); if (_scene_setup->get_inverted()) { diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index af09da5408..5288c446b5 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -269,10 +269,18 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext Shader::ShaderMatSpec bind; bind._id = arg_id; bind._func = Shader::SMF_compose; - if (transpose) { - bind._piece = Shader::SMP_transpose; + if (param_type == GL_FLOAT_MAT3) { + if (transpose) { + bind._piece = Shader::SMP_upper3x3; + } else { + bind._piece = Shader::SMP_transpose3x3; + } } else { - bind._piece = Shader::SMP_whole; + if (transpose) { + bind._piece = Shader::SMP_transpose; + } else { + bind._piece = Shader::SMP_whole; + } } bind._arg[0] = NULL; bind._arg[1] = NULL; @@ -281,49 +289,34 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext if (matrix_name == "ModelViewProjectionMatrix") { if (inverse) { - bind._part[0] = Shader::SMO_apiclip_to_view; - bind._part[1] = Shader::SMO_view_to_model; + bind._part[0] = Shader::SMO_apiclip_to_apiview; + bind._part[1] = Shader::SMO_apiview_to_model; } else { - bind._part[0] = Shader::SMO_model_to_view; - bind._part[1] = Shader::SMO_view_to_apiclip; + bind._part[0] = Shader::SMO_model_to_apiview; + bind._part[1] = Shader::SMO_apiview_to_apiclip; } } else if (matrix_name == "ModelViewMatrix") { - if (inverse) { - bind._part[0] = Shader::SMO_apiview_to_view; - bind._part[1] = Shader::SMO_view_to_model; - } else { - bind._part[0] = Shader::SMO_model_to_view; - bind._part[1] = Shader::SMO_view_to_apiview; - } + bind._func = Shader::SMF_first; + bind._part[0] = inverse ? Shader::SMO_apiview_to_model + : Shader::SMO_model_to_apiview; + bind._part[1] = Shader::SMO_identity; } else if (matrix_name == "ProjectionMatrix") { - if (inverse) { - bind._part[0] = Shader::SMO_apiclip_to_view; - bind._part[1] = Shader::SMO_view_to_apiview; - } else { - bind._part[0] = Shader::SMO_apiview_to_view; - bind._part[1] = Shader::SMO_view_to_apiclip; - } + bind._func = Shader::SMF_first; + bind._part[0] = inverse ? Shader::SMO_apiclip_to_apiview + : Shader::SMO_apiview_to_apiclip; + bind._part[1] = Shader::SMO_identity; } else if (matrix_name == "NormalMatrix") { // This is really the upper 3x3 of the ModelViewMatrixInverseTranspose. - if (inverse) { - bind._part[0] = Shader::SMO_model_to_view; - bind._part[1] = Shader::SMO_view_to_apiview; - } else { - bind._part[0] = Shader::SMO_apiview_to_view; - bind._part[1] = Shader::SMO_view_to_model; - } + bind._func = Shader::SMF_first; + bind._part[0] = inverse ? Shader::SMO_model_to_apiview + : Shader::SMO_apiview_to_model; + bind._part[1] = Shader::SMO_identity; if (param_type != GL_FLOAT_MAT3) { GLCAT.error() << "p3d_NormalMatrix input should be mat3, not mat4!\n"; - } else { - if (transpose) { - bind._piece = Shader::SMP_upper3x3; - } else { - bind._piece = Shader::SMP_transpose3x3; - } } } else if (matrix_name == "ModelMatrix") { diff --git a/panda/src/glstuff/glmisc_src.cxx b/panda/src/glstuff/glmisc_src.cxx index 23e9c700ad..2358603e04 100644 --- a/panda/src/glstuff/glmisc_src.cxx +++ b/panda/src/glstuff/glmisc_src.cxx @@ -278,6 +278,15 @@ ConfigVariableBool gl_support_shadow_filter "cards suffered from a broken implementation of the " "shadow map filtering features.")); +ConfigVariableEnum gl_coordinate_system + ("gl-coordinate-system", CS_yup_right, + PRC_DESC("Which coordinate system to use as the internal " + "coordinate system for OpenGL operations. If you are " + "using features like fixed-function sphere mapping, it is " + "best to leave this to yup-right. However, if you are " + "creating a shader-only application, it may be easier and " + "more efficient to set this to default.")); + extern ConfigVariableBool gl_parallel_arrays; void CLP(init_classes)() { diff --git a/panda/src/glstuff/glmisc_src.h b/panda/src/glstuff/glmisc_src.h index 98e5bc8121..dd6f21d4c6 100644 --- a/panda/src/glstuff/glmisc_src.h +++ b/panda/src/glstuff/glmisc_src.h @@ -17,6 +17,7 @@ #include "configVariableInt.h" #include "configVariableEnum.h" #include "geomEnums.h" +#include "coordinateSystem.h" // Define some macros to transparently map to the double or float // versions of the OpenGL function names. @@ -76,6 +77,7 @@ extern ConfigVariableBool gl_vertex_array_objects; extern ConfigVariableBool gl_support_primitive_restart_index; extern ConfigVariableBool gl_support_sampler_objects; extern ConfigVariableBool gl_support_shadow_filter; +extern ConfigVariableEnum gl_coordinate_system; extern EXPCL_GL void CLP(init_classes)(); diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index ced776921d..4d926ccd80 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -483,6 +483,43 @@ cp_optimize_mat_spec(ShaderMatSpec &spec) { spec._part[0] = spec._part[1]; spec._arg[0] = spec._arg[1]; } + + // More optimal combinations for common matrices. + + if (spec._part[0] == SMO_model_to_view && + spec._part[1] == SMO_view_to_apiclip) { + spec._part[0] = SMO_model_to_apiview; + spec._part[1] = SMO_apiview_to_apiclip; + + } else if (spec._part[0] == SMO_apiclip_to_view && + spec._part[1] == SMO_view_to_model) { + spec._part[0] = SMO_apiclip_to_apiview; + spec._part[1] = SMO_apiview_to_model; + + } else if (spec._part[0] == SMO_apiview_to_view && + spec._part[1] == SMO_view_to_apiclip) { + spec._func = SMF_first; + spec._part[0] = SMO_apiview_to_apiclip; + spec._part[1] = SMO_identity; + + } else if (spec._part[0] == SMO_apiclip_to_view && + spec._part[1] == SMO_view_to_apiview) { + spec._func = SMF_first; + spec._part[0] = SMO_apiclip_to_apiview; + spec._part[1] = SMO_identity; + + } else if (spec._part[0] == SMO_apiview_to_view && + spec._part[1] == SMO_view_to_model) { + spec._func = SMF_first; + spec._part[0] = SMO_apiview_to_model; + spec._part[1] = SMO_identity; + + } else if (spec._part[0] == SMO_model_to_view && + spec._part[1] == SMO_view_to_apiview) { + spec._func = SMF_first; + spec._part[0] = SMO_model_to_apiview; + spec._part[1] = SMO_identity; + } } // Calculate state and transform dependencies. diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 805e2ea4f6..45bcab70f9 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -186,6 +186,11 @@ public: // SMO_clipplane_x is world coords, GLSL needs eye coords SMO_apiview_clipplane_i, + SMO_model_to_apiview, + SMO_apiview_to_model, + SMO_apiview_to_apiclip, + SMO_apiclip_to_apiview, + SMO_INVALID };