texture-minfilter etc.

This commit is contained in:
David Rose 2009-03-30 20:00:42 +00:00
parent 80cb0752bf
commit d05d89a5e4
13 changed files with 191 additions and 81 deletions

View File

@ -203,8 +203,8 @@ apply_texture(int i, TextureContext *tc) {
_d3d_device->SetTextureStageState(i, D3DTSS_BORDERCOLOR,
Colorf_to_D3DCOLOR(tex->get_border_color()));
uint aniso_degree = tex->get_anisotropic_degree();
Texture::FilterType ft = tex->get_magfilter();
uint aniso_degree = tex->get_effective_anisotropic_degree();
Texture::FilterType ft = tex->get_effective_magfilter();
if (aniso_degree >= 1) {
_d3d_device->SetTextureStageState(i, D3DTSS_MAXANISOTROPY, aniso_degree);
@ -220,10 +220,8 @@ apply_texture(int i, TextureContext *tc) {
_d3d_device->SetTextureStageState(i, D3DTSS_MAGFILTER, new_mag_filter);
// map Panda composite min+mip filter types to d3d's separate min & mip filter types
D3DTEXTUREFILTERTYPE new_min_filter = get_d3d_min_type(tex->get_minfilter(),
tex->get_format());
D3DTEXTUREFILTERTYPE new_mip_filter = get_d3d_mip_type(tex->get_minfilter(),
tex->get_format());
D3DTEXTUREFILTERTYPE new_min_filter = get_d3d_min_type(tex->get_effective_minfilter());
D3DTEXTUREFILTERTYPE new_mip_filter = get_d3d_mip_type(tex->get_effective_minfilter());
if (!tex->might_have_ram_image()) {
// If the texture is completely dynamic, don't try to issue
@ -4014,8 +4012,7 @@ copy_pres_reset(DXScreenData *screen) {
// Description:
////////////////////////////////////////////////////////////////////
D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian8::
get_d3d_min_type(Texture::FilterType filter_type,
Texture::Format format) {
get_d3d_min_type(Texture::FilterType filter_type) {
switch (filter_type) {
case Texture::FT_nearest:
return D3DTEXF_POINT;
@ -4051,8 +4048,7 @@ get_d3d_min_type(Texture::FilterType filter_type,
// Description:
////////////////////////////////////////////////////////////////////
D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian8::
get_d3d_mip_type(Texture::FilterType filter_type,
Texture::Format format) {
get_d3d_mip_type(Texture::FilterType filter_type) {
switch (filter_type) {
case Texture::FT_nearest:
return D3DTEXF_NONE;

View File

@ -195,10 +195,8 @@ protected:
bool release_swap_chain (DXScreenData *new_context);
void copy_pres_reset(DXScreenData *new_context);
static D3DTEXTUREFILTERTYPE get_d3d_min_type(Texture::FilterType filter_type,
Texture::Format format);
static D3DTEXTUREFILTERTYPE get_d3d_mip_type(Texture::FilterType filter_type,
Texture::Format format);
static D3DTEXTUREFILTERTYPE get_d3d_min_type(Texture::FilterType filter_type);
static D3DTEXTUREFILTERTYPE get_d3d_mip_type(Texture::FilterType filter_type);
static D3DTEXTUREOP get_texture_operation(TextureStage::CombineMode mode, int scale);
static DWORD get_texture_argument(TextureStage::CombineSource source,
TextureStage::CombineOperand operand);

View File

@ -253,8 +253,8 @@ apply_texture(int i, TextureContext *tc) {
set_sampler_state(i, D3DSAMP_BORDERCOLOR, border_color);
uint aniso_degree = tex->get_anisotropic_degree();
Texture::FilterType ft = tex->get_magfilter();
uint aniso_degree = tex->get_effective_anisotropic_degree();
Texture::FilterType ft = tex->get_effective_magfilter();
if (aniso_degree >= 1) {
set_sampler_state(i, D3DSAMP_MAXANISOTROPY, aniso_degree);
@ -279,10 +279,8 @@ apply_texture(int i, TextureContext *tc) {
}
// map Panda composite min+mip filter types to d3d's separate min & mip filter types
D3DTEXTUREFILTERTYPE new_min_filter = get_d3d_min_type(tex->get_minfilter(),
tex->get_format());
D3DTEXTUREFILTERTYPE new_mip_filter = get_d3d_mip_type(tex->get_minfilter(),
tex->get_format());
D3DTEXTUREFILTERTYPE new_min_filter = get_d3d_min_type(tex->get_effective_minfilter());
D3DTEXTUREFILTERTYPE new_mip_filter = get_d3d_mip_type(tex->get_effective_minfilter());
if (!tex->might_have_ram_image()) {
// If the texture is completely dynamic, don't try to issue
@ -4961,8 +4959,7 @@ copy_pres_reset(DXScreenData *screen) {
// Description:
////////////////////////////////////////////////////////////////////
D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
get_d3d_min_type(Texture::FilterType filter_type,
Texture::Format format) {
get_d3d_min_type(Texture::FilterType filter_type) {
switch (filter_type) {
case Texture::FT_nearest:
return D3DTEXF_POINT;
@ -4998,8 +4995,7 @@ get_d3d_min_type(Texture::FilterType filter_type,
// Description:
////////////////////////////////////////////////////////////////////
D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
get_d3d_mip_type(Texture::FilterType filter_type,
Texture::Format format) {
get_d3d_mip_type(Texture::FilterType filter_type) {
switch (filter_type) {
case Texture::FT_nearest:
return D3DTEXF_NONE;

View File

@ -235,10 +235,8 @@ protected:
bool release_swap_chain (DXScreenData *new_context);
void copy_pres_reset(DXScreenData *new_context);
static D3DTEXTUREFILTERTYPE get_d3d_min_type(Texture::FilterType filter_type,
Texture::Format format);
static D3DTEXTUREFILTERTYPE get_d3d_mip_type(Texture::FilterType filter_type,
Texture::Format format);
static D3DTEXTUREFILTERTYPE get_d3d_min_type(Texture::FilterType filter_type);
static D3DTEXTUREFILTERTYPE get_d3d_mip_type(Texture::FilterType filter_type);
static D3DTEXTUREOP get_texture_operation(TextureStage::CombineMode mode, int scale);
DWORD get_texture_argument(TextureStage::CombineSource source,
TextureStage::CombineOperand operand) const;

View File

@ -2806,6 +2806,7 @@ update_texture(TextureContext *tc, bool force) {
// need to reload the texture.
if (specify_texture(gtc)) {
// Actually, looks like the texture *does* need to be reloaded.
gtc->mark_needs_reload();
bool okflag = upload_texture(gtc, force);
if (!okflag) {
GLCAT.error()
@ -5098,8 +5099,7 @@ get_panda_wrap_mode(GLenum wm) {
// to GL's.
////////////////////////////////////////////////////////////////////
GLenum CLP(GraphicsStateGuardian)::
get_texture_filter_type(Texture::FilterType ft, Texture::Format fmt,
bool ignore_mipmaps) {
get_texture_filter_type(Texture::FilterType ft, bool ignore_mipmaps) {
if (CLP(ignore_filters)) {
return GL_NEAREST;
@ -5116,11 +5116,6 @@ get_texture_filter_type(Texture::FilterType ft, Texture::Format fmt,
case Texture::FT_shadow:
return GL_LINEAR;
case Texture::FT_default:
if (fmt == Texture::F_depth_stencil || fmt == Texture::F_depth_component) {
return GL_NEAREST;
} else {
return GL_LINEAR;
}
case Texture::FT_invalid:
break;
}
@ -5142,11 +5137,6 @@ get_texture_filter_type(Texture::FilterType ft, Texture::Format fmt,
case Texture::FT_shadow:
return GL_LINEAR;
case Texture::FT_default:
if (fmt == Texture::F_depth_stencil || fmt == Texture::F_depth_component) {
return GL_NEAREST;
} else {
return GL_LINEAR;
}
case Texture::FT_invalid:
break;
}
@ -7238,9 +7228,9 @@ specify_texture(CLP(TextureContext) *gtc) {
GLP(TexParameterfv)(target, GL_TEXTURE_BORDER_COLOR,
border_color.get_data());
Texture::FilterType minfilter = tex->get_minfilter();
Texture::FilterType magfilter = tex->get_magfilter();
bool uses_mipmaps = tex->uses_mipmaps() && !CLP(ignore_mipmaps);
Texture::FilterType minfilter = tex->get_effective_minfilter();
Texture::FilterType magfilter = tex->get_effective_magfilter();
bool uses_mipmaps = Texture::is_mipmap(minfilter) && !CLP(ignore_mipmaps);
#ifndef NDEBUG
if (CLP(force_mipmaps)) {
@ -7264,12 +7254,12 @@ specify_texture(CLP(TextureContext) *gtc) {
}
GLP(TexParameteri)(target, GL_TEXTURE_MIN_FILTER,
get_texture_filter_type(minfilter, tex->get_format(), !uses_mipmaps));
get_texture_filter_type(minfilter, !uses_mipmaps));
GLP(TexParameteri)(target, GL_TEXTURE_MAG_FILTER,
get_texture_filter_type(magfilter, tex->get_format(), true));
get_texture_filter_type(magfilter, true));
// Set anisotropic filtering.
float anisotropy = tex->get_anisotropic_degree();
float anisotropy = tex->get_effective_anisotropic_degree();
if (anisotropy > _max_anisotropy) {
anisotropy = _max_anisotropy;
}
@ -7451,10 +7441,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force) {
}
if (image_compression != Texture::CM_off) {
Texture::QualityLevel quality_level = tex->get_quality_level();
if (quality_level == Texture::QL_default) {
quality_level = texture_quality_level;
}
Texture::QualityLevel quality_level = tex->get_effective_quality_level();
switch (quality_level) {
case Texture::QL_fastest:

View File

@ -302,7 +302,7 @@ protected:
GLenum get_texture_wrap_mode(Texture::WrapMode wm) const;
static Texture::WrapMode get_panda_wrap_mode(GLenum wm);
static GLenum get_texture_filter_type(Texture::FilterType ft,
Texture::Format fmt, bool ignore_mipmaps);
bool ignore_mipmaps);
static Texture::FilterType get_panda_filter_type(GLenum ft);
static GLenum get_component_type(Texture::ComponentType component_type);
GLint get_external_image_format(Texture *tex) const;

View File

@ -646,10 +646,14 @@ set_magfilter(Texture::FilterType filter) {
// Function: Texture::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.
// to the texture. Set this 0 to indicate the default
// value, which is specified in the
// texture-anisotropic-degree config variable.
//
// To explicitly disable anisotropic filtering, set this
// value to 1. To explicitly enable anisotropic
// filtering, set it to a value higher than 1; larger
// numbers indicate greater degrees of filtering.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
set_anisotropic_degree(int anisotropic_degree) {
@ -757,7 +761,9 @@ get_wrap_w() const {
// Access: Published
// Description: Returns the filter mode of the texture for
// minification. If this is one of the mipmap
// constants, then the texture requires mipmaps.
// constants, then the texture requires mipmaps. This
// may return FT_default; see also
// get_effective_minfilter().
////////////////////////////////////////////////////////////////////
INLINE Texture::FilterType Texture::
get_minfilter() const {
@ -769,7 +775,8 @@ get_minfilter() const {
// Access: Published
// Description: Returns the filter mode of the texture for
// magnification. The mipmap constants are invalid
// here.
// here. This may return FT_default; see also
// get_effective_minfilter().
////////////////////////////////////////////////////////////////////
INLINE Texture::FilterType Texture::
get_magfilter() const {
@ -780,17 +787,31 @@ get_magfilter() const {
// Function: Texture::get_anisotropic_degree
// Access: Published
// Description: Returns the degree of anisotropic filtering that
// should be applied to the texture. Normally, this is
// 1, to indicate that anisotropic filtering should be
// disabled. If this is a number higher than 1,
// anisotropic filtering should be enabled (if the
// rendering backend supports it).
// should be applied to the texture. This value may
// return 0, indicating the default value; see also
// get_effective_anisotropic_degree.
////////////////////////////////////////////////////////////////////
INLINE int Texture::
get_anisotropic_degree() const {
return _anisotropic_degree;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_effective_anisotropic_degree
// Access: Published
// Description: Returns the degree of anisotropic filtering that
// should be applied to the texture. This value will
// normally not return 0, unless there is an error in
// the config file.
////////////////////////////////////////////////////////////////////
INLINE int Texture::
get_effective_anisotropic_degree() const {
if (_anisotropic_degree != 0) {
return _anisotropic_degree;
}
return texture_anisotropic_degree;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_border_color
// Access: Published
@ -870,7 +891,7 @@ get_render_to_texture() const {
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
uses_mipmaps() const {
return is_mipmap(get_minfilter());
return is_mipmap(get_effective_minfilter());
}
////////////////////////////////////////////////////////////////////
@ -892,13 +913,31 @@ set_quality_level(Texture::QualityLevel quality_level) {
// Function: Texture::get_quality_level
// Access: Public
// Description: Returns the current quality_level hint. See
// set_quality_level().
// set_quality_level(). This value may return
// QL_default; see get_effective_quality_level().
////////////////////////////////////////////////////////////////////
INLINE Texture::QualityLevel Texture::
get_quality_level() const {
return _quality_level;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_effective_quality_level
// Access: Public
// Description: Returns the current quality_level hint, or the global
// default quality_level if this texture doesn't specify
// a quality level. This value will not normally return
// QL_default (unless there is an error in the config
// file)
////////////////////////////////////////////////////////////////////
INLINE Texture::QualityLevel Texture::
get_effective_quality_level() const {
if (_quality_level == QL_default) {
return texture_quality_level;
}
return _quality_level;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_expected_num_mipmap_levels
// Access: Published

View File

@ -55,6 +55,36 @@ ConfigVariableEnum<Texture::QualityLevel> texture_quality_level
"it has little or no effect on normal, hardware-accelerated "
"renderers. See Texture::set_quality_level()."));
ConfigVariableEnum<Texture::FilterType> texture_minfilter
("texture-minfilter", Texture::FT_linear,
PRC_DESC("This specifies the default minfilter that is applied to a texture "
"in the absence of a specific minfilter setting. Normally this "
"is either 'linear' to disable mipmapping by default, or "
"'mipmap', to enable trilinear mipmapping by default. This "
"does not apply to depth textures. Note if this variable is "
"changed at runtime, you may need to reload textures explicitly "
"in order to change their visible properties."));
ConfigVariableEnum<Texture::FilterType> texture_magfilter
("texture-magfilter", Texture::FT_linear,
PRC_DESC("This specifies the default magfilter that is applied to a texture "
"in the absence of a specific magfilter setting. Normally this "
"is 'linear' (since mipmapping does not apply to magfilters). This "
"does not apply to depth textures. Note if this variable is "
"changed at runtime, you may need to reload textures explicitly "
"in order to change their visible properties."));
ConfigVariableInt texture_anisotropic_degree
("texture-anisotropic-degree", 1,
PRC_DESC("This specifies the default anisotropic degree that is applied "
"to a texture in the absence of a particular anisotropic degree "
"setting (that is, a texture for which the anisotropic degree "
"is 0, meaning the default setting). It should be 1 to disable "
"anisotropic filtering, or a higher number to enable it. "
"Note if this variable is "
"changed at runtime, you may need to reload textures explicitly "
"in order to change their visible properties."));
PStatCollector Texture::_texture_read_pcollector("*:Texture:Read");
TypeHandle Texture::_type_handle;
AutoTextureScale Texture::_textures_power_2 = ATS_UNSPECIFIED;
@ -149,7 +179,7 @@ Texture(const string &name) :
_wrap_u = WM_repeat;
_wrap_v = WM_repeat;
_wrap_w = WM_repeat;
_anisotropic_degree = 1;
_anisotropic_degree = 0;
_keep_ram_image = true;
_border_color.set(0.0f, 0.0f, 0.0f, 1.0f);
_compression = CM_default;
@ -583,7 +613,7 @@ estimate_texture_memory() const {
}
size_t bytes = pixels * bpp;
if (is_mipmap(_minfilter)) {
if (uses_mipmaps()) {
bytes = (bytes * 4) / 3;
}
@ -769,6 +799,46 @@ load_related(const InternalName *suffix) const {
return res;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_effective_minfilter
// Access: Published
// Description: Returns the filter mode of the texture for
// minification, with special treatment for FT_default.
// This will normally not return FT_default, unless
// there is an error in the config file.
////////////////////////////////////////////////////////////////////
Texture::FilterType Texture::
get_effective_minfilter() const {
if (_minfilter != FT_default) {
return _minfilter;
}
if (_format == Texture::F_depth_stencil ||
_format == Texture::F_depth_component) {
return FT_nearest;
}
return texture_minfilter;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_effective_magfilter
// Access: Published
// Description: Returns the filter mode of the texture for
// magnification, with special treatment for FT_default.
// This will normally not return FT_default, unless
// there is an error in the config file.
////////////////////////////////////////////////////////////////////
Texture::FilterType Texture::
get_effective_magfilter() const {
if (_magfilter != FT_default) {
return _magfilter;
}
if (_format == Texture::F_depth_stencil ||
_format == Texture::F_depth_component) {
return FT_nearest;
}
return texture_magfilter;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::set_ram_image
// Access: Published
@ -841,7 +911,7 @@ get_num_loadable_ram_mipmap_images() const {
// If we don't even have a base image, the answer is none.
return 0;
}
if (!is_mipmap(_minfilter)) {
if (!uses_mipmaps()) {
// If we have a base image and don't require mipmapping, the
// answer is 1.
return 1;
@ -3463,7 +3533,7 @@ do_has_all_ram_mipmap_images() const {
// If we don't even have a base image, the answer is no.
return false;
}
if (!is_mipmap(_minfilter)) {
if (!uses_mipmaps()) {
// If we have a base image and don't require mipmapping, the
// answer is yes.
return true;
@ -5968,12 +6038,23 @@ fillin_from(Texture *dummy) {
do_set_wrap_u(dummy->get_wrap_u());
do_set_wrap_v(dummy->get_wrap_v());
do_set_wrap_w(dummy->get_wrap_w());
do_set_minfilter(dummy->get_minfilter());
do_set_magfilter(dummy->get_magfilter());
do_set_anisotropic_degree(dummy->get_anisotropic_degree());
do_set_border_color(dummy->get_border_color());
do_set_compression(dummy->get_compression());
do_set_quality_level(dummy->get_quality_level());
if (dummy->get_minfilter() != FT_default) {
do_set_minfilter(dummy->get_minfilter());
}
if (dummy->get_magfilter() != FT_default) {
do_set_magfilter(dummy->get_magfilter());
}
if (dummy->get_anisotropic_degree() != 0) {
do_set_anisotropic_degree(dummy->get_anisotropic_degree());
}
if (dummy->get_compression() != CM_default) {
do_set_compression(dummy->get_compression());
}
if (dummy->get_quality_level() != QL_default) {
do_set_quality_level(dummy->get_quality_level());
}
Format format = dummy->get_format();
int num_components = dummy->get_num_components();

View File

@ -280,7 +280,10 @@ PUBLISHED:
INLINE WrapMode get_wrap_w() const;
INLINE FilterType get_minfilter() const;
INLINE FilterType get_magfilter() const;
FilterType get_effective_minfilter() const;
FilterType get_effective_magfilter() const;
INLINE int get_anisotropic_degree() const;
INLINE int get_effective_anisotropic_degree() const;
INLINE Colorf get_border_color() const;
INLINE CompressionMode get_compression() const;
INLINE bool has_compression() const;
@ -289,6 +292,7 @@ PUBLISHED:
INLINE void set_quality_level(QualityLevel quality_level);
INLINE QualityLevel get_quality_level() const;
INLINE QualityLevel get_effective_quality_level() const;
INLINE int get_expected_num_mipmap_levels() const;
INLINE int get_expected_mipmap_x_size(int n) const;
@ -767,6 +771,9 @@ private:
};
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<Texture::QualityLevel> texture_quality_level;
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<Texture::FilterType> texture_minfilter;
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<Texture::FilterType> texture_magfilter;
extern EXPCL_PANDA_GOBJ ConfigVariableInt texture_anisotropic_degree;
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::TextureType tt);
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::ComponentType ct);

View File

@ -146,3 +146,14 @@ mark_unloaded() {
set_resident(false);
}
////////////////////////////////////////////////////////////////////
// Function: TextureContext::mark_needs_reload
// Access: Public
// Description: Should be called to indicate the texture should be
// reloaded at the nearest opportunity.
////////////////////////////////////////////////////////////////////
INLINE void TextureContext::
mark_needs_reload() {
_image_modified = UpdateSeq::old();
}

View File

@ -52,6 +52,7 @@ public:
INLINE void mark_loaded();
INLINE void mark_simple_loaded();
INLINE void mark_unloaded();
INLINE void mark_needs_reload();
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level) const;

View File

@ -337,8 +337,8 @@ get_magfilter() const {
// Access: Published
// Description: Enables or disables anisotropic filtering on the
// textures created for this font. The default value is
// usually 1, or off. See
// Texture::set_anisotropic_degree().
// specified by the text-anisotropic-degree variable.
// See Texture::set_anisotropic_degree().
////////////////////////////////////////////////////////////////////
INLINE void DynamicTextFont::
set_anisotropic_degree(int anisotropic_degree) {

View File

@ -2247,12 +2247,8 @@ do_issue_texture() {
magfilter = Texture::FT_nearest;
} else if (quality_level == Texture::QL_best) {
if (minfilter == Texture::FT_default) {
minfilter = Texture::FT_linear;
}
if (magfilter == Texture::FT_default) {
magfilter = Texture::FT_linear;
}
minfilter = texture->get_effective_minfilter();
magfilter = texture->get_effective_magfilter();
}
texture_def->tex_minfilter_func = get_tex_filter_func(minfilter);