new texture dirty flags

This commit is contained in:
David Rose 2001-11-27 23:13:35 +00:00
parent 523fd913dd
commit f90bba39e8
16 changed files with 412 additions and 268 deletions

View File

@ -21,9 +21,7 @@
hardwareChannel.h interactiveGraphicsPipe.I \ hardwareChannel.h interactiveGraphicsPipe.I \
interactiveGraphicsPipe.h noninteractiveGraphicsPipe.I \ interactiveGraphicsPipe.h noninteractiveGraphicsPipe.I \
noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h \ noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h \
savedContext.I savedContext.h \ savedFrameBuffer.I savedFrameBuffer.h
savedFrameBuffer.I savedFrameBuffer.h textureContext.I \
textureContext.h
#define INCLUDED_SOURCES \ #define INCLUDED_SOURCES \
config_display.cxx displayRegion.cxx \ config_display.cxx displayRegion.cxx \
@ -32,8 +30,7 @@
graphicsWindow.cxx graphicsWindowInputDevice.cxx \ graphicsWindow.cxx graphicsWindowInputDevice.cxx \
hardwareChannel.cxx interactiveGraphicsPipe.cxx \ hardwareChannel.cxx interactiveGraphicsPipe.cxx \
noninteractiveGraphicsPipe.cxx pipeSpec.cxx \ noninteractiveGraphicsPipe.cxx pipeSpec.cxx \
savedContext.cxx \ savedFrameBuffer.cxx
savedFrameBuffer.cxx textureContext.cxx
#define INSTALL_HEADERS \ #define INSTALL_HEADERS \
config_display.h \ config_display.h \
@ -47,9 +44,7 @@
hardwareChannel.I hardwareChannel.h interactiveGraphicsPipe.I \ hardwareChannel.I hardwareChannel.h interactiveGraphicsPipe.I \
interactiveGraphicsPipe.h noninteractiveGraphicsPipe.I \ interactiveGraphicsPipe.h noninteractiveGraphicsPipe.I \
noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h renderBuffer.h \ noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h renderBuffer.h \
savedContext.I savedContext.h \ savedFrameBuffer.I savedFrameBuffer.h
savedFrameBuffer.I savedFrameBuffer.h textureContext.I \
textureContext.h
#define IGATESCAN all #define IGATESCAN all

View File

@ -4,6 +4,4 @@
#include "interactiveGraphicsPipe.cxx" #include "interactiveGraphicsPipe.cxx"
#include "noninteractiveGraphicsPipe.cxx" #include "noninteractiveGraphicsPipe.cxx"
#include "pipeSpec.cxx" #include "pipeSpec.cxx"
#include "savedContext.cxx"
#include "savedFrameBuffer.cxx" #include "savedFrameBuffer.cxx"
#include "textureContext.cxx"

View File

@ -1,29 +0,0 @@
// Filename: textureContext.I
// Created by: drose (07Oct99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: TextureContext::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TextureContext::
TextureContext(Texture *tex) :
_texture(tex)
{
}

View File

