فهرست منبع

Optimize shader matrix generator, allow changing GL internal coord system

rdb 10 سال پیش
والد
کامیت
07ea84a1a0

+ 13 - 0
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());

+ 3 - 2
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()) {

+ 27 - 34
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") {

+ 9 - 0
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<CoordinateSystem> 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)() {

+ 2 - 0
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<CoordinateSystem> gl_coordinate_system;
 
 extern EXPCL_GL void CLP(init_classes)();
 

+ 37 - 0
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.

+ 5 - 0
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
   };