Browse Source

One more step towards PointLight shadows

rdb 14 years ago
parent
commit
90eac01be0
1 changed files with 80 additions and 22 deletions
  1. 80 22
      panda/src/display/graphicsStateGuardian.cxx

+ 80 - 22
panda/src/display/graphicsStateGuardian.cxx

@@ -2638,34 +2638,59 @@ PT(Texture) GraphicsStateGuardian::
 make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) {
   // Make sure everything is valid.
   nassertr(light_np.node()->is_of_type(DirectionalLight::get_class_type()) ||
+           light_np.node()->is_of_type(PointLight::get_class_type()) ||
            light_np.node()->is_of_type(Spotlight::get_class_type()), NULL);
+
   PT(LightLensNode) light = DCAST(LightLensNode, light_np.node());
   if (light == NULL || !light->_shadow_caster) {
     return NULL;
   }
-  
+
+  bool is_point = light->is_of_type(PointLight::get_class_type());
+
   nassertr(light->_sbuffers.count(this) == 0, NULL);
-  
+
   display_cat.debug() << "Constructing shadow buffer for light '" << light->get_name()
     << "', size=" << light->_sb_xsize << "x" << light->_sb_ysize
     << ", sort=" << light->_sb_sort << "\n";
+
+  // Setup some flags and properties
   FrameBufferProperties fbp;
   fbp.set_depth_bits(1); // We only need depth
+  WindowProperties props = WindowProperties::size(light->_sb_xsize, light->_sb_ysize);
+  int flags = GraphicsPipe::BF_refuse_window;
+  if (is_point) {
+    flags |= GraphicsPipe::BF_size_square;
+  }
+
+  // Create the buffer
   PT(GraphicsOutput) sbuffer = get_engine()->make_output(get_pipe(), light->get_name(),
-      light->_sb_sort, fbp, WindowProperties::size(light->_sb_xsize, light->_sb_ysize),
-      GraphicsPipe::BF_refuse_window, this, DCAST(GraphicsOutput, host));
+      light->_sb_sort, fbp, props, flags, this, DCAST(GraphicsOutput, host));
   nassertr(sbuffer != NULL, NULL);
-  
+
   // Create a texture and fill it in with some data to workaround an OpenGL error
   PT(Texture) tex = new Texture(light->get_name());
-  tex->setup_2d_texture(light->_sb_xsize, light->_sb_ysize, Texture::T_float, Texture::F_depth_component);
+  if (is_point) {
+    if (light->_sb_xsize != light->_sb_ysize) {
+      display_cat.error()
+        << "PointLight shadow buffers must have an equal width and height!\n";
+    }
+    tex->setup_cube_map(light->_sb_xsize, Texture::T_float, Texture::F_depth_component);
+  } else {
+    tex->setup_2d_texture(light->_sb_xsize, light->_sb_ysize, Texture::T_float, Texture::F_depth_component);
+  }
   tex->make_ram_image();
-  sbuffer->add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy,
-                                   GraphicsOutput::RTP_depth);
-  // Set the wrap mode to BORDER_COLOR
-  tex->set_wrap_u(Texture::WM_border_color);
-  tex->set_wrap_v(Texture::WM_border_color);
-  tex->set_border_color(LVecBase4(1, 1, 1, 1));
+  sbuffer->add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy, GraphicsOutput::RTP_depth);
+
+  // Set the wrap mode
+  if (is_point) {
+    tex->set_wrap_u(Texture::WM_clamp);
+    tex->set_wrap_v(Texture::WM_clamp);
+  } else {
+    tex->set_wrap_u(Texture::WM_border_color);
+    tex->set_wrap_v(Texture::WM_border_color);
+    tex->set_border_color(LVecBase4(1, 1, 1, 1));
+  }
 
   if (get_supports_shadow_filter()) {
     // If we have the ARB_shadow extension, enable shadow filtering.
@@ -2676,9 +2701,23 @@ make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) {
     tex->set_minfilter(Texture::FT_linear);
     tex->set_magfilter(Texture::FT_linear);
   }
-  sbuffer->make_display_region(0, 1, 0, 1)->set_camera(light_np);
+
+  // Assign display region(s) to the buffer and camera
+  if (is_point) {
+    for (int i = 0; i < 6; ++i) {
+      PT(DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1);
+      dr->set_lens_index(i);
+      dr->set_cube_map_index(i);
+      dr->set_camera(light_np);
+      dr->set_clear_depth_active(true);
+    }
+  } else {
+    PT(DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1);
+    dr->set_camera(light_np);
+    dr->set_clear_depth_active(true);
+  }
   light->_sbuffers[this] = sbuffer;
-  
+
   return tex;
 }
 
@@ -2687,47 +2726,66 @@ make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) {
 //       Access: Public, Virtual
 //  Description: Returns the vendor of the video card driver 
 ////////////////////////////////////////////////////////////////////
-string GraphicsStateGuardian::get_driver_vendor() { return string("0"); }
+string GraphicsStateGuardian::
+get_driver_vendor() {
+  return string("0");
+}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_driver_vendor
 //       Access: Public, Virtual
 //  Description: Returns GL_Renderer
 ////////////////////////////////////////////////////////////////////
-string GraphicsStateGuardian::get_driver_renderer() { return string("0"); }
+string GraphicsStateGuardian::get_driver_renderer() {
+  return string("0");
+}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_driver_version
 //       Access: Public, Virtual
 //  Description: Returns driver version
 ////////////////////////////////////////////////////////////////////
-string GraphicsStateGuardian::get_driver_version() { return string("0"); }
+string GraphicsStateGuardian::
+get_driver_version() {
+  return string("0");
+}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_driver_version_major
 //       Access: Public, Virtual
 //  Description: Returns major version of the video driver
 ////////////////////////////////////////////////////////////////////
-int GraphicsStateGuardian::get_driver_version_major() { return -1; }
+int GraphicsStateGuardian::
+get_driver_version_major() {
+  return -1;
+}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_driver_version_minor
 //       Access: Public, Virtual
 //  Description: Returns the minor version of the video driver
 ////////////////////////////////////////////////////////////////////
-int GraphicsStateGuardian::get_driver_version_minor() { return -1; }
+int GraphicsStateGuardian::
+get_driver_version_minor() {
+  return -1;
+}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_driver_shader_version_major
 //       Access: Public, Virtual
 //  Description: Returns the major version of the shader model
 ////////////////////////////////////////////////////////////////////
-int GraphicsStateGuardian::get_driver_shader_version_major() { return -1; }
+int GraphicsStateGuardian::
+get_driver_shader_version_major() {
+  return -1;
+}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_driver_shader_version_minor
 //       Access: Public, Virtual
 //  Description: Returns the minor version of the shader model
 ////////////////////////////////////////////////////////////////////
-int GraphicsStateGuardian::get_driver_shader_version_minor() { return -1; }
-
+int GraphicsStateGuardian::
+get_driver_shader_version_minor() {
+  return -1;
+}