Browse Source

RescaleNormalAttrib

David Rose 17 năm trước cách đây
mục cha
commit
e499287e8c

+ 2 - 0
panda/src/tinydisplay/init.cxx

@@ -23,6 +23,8 @@ void glInit(GLContext *c, ZBuffer *zbuffer)
   c->local_light_model=0;
   c->lighting_enabled=0;
   c->light_model_two_side = 0;
+  c->normalize_enabled = 0;
+  c->normal_scale = 1.0f;
 
   /* default materials */
   for(i=0;i<2;i++) {

+ 66 - 0
panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx

@@ -108,6 +108,7 @@ reset() {
   _texfilter_state = 0;
   _texture_replace = false;
   _filled_flat = false;
+  _auto_rescale_normal = false;
 
   // Now that the GSG has been initialized, make it available for
   // optimizations.
@@ -1397,6 +1398,12 @@ set_state_and_transform(const RenderState *target,
     do_issue_cull_face();
     _state._cull_face = _target._cull_face;
   }
+  
+  if (_target._rescale_normal != _state._rescale_normal) {
+    PStatTimer timer(_draw_set_state_rescale_normal_pcollector);
+    do_issue_rescale_normal();
+    _state._rescale_normal = _target._rescale_normal;
+  }
 
   if (_target._render_mode != _state._render_mode) {
     PStatTimer timer(_draw_set_state_render_mode_pcollector);
@@ -1784,6 +1791,10 @@ void TinyGraphicsStateGuardian::
 do_issue_transform() {
   _transform_state_pcollector.add_level(1);
   _transform_stale = true;
+
+  if (_auto_rescale_normal) {
+    do_auto_rescale_normal();
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -1826,6 +1837,41 @@ do_issue_render_mode() {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TinyGraphicsStateGuardian::do_issue_rescale_normal
+//       Access: Protected
+//  Description:
+////////////////////////////////////////////////////////////////////
+void TinyGraphicsStateGuardian::
+do_issue_rescale_normal() {
+  const RescaleNormalAttrib *attrib = _target._rescale_normal;
+  RescaleNormalAttrib::Mode mode = attrib->get_mode();
+
+  _auto_rescale_normal = false;
+
+  switch (mode) {
+  case RescaleNormalAttrib::M_none:
+    _c->normalize_enabled = false;
+    _c->normal_scale = 1.0f;
+    break;
+
+  case RescaleNormalAttrib::M_normalize:
+    _c->normalize_enabled = true;
+    _c->normal_scale = 1.0f;
+    break;
+
+  case RescaleNormalAttrib::M_rescale:
+  case RescaleNormalAttrib::M_auto:
+    _auto_rescale_normal = true;
+    do_auto_rescale_normal();
+    break;
+
+  default:
+    tinydisplay_cat.error()
+      << "Unknown rescale_normal mode " << (int)mode << endl;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TinyGraphicsStateGuardian::do_issue_cull_face
 //       Access: Protected
@@ -2583,6 +2629,26 @@ setup_material(GLMaterial *gl_material, const Material *material) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TinyGraphicsStateGuardian::do_auto_rescale_normal
+//       Access: Protected
+//  Description: Sets the state to either rescale or normalize the
+//               normals according to the current transform.
+////////////////////////////////////////////////////////////////////
+void TinyGraphicsStateGuardian::
+do_auto_rescale_normal() {
+  if (_internal_transform->has_uniform_scale()) {
+    // There's a uniform scale; rescale the normals uniformly.
+    _c->normalize_enabled = false;
+    _c->normal_scale = _internal_transform->get_uniform_scale();
+
+  } else {
+    // If there's a non-uniform scale, normalize everything.
+    _c->normalize_enabled = true;
+    _c->normal_scale = 1.0f;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TinyGraphicsStateGuardian::load_matrix
 //       Access: Private, Static

+ 3 - 0
panda/src/tinydisplay/tinyGraphicsStateGuardian.h

@@ -100,6 +100,7 @@ private:
   void do_issue_transform();
   void do_issue_render_mode();
   void do_issue_cull_face();
+  void do_issue_rescale_normal();
   void do_issue_material();
   void do_issue_texture();
   void do_issue_scissor();
@@ -120,6 +121,7 @@ private:
   static void copy_rgba_image(ZTextureLevel *dest, int xsize, int ysize, Texture *tex, int level);
 
   void setup_material(GLMaterial *gl_material, const Material *material);
+  void do_auto_rescale_normal();
   static void load_matrix(M4 *matrix, const TransformState *transform);
   static int get_color_blend_op(ColorBlendAttrib::Operand operand);
   static ZB_lookupTextureFunc get_tex_filter_func(Texture::FilterType filter);
@@ -144,6 +146,7 @@ private:
   int _texfilter_state;
   bool _texture_replace;
   bool _filled_flat;
+  bool _auto_rescale_normal;
 
   CPT(TransformState) _scissor_mat;
 

+ 3 - 3
panda/src/tinydisplay/vertex.cxx

@@ -54,9 +54,9 @@ void gl_vertex_transform(GLContext * c, GLVertex * v)
 	m = &c->matrix_model_view_inv.m[0][0];
 	n = &c->current_normal;
 
-	v->normal.X = (n->X * m[0] + n->Y * m[1] + n->Z * m[2]);
-	v->normal.Y = (n->X * m[4] + n->Y * m[5] + n->Z * m[6]);
-	v->normal.Z = (n->X * m[8] + n->Y * m[9] + n->Z * m[10]);
+	v->normal.X = (n->X * m[0] + n->Y * m[1] + n->Z * m[2]) * c->normal_scale;
+	v->normal.Y = (n->X * m[4] + n->Y * m[5] + n->Z * m[6]) * c->normal_scale;
+	v->normal.Z = (n->X * m[8] + n->Y * m[9] + n->Z * m[10]) * c->normal_scale;
 
 	if (c->normalize_enabled) {
 	    gl_V3_Norm(&v->normal);

+ 2 - 0
panda/src/tinydisplay/zgl.h

@@ -172,6 +172,8 @@ typedef struct GLContext {
   int cull_face_enabled;
   int cull_clockwise;
   int normalize_enabled;
+  float normal_scale;
+
   gl_draw_triangle_func draw_triangle_front,draw_triangle_back;
   ZB_fillTriangleFunc zb_fill_tri;