Bläddra i källkod

expose Texture::T_depth_component, sanify a few things

David Rose 20 år sedan
förälder
incheckning
67e3f1daa6

+ 9 - 6
panda/src/display/graphicsStateGuardian.cxx

@@ -641,13 +641,16 @@ begin_frame() {
   // For Pstats to track our current texture memory usage, we have to
   // reset the set of current textures each frame.
   init_frame_pstats();
-
-  // But since we don't get sent a new issue_texture() unless our
-  // texture state has changed, we have to be sure to clear the
-  // current texture state now.  A bit unfortunate, but probably not
-  // measurably expensive.
-  modify_state(get_untextured_state());
 #endif
+
+  // We should reset the state to the default at the beginning of
+  // every frame.  Although this will incur additional overhead,
+  // particularly in a simple scene, it helps ensure that states that
+  // have changed properties since last time without changing
+  // attribute pointers--like textures, lighting, or fog--will still
+  // be accurately updated.
+  set_state(RenderState::make_empty());
+
   return true;
 }
 

+ 120 - 79
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -880,22 +880,22 @@ do_clear(const RenderBuffer &buffer) {
     mask |= GL_ACCUM_BUFFER_BIT;
   }
 
-#ifdef GSG_VERBOSE
-  GLCAT.spam() << "glClear(";
-  if (mask & GL_COLOR_BUFFER_BIT) {
-    GLCAT.spam(false) << "GL_COLOR_BUFFER_BIT|";
-  }
-  if (mask & GL_DEPTH_BUFFER_BIT) {
-    GLCAT.spam(false) << "GL_DEPTH_BUFFER_BIT|";
-  }
-  if (mask & GL_STENCIL_BUFFER_BIT) {
-    GLCAT.spam(false) << "GL_STENCIL_BUFFER_BIT|";
-  }
-  if (mask & GL_ACCUM_BUFFER_BIT) {
-    GLCAT.spam(false) << "GL_ACCUM_BUFFER_BIT|";
+  if (GLCAT.is_spam()) {
+    GLCAT.spam() << "glClear(";
+    if (mask & GL_COLOR_BUFFER_BIT) {
+      GLCAT.spam(false) << "GL_COLOR_BUFFER_BIT|";
+    }
+    if (mask & GL_DEPTH_BUFFER_BIT) {
+      GLCAT.spam(false) << "GL_DEPTH_BUFFER_BIT|";
+    }
+    if (mask & GL_STENCIL_BUFFER_BIT) {
+      GLCAT.spam(false) << "GL_STENCIL_BUFFER_BIT|";
+    }
+    if (mask & GL_ACCUM_BUFFER_BIT) {
+      GLCAT.spam(false) << "GL_ACCUM_BUFFER_BIT|";
+    }
+    GLCAT.spam(false) << ")" << endl;
   }
-  GLCAT.spam(false) << ")" << endl;
-#endif
 
   modify_state(state);
 
@@ -981,10 +981,10 @@ prepare_lens() {
     _projection_mat *= invert_mat;
   }
 
-#ifdef GSG_VERBOSE
-  GLCAT.spam()
-    << "glMatrixMode(GL_PROJECTION): " << _projection_mat << endl;
-#endif
+  if (GLCAT.is_spam()) {
+    GLCAT.spam()
+      << "glMatrixMode(GL_PROJECTION): " << _projection_mat << endl;
+  }
   GLP(MatrixMode)(GL_PROJECTION);
   GLP(LoadMatrixf)(_projection_mat.get_data());
   report_my_gl_errors();
@@ -2135,12 +2135,22 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   tex->set_y_size(h);
 
   if (tex->get_match_framebuffer_format()) {
-    FrameBufferProperties properties = get_properties();
+    const FrameBufferProperties &properties = get_properties();
     int mode = properties.get_frame_buffer_mode();
-    if (mode & FrameBufferProperties::FM_alpha) {
-      tex->set_format(Texture::F_rgba);
-    } else {
-      tex->set_format(Texture::F_rgb);
+
+    switch (tex->get_format()) {
+    case Texture::F_depth_component:
+    case Texture::F_stencil_index:
+      // If the texture is one of these special formats, we don't want
+      // to adapt it to the framebuffer's color format.
+      break;
+
+    default:
+      if (mode & FrameBufferProperties::FM_alpha) {
+        tex->set_format(Texture::F_rgba);
+      } else {
+        tex->set_format(Texture::F_rgb);
+      }
     }
   }
 
@@ -2210,19 +2220,41 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
   dr->get_region_pixels(xo, yo, w, h);
 
   const FrameBufferProperties &properties = get_properties();
+  int mode = properties.get_frame_buffer_mode();
 
-  Texture::ComponentType component_type;
-  if (properties.get_color_bits() <= 24) {
-    component_type = Texture::T_unsigned_byte;
-  } else {
-    component_type = Texture::T_unsigned_short;
-  }
+  Texture::Format format = tex->get_format();
+  Texture::ComponentType component_type = tex->get_component_type();
+  bool color_mode = false;
 
-  Texture::Format format;
-  if (properties.get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) {
-    format = Texture::F_rgba;
-  } else {
-    format = Texture::F_rgb;
+  switch (format) {
+  case Texture::F_depth_component:
+    if (properties.get_depth_bits() <= 8) {
+      component_type = Texture::T_unsigned_byte;
+    } else {
+      component_type = Texture::T_unsigned_short;
+    }
+    break;
+
+  case Texture::F_stencil_index:
+    if (properties.get_stencil_bits() <= 8) {
+      component_type = Texture::T_unsigned_byte;
+    } else {
+      component_type = Texture::T_unsigned_short;
+    }
+    break;
+
+  default:
+    color_mode = true;
+    if (mode & FrameBufferProperties::FM_alpha) {
+      format = Texture::F_rgba;
+    } else {
+      format = Texture::F_rgb;
+    }
+    if (properties.get_color_bits() <= 24) {
+      component_type = Texture::T_unsigned_byte;
+    } else {
+      component_type = Texture::T_unsigned_short;
+    }
   }
 
   Texture::TextureType texture_type;
@@ -2243,46 +2275,46 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
 
   GLenum external_format = get_external_image_format(format);
 
-#ifdef GSG_VERBOSE
-  GLCAT.debug()
-    << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", ";
-  switch (external_format) {
-  case GL_DEPTH_COMPONENT:
-    GLCAT.debug(false) << "GL_DEPTH_COMPONENT, ";
-    break;
-  case GL_RGB:
-    GLCAT.debug(false) << "GL_RGB, ";
-    break;
-  case GL_RGBA:
-    GLCAT.debug(false) << "GL_RGBA, ";
-    break;
-  case GL_BGR:
-    GLCAT.debug(false) << "GL_BGR, ";
-    break;
-  case GL_BGRA:
-    GLCAT.debug(false) << "GL_BGRA, ";
-    break;
-  default:
-    GLCAT.debug(false) << "unknown, ";
-    break;
-  }
-  switch (get_component_type(component_type)) {
-  case GL_UNSIGNED_BYTE:
-    GLCAT.debug(false) << "GL_UNSIGNED_BYTE, ";
-    break;
-  case GL_UNSIGNED_SHORT:
-    GLCAT.debug(false) << "GL_UNSIGNED_SHORT, ";
-    break;
-  case GL_FLOAT:
-    GLCAT.debug(false) << "GL_FLOAT, ";
-    break;
-  default:
-    GLCAT.debug(false) << "unknown, ";
-    break;
+  if (GLCAT.is_spam()) {
+    GLCAT.spam()
+      << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", ";
+    switch (external_format) {
+    case GL_DEPTH_COMPONENT:
+      GLCAT.spam(false) << "GL_DEPTH_COMPONENT, ";
+      break;
+    case GL_RGB:
+      GLCAT.spam(false) << "GL_RGB, ";
+      break;
+    case GL_RGBA:
+      GLCAT.spam(false) << "GL_RGBA, ";
+      break;
+    case GL_BGR:
+      GLCAT.spam(false) << "GL_BGR, ";
+      break;
+    case GL_BGRA:
+      GLCAT.spam(false) << "GL_BGRA, ";
+      break;
+    default:
+      GLCAT.spam(false) << "unknown, ";
+      break;
+    }
+    switch (get_component_type(component_type)) {
+    case GL_UNSIGNED_BYTE:
+      GLCAT.spam(false) << "GL_UNSIGNED_BYTE, ";
+      break;
+    case GL_UNSIGNED_SHORT:
+      GLCAT.spam(false) << "GL_UNSIGNED_SHORT, ";
+      break;
+    case GL_FLOAT:
+      GLCAT.spam(false) << "GL_FLOAT, ";
+      break;
+    default:
+      GLCAT.spam(false) << "unknown, ";
+      break;
+    }
+    GLCAT.spam(false)
+      << ")" << endl;
   }
-  GLCAT.debug(false)
-    << ")" << endl;
-#endif
 
   unsigned char *image = tex->modify_ram_image();
   if (z >= 0) {
@@ -2298,7 +2330,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
   // didn't do it for us.  This assumes we render out the six faces of
   // a cube map in ascending order, since we can't do this until we
   // have rendered the last face.
-  if (!_supports_bgr && (z == -1 || z == 5)) {
+  if (color_mode && !_supports_bgr && (z == -1 || z == 5)) {
     tex->set_ram_image(fix_component_ordering(tex->get_ram_image(), 
                                               external_format, tex));
   }
@@ -2343,10 +2375,11 @@ apply_fog(Fog *fog) {
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 issue_transform(const TransformState *transform) {
-#ifdef GSG_VERBOSE
-  GLCAT.spam()
-    << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
-#endif
+  if (GLCAT.is_spam()) {
+    GLCAT.spam()
+      << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
+  }
+
   DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
   GLP(MatrixMode)(GL_MODELVIEW);
   GLP(LoadMatrixf)(transform->get_mat().get_data());
@@ -3401,6 +3434,7 @@ get_external_image_format(Texture::Format format) const {
     return GL_STENCIL_INDEX;
   case Texture::F_depth_component:
     return GL_DEPTH_COMPONENT;
+
   case Texture::F_red:
     return GL_RED;
   case Texture::F_green:
@@ -3443,6 +3477,13 @@ get_external_image_format(Texture::Format format) const {
 GLint CLP(GraphicsStateGuardian)::
 get_internal_image_format(Texture::Format format) {
   switch (format) {
+  case Texture::F_color_index:
+    return GL_COLOR_INDEX;
+  case Texture::F_stencil_index:
+    return GL_STENCIL_INDEX;
+  case Texture::F_depth_component:
+    return GL_DEPTH_COMPONENT;
+
   case Texture::F_rgba:
   case Texture::F_rgbm:
     return GL_RGBA;

+ 12 - 12
panda/src/gobj/texture.I

@@ -529,7 +529,7 @@ get_keep_ram_image() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_filename
-//       Access: Public
+//       Access: Published
 //  Description: Sets the name of the file that contains the image's
 //               contents.  Normally, this is set automatically when
 //               the image is loaded, for instance via
@@ -547,7 +547,7 @@ set_filename(const Filename &filename) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::clear_filename
-//       Access: Public
+//       Access: Published
 //  Description: Removes the alpha filename, if it was previously set.
 //               See set_filename().
 ////////////////////////////////////////////////////////////////////
@@ -558,7 +558,7 @@ clear_filename() {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_alpha_filename
-//       Access: Public
+//       Access: Published
 //  Description: Sets the name of the file that contains the image's
 //               alpha channel contents.  Normally, this is set
 //               automatically when the image is loaded, for instance
@@ -579,7 +579,7 @@ set_alpha_filename(const Filename &alpha_filename) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::clear_alpha_filename
-//       Access: Public
+//       Access: Published
 //  Description: Removes the alpha filename, if it was previously set.
 //               See set_alpha_filename().
 ////////////////////////////////////////////////////////////////////
@@ -590,7 +590,7 @@ clear_alpha_filename() {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_fullpath
-//       Access: Public
+//       Access: Published
 //  Description: Sets the full pathname to the file that contains the
 //               image's contents, as found along the search path.
 //               Normally, this is set automatically when the image is
@@ -603,7 +603,7 @@ set_fullpath(const Filename &fullpath) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::clear_fullpath
-//       Access: Public
+//       Access: Published
 //  Description: Removes the alpha fullpath, if it was previously set.
 //               See set_fullpath().
 ////////////////////////////////////////////////////////////////////
@@ -614,7 +614,7 @@ clear_fullpath() {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_alpha_fullpath
-//       Access: Public
+//       Access: Published
 //  Description: Sets the full pathname to the file that contains the
 //               image's alpha channel contents, as found along the
 //               search path.  Normally, this is set automatically
@@ -628,7 +628,7 @@ set_alpha_fullpath(const Filename &alpha_fullpath) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::clear_alpha_fullpath
-//       Access: Public
+//       Access: Published
 //  Description: Removes the alpha fullpath, if it was previously set.
 //               See set_alpha_fullpath().
 ////////////////////////////////////////////////////////////////////
@@ -639,7 +639,7 @@ clear_alpha_fullpath() {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_x_size
-//       Access: Public
+//       Access: Published
 //  Description: Changes the x size indicated for the texture.  This
 //               also implicitly unloads the texture if it has already
 //               been loaded.
@@ -654,7 +654,7 @@ set_x_size(int x_size) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_y_size
-//       Access: Public
+//       Access: Published
 //  Description: Changes the y size indicated for the texture.  This
 //               also implicitly unloads the texture if it has already
 //               been loaded.
@@ -670,7 +670,7 @@ set_y_size(int y_size) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_z_size
-//       Access: Public
+//       Access: Published
 //  Description: Changes the z size indicated for the texture.  This
 //               also implicitly unloads the texture if it has already
 //               been loaded.
@@ -688,7 +688,7 @@ set_z_size(int z_size) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_loaded_from_disk
-//       Access: Public
+//       Access: Published
 //  Description: Sets the flag that indicates the texture has been
 //               loaded from a disk file.  You should also ensure the
 //               filename has been set correctly.  When this flag is

+ 3 - 2
panda/src/gobj/texture.cxx

@@ -720,6 +720,7 @@ load(const PNMImage &pnmimage, int z) {
 ////////////////////////////////////////////////////////////////////
 bool Texture::
 store(PNMImage &pnmimage, int z) const {
+  nassertr(has_ram_image(), false);
   nassertr(z >= 0 && z < _z_size, false);
 
   if (_component_type == T_unsigned_byte) {
@@ -1070,7 +1071,7 @@ release_all() {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_format
-//       Access: Public
+//       Access: Published
 //  Description: Changes the format value for the texture components.
 //               This implicitly sets num_components as well.
 ////////////////////////////////////////////////////////////////////
@@ -1116,7 +1117,7 @@ set_format(Texture::Format format) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_component_type
-//       Access: Public
+//       Access: Published
 //  Description: Changes the data value for the texture components.
 //               This implicitly sets component_width as well.
 ////////////////////////////////////////////////////////////////////

+ 3 - 3
panda/src/gobj/texture.h

@@ -218,9 +218,9 @@ PUBLISHED:
   bool release(PreparedGraphicsObjects *prepared_objects);
   int release_all();
 
-public:
-  // These are public, but in general, you shouldn't be mucking with
-  // these values; they are set automatically when a texture is
+PUBLISHED:
+  // These are published, but in general, you shouldn't be mucking
+  // with these values; they are set automatically when a texture is
   // loaded.
   INLINE void set_filename(const Filename &filename);
   INLINE void clear_filename();

+ 16 - 0
panda/src/grutil/cardMaker.I

@@ -103,6 +103,22 @@ set_color(const LVecBase4f &color) {
   _has_color = true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CardMaker::set_has_normals
+//       Access: Public
+//  Description: Sets the flag indicating whether vertices will be
+//               generated with normals or not.  Normals are required
+//               if you intend to enable lighting on the card, but are
+//               just wasted space and bandwidth otherwise, so there
+//               is a (slight) optimization for disabling them.  If
+//               enabled, the normals will be generated perpendicular
+//               to the card's face.
+////////////////////////////////////////////////////////////////////
+INLINE void CardMaker::
+set_has_normals(bool flag) {
+  _has_normals = flag;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CardMaker::set_source_geometry
 //       Access: Published

+ 21 - 3
panda/src/grutil/cardMaker.cxx

@@ -39,6 +39,7 @@ reset() {
   _frame.set(0.0f, 1.0f, 0.0f, 1.0f);
   _has_color = false;
   _color.set(1.0f, 1.0f, 1.0f, 1.0f);
+  _has_normals = true;
   _source_geometry = (PandaNode *)NULL;
   _source_frame.set(0.0f, 0.0f, 0.0f, 0.0f);
 }
@@ -64,10 +65,18 @@ generate() {
   float top = _frame[3];
 
   CPT(GeomVertexFormat) format;
-  if (_has_uvs) {
-    format = GeomVertexFormat::get_v3cpt2();
+  if (_has_normals) {
+    if (_has_uvs) {
+      format = GeomVertexFormat::get_v3n3cpt2();
+    } else {
+      format = GeomVertexFormat::get_v3n3cp();
+    }
   } else {
-    format = GeomVertexFormat::get_v3cp();
+    if (_has_uvs) {
+      format = GeomVertexFormat::get_v3cpt2();
+    } else {
+      format = GeomVertexFormat::get_v3cp();
+    }
   }
   
   PT(GeomVertexData) vdata = new GeomVertexData
@@ -93,7 +102,16 @@ generate() {
     texcoord.add_data2f(_ur[0], _ll[1]);
   }
   
+  if (_has_normals) {
+    GeomVertexWriter normal(vdata, InternalName::get_normal());
+    normal.add_data3f(LVector3f::back());
+    normal.add_data3f(LVector3f::back());
+    normal.add_data3f(LVector3f::back());
+    normal.add_data3f(LVector3f::back());
+  }
+  
   PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
+  strip->set_shade_model(Geom::SM_uniform);
   strip->add_next_vertices(4);
   strip->close_primitive();
   

+ 4 - 0
panda/src/grutil/cardMaker.h

@@ -47,6 +47,8 @@ PUBLISHED:
   INLINE void set_color(float r, float g, float b, float a);
   INLINE void set_color(const Colorf &color);
 
+  INLINE void set_has_normals(bool flag);
+
   INLINE void set_source_geometry(PandaNode *node, const LVecBase4f &frame);
   INLINE void clear_source_geometry();
 
@@ -62,6 +64,8 @@ private:
   bool _has_color;
   Colorf _color;
 
+  bool _has_normals;
+
   PT(PandaNode) _source_geometry;
   LVecBase4f _source_frame;
 };

+ 3 - 1
panda/src/pgraph/lensNode.cxx

@@ -22,6 +22,7 @@
 #include "bamReader.h"
 #include "datagram.h"
 #include "datagramIterator.h"
+#include "perspectiveLens.h"
 #include "geomNode.h"
 
 TypeHandle LensNode::_type_handle;
@@ -33,7 +34,8 @@ TypeHandle LensNode::_type_handle;
 ////////////////////////////////////////////////////////////////////
 LensNode::
 LensNode(const string &name) :
-  PandaNode(name)
+  PandaNode(name),
+  _lens(new PerspectiveLens())
 {
 }
 

+ 4 - 13
panda/src/pgraph/nodePath.cxx

@@ -3701,24 +3701,15 @@ find_all_texture_stages(const string &name) const {
 //  Description: Sets the geometry at this level and below to render
 //               using the indicated material.
 //
-//               This operation copies the given material pointer.  If
-//               the material structure is changed later, it must be
-//               reapplied via another call to set_material().
+//               Previously, this operation made a copy of the
+//               material structure, but nowadays it assigns the
+//               pointer directly.
 ////////////////////////////////////////////////////////////////////
 void NodePath::
 set_material(Material *mat, int priority) {
   nassertv_always(!is_empty());
   nassertv(mat != NULL);
-
-  // We create a temporary Material pointer, a copy of the one we are
-  // given, to allow the user to monkey with the material and set it
-  // again later, with the desired effect.  If we stored the user's
-  // pointer directly, it would be bad if the user later modified the
-  // values within the Material.
-  PT(Material) temp = new Material(*mat);
-  const Material *mp = MaterialPool::get_material(temp);
-
-  node()->set_attrib(MaterialAttrib::make(mp), priority);
+  node()->set_attrib(MaterialAttrib::make(mat), priority);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 2
panda/src/pnmimage/pnmImage.cxx

@@ -394,10 +394,10 @@ make_grayscale(double rc, double gc, double bc) {
 ////////////////////////////////////////////////////////////////////
 void PNMImage::
 set_maxval(xelval maxval) {
-  nassertv(maxval > 0.0);
+  nassertv(maxval > 0);
 
   if (maxval != _maxval) {
-    double ratio = maxval / _maxval;
+    double ratio = (double)maxval / (double)_maxval;
 
     if (is_grayscale()) {
       for (int y = 0; y < get_y_size(); y++) {