@ -1793,11 +1793,18 @@ apply_texture(TextureContext *tc) {
add_to_texture_record(tc); add_to_texture_record(tc);
bind_texture(tc); bind_texture(tc);
/* int dirty = tc->get_dirty_flags();
To render in immediate mode: if ((dirty & (Texture::DF_wrap | Texture::DF_filter)) != 0) {
specify_texture(tex); // We need to re-specify the texture properties.
apply_texture_immediate(tex); specify_texture(tc->_texture);
*/ }
if ((dirty & (Texture::DF_image | Texture::DF_mipmap)) != 0) {
// We need to re-apply the image.
apply_texture_immediate(tc->_texture);
}
tc->clear_dirty_flags();
report_errors(); report_errors();
} }
@ -3857,20 +3864,7 @@ apply_texture_immediate(Texture *tex) {
#endif #endif
if (!gl_ignore_mipmaps || gl_force_mipmaps) { if (!gl_ignore_mipmaps || gl_force_mipmaps) {
bool use_mipmaps; if (tex->uses_mipmaps() || gl_force_mipmaps) {
switch (tex->get_minfilter()) {
case Texture::FT_nearest_mipmap_nearest:
case Texture::FT_linear_mipmap_nearest:
case Texture::FT_nearest_mipmap_linear:
case Texture::FT_linear_mipmap_linear:
use_mipmaps = true;
break;
default:
use_mipmaps = false;
break;
}
if (use_mipmaps || gl_force_mipmaps) {
#ifndef NDEBUG #ifndef NDEBUG
if (gl_show_mipmaps) { if (gl_show_mipmaps) {
build_phony_mipmaps(tex); build_phony_mipmaps(tex);

View File

@ -16,7 +16,10 @@
material.I material.h materialPool.I materialPool.h \ material.I material.h materialPool.I materialPool.h \
orthoProjection.I orthoProjection.h perspectiveProjection.I \ orthoProjection.I orthoProjection.h perspectiveProjection.I \
perspectiveProjection.h pixelBuffer.I pixelBuffer.N \ perspectiveProjection.h pixelBuffer.I pixelBuffer.N \
pixelBuffer.h projection.h texture.I texture.N texture.h \ pixelBuffer.h projection.h \
savedContext.I savedContext.h \
texture.I texture.N texture.h \
textureContext.I textureContext.h \
texturePool.I texturePool.h texturePool.I texturePool.h
#define INCLUDED_SOURCES \ #define INCLUDED_SOURCES \
@ -26,7 +29,7 @@
geomTrifan.cxx geomTristrip.cxx imageBuffer.cxx material.cxx \ geomTrifan.cxx geomTristrip.cxx imageBuffer.cxx material.cxx \
materialPool.cxx orthoProjection.cxx \ materialPool.cxx orthoProjection.cxx \
perspectiveProjection.cxx pixelBuffer.cxx projection.cxx \ perspectiveProjection.cxx pixelBuffer.cxx projection.cxx \
texture.cxx texturePool.cxx savedContext.cxx texture.cxx textureContext.cxx texturePool.cxx
#define INSTALL_HEADERS \ #define INSTALL_HEADERS \
LOD.I LOD.h config_gobj.h \ LOD.I LOD.h config_gobj.h \
@ -37,7 +40,10 @@
materialPool.I materialPool.h \ materialPool.I materialPool.h \
orthoProjection.I orthoProjection.h perspectiveProjection.I \ orthoProjection.I orthoProjection.h perspectiveProjection.I \
perspectiveProjection.h pixelBuffer.I pixelBuffer.h projection.h \ perspectiveProjection.h pixelBuffer.I pixelBuffer.h projection.h \
texture.I texture.h texturePool.I texturePool.h savedContext.I savedContext.h \
texture.I texture.h \
textureContext.I textureContext.h \
texturePool.I texturePool.h
#define IGATESCAN all #define IGATESCAN all

View File

@ -9,5 +9,7 @@
#include "perspectiveProjection.cxx" #include "perspectiveProjection.cxx"
#include "pixelBuffer.cxx" #include "pixelBuffer.cxx"
#include "projection.cxx" #include "projection.cxx"
#include "savedContext.cxx"
#include "texture.cxx" #include "texture.cxx"
#include "textureContext.cxx"
#include "texturePool.cxx" #include "texturePool.cxx"

View File

@ -17,29 +17,6 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: Texture::has_ram_image
// Access: Public
// Description: Returns true if the Texture keeps has its image
// contents available in main RAM, false if it exists
// only in texture memory or in the prepared GSG
// context.
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
has_ram_image() const {
return !_pbuffer->_image.empty();
}
////////////////////////////////////////////////////////////////////
// Function: Texture::apply
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Texture::
apply(GraphicsStateGuardianBase *gsg) {
gsg->apply_texture(prepare(gsg));
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::get_wrapu // Function: Texture::get_wrapu
// Access: Published // Access: Published
@ -94,3 +71,38 @@ INLINE int Texture::
get_anisotropic_degree() const { get_anisotropic_degree() const {
return _anisotropic_degree; return _anisotropic_degree;
} }
////////////////////////////////////////////////////////////////////
// Function: Texture::uses_mipmaps
// Access: Public
// Description: Returns true if the minfilter settings on this
// texture require the use of mipmapping, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
uses_mipmaps() const {
return is_mipmap(get_minfilter());
}
////////////////////////////////////////////////////////////////////
// Function: Texture::has_ram_image
// Access: Public
// Description: Returns true if the Texture keeps has its image
// contents available in main RAM, false if it exists
// only in texture memory or in the prepared GSG
// context.
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
has_ram_image() const {
return !_pbuffer->_image.empty();
}
////////////////////////////////////////////////////////////////////
// Function: Texture::apply
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Texture::
apply(GraphicsStateGuardianBase *gsg) {
gsg->apply_texture(prepare(gsg));
}

View File

@ -19,18 +19,18 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Includes // Includes
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include <pandabase.h> #include "pandabase.h"
#include "texture.h" #include "texture.h"
#include "config_gobj.h" #include "config_gobj.h"
#include "texturePool.h"
#include "textureContext.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include <stddef.h> #include <stddef.h>
#include <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
//Should this be here?
#include "texturePool.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Static variables // Static variables
@ -123,6 +123,7 @@ Texture() : ImageBuffer() {
_anisotropic_degree = 1; _anisotropic_degree = 1;
_pbuffer = new PixelBuffer; _pbuffer = new PixelBuffer;
_has_requested_size = false; _has_requested_size = false;
_all_dirty_flags = 0;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -222,6 +223,79 @@ write(const string &name) const {
return _pbuffer->write(name); return _pbuffer->write(name);
} }
////////////////////////////////////////////////////////////////////
// Function: set_wrapu
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
set_wrapu(Texture::WrapMode wrap) {
if (_wrapu != wrap) {
mark_dirty(DF_wrap);
_wrapu = wrap;
}
}
////////////////////////////////////////////////////////////////////
// Function: set_wrapv
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
set_wrapv(Texture::WrapMode wrap) {
if (_wrapv != wrap) {
mark_dirty(DF_wrap);
_wrapv = wrap;
}
}
////////////////////////////////////////////////////////////////////
// Function: set_minfilter
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
set_minfilter(Texture::FilterType filter) {
if (_minfilter != filter) {
if (is_mipmap(_minfilter) != is_mipmap(filter)) {
mark_dirty(DF_filter | DF_mipmap);
} else {
mark_dirty(DF_filter);
}
_minfilter = filter;
}
}
////////////////////////////////////////////////////////////////////
// Function: set_magfilter
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
set_magfilter(Texture::FilterType filter) {
if (_magfilter != filter) {
mark_dirty(DF_filter);
_magfilter = filter;
}
}
////////////////////////////////////////////////////////////////////
// Function: set_anisotropic_degree
// Access: Published
// Description: Specifies the level of anisotropic filtering to apply
// to the texture. Normally, this is 1, to indicate
// anisotropic filtering is disabled. This may be set
// to a number higher than one to enable anisotropic
// filtering, if the rendering backend supports this.
////////////////////////////////////////////////////////////////////
void Texture::
set_anisotropic_degree(int anisotropic_degree) {
if (_anisotropic_degree != anisotropic_degree) {
mark_dirty(DF_filter);
_anisotropic_degree = anisotropic_degree;
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: load // Function: load
// Access: Public // Access: Public
@ -232,11 +306,7 @@ load(const PNMImage &pnmimage) {
if (!_pbuffer->load(pnmimage)) if (!_pbuffer->load(pnmimage))
return false; return false;
// It's not a good idea to call this here, since this function might mark_dirty(DF_image);
// be called from within the GSG itself--which won't expect the
// texture to suddenly unprepare itself. Better to have the user
// explicitly unprepare() the texture if she loads a new file.
// unprepare();
return true; return true;
} }
@ -252,6 +322,26 @@ store(PNMImage &pnmimage) const {
return _pbuffer->store( pnmimage ); return _pbuffer->store( pnmimage );
} }
////////////////////////////////////////////////////////////////////
// Function: Texture::is_mipmap
// Access: Public, Static
// Description: Returns true if the indicated filter type requires
// the use of mipmaps, or false if it does not.
////////////////////////////////////////////////////////////////////
bool Texture::
is_mipmap(FilterType type) {
switch (type) {
case FT_nearest_mipmap_nearest:
case FT_linear_mipmap_nearest:
case FT_nearest_mipmap_linear:
case FT_linear_mipmap_linear:
return true;
default:
return false;
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: prepare // Function: prepare
// Access: Public // Access: Public
@ -270,6 +360,12 @@ prepare(GraphicsStateGuardianBase *gsg) {
TextureContext *tc = gsg->prepare_texture(this); TextureContext *tc = gsg->prepare_texture(this);
_contexts[gsg] = tc; _contexts[gsg] = tc;
// Now that we have a new TextureContext with zero dirty flags, our
// intersection of all dirty flags must be zero. This doesn't mean
// that some other contexts aren't still dirty, but at least one
// context isn't.
_all_dirty_flags = 0;
if (!keep_texture_ram) { if (!keep_texture_ram) {
// Once we have prepared the texture, we can generally safely // Once we have prepared the texture, we can generally safely
// remove the pixels from main RAM. The GSG is now responsible // remove the pixels from main RAM. The GSG is now responsible
@ -409,72 +505,46 @@ void Texture::draw(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: set_wrapu // Function: Texture::mark_dirty
// Access: Published // Access: Public
// Description: // Description: Sets the indicated dirty bits on for all texture
// contexts that share this Texture. Does not change
// the bits that are not on. This presumably will
// inform the GSG that the texture properties have
// changed. See also TextureContext::mark_dirty().
//
// Normally, this does not need to be called directly;
// changing the properties on the texture will
// automatically call this. However, if you fiddle with
// the texture image directly, for instance by meddling
// with the _pbuffer member, you may need to explicitly
// call mark_dirty(Texture::DF_image).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void Texture:: void Texture::
set_wrapu(Texture::WrapMode wrap) { mark_dirty(int flags_to_set) {
if (_wrapu != wrap) { if ((_all_dirty_flags & flags_to_set) == flags_to_set) {
unprepare(); // If all the texture contexts already share these bits, no need
_wrapu = wrap; // to do anything else.
return;
} }
// Otherwise, iterate through the contexts and mark them all dirty.
Contexts::iterator ci;
for (ci = _contexts.begin(); ci != _contexts.end(); ++ci) {
(*ci).second->mark_dirty(flags_to_set);
}
_all_dirty_flags |= flags_to_set;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: set_wrapv // Function: Texture::register_with_read_factory
// Access: Published // Access: Public, Static
// Description: // Description: Factory method to generate a Texture object
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void Texture:: void Texture::
set_wrapv(Texture::WrapMode wrap) { register_with_read_factory() {
if (_wrapv != wrap) { BamReader::get_factory()->register_factory(get_class_type(), make_Texture);
unprepare();
_wrapv = wrap;
}
}
////////////////////////////////////////////////////////////////////
// Function: set_minfilter
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
set_minfilter(Texture::FilterType filter) {
if (_minfilter != filter) {
unprepare();
_minfilter = filter;
}
}
////////////////////////////////////////////////////////////////////
// Function: set_magfilter
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
set_magfilter(Texture::FilterType filter) {
if (_magfilter != filter) {
unprepare();
_magfilter = filter;
}
}
////////////////////////////////////////////////////////////////////
// Function: set_anisotropic_degree
// Access: Published
// Description: Specifies the level of anisotropic filtering to apply
// to the texture. Normally, this is 1, to indicate
// anisotropic filtering is disabled. This may be set
// to a number higher than one to enable anisotropic
// filtering, if the rendering backend supports this.
////////////////////////////////////////////////////////////////////
void Texture::
set_anisotropic_degree(int anisotropic_degree) {
if (_anisotropic_degree != anisotropic_degree) {
unprepare();
_anisotropic_degree = anisotropic_degree;
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -505,53 +575,6 @@ write_datagram(BamWriter *manager, Datagram &me) {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: Texture::fillin
// Access: Protected
// Description: Function that reads out of the datagram (or asks
// manager to read) all of the data that is needed to
// re-create this object and stores it in the appropiate
// place
////////////////////////////////////////////////////////////////////
void Texture::
fillin(DatagramIterator &scan, BamReader *manager) {
//We don't want to call ImageBuffer::fillin, like we
//would normally, since due to needing to know the name
//of the Texture before creating it, we have already read
//that name in. This is something of a problem as it forces
//Texture to know how the parent write_datagram works. And
//makes the assumption that the only data being written is
//the name
scan.get_uint32(); // For historical purposes
_wrapu = (enum WrapMode) scan.get_uint8();
_wrapv = (enum WrapMode) scan.get_uint8();
_minfilter = (enum FilterType) scan.get_uint8();
_magfilter = (enum FilterType) scan.get_uint8();
_magfiltercolor = (enum FilterType) scan.get_uint8();
_magfilteralpha = (enum FilterType) scan.get_uint8();
_anisotropic_degree = scan.get_int16();
if (scan.get_remaining_size() > 0) {
bool has_pbuffer = scan.get_bool();
if (has_pbuffer) {
PixelBuffer::Format format = (PixelBuffer::Format)scan.get_uint8();
int num_components = -1;
if (scan.get_remaining_size() > 0) {
num_components = scan.get_uint8();
}
if (_pbuffer != (PixelBuffer *)NULL) {
if (num_components == _pbuffer->get_num_components()) {
// Only reset the format if the number of components hasn't
// changed.
_pbuffer->set_format(format);
}
}
}
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::make_Texture // Function: Texture::make_Texture
// Access: Protected // Access: Protected
@ -598,13 +621,50 @@ make_Texture(const FactoryParams &params) {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::register_with_factory // Function: Texture::fillin
// Access: Public, Static // Access: Protected
// Description: Factory method to generate a Texture object // Description: Function that reads out of the datagram (or asks
// manager to read) all of the data that is needed to
// re-create this object and stores it in the appropiate
// place
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void Texture:: void Texture::
register_with_read_factory() { fillin(DatagramIterator &scan, BamReader *manager) {
BamReader::get_factory()->register_factory(get_class_type(), make_Texture); //We don't want to call ImageBuffer::fillin, like we
//would normally, since due to needing to know the name
//of the Texture before creating it, we have already read
//that name in. This is something of a problem as it forces
//Texture to know how the parent write_datagram works. And
//makes the assumption that the only data being written is
//the name
scan.get_uint32(); // For historical purposes
_wrapu = (enum WrapMode) scan.get_uint8();
_wrapv = (enum WrapMode) scan.get_uint8();
_minfilter = (enum FilterType) scan.get_uint8();
_magfilter = (enum FilterType) scan.get_uint8();
_magfiltercolor = (enum FilterType) scan.get_uint8();
_magfilteralpha = (enum FilterType) scan.get_uint8();
_anisotropic_degree = scan.get_int16();
if (scan.get_remaining_size() > 0) {
bool has_pbuffer = scan.get_bool();
if (has_pbuffer) {
PixelBuffer::Format format = (PixelBuffer::Format)scan.get_uint8();
int num_components = -1;
if (scan.get_remaining_size() > 0) {
num_components = scan.get_uint8();
}
if (_pbuffer != (PixelBuffer *)NULL) {
if (num_components == _pbuffer->get_num_components()) {
// Only reset the format if the number of components hasn't
// changed.
_pbuffer->set_format(format);
}
}
}
}
} }

View File

@ -33,6 +33,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class PNMImage; class PNMImage;
class TextureContext;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : Texture // Class : Texture
@ -78,10 +79,25 @@ PUBLISHED:
virtual bool read(const string &name, const string &gray); virtual bool read(const string &name, const string &gray);
virtual bool write(const string &name = "") const; virtual bool write(const string &name = "") const;
void set_wrapu(WrapMode wrap);
void set_wrapv(WrapMode wrap);
void set_minfilter(FilterType filter);
void set_magfilter(FilterType filter);
void set_anisotropic_degree(int anisotropic_degree);
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 bool uses_mipmaps() const;
public: public:
bool load(const PNMImage &pnmimage); bool load(const PNMImage &pnmimage);
bool store(PNMImage &pnmimage) const; bool store(PNMImage &pnmimage) const;
static bool is_mipmap(FilterType type);
TextureContext *prepare(GraphicsStateGuardianBase *gsg); TextureContext *prepare(GraphicsStateGuardianBase *gsg);
void unprepare(); void unprepare();
void unprepare(GraphicsStateGuardianBase *gsg); void unprepare(GraphicsStateGuardianBase *gsg);
@ -100,19 +116,55 @@ public:
virtual void draw(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr, virtual void draw(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
const RenderBuffer &rb); const RenderBuffer &rb);
PUBLISHED: // These bits are used as parameters to Texture::mark_dirty() and
void set_wrapu(WrapMode wrap); // also TextureContext::mark_dirty() (and related functions in
void set_wrapv(WrapMode wrap); // TextureContext).
void set_minfilter(FilterType filter); enum DirtyFlags {
void set_magfilter(FilterType filter); DF_image = 0x001, // The image pixels have changed.
void set_anisotropic_degree(int anisotropic_degree); 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.
};
INLINE WrapMode get_wrapu() const; void mark_dirty(int flags_to_set);
INLINE WrapMode get_wrapv() const;
INLINE FilterType get_minfilter() const;
INLINE FilterType get_magfilter() const;
INLINE int get_anisotropic_degree() const;
private:
WrapMode _wrapu;
WrapMode _wrapv;
FilterType _minfilter;
FilterType _magfilter;
FilterType _magfiltercolor;
FilterType _magfilteralpha;
int _anisotropic_degree;
// A Texture keeps a list (actually, a map) of all the GSG's that it
// has been prepared into. Each GSG conversely keeps a list (a set)
// of all the Textures that have been prepared there. When either
// destructs, it removes itself from the other's list.
typedef pmap<GraphicsStateGuardianBase *, TextureContext *> Contexts;
Contexts _contexts;
// This value represents the intersection of all the dirty flags of
// the various TextureContexts that might be associated with this
// texture.
int _all_dirty_flags;
public:
// These are public to allow direct manipulation of the underlying
// pixel buffer when needed. Know what you are doing!
PT(PixelBuffer) _pbuffer;
// If you request a region from the framebuffer that is not a power of 2,
// we need to grab a larger region that is a power of 2 that contains the
// requested region and set the pixel buffer size accordingly. We store
// the size you requested in the members below.
bool _has_requested_size;
int _requested_w;
int _requested_h;
// Datagram stuff
public: public:
static void register_with_read_factory(void); static void register_with_read_factory(void);
virtual void write_datagram(BamWriter* manager, Datagram &me); virtual void write_datagram(BamWriter* manager, Datagram &me);
@ -140,38 +192,7 @@ private:
static TypeHandle _type_handle; static TypeHandle _type_handle;
//////////////////////////////////////////////////////////////////// friend TextureContext;
protected:
WrapMode _wrapu;
WrapMode _wrapv;
FilterType _minfilter;
FilterType _magfilter;
FilterType _magfiltercolor;
FilterType _magfilteralpha;
int _anisotropic_degree;
// A Texture keeps a list (actually, a map) of all the GSG's that it
// has been prepared into. Each GSG conversely keeps a list (a set)
// of all the Texture's that have been prepared there. When either
// destructs, it removes itself from the other's list.
typedef pmap<GraphicsStateGuardianBase *, TextureContext *> Contexts;
Contexts _contexts;
// These are public to allow direct manipulation of the underlying
// pixel buffer when needed. Know what you are doing!
public:
PT(PixelBuffer) _pbuffer;
// If you request a region from the framebuffer that is not a power of 2,
// we need to grab a larger region that is a power of 2 that contains the
// requested region and set the pixel buffer size accordingly. We store
// the size you requested in the members below.
bool _has_requested_size;
int _requested_w;
int _requested_h;
}; };
#include "texture.I" #include "texture.I"

View File

@ -0,0 +1,91 @@
// Filename: textureContext.I
// Created by: drose (07Oct99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: TextureContext::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TextureContext::
TextureContext(Texture *tex) :
_texture(tex)
{
_dirty_flags = 0;
}
////////////////////////////////////////////////////////////////////
// Function: TextureContext::mark_dirty
// Access: Public
// Description: Marks the context "dirty", i.e. its properties are
// different from the last time the GSG has seen them.
// Presumably, the GSG will respond by updating the
// properties and clearing the dirty bits the next time
// it renders the texture.
//
// The value is the union of all the bits that are to be
// set dirty; bits that are not set in this parameter
// are left unchanged. See Texture::DirtyFlags for a
// list of available bits.
//
// Usually this function is not called directly, but
// rather is called by Texture::mark_dirty() as a result
// of changing properties directly on the texture.
////////////////////////////////////////////////////////////////////
INLINE void TextureContext::
mark_dirty(int flags_to_set) {
_dirty_flags |= flags_to_set;
}
////////////////////////////////////////////////////////////////////
// Function: TextureContext::clear_dirty_flags
// Access: Public
// Description: Removes the indicated flags from the "dirty" bits.
// See mark_dirty().
//
// The value is the union of all the bits that are to be
// cleared; if a bit is set in the parameter, it will be
// removed from the dirty set. Bits that are not set in
// this parameter are left unchanged.
//
// This function is intended to be called by the GSG
// after it has updated the texture parameters.
////////////////////////////////////////////////////////////////////
INLINE void TextureContext::
clear_dirty_flags(int flags_to_clear) {
_dirty_flags &= ~flags_to_clear;
_texture->_all_dirty_flags &= ~flags_to_clear;
}
////////////////////////////////////////////////////////////////////
// Function: TextureContext::get_dirty_flags
// Access: Public
// Description: Returns the current state of the dirty flags. If
// this is non-zero, it represents the union of all
// properties that have been changed since the last call
// to clear_dirty_flags().
//
// This function is intended to be called by the GSG to
// determine what properties need to be updated. See
// Texture::DirtyFlags for a list of possible bits.
////////////////////////////////////////////////////////////////////
INLINE int TextureContext::
get_dirty_flags() const {
return _dirty_flags;
}

View File

@ -18,8 +18,8 @@
#include "textureContext.h" #include "textureContext.h"
#include <pixelBuffer.h> #include "pixelBuffer.h"
#include <texture.h> #include "texture.h"
TypeHandle TextureContext::_type_handle; TypeHandle TextureContext::_type_handle;

View File

@ -19,11 +19,10 @@
#ifndef TEXTURECONTEXT_H #ifndef TEXTURECONTEXT_H
#define TEXTURECONTEXT_H #define TEXTURECONTEXT_H
#include <pandabase.h> #include "pandabase.h"
#include "savedContext.h" #include "savedContext.h"
#include "texture.h"
class Texture;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : TextureContext // Class : TextureContext
@ -49,6 +48,14 @@ public:
// reference count. // reference count.
Texture *_texture; Texture *_texture;
INLINE void mark_dirty(int flags_to_set);
INLINE void clear_dirty_flags(int flags_to_clear = ~0);
INLINE int get_dirty_flags() const;
private:
int _dirty_flags;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -384,20 +384,7 @@ collect_statistics(Texture *texture) {
pb->get_xsize() * pb->get_ysize() * pb->get_num_components() * pb->get_xsize() * pb->get_ysize() * pb->get_num_components() *
pb->get_component_width(); pb->get_component_width();
bool is_mipmapped = false; if (texture->uses_mipmaps()) {
switch (texture->get_minfilter()) {
case Texture::FT_nearest_mipmap_nearest:
case Texture::FT_linear_mipmap_nearest:
case Texture::FT_nearest_mipmap_linear:
case Texture::FT_linear_mipmap_linear:
is_mipmapped = true;
break;
default:
break;
}
if (is_mipmapped) {
bytes *= 4/3; bytes *= 4/3;
} }