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

View File

@ -4,6 +4,4 @@
#include "interactiveGraphicsPipe.cxx"
#include "noninteractiveGraphicsPipe.cxx"
#include "pipeSpec.cxx"
#include "savedContext.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);
bind_texture(tc);
/*
To render in immediate mode:
specify_texture(tex);
apply_texture_immediate(tex);
*/
int dirty = tc->get_dirty_flags();
if ((dirty & (Texture::DF_wrap | Texture::DF_filter)) != 0) {
// We need to re-specify the texture properties.
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();
}
@ -3857,20 +3864,7 @@ apply_texture_immediate(Texture *tex) {
#endif
if (!gl_ignore_mipmaps || gl_force_mipmaps) {
bool use_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) {
if (tex->uses_mipmaps() || gl_force_mipmaps) {
#ifndef NDEBUG
if (gl_show_mipmaps) {
build_phony_mipmaps(tex);

View File

@ -16,7 +16,10 @@
material.I material.h materialPool.I materialPool.h \
orthoProjection.I orthoProjection.h perspectiveProjection.I \
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
#define INCLUDED_SOURCES \
@ -26,7 +29,7 @@
geomTrifan.cxx geomTristrip.cxx imageBuffer.cxx material.cxx \
materialPool.cxx orthoProjection.cxx \
perspectiveProjection.cxx pixelBuffer.cxx projection.cxx \
texture.cxx texturePool.cxx
savedContext.cxx texture.cxx textureContext.cxx texturePool.cxx
#define INSTALL_HEADERS \
LOD.I LOD.h config_gobj.h \
@ -37,7 +40,10 @@
materialPool.I materialPool.h \
orthoProjection.I orthoProjection.h perspectiveProjection.I \
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

View File

@ -9,5 +9,7 @@
#include "perspectiveProjection.cxx"
#include "pixelBuffer.cxx"
#include "projection.cxx"
#include "savedContext.cxx"
#include "texture.cxx"
#include "textureContext.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
// Access: Published
@ -94,3 +71,38 @@ INLINE int Texture::
get_anisotropic_degree() const {
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
////////////////////////////////////////////////////////////////////
#include <pandabase.h>
#include "pandabase.h"
#include "texture.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 <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
//Should this be here?
#include "texturePool.h"
////////////////////////////////////////////////////////////////////
// Static variables
@ -123,6 +123,7 @@ Texture() : ImageBuffer() {
_anisotropic_degree = 1;
_pbuffer = new PixelBuffer;
_has_requested_size = false;
_all_dirty_flags = 0;
}
////////////////////////////////////////////////////////////////////
@ -222,6 +223,79 @@ write(const string &name) const {
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
// Access: Public
@ -232,11 +306,7 @@ load(const PNMImage &pnmimage) {
if (!_pbuffer->load(pnmimage))
return false;
// It's not a good idea to call this here, since this function might
// 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();
mark_dirty(DF_image);
return true;
}
@ -252,6 +322,26 @@ store(PNMImage &pnmimage) const {
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
// Access: Public
@ -270,6 +360,12 @@ prepare(GraphicsStateGuardianBase *gsg) {
TextureContext *tc = gsg->prepare_texture(this);
_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) {
// Once we have prepared the texture, we can generally safely
// 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
// Access: Published
// Description:
// Function: Texture::mark_dirty
// Access: Public
// 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::
set_wrapu(Texture::WrapMode wrap) {
if (_wrapu != wrap) {
unprepare();
_wrapu = wrap;
mark_dirty(int flags_to_set) {
if ((_all_dirty_flags & flags_to_set) == flags_to_set) {
// If all the texture contexts already share these bits, no need
// 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
// Access: Published
// Description:
// Function: Texture::register_with_read_factory
// Access: Public, Static
// Description: Factory method to generate a Texture object
////////////////////////////////////////////////////////////////////
void Texture::
set_wrapv(Texture::WrapMode wrap) {
if (_wrapv != wrap) {
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;
}
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_Texture);
}
////////////////////////////////////////////////////////////////////
@ -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
// Access: Protected
@ -598,13 +621,50 @@ make_Texture(const FactoryParams &params) {
}
////////////////////////////////////////////////////////////////////
// Function: Texture::register_with_factory
// Access: Public, Static
// Description: Factory method to generate a Texture object
// 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::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_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);
}
}
}
}
}

View File

@ -33,6 +33,7 @@
////////////////////////////////////////////////////////////////////
class PNMImage;
class TextureContext;
////////////////////////////////////////////////////////////////////
// Class : Texture
@ -78,10 +79,25 @@ PUBLISHED:
virtual bool read(const string &name, const string &gray);
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:
bool load(const PNMImage &pnmimage);
bool store(PNMImage &pnmimage) const;
static bool is_mipmap(FilterType type);
TextureContext *prepare(GraphicsStateGuardianBase *gsg);
void unprepare();
void unprepare(GraphicsStateGuardianBase *gsg);
@ -100,19 +116,55 @@ public:
virtual void draw(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
const RenderBuffer &rb);
PUBLISHED:
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);
// These bits are used as parameters to Texture::mark_dirty() and
// also TextureContext::mark_dirty() (and related functions in
// TextureContext).
enum DirtyFlags {
DF_image = 0x001, // The image pixels have changed.
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;
INLINE WrapMode get_wrapv() const;
INLINE FilterType get_minfilter() const;
INLINE FilterType get_magfilter() const;
INLINE int get_anisotropic_degree() const;
void mark_dirty(int flags_to_set);
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:
static void register_with_read_factory(void);
virtual void write_datagram(BamWriter* manager, Datagram &me);
@ -140,38 +192,7 @@ private:
static TypeHandle _type_handle;
////////////////////////////////////////////////////////////////////
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;
friend TextureContext;
};
#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 <pixelBuffer.h>
#include <texture.h>
#include "pixelBuffer.h"
#include "texture.h"
TypeHandle TextureContext::_type_handle;

View File

@ -19,11 +19,10 @@
#ifndef TEXTURECONTEXT_H
#define TEXTURECONTEXT_H
#include <pandabase.h>
#include "pandabase.h"
#include "savedContext.h"
class Texture;
#include "texture.h"
////////////////////////////////////////////////////////////////////
// Class : TextureContext
@ -49,6 +48,14 @@ public:
// reference count.
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:
static TypeHandle get_class_type() {
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_component_width();
bool is_mipmapped = false;
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) {
if (texture->uses_mipmaps()) {
bytes *= 4/3;
}