Sfoglia il codice sorgente

Make fetching of p3d_LightSource[n] input clearly defined for non-existent lights

Refer to OpenGL 2.1 spec page 61

Closes: #129
rdb 9 anni fa
parent
commit
7db45cb647
1 ha cambiato i file con 92 aggiunte e 33 eliminazioni
  1. 92 33
      panda/src/display/graphicsStateGuardian.cxx

+ 92 - 33
panda/src/display/graphicsStateGuardian.cxx

@@ -1363,8 +1363,18 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
       }
     }
 
-    // TODO: dummy light
-    nassertr(false, &LMatrix4::ident_mat());
+    // Apply the default OpenGL lights otherwise.
+    // Special exception for light 0, which defaults to white.
+    if (index == 0) {
+      string basename = name->get_basename();
+      if (basename == "color" || basename == "diffuse") {
+        t.set_row(3, _light_color_scale);
+        return &t;
+      } else if (basename == "specular") {
+        return &LMatrix4::ones_mat();
+      }
+    }
+    return fetch_specified_member(NodePath(), name, t);
   }
   default:
     nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
@@ -1395,8 +1405,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
   static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation");
   static const CPT_InternalName IN_shadowMatrix("shadowMatrix");
 
+  PandaNode *node = NULL;
+  if (!np.is_empty()) {
+    node = np.node();
+  }
+
   if (attrib == IN_color) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     LColor c = light->get_color();
     c.componentwise_mult(_light_color_scale);
@@ -1404,9 +1422,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
 
   } else if (attrib == IN_ambient) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node->is_of_type(AmbientLight::get_class_type())) {
       LColor c = light->get_color();
       c.componentwise_mult(_light_color_scale);
       t.set_row(3, c);
@@ -1417,9 +1438,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
 
   } else if (attrib == IN_diffuse) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no diffuse color.
       t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
     } else {
@@ -1430,19 +1454,25 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
 
   } else if (attrib == IN_specular) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
     t.set_row(3, light->get_specular_color());
     return &t;
 
   } else if (attrib == IN_position) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (np.is_empty()) {
+      t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no position.
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       return &t;
-    } else if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
+    } else if (node->is_of_type(DirectionalLight::get_class_type())) {
       DirectionalLight *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
 
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
@@ -1451,7 +1481,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       return &t;
     } else {
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
@@ -1466,13 +1496,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
 
   } else if (attrib == IN_halfVector) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (np.is_empty()) {
+      t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no half-vector.
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       return &t;
-    } else if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
+    } else if (node->is_of_type(DirectionalLight::get_class_type())) {
       DirectionalLight *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
 
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
@@ -1484,7 +1517,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       return &t;
     } else {
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
@@ -1502,13 +1535,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
 
   } else if (attrib == IN_spotDirection) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node == (PandaNode *)NULL) {
+      t.set_row(3, LVector3(0.0f, 0.0f, -1.0f));
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no spot direction.
       t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
       return &t;
     } else {
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
@@ -1523,9 +1559,10 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
 
   } else if (attrib == IN_spotCutoff) {
-    if (np.node()->is_of_type(Spotlight::get_class_type())) {
+    if (node != (PandaNode *)NULL &&
+        node->is_of_type(Spotlight::get_class_type())) {
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
@@ -1539,9 +1576,10 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
 
   } else if (attrib == IN_spotCosCutoff) {
-    if (np.node()->is_of_type(Spotlight::get_class_type())) {
+    if (node != (PandaNode *)NULL &&
+        node->is_of_type(Spotlight::get_class_type())) {
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
@@ -1553,51 +1591,72 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       t.set_row(3, LVecBase4(-1));
       return &t;
     }
+
   } else if (attrib == IN_spotExponent) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
     t.set_row(3, LVecBase4(light->get_exponent()));
     return &t;
 
   } else if (attrib == IN_attenuation) {
-    Light *light = np.node()->as_light();
-    nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
+    if (node != (PandaNode *)NULL) {
+      Light *light = node->as_light();
+      nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
 
-    t.set_row(3, LVecBase4(light->get_attenuation(), 0));
+      t.set_row(3, LVecBase4(light->get_attenuation(), 0));
+    } else {
+      t.set_row(3, LVecBase4(1, 0, 0, 0));
+    }
     return &t;
 
   } else if (attrib == IN_constantAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ones_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
 
     t.set_row(3, LVecBase4(light->get_attenuation()[0]));
     return &t;
 
   } else if (attrib == IN_linearAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
     t.set_row(3, LVecBase4(light->get_attenuation()[1]));
     return &t;
 
   } else if (attrib == IN_quadraticAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
     t.set_row(3, LVecBase4(light->get_attenuation()[2]));
     return &t;
 
   } else if (attrib == IN_shadowMatrix) {
-    LensNode *lnode;
-    DCAST_INTO_R(lnode, np.node(), &LMatrix4::ident_mat());
-    Lens *lens = lnode->get_lens();
-
     static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
                                   0.0f, 0.5f, 0.0f, 0.0f,
                                   0.0f, 0.0f, 0.5f, 0.0f,
                                   0.5f, 0.5f, 0.5f, 1.0f);
 
+    if (node == (PandaNode *)NULL) {
+      return &biasmat;
+    }
+
+    LensNode *lnode;
+    DCAST_INTO_R(lnode, node, &LMatrix4::ident_mat());
+    Lens *lens = lnode->get_lens();
+
     t = get_external_transform()->get_mat() *
       get_scene()->get_camera_transform()->get_mat() *
       np.get_net_transform()->get_inverse()->get_mat() *