mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-17 12:12:10 -04:00
new texture dirty flags
This commit is contained in:
parent
523fd913dd
commit
f90bba39e8
@ -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
|
||||
|
||||
|
@ -4,6 +4,4 @@
|
||||
#include "interactiveGraphicsPipe.cxx"
|
||||
#include "noninteractiveGraphicsPipe.cxx"
|
||||
#include "pipeSpec.cxx"
|
||||
#include "savedContext.cxx"
|
||||
#include "savedFrameBuffer.cxx"
|
||||
#include "textureContext.cxx"
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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 ¶ms) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
91
panda/src/gobj/textureContext.I
Normal file
91
panda/src/gobj/textureContext.I
Normal 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;
|
||||
}
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
#include "textureContext.h"
|
||||
|
||||
#include <pixelBuffer.h>
|
||||
#include <texture.h>
|
||||
#include "pixelBuffer.h"
|
||||
#include "texture.h"
|
||||
|
||||
TypeHandle TextureContext::_type_handle;
|
||||
|
@ -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;
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user