Browse Source

clean up texture, projector more

David Rose 21 years ago
parent
commit
bccfb40463

+ 2 - 1
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -3067,7 +3067,8 @@ copy_texture(Texture *tex, const DisplayRegion *dr) {
   dr->get_region_pixels(xo, yo, w, h);
 
   PixelBuffer *pb = tex->_pbuffer;
-  pb->set_size(0,0,w-xo,h-yo);
+  pb->set_xsize(w-xo);
+  pb->set_ysize(h-yo);
 
   TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
   if (tc == (TextureContext *)NULL) {

+ 2 - 1
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -3065,7 +3065,8 @@ copy_texture(Texture *tex, const DisplayRegion *dr) {
   dr->get_region_pixels(xo, yo, w, h);
 
   PixelBuffer *pb = tex->_pbuffer;
-  pb->set_size(0,0,w-xo,h-yo);
+  pb->set_xsize(w-xo);
+  pb->set_ysize(h-yo);
 
   TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
   if (tc == (TextureContext *)NULL) {

+ 54 - 24
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -341,6 +341,27 @@ reset() {
     _edge_clamp = GL_CLAMP_TO_EDGE;
   }
 
+  _border_clamp = GL_CLAMP;
+  if (has_extension("GL_ARB_texture_border_clamp") ||
+      is_at_least_version(1, 3)) {
+    _border_clamp = GL_CLAMP_TO_BORDER;
+  }
+
+  _mirror_repeat = GL_REPEAT;
+  if (has_extension("GL_ARB_texture_mirrored_repeat") ||
+      is_at_least_version(1, 4)) {
+    _mirror_repeat = GL_MIRRORED_REPEAT;
+  }
+
+  _mirror_clamp = GL_CLAMP;
+  _mirror_edge_clamp = _edge_clamp;
+  _mirror_border_clamp = _border_clamp;
+  if (has_extension("GL_EXT_texture_mirror_clamp")) {
+    _mirror_clamp = GL_MIRROR_CLAMP_EXT;
+    _mirror_edge_clamp = GL_MIRROR_CLAMP_TO_EDGE_EXT;
+    _mirror_border_clamp = GL_MIRROR_CLAMP_TO_BORDER_EXT;
+  }
+
   report_my_gl_errors();
 
   _buffer_mask = 0;
@@ -1850,11 +1871,11 @@ apply_texture(TextureContext *tc) {
   bind_texture(gtc);
 
   int dirty = gtc->get_dirty_flags();
-  if ((dirty & (Texture::DF_wrap | Texture::DF_filter)) != 0) {
+  if ((dirty & (Texture::DF_wrap | Texture::DF_filter | Texture::DF_border)) != 0) {
     // We need to re-specify the texture properties.
     specify_texture(gtc->_texture);
   }
-  if ((dirty & (Texture::DF_image | Texture::DF_mipmap)) != 0) {
+  if ((dirty & (Texture::DF_image | Texture::DF_mipmap | Texture::DF_border)) != 0) {
     // We need to re-apply the image.
     apply_texture_immediate(gtc, gtc->_texture);
   }
@@ -2035,7 +2056,8 @@ copy_texture(Texture *tex, const DisplayRegion *dr) {
 #endif
 
   PixelBuffer *pb = tex->_pbuffer;
-  pb->set_size(xo,yo,w,h);
+  pb->set_xsize(w);
+  pb->set_ysize(h);
 
   TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
   nassertv(tc != (TextureContext *)NULL);
@@ -2043,7 +2065,7 @@ copy_texture(Texture *tex, const DisplayRegion *dr) {
 
   GLP(CopyTexImage2D)(GL_TEXTURE_2D, 0,
                       get_internal_image_format(pb->get_format()),
-                      xo, yo, w, h, pb->get_border());
+                      xo, yo, w, h, tex->get_border_width());
 
   // Clear the internal texture state, since we've just monkeyed with it.
   modify_state(get_untextured_state());
@@ -2138,7 +2160,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
 
 #ifdef GSG_VERBOSE
   GLCAT.debug()
-    << "glReadPixels(" << pb->get_xorg() << ", " << pb->get_yorg()
+    << "glReadPixels(" << xo << ", " << yo
     << ", " << pb->get_xsize() << ", " << pb->get_ysize()
     << ", ";
   switch (external_format) {
@@ -2179,11 +2201,11 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
   // pixelbuffer "origin" represents upper left screen point at which
   // pixelbuffer should be drawn using draw_pixel_buffer
   nassertr(!pb->_image.empty(), false);
-  GLP(ReadPixels)(pb->get_xorg() + xo, pb->get_yorg() + yo,
-               pb->get_xsize(), pb->get_ysize(),
-               external_format,
-               get_image_type(pb->get_image_type()),
-               pb->_image.p());
+  GLP(ReadPixels)(xo, yo,
+                  pb->get_xsize(), pb->get_ysize(),
+                  external_format,
+                  get_image_type(pb->get_image_type()),
+                  pb->_image.p());
 
   // We may have to reverse the byte ordering of the image if GL
   // didn't do it for us.
@@ -3207,6 +3229,10 @@ specify_texture(Texture *tex) {
   GLP(TexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
                      get_texture_wrap_mode(tex->get_wrapv()));
 
+  Colorf border_color = tex->get_border_color();
+  GLP(TexParameterfv)(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR,
+                      border_color.get_data());
+
   Texture::FilterType minfilter = tex->get_minfilter();
   Texture::FilterType magfilter = tex->get_magfilter();
 
@@ -3336,7 +3362,7 @@ apply_texture_immediate(CLP(TextureContext) *gtc, Texture *tex) {
     << "glTexImage2D(GL_TEXTURE_2D, "
     << (int)internal_format << ", "
     << width << ", " << height << ", "
-    << pb->get_border() << ", " << (int)external_format << ", "
+    << tex->get_border_width() << ", " << (int)external_format << ", "
     << (int)type << ", " << tex->get_name() << ")\n";
 #endif
 
@@ -3371,7 +3397,7 @@ apply_texture_immediate(CLP(TextureContext) *gtc, Texture *tex) {
         gtc->_internal_format = internal_format;
         gtc->_width = width;
         gtc->_height = height;
-        gtc->_border = 0;
+        gtc->_border_width = 0;
         
 #ifndef NDEBUG
         if (CLP(save_mipmaps)) {
@@ -3387,22 +3413,22 @@ apply_texture_immediate(CLP(TextureContext) *gtc, Texture *tex) {
     }
   }
 
-  GLint border = pb->get_border();
+  GLint border_width = tex->get_border_width();
 
   if (!gtc->_already_applied || 
       gtc->_internal_format != internal_format ||
       gtc->_width != width ||
       gtc->_height != height ||
-      gtc->_border != border) {
+      gtc->_border_width != border_width) {
     // We need to reload a new image.
     GLP(TexImage2D)(GL_TEXTURE_2D, 0, internal_format,
-                    width, height, pb->get_border(),
+                    width, height, border_width,
                     external_format, type, image);
     gtc->_already_applied = true;
     gtc->_internal_format = internal_format;
     gtc->_width = width;
     gtc->_height = height;
-    gtc->_border = border;
+    gtc->_border_width = border_width;
 
   } else {
     // We can reload the image over the previous image, saving on
@@ -3623,11 +3649,11 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
     << (void *)pb->_image.p() << ")" << endl;
 #endif
 
-  GLP(RasterPos2i)( pb->get_xorg(), pb->get_yorg() );
-  GLP(DrawPixels)( pb->get_xsize(), pb->get_ysize(),
-                get_external_image_format(pb->get_format()),
-                get_image_type(pb->get_image_type()),
-                pb->_image.p() );
+  GLP(RasterPos2i)(0, 0);
+  GLP(DrawPixels)(pb->get_xsize(), pb->get_ysize(),
+                  get_external_image_format(pb->get_format()),
+                  get_image_type(pb->get_image_type()),
+                  pb->_image.p() );
 
   GLP(MatrixMode)( GL_PROJECTION );
   GLP(PopMatrix)();
@@ -3663,14 +3689,18 @@ get_texture_wrap_mode(Texture::WrapMode wm) {
   switch (wm) {
   case Texture::WM_clamp:
     return _edge_clamp;
+
   case Texture::WM_repeat:
     return GL_REPEAT;
 
   case Texture::WM_mirror:
+    return _mirror_repeat;
+
   case Texture::WM_mirror_once:
+    return _mirror_border_clamp;
+
   case Texture::WM_border_color:
-    // These are unsupported for now.
-    return GL_REPEAT;
+    return _border_clamp;
 
   case Texture::WM_invalid:
     break;
@@ -4684,7 +4714,7 @@ build_phony_mipmap_level(int level, int xsize, int ysize) {
   GLenum type = get_image_type(pb->get_image_type());
 
   GLP(TexImage2D)(GL_TEXTURE_2D, level, internal_format,
-                  pb->get_xsize(), pb->get_ysize(), pb->get_border(),
+                  pb->get_xsize(), pb->get_ysize(), 0,
                   external_format, type, pb->_image );
 
   delete pb;

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

@@ -337,6 +337,11 @@ public:
   PFNGLMULTITEXCOORD2FVPROC _glMultiTexCoord2fv;
 
   GLenum _edge_clamp;
+  GLenum _border_clamp;
+  GLenum _mirror_repeat;
+  GLenum _mirror_clamp;
+  GLenum _mirror_edge_clamp;
+  GLenum _mirror_border_clamp;
 
 public:
   static GraphicsStateGuardian *

+ 1 - 1
panda/src/glstuff/glTextureContext_src.h

@@ -40,7 +40,7 @@ public:
   GLint _internal_format;
   GLsizei _width;
   GLsizei _height;
-  GLint _border;
+  GLint _border_width;
 
 public:
   static TypeHandle get_class_type() {

+ 0 - 88
panda/src/gobj/pixelBuffer.I

@@ -97,63 +97,6 @@ INLINE void PixelBuffer::set_ysize(int size)
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: PixelBuffer::set_xorg
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void PixelBuffer::set_xorg(int org)
-{
-  if (_xorg != org) {
-    _xorg = org;
-    make_dirty();
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PixelBuffer::set_yorg
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void PixelBuffer::set_yorg(int org)
-{
-  if (_yorg != org) {
-    _yorg = org;
-    make_dirty();
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PixelBuffer::set_size
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void PixelBuffer::
-set_size(int x_org, int y_org, int x_size, int y_size) {
-  if ((_xsize != x_size) || (_ysize != y_size) ||
-      (_xorg != x_org) || (_yorg != y_org)) {
-    make_dirty();
-  }
-
-  _xsize = x_size;
-  _ysize = y_size;
-  _xorg = x_org;
-  _yorg = y_org;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PixelBuffer::set_border
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void PixelBuffer::
-set_border(int border) {
-  if (_border != border) {
-    _border = border;
-    make_dirty();
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PixelBuffer::set_num_components
 //       Access: Public
@@ -236,37 +179,6 @@ get_ysize() const {
   return _ysize;
 }
 
-
-////////////////////////////////////////////////////////////////////
-//     Function: PixelBuffer::get_xorg
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE int PixelBuffer::
-get_xorg() const {
-  return _xorg;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PixelBuffer::get_yorg
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE int PixelBuffer::
-get_yorg() const {
-  return _yorg;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PixelBuffer::get_border
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE int PixelBuffer::
-get_border() const {
-  return _border;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PixelBuffer::get_num_components
 //       Access: Public

+ 0 - 18
panda/src/gobj/pixelBuffer.cxx

@@ -34,9 +34,6 @@ PixelBuffer(void) : ImageBuffer()
 {
   _xsize = 0;
   _ysize = 0;
-  _xorg = 0;
-  _yorg = 0;
-  _border = 0;
   _format = F_rgb;
   _type = T_unsigned_byte;
   _num_components = 3;
@@ -58,9 +55,6 @@ PixelBuffer(int xsize, int ysize, int components, int component_width,
 {
   _xsize = xsize;
   _ysize = ysize;
-  _xorg = 0;
-  _yorg = 0;
-  _border = 0;
   _num_components = components;
   _component_width = component_width;
   _type = type;
@@ -80,9 +74,6 @@ PixelBuffer(int xsize, int ysize, int components, int component_width, Type type
 {
   _xsize = xsize;
   _ysize = ysize;
-  _xorg = 0;
-  _yorg = 0;
-  _border = 0;
   _num_components = components;
   _component_width = component_width;
   _type = type;
@@ -102,9 +93,6 @@ PixelBuffer::
 PixelBuffer(const PixelBuffer &copy) :
   _xsize(copy._xsize),
   _ysize(copy._ysize),
-  _xorg(copy._xorg),
-  _yorg(copy._yorg),
-  _border(copy._border),
   _num_components(copy._num_components),
   _component_width(copy._component_width),
   _format(copy._format),
@@ -123,9 +111,6 @@ void PixelBuffer::
 operator = (const PixelBuffer &copy) {
   _xsize = copy._xsize;
   _ysize = copy._ysize;
-  _xorg = copy._xorg;
-  _yorg = copy._yorg;
-  _border = copy._border;
   _num_components = copy._num_components;
   _component_width = copy._component_width;
   _format = copy._format;
@@ -409,11 +394,8 @@ store(PNMImage &pnmimage) const {
 void PixelBuffer::
 copy(const PixelBuffer *pb) {
   nassertv(pb != NULL);
-  _xorg = pb->_xorg;
-  _yorg = pb->_yorg;
   _xsize = pb->_xsize;
   _ysize = pb->_ysize;
-  _border = pb->_border;
   _num_components = pb->_num_components;
   _component_width = pb->_component_width;
   _format = pb->_format;

+ 0 - 13
panda/src/gobj/pixelBuffer.h

@@ -108,10 +108,6 @@ public:
 
   INLINE void set_xsize(int size);
   INLINE void set_ysize(int size);
-  INLINE void set_xorg(int org);
-  INLINE void set_yorg(int org);
-  INLINE void set_size(int x_org, int y_org, int x_size, int y_size);
-  INLINE void set_border(int border); 
   INLINE void set_num_components(int num_components);
   INLINE void set_component_width(int component_width);
   INLINE void set_format(Format format);
@@ -120,9 +116,6 @@ public:
 
   INLINE int get_xsize() const;
   INLINE int get_ysize() const;
-  INLINE int get_xorg() const;
-  INLINE int get_yorg() const;
-  INLINE int get_border() const;
   INLINE int get_num_components() const;
   INLINE int get_component_width() const;
   INLINE Format get_format() const;
@@ -163,12 +156,6 @@ private:
 protected:
   int _xsize;
   int _ysize;
-
-  // pixelbuffer "origin" represents upper left screen point at which
-  // pixelbuffer should be drawn using draw_pixel_buffer
-  int _xorg;
-  int _yorg;
-  int _border;
   int _num_components;
   int _component_width;
   Format _format;

+ 20 - 0
panda/src/gobj/texture.I

@@ -72,6 +72,26 @@ get_anisotropic_degree() const {
   return _anisotropic_degree;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::get_border_color
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE Colorf Texture::
+get_border_color() const {
+  return _border_color;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::get_border_width
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE int Texture::
+get_border_width() const {
+  return _border_width;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::uses_mipmaps
 //       Access: Public

+ 30 - 11
panda/src/gobj/texture.cxx

@@ -142,7 +142,8 @@ Texture() : ImageBuffer() {
   _pbuffer = new PixelBuffer;
   // _has_requested_size = false;
   _all_dirty_flags = 0;
-  memset(&_border_color,0,sizeof(Colorf));
+  _border_color.set(0.0f, 0.0f, 0.0f, 1.0f);
+  _border_width = 0;
 }
 
 
@@ -152,7 +153,8 @@ Texture() : ImageBuffer() {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 Texture::
-Texture(int xsize, int ysize, int components, int component_width, PixelBuffer::Type type, 
+Texture(int xsize, int ysize, int components, int component_width, 
+        PixelBuffer::Type type, 
         PixelBuffer::Format format, bool bAllocateRAM) : ImageBuffer() {
   _magfilter = FT_linear;
   _minfilter = FT_linear;
@@ -163,7 +165,8 @@ Texture(int xsize, int ysize, int components, int component_width, PixelBuffer::
   _pbuffer = new PixelBuffer(xsize,ysize,components,component_width,type,format,bAllocateRAM);
   // _has_requested_size = false;
   _all_dirty_flags = 0;
-  memset(&_border_color,0,sizeof(Colorf));
+  _border_color.set(0.0f, 0.0f, 0.0f, 1.0f);
+  _border_width = 0;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -406,11 +409,33 @@ set_anisotropic_degree(int anisotropic_degree) {
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::set_border_color
 //       Access: Published
-//  Description:
+//  Description: Specifies the uniform color of the texture border, if
+//               it has one (see set_border_width()), and if the
+//               border color is not part of the image.
 ////////////////////////////////////////////////////////////////////
 void Texture::
 set_border_color(const Colorf &color) {
-   memcpy(&_border_color,&color,sizeof(Colorf));
+  if (_border_color != color) {
+    mark_dirty(DF_border);
+    _border_color = color;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::set_border_width
+//       Access: Published
+//  Description: Specifies the width of the texture border, in pixels.
+//               Generally, this can be either 0 or 1, and the default
+//               is 0.  This is intended to be used for tiling large
+//               textures, although it has one or two other
+//               applications.
+////////////////////////////////////////////////////////////////////
+void Texture::
+set_border_width(int width) {
+  if (_border_width != width) {
+    mark_dirty(DF_border);
+    _border_width = width;
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -870,9 +895,6 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
         _pbuffer->set_format(format);
         _pbuffer->set_xsize(scan.get_int32());
         _pbuffer->set_ysize(scan.get_int32());
-        _pbuffer->set_xorg(scan.get_int32());
-        _pbuffer->set_yorg(scan.get_int32());
-        _pbuffer->set_border(scan.get_uint8());
         _pbuffer->set_image_type((PixelBuffer::Type)scan.get_uint8());
         _pbuffer->set_num_components(scan.get_uint8());
         _pbuffer->set_component_width(scan.get_uint8());
@@ -927,9 +949,6 @@ write_datagram(BamWriter *manager, Datagram &me) {
   if (has_rawdata) {
     me.add_int32(_pbuffer->get_xsize());
     me.add_int32(_pbuffer->get_ysize());
-    me.add_int32(_pbuffer->get_xorg());
-    me.add_int32(_pbuffer->get_yorg());
-    me.add_uint8(_pbuffer->get_border());
     me.add_uint8(_pbuffer->get_image_type());
     me.add_uint8(_pbuffer->get_num_components());
     me.add_uint8(_pbuffer->get_component_width());

+ 5 - 0
panda/src/gobj/texture.h

@@ -91,12 +91,15 @@ PUBLISHED:
   void set_magfilter(FilterType filter);
   void set_anisotropic_degree(int anisotropic_degree);
   void set_border_color(const Colorf &color);
+  void set_border_width(int border_width);
 
   INLINE WrapMode get_wrapu() const;
   INLINE WrapMode get_wrapv() const;
   INLINE FilterType get_minfilter() const;
   INLINE FilterType get_magfilter() const;
   INLINE int get_anisotropic_degree() const;
+  INLINE Colorf get_border_color() const;
+  INLINE int get_border_width() const;
   INLINE bool uses_mipmaps() const;
 
   void prepare(PreparedGraphicsObjects *prepared_objects);
@@ -125,6 +128,7 @@ public:
     DF_wrap       = 0x002,  // The wrap properties have changed.
     DF_filter     = 0x004,  // The minfilter or magfilter have changed.
     DF_mipmap     = 0x008,  // The use of mipmaps or not has changed.
+    DF_border     = 0x010,  // The border has changed.
   };
 
   void mark_dirty(int flags_to_set);
@@ -142,6 +146,7 @@ private:
   int _anisotropic_degree;
   bool _keep_ram_image;
   Colorf _border_color;
+  int _border_width;
 
   // A Texture keeps a list (actually, a map) of all the
   // PreparedGraphicsObjects tables that it has been prepared into.

+ 17 - 1
panda/src/pgraph/texProjectorEffect.cxx

@@ -219,7 +219,23 @@ cull_callback(CullTraverser *trav, CullTraverserData &data,
 
     if (def._to_lens_node != (LensNode *)NULL &&
         def._to_lens_node->get_lens() != (Lens *)NULL) {
-      transform = TransformState::make_mat(def._to_lens_node->get_lens()->get_projection_mat())->compose(transform);
+      
+      // Get the lens's projection matrix, as a TransformState.
+      CPT(TransformState) projmat = TransformState::make_mat(def._to_lens_node->get_lens()->get_projection_mat());
+
+      // We need a special transform to convert the -0.5, 0.5
+      // centering of the lens's projection matrix to UV's in the
+      // range of (0, 1).
+      static CPT(TransformState) fixmat;
+      if (fixmat == (TransformState *)NULL) {
+        fixmat = TransformState::make_pos_hpr_scale
+          (LVecBase3f(0.5f, 0.5f, 0.0f),
+           LVecBase3f(0.0f, 0.0f, 0.0f),
+           LVecBase3f(0.5f, 0.5f, 1.0f));
+      }
+
+      // Now apply both to the current transform.
+      transform = fixmat->compose(projmat)->compose(transform);
     }
 
     if (!transform->is_identity()) {