Browse Source

Move auto-rescale-normal handling out of GSG, support normalizing normals in shader generator

rdb 10 years ago
parent
commit
82e098e578

+ 5 - 32
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -2316,8 +2316,6 @@ reset() {
     Geom::GR_triangle_strip | Geom::GR_triangle_fan |
     Geom::GR_flat_first_vertex;
 
-  _auto_rescale_normal = false;
-
   // overwrite gsg defaults with these values
 
   HRESULT hr;
@@ -2864,10 +2862,6 @@ do_issue_transform() {
   }
 
   _transform_stale = false;
-
-  if (_auto_rescale_normal) {
-    do_auto_rescale_normal();
-  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -3001,10 +2995,12 @@ do_issue_render_mode() {
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian9::
 do_issue_rescale_normal() {
-  const RescaleNormalAttrib *target_rescale_normal = DCAST(RescaleNormalAttrib, _target_rs->get_attrib_def(RescaleNormalAttrib::get_class_slot()));
-  RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode();
+  RescaleNormalAttrib::Mode mode = RescaleNormalAttrib::M_none;
 
-  _auto_rescale_normal = false;
+  const RescaleNormalAttrib *target_rescale_normal;
+  if (_target_rs->get_attrib(target_rescale_normal)) {
+    mode = target_rescale_normal->get_mode();
+  }
 
   switch (mode) {
   case RescaleNormalAttrib::M_none:
@@ -3016,11 +3012,6 @@ do_issue_rescale_normal() {
     set_render_state(D3DRS_NORMALIZENORMALS, true);
     break;
 
-  case RescaleNormalAttrib::M_auto:
-    _auto_rescale_normal = true;
-    do_auto_rescale_normal();
-    break;
-
   default:
     dxgsg9_cat.error()
       << "Unknown rescale_normal mode " << (int)mode << endl;
@@ -4234,24 +4225,6 @@ set_read_buffer(const RenderBuffer &rb) {
   return;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::do_auto_rescale_normal
-//       Access: Protected
-//  Description: Issues the appropriate DX commands to either rescale
-//               or normalize the normals according to the current
-//               transform.
-////////////////////////////////////////////////////////////////////
-void DXGraphicsStateGuardian9::
-do_auto_rescale_normal() {
-  if (_internal_transform->has_identity_scale()) {
-    // If there's no scale, don't normalize anything.
-    set_render_state(D3DRS_NORMALIZENORMALS, false);
-  } else {
-    // If there is a scale, turn on normalization.
-    set_render_state(D3DRS_NORMALIZENORMALS, true);
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian9::get_light_color
 //       Access: Public

+ 0 - 3
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -208,8 +208,6 @@ protected:
   void set_draw_buffer(const RenderBuffer &rb);
   void set_read_buffer(const RenderBuffer &rb);
 
-  void do_auto_rescale_normal();
-
   void disable_standard_vertex_arrays();
   bool update_standard_vertex_arrays(bool force);
   void disable_standard_texture_bindings();
@@ -277,7 +275,6 @@ protected:
   bool _supports_render_texture;
 
   RenderBuffer::Type _cur_read_pixel_buffer;  // source for copy_pixel_buffer operation
-  bool _auto_rescale_normal;
 
   PN_stdfloat _material_ambient;
   PN_stdfloat _material_diffuse;

+ 5 - 71
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -2280,8 +2280,6 @@ reset() {
   }
 #endif
 
-  _auto_rescale_normal = false;
-
   // Ensure the initial state is what we say it should be (in some
   // cases, we don't want the GL default settings; in others, we have
   // to force the point with some drivers that aren't strictly
@@ -5932,10 +5930,6 @@ do_issue_transform() {
   DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
   glMatrixMode(GL_MODELVIEW);
   GLPf(LoadMatrix)(transform->get_mat().get_data());
-
-  if (_auto_rescale_normal) {
-    do_auto_rescale_normal();
-  }
 #endif
   _transform_stale = false;
 
@@ -6155,12 +6149,12 @@ do_issue_antialias() {
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 do_issue_rescale_normal() {
-  const RescaleNormalAttrib *target_rescale_normal;
-  _target_rs->get_attrib_def(target_rescale_normal);
-
-  RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode();
+  RescaleNormalAttrib::Mode mode = RescaleNormalAttrib::M_none;
 
-  _auto_rescale_normal = false;
+  const RescaleNormalAttrib *target_rescale_normal;
+  if (_target_rs->get_attrib(target_rescale_normal)) {
+    mode = target_rescale_normal->get_mode();
+  }
 
   switch (mode) {
   case RescaleNormalAttrib::M_none:
@@ -6186,11 +6180,6 @@ do_issue_rescale_normal() {
     }
     break;
 
-  case RescaleNormalAttrib::M_auto:
-    _auto_rescale_normal = true;
-    do_auto_rescale_normal();
-    break;
-
   default:
     GLCAT.error()
       << "Unknown rescale_normal mode " << (int)mode << endl;
@@ -9463,61 +9452,6 @@ free_pointers() {
 #endif
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::do_auto_rescale_normal
-//       Access: Protected
-//  Description: Issues the appropriate GL commands to either rescale
-//               or normalize the normals according to the current
-//               transform.
-////////////////////////////////////////////////////////////////////
-void CLP(GraphicsStateGuardian)::
-do_auto_rescale_normal() {
-#ifndef OPENGLES_2
-  if (_internal_transform->has_identity_scale()) {
-    // If there's no scale at all, don't do anything.
-    glDisable(GL_NORMALIZE);
-    if (GLCAT.is_spam()) {
-      GLCAT.spam() << "glDisable(GL_NORMALIZE)\n";
-    }
-    if (_supports_rescale_normal && support_rescale_normal) {
-      glDisable(GL_RESCALE_NORMAL);
-      if (GLCAT.is_spam()) {
-        GLCAT.spam() << "glDisable(GL_RESCALE_NORMAL)\n";
-      }
-    }
-
-  } else if (_internal_transform->has_uniform_scale()) {
-    // There's a uniform scale; use the rescale feature if available.
-    if (_supports_rescale_normal && support_rescale_normal) {
-      glEnable(GL_RESCALE_NORMAL);
-      glDisable(GL_NORMALIZE);
-      if (GLCAT.is_spam()) {
-        GLCAT.spam() << "glEnable(GL_RESCALE_NORMAL)\n";
-        GLCAT.spam() << "glDisable(GL_NORMALIZE)\n";
-      }
-    } else {
-      glEnable(GL_NORMALIZE);
-      if (GLCAT.is_spam()) {
-        GLCAT.spam() << "glEnable(GL_NORMALIZE)\n";
-      }
-    }
-
-  } else {
-    // If there's a non-uniform scale, normalize everything.
-    glEnable(GL_NORMALIZE);
-    if (GLCAT.is_spam()) {
-      GLCAT.spam() << "glEnable(GL_NORMALIZE)\n";
-    }
-    if (_supports_rescale_normal && support_rescale_normal) {
-      glDisable(GL_RESCALE_NORMAL);
-      if (GLCAT.is_spam()) {
-        GLCAT.spam() << "glDisable(GL_RESCALE_NORMAL)\n";
-      }
-    }
-  }
-#endif
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::do_issue_texture
 //       Access: Protected, Virtual

+ 0 - 2
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -525,7 +525,6 @@ protected:
   void upload_usage_texture(int width, int height);
 #endif  // NDEBUG
 
-  void do_auto_rescale_normal();
   bool specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler);
   bool apply_texture(TextureContext *tc);
   bool apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc);
@@ -625,7 +624,6 @@ protected:
   DirectionalLights _dlights;
 
   int _pass_number;
-  bool _auto_rescale_normal;
   GLuint _geom_display_list;
   GLuint _current_vbuffer_index;
   GLuint _current_ibuffer_index;

+ 21 - 4
panda/src/pgraph/cullResult.cxx

@@ -24,6 +24,7 @@
 #include "fogAttrib.h"
 #include "transparencyAttrib.h"
 #include "renderState.h"
+#include "rescaleNormalAttrib.h"
 #include "clockObject.h"
 #include "config_pgraph.h"
 #include "depthOffsetAttrib.h"
@@ -122,14 +123,30 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
   Thread *current_thread = traverser->get_current_thread();
   CullBinManager *bin_manager = CullBinManager::get_global_ptr();
 
-  // Check to see if there's a special transparency setting.
   const RenderState *state = object->_state;
   nassertv(state != (const RenderState *)NULL);
 
-  const TransparencyAttrib *trans = (const TransparencyAttrib *)
-    state->get_attrib(TransparencyAttrib::get_class_slot());
+  // This is probably a good time to check for an auto rescale setting.
+  const RescaleNormalAttrib *rescale;
+  state->get_attrib_def(rescale);
+  if (rescale->get_mode() == RescaleNormalAttrib::M_auto) {
+    RescaleNormalAttrib::Mode mode;
+
+    if (object->_internal_transform->has_identity_scale()) {
+      mode = RescaleNormalAttrib::M_none;
+    } else if (object->_internal_transform->has_uniform_scale()) {
+      mode = RescaleNormalAttrib::M_rescale;
+    } else {
+      mode = RescaleNormalAttrib::M_normalize;
+    }
 
-  if (trans != (const TransparencyAttrib *)NULL) {
+    state = state->set_attrib(RescaleNormalAttrib::make(mode));
+    object->_state = state;
+  }
+
+  // Check to see if there's a special transparency setting.
+  const TransparencyAttrib *trans;
+  if (state->get_attrib(trans)) {
     switch (trans->get_mode()) {
     case TransparencyAttrib::M_alpha:
       // M_alpha implies an alpha-write test, so we don't waste time

+ 15 - 0
panda/src/pgraph/rescaleNormalAttrib.cxx

@@ -114,6 +114,21 @@ get_hash_impl() const {
   return hash;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: RescaleNormalAttrib::get_auto_shader_attrib_impl
+//       Access: Protected, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) RescaleNormalAttrib::
+get_auto_shader_attrib_impl(const RenderState *state) const {
+  // We currently only support M_normalize in the ShaderGenerator.
+  if (_mode == M_none || _mode == M_normalize) {
+    return this;
+  } else {
+    return RescaleNormalAttrib::make(M_normalize);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: RescaleNormalAttrib::register_with_read_factory
 //       Access: Public, Static

+ 1 - 0
panda/src/pgraph/rescaleNormalAttrib.h

@@ -59,6 +59,7 @@ public:
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;
   virtual size_t get_hash_impl() const;
+  virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const;
 
 private:
   Mode _mode;

+ 13 - 1
panda/src/pgraphnodes/shaderGenerator.cxx

@@ -37,6 +37,7 @@
 #include "texture.h"
 #include "ambientLight.h"
 #include "directionalLight.h"
+#include "rescaleNormalAttrib.h"
 #include "pointLight.h"
 #include "spotlight.h"
 #include "lightLensNode.h"
@@ -326,6 +327,12 @@ analyze_renderstate(const RenderState *rs) {
     _need_eye_normal = true;
   }
 
+  // Determine whether we should normalize the normals.
+  const RescaleNormalAttrib *rescale;
+  rs->get_attrib_def(rescale);
+
+  _normalize_normals = (rescale->get_mode() != RescaleNormalAttrib::M_none);
+
   // Find the material.
 
   const MaterialAttrib *material = DCAST(MaterialAttrib, rs->get_attrib_def(MaterialAttrib::get_class_slot()));
@@ -487,6 +494,7 @@ clear_analysis() {
   _need_world_normal = false;
   _need_eye_position = false;
   _need_eye_normal = false;
+  _normalize_normals = false;
   _auto_normal_on = false;
   _auto_glow_on   = false;
   _auto_gloss_on  = false;
@@ -774,7 +782,11 @@ synthesize_shader(const RenderState *rs) {
     text << "\t l_eye_position = mul(trans_model_to_view, vtx_position);\n";
   }
   if (_need_eye_normal) {
-    text << "\t l_eye_normal.xyz = mul((float3x3)tpose_view_to_model, vtx_normal);\n";
+    if (_normalize_normals) {
+      text << "\t l_eye_normal.xyz = normalize(mul((float3x3)tpose_view_to_model, vtx_normal));\n";
+    } else {
+      text << "\t l_eye_normal.xyz = mul((float3x3)tpose_view_to_model, vtx_normal);\n";
+    }
     text << "\t l_eye_normal.w = 0;\n";
   }
   pmap<const InternalName *, const char *>::const_iterator it;

+ 1 - 0
panda/src/pgraphnodes/shaderGenerator.h

@@ -146,6 +146,7 @@ protected:
   bool _need_world_normal;
   bool _need_eye_position;
   bool _need_eye_normal;
+  bool _normalize_normals;
   bool _auto_normal_on;
   bool _auto_glow_on;
   bool _auto_gloss_on